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

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