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-stable
mailing list