svn commit: r287266 - stable/10/usr.bin/find

Jilles Tjoelker jilles at FreeBSD.org
Fri Aug 28 20:53:09 UTC 2015


Author: jilles
Date: Fri Aug 28 20:53:08 2015
New Revision: 287266
URL: https://svnweb.freebsd.org/changeset/base/287266

Log:
  MFC r286344: find: Fix segfault with very long path in -exec/-ok ... {} \;.
  
  If the resulting argument is longer than MAXPATHLEN, realloc() was called to
  extend the space, but the new pointer was not correctly stored.
  
  Different from what OpenBSD has done, rewrite brace_subst() to calculate the
  necessary space first and realloc() at most once.
  
  As before, the e_len fields are not updated in case of a realloc.
  Therefore, a following long argument will do another realloc.
  
  PR:		201750

Modified:
  stable/10/usr.bin/find/extern.h
  stable/10/usr.bin/find/misc.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/usr.bin/find/extern.h
==============================================================================
--- stable/10/usr.bin/find/extern.h	Fri Aug 28 20:06:58 2015	(r287265)
+++ stable/10/usr.bin/find/extern.h	Fri Aug 28 20:53:08 2015	(r287266)
@@ -32,7 +32,7 @@
 
 #include <sys/cdefs.h>
 
-void	 brace_subst(char *, char **, char *, int);
+void	 brace_subst(char *, char **, char *, size_t);
 PLAN	*find_create(char ***);
 int	 find_execute(PLAN *, char **);
 PLAN	*find_formplan(char **);

Modified: stable/10/usr.bin/find/misc.c
==============================================================================
--- stable/10/usr.bin/find/misc.c	Fri Aug 28 20:06:58 2015	(r287265)
+++ stable/10/usr.bin/find/misc.c	Fri Aug 28 20:53:08 2015	(r287266)
@@ -57,23 +57,33 @@ __FBSDID("$FreeBSD$");
  *	Replace occurrences of {} in s1 with s2 and return the result string.
  */
 void
-brace_subst(char *orig, char **store, char *path, int len)
+brace_subst(char *orig, char **store, char *path, size_t len)
 {
-	int plen;
-	char ch, *p;
+	const char *pastorigend, *p, *q;
+	char *dst;
+	size_t newlen, plen;
 
 	plen = strlen(path);
-	for (p = *store; (ch = *orig) != '\0'; ++orig)
-		if (ch == '{' && orig[1] == '}') {
-			while ((p - *store) + plen > len)
-				if (!(*store = realloc(*store, len *= 2)))
-					err(1, NULL);
-			memmove(p, path, plen);
-			p += plen;
-			++orig;
-		} else
-			*p++ = ch;
-	*p = '\0';
+	newlen = strlen(orig) + 1;
+	pastorigend = orig + newlen;
+	for (p = orig; (q = strstr(p, "{}")) != NULL; p = q + 2) {
+		if (plen > 2 && newlen + plen - 2 < newlen)
+			errx(2, "brace_subst overflow");
+		newlen += plen - 2;
+	}
+	if (newlen > len) {
+		*store = reallocf(*store, newlen);
+		if (*store == NULL)
+			err(2, NULL);
+	}
+	dst = *store;
+	for (p = orig; (q = strstr(p, "{}")) != NULL; p = q + 2) {
+		memcpy(dst, p, q - p);
+		dst += q - p;
+		memcpy(dst, path, plen);
+		dst += plen;
+	}
+	memcpy(dst, p, pastorigend - p);
 }
 
 /*


More information about the svn-src-all mailing list