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

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