svn commit: r212118 - in stable/7: bin/sh
tools/regression/bin/sh/expansion
Jilles Tjoelker
jilles at FreeBSD.org
Wed Sep 1 21:51:29 UTC 2010
Author: jilles
Date: Wed Sep 1 21:51:29 2010
New Revision: 212118
URL: http://svn.freebsd.org/changeset/base/212118
Log:
MFC r211155: sh: Fix heap-based buffer overflow in pathname generation.
The buffer for generated pathnames could be too small in some cases. It
happened to be always at least PATH_MAX long, so there was never an overflow
if the resulting pathnames would be usable.
This bug may be abused if a script subjects input from an untrusted source
to pathname generation, which a bad idea anyhow. Most shell scripts do not
work on untrusted data. secteam@ says no advisory is necessary.
PR: bin/148733
Reported by: Changming Sun snnn119 at gmail com
Added:
stable/7/tools/regression/bin/sh/expansion/pathname3.0
- copied unchanged from r211155, head/tools/regression/bin/sh/expansion/pathname3.0
Modified:
stable/7/bin/sh/expand.c
Directory Properties:
stable/7/bin/sh/ (props changed)
stable/7/tools/regression/bin/sh/ (props changed)
Modified: stable/7/bin/sh/expand.c
==============================================================================
--- stable/7/bin/sh/expand.c Wed Sep 1 21:44:36 2010 (r212117)
+++ stable/7/bin/sh/expand.c Wed Sep 1 21:51:29 2010 (r212118)
@@ -1054,8 +1054,8 @@ ifsbreakup(char *string, struct arglist
* should be escapes. The results are stored in the list exparg.
*/
-STATIC char *expdir;
-
+STATIC char expdir[PATH_MAX];
+#define expdir_end (expdir + sizeof(expdir))
STATIC void
expandmeta(struct strlist *str, int flag __unused)
@@ -1078,14 +1078,7 @@ expandmeta(struct strlist *str, int flag
}
savelastp = exparg.lastp;
INTOFF;
- if (expdir == NULL) {
- int i = strlen(str->text);
- expdir = ckmalloc(i < 2048 ? 2048 : i); /* XXX */
- }
-
expmeta(expdir, str->text);
- ckfree(expdir);
- expdir = NULL;
INTON;
if (exparg.lastp == savelastp) {
/*
@@ -1174,6 +1167,8 @@ expmeta(char *enddir, char *name)
*enddir++ = *p;
if (*p == '\0')
break;
+ if (enddir == expdir_end)
+ return;
}
if (metaflag == 0 || lstat(expdir, &statb) >= 0)
addfname(expdir);
@@ -1188,6 +1183,8 @@ expmeta(char *enddir, char *name)
if (*p == CTLESC)
p++;
*enddir++ = *p++;
+ if (enddir == expdir_end)
+ return;
}
}
if (enddir == expdir) {
@@ -1221,15 +1218,17 @@ expmeta(char *enddir, char *name)
if (dp->d_name[0] == '.' && ! matchdot)
continue;
if (patmatch(start, dp->d_name, 0)) {
- if (atend) {
- scopy(dp->d_name, enddir);
+ if (enddir + dp->d_namlen + 1 > expdir_end)
+ continue;
+ memcpy(enddir, dp->d_name, dp->d_namlen + 1);
+ if (atend)
addfname(expdir);
- } else {
- for (p = enddir, q = dp->d_name;
- (*p++ = *q++) != '\0';)
+ else {
+ if (enddir + dp->d_namlen + 2 > expdir_end)
continue;
- p[-1] = '/';
- expmeta(p, endname);
+ enddir[dp->d_namlen] = '/';
+ enddir[dp->d_namlen + 1] = '\0';
+ expmeta(enddir + dp->d_namlen + 1, endname);
}
}
}
Copied: stable/7/tools/regression/bin/sh/expansion/pathname3.0 (from r211155, head/tools/regression/bin/sh/expansion/pathname3.0)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ stable/7/tools/regression/bin/sh/expansion/pathname3.0 Wed Sep 1 21:51:29 2010 (r212118, copy of r211155, head/tools/regression/bin/sh/expansion/pathname3.0)
@@ -0,0 +1,29 @@
+# $FreeBSD$
+
+v=12345678
+v=$v$v$v$v
+v=$v$v$v$v
+v=$v$v$v$v
+v=$v$v$v$v
+v=$v$v$v$v
+# 8192 bytes
+v=${v##???}
+[ /*/$v = "/*/$v" ] || exit 1
+
+s=////
+s=$s$s$s$s
+s=$s$s$s$s
+s=$s$s$s$s
+s=$s$s$s$s
+# 1024 bytes
+s=${s##??????????}
+[ /var/empt[y]/$s/$v = "/var/empt[y]/$s/$v" ] || exit 2
+while [ ${#s} -lt 1034 ]; do
+ set -- /.${s}et[c]
+ [ ${#s} -gt 1018 ] || [ "$1" = /.${s}etc ] || exit 3
+ set -- /.${s}et[c]/
+ [ ${#s} -gt 1017 ] || [ "$1" = /.${s}etc/ ] || exit 4
+ set -- /.${s}et[c]/.
+ [ ${#s} -gt 1016 ] || [ "$1" = /.${s}etc/. ] || exit 5
+ s=$s/
+done
More information about the svn-src-all
mailing list