Blame SOURCES/autofs-5.1.0-fix-incorrect-check-in-parse_mount.patch

516ab0
autofs-5.1.0 - fix incorrect check in parse_mount()
516ab0
516ab0
From: Ian Kent <ikent@redhat.com>
516ab0
516ab0
The change to allow the use of the hosts map in map entries introduced
516ab0
an invalid check into parse_mount(). The case attempts to check the
516ab0
contents of an options string that is always invalid for the return
516ab0
value case in which it is checked, not to mention the check itself is
516ab0
incorrect.
516ab0
---
516ab0
 CHANGELOG           |    1 
516ab0
 modules/parse_sun.c |   70 ++++++++++++++++++++++++++++++++--------------------
516ab0
 2 files changed, 45 insertions(+), 26 deletions(-)
516ab0
516ab0
--- autofs-5.0.7.orig/CHANGELOG
516ab0
+++ autofs-5.0.7/CHANGELOG
516ab0
@@ -164,6 +164,7 @@
516ab0
 - dont add wildcard to negative cache.
516ab0
 - add a prefix to program map stdvars.
516ab0
 - add config option to force use of program map stdvars.
516ab0
+- fix incorrect check in parse_mount().
516ab0
 
516ab0
 25/07/2012 autofs-5.0.7
516ab0
 =======================
516ab0
--- autofs-5.0.7.orig/modules/parse_sun.c
516ab0
+++ autofs-5.0.7/modules/parse_sun.c
516ab0
@@ -756,6 +756,8 @@ update_offset_entry(struct autofs_point
516ab0
 
516ab0
 	mc = source->mc;
516ab0
 
516ab0
+	memset(m_mapent, 0, MAPENT_MAX_LEN + 1);
516ab0
+
516ab0
 	/* Internal hosts map may have loc == NULL */
516ab0
 	if (!*path) {
516ab0
 		error(ap->logopt,
516ab0
@@ -782,7 +784,7 @@ update_offset_entry(struct autofs_point
516ab0
 	if (*myoptions)
516ab0
 		m_options_len = strlen(myoptions) + 2;
516ab0
 
516ab0
-	m_mapent_len = strlen(loc);
516ab0
+	m_mapent_len = loc ? strlen(loc) : 0;
516ab0
 	if (m_mapent_len + m_options_len > MAPENT_MAX_LEN) {
516ab0
 		error(ap->logopt, MODPREFIX "multi mount mapent too long");
516ab0
 		return CHE_FAIL;
516ab0
@@ -793,10 +795,13 @@ update_offset_entry(struct autofs_point
516ab0
 		strcat(m_mapent, myoptions);
516ab0
 		if (loc) {
516ab0
 			strcat(m_mapent, " ");
516ab0
-			strcat(m_mapent, loc);
516ab0
+			if (loc)
516ab0
+				strcat(m_mapent, loc);
516ab0
 		}
516ab0
-	} else
516ab0
-		strcpy(m_mapent, loc);
516ab0
+	} else {
516ab0
+		if (loc)
516ab0
+			strcpy(m_mapent, loc);
516ab0
+	}
516ab0
 
516ab0
 	ret = cache_update_offset(mc, name, m_key, m_mapent, age);
516ab0
 	if (ret == CHE_DUPLICATE)
516ab0
@@ -923,9 +928,15 @@ static int parse_mapent(const char *ent,
516ab0
 	l = chunklen(p, check_colon(p));
516ab0
 	loc = dequote(p, l, logopt);
516ab0
 	if (!loc) {
516ab0
-		warn(logopt, MODPREFIX "possible missing location");
516ab0
-		free(myoptions);
516ab0
-		return 0;
516ab0
+		if (strstr(myoptions, "fstype=autofs") &&
516ab0
+		    strstr(myoptions, "hosts")) {
516ab0
+			warn(logopt, MODPREFIX "possible missing location");
516ab0
+			free(myoptions);
516ab0
+			return 0;
516ab0
+		}
516ab0
+		*options = myoptions;
516ab0
+		*location = NULL;
516ab0
+		return (p - ent);
516ab0
 	}
516ab0
 
516ab0
 	/* Location can't begin with a '/' */
516ab0
@@ -953,10 +964,15 @@ static int parse_mapent(const char *ent,
516ab0
 		l = chunklen(p, check_colon(p));
516ab0
 		ent_chunk = dequote(p, l, logopt);
516ab0
 		if (!ent_chunk) {
516ab0
-			warn(logopt, MODPREFIX "null location or out of memory");
516ab0
-			free(myoptions);
516ab0
-			free(loc);
516ab0
-			return 0;
516ab0
+			if (strstr(myoptions, "fstype=autofs") &&
516ab0
+			    strstr(myoptions, "hosts")) {
516ab0
+				warn(logopt, MODPREFIX
516ab0
+				     "null location or out of memory");
516ab0
+				free(myoptions);
516ab0
+				free(loc);
516ab0
+				return 0;
516ab0
+			}
516ab0
+			goto next;
516ab0
 		}
516ab0
 
516ab0
 		/* Location can't begin with a '/' */
516ab0
@@ -992,7 +1008,7 @@ static int parse_mapent(const char *ent,
516ab0
 		strcat(loc, ent_chunk);
516ab0
 
516ab0
 		free(ent_chunk);
516ab0
-
516ab0
+next:
516ab0
 		p += l;
516ab0
 		p = skipspace(p);
516ab0
 	}
516ab0
@@ -1093,7 +1109,9 @@ static int mount_subtree(struct autofs_p
516ab0
 				cache_delete_offset_list(me->mc, name);
516ab0
 				return 1;
516ab0
 			}
516ab0
-			ro_len = strlen(ro_loc);
516ab0
+			ro_len = 0;
516ab0
+			if (ro_loc)
516ab0
+				ro_len = strlen(ro_loc);
516ab0
 
516ab0
 			tmp = alloca(mnt_root_len + 2);
516ab0
 			strcpy(tmp, mnt_root);
516ab0
@@ -1104,7 +1122,8 @@ static int mount_subtree(struct autofs_p
516ab0
 			rv = sun_mount(ap, root, name, namelen, ro_loc, ro_len, myoptions, ctxt);
516ab0
 
516ab0
 			free(myoptions);
516ab0
-			free(ro_loc);
516ab0
+			if (ro_loc)
516ab0
+				free(ro_loc);
516ab0
 		}
516ab0
 
516ab0
 		if (ro && rv == 0) {
516ab0
@@ -1420,16 +1439,13 @@ int parse_mount(struct autofs_point *ap,
516ab0
 
516ab0
 			l = parse_mapent(p, options, &myoptions, &loc, ap->logopt);
516ab0
 			if (!l) {
516ab0
-				if (!(strstr(myoptions, "fstype=autofs") &&
516ab0
-				      strstr(myoptions, "hosts"))) {
516ab0
-					cache_delete_offset_list(mc, name);
516ab0
-					cache_multi_unlock(me);
516ab0
-					cache_unlock(mc);
516ab0
-					free(path);
516ab0
-					free(options);
516ab0
-					pthread_setcancelstate(cur_state, NULL);
516ab0
-					return 1;
516ab0
-				}
516ab0
+				cache_delete_offset_list(mc, name);
516ab0
+				cache_multi_unlock(me);
516ab0
+				cache_unlock(mc);
516ab0
+				free(path);
516ab0
+				free(options);
516ab0
+				pthread_setcancelstate(cur_state, NULL);
516ab0
+				return 1;
516ab0
 			}
516ab0
 
516ab0
 			p += l;
516ab0
@@ -1450,12 +1466,14 @@ int parse_mount(struct autofs_point *ap,
516ab0
 				free(path);
516ab0
 				free(options);
516ab0
 				free(myoptions);
516ab0
-				free(loc);
516ab0
+				if (loc)
516ab0
+					free(loc);
516ab0
 				pthread_setcancelstate(cur_state, NULL);
516ab0
 				return 1;
516ab0
 			}
516ab0
 
516ab0
-			free(loc);
516ab0
+			if (loc)
516ab0
+				free(loc);
516ab0
 			free(path);
516ab0
 			free(myoptions);
516ab0
 		} while (*p == '/' || (*p == '"' && *(p + 1) == '/'));