summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>1997-04-12 19:05:49 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>1997-04-12 19:05:49 +0000
commit22f018e0eac226f6b4c1ab2faaf0f9b223d99743 (patch)
tree2ca399d9ae713a54ae5bb3c116d32ca3e8b19d0a
parent3ca9daaf8cc60f08d9a19a9f176866173e5398b7 (diff)
Different fix for buffer overflow. From Keith Bostic <bostic@bostic.com>
-rw-r--r--lib/libc/gen/glob.c74
1 files changed, 39 insertions, 35 deletions
diff --git a/lib/libc/gen/glob.c b/lib/libc/gen/glob.c
index 21abf96c730..ce5874bc023 100644
--- a/lib/libc/gen/glob.c
+++ b/lib/libc/gen/glob.c
@@ -35,7 +35,11 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char rcsid[] = "$OpenBSD: glob.c,v 1.4 1996/10/27 17:46:40 deraadt Exp $";
+#if 0
+static char sccsid[] = "@(#)glob.c 8.3 (Berkeley) 10/13/93";
+#else
+static char rcsid[] = "$OpenBSD: glob.c,v 1.5 1997/04/12 19:05:48 millert Exp $";
+#endif
#endif /* LIBC_SCCS and not lint */
/*
@@ -58,7 +62,7 @@ static char rcsid[] = "$OpenBSD: glob.c,v 1.4 1996/10/27 17:46:40 deraadt Exp $"
* GLOB_TILDE:
* expand ~user/foo to the /home/dir/of/user/foo
* GLOB_BRACE:
- * expand {1,2}{a,b} to 1a 1b 2a 2b
+ * expand {1,2}{a,b} to 1a 1b 2a 2b
* gl_matchc:
* Number of matches in the current invocation of glob.
*/
@@ -140,7 +144,7 @@ static int glob1 __P((Char *, glob_t *));
static int glob2 __P((Char *, Char *, Char *, glob_t *));
static int glob3 __P((Char *, Char *, Char *, Char *, glob_t *));
static int globextend __P((const Char *, glob_t *));
-static const Char * globtilde __P((const Char *, Char *, glob_t *));
+static const Char * globtilde __P((const Char *, Char *, size_t, glob_t *));
static int globexp1 __P((const Char *, glob_t *));
static int globexp2 __P((const Char *, const Char *, glob_t *, int *));
static int match __P((Char *, Char *, Char *));
@@ -173,7 +177,7 @@ glob(pattern, flags, errfunc, pglob)
bufend = bufnext + MAXPATHLEN;
if (flags & GLOB_QUOTE) {
/* Protect the quoted characters. */
- while (bufnext < bufend && (c = *patnext++) != EOS)
+ while (bufnext < bufend && (c = *patnext++) != EOS)
if (c == QUOTE) {
if ((c = *patnext++) == EOS) {
c = QUOTE;
@@ -184,8 +188,8 @@ glob(pattern, flags, errfunc, pglob)
else
*bufnext++ = c;
}
- else
- while (bufnext < bufend && (c = *patnext++) != EOS)
+ else
+ while (bufnext < bufend && (c = *patnext++) != EOS)
*bufnext++ = c;
*bufnext = EOS;
@@ -246,7 +250,7 @@ static int globexp2(ptr, pattern, pglob, rv)
for (pm = pe++; *pe != RBRACKET && *pe != EOS; pe++)
continue;
if (*pe == EOS) {
- /*
+ /*
* We could not find a matching RBRACKET.
* Ignore and just look for RBRACE
*/
@@ -274,7 +278,7 @@ static int globexp2(ptr, pattern, pglob, rv)
for (pl = pm++; *pm != RBRACKET && *pm != EOS; pm++)
continue;
if (*pm == EOS) {
- /*
+ /*
* We could not find a matching RBRACKET.
* Ignore and just look for RBRACE
*/
@@ -299,7 +303,7 @@ static int globexp2(ptr, pattern, pglob, rv)
/* Append the current string */
for (lm = ls; (pl < pm); *lm++ = *pl++)
continue;
- /*
+ /*
* Append the rest of the pattern after the
* closing brace
*/
@@ -330,29 +334,31 @@ static int globexp2(ptr, pattern, pglob, rv)
* expand tilde from the passwd file.
*/
static const Char *
-globtilde(pattern, patbuf, pglob)
+globtilde(pattern, patbuf, patbuf_len, pglob)
const Char *pattern;
Char *patbuf;
+ size_t patbuf_len;
glob_t *pglob;
{
struct passwd *pwd;
char *h;
const Char *p;
- Char *b;
+ Char *b, *eb;
if (*pattern != TILDE || !(pglob->gl_flags & GLOB_TILDE))
return pattern;
/* Copy up to the end of the string or / */
- for (p = pattern + 1, h = (char *) patbuf; *p && *p != SLASH;
- *h++ = *p++)
+ eb = &patbuf[patbuf_len - 1];
+ for (p = pattern + 1, h = (char *) patbuf;
+ h < (char *)eb && *p && *p != SLASH; *h++ = *p++)
continue;
*h = EOS;
if (((char *) patbuf)[0] == EOS) {
- /*
- * handle a plain ~ or ~/ by expanding $HOME
+ /*
+ * handle a plain ~ or ~/ by expanding $HOME
* first and then trying the password file
*/
if (issetugid() != 0 || (h = getenv("HOME")) == NULL) {
@@ -360,9 +366,6 @@ globtilde(pattern, patbuf, pglob)
return pattern;
else
h = pwd->pw_dir;
- } else {
- if (strlen(h) >= MAXPATHLEN-1)
- return pattern;
}
}
else {
@@ -376,16 +379,17 @@ globtilde(pattern, patbuf, pglob)
}
/* Copy the home directory */
- for (b = patbuf; *h; *b++ = *h++)
+ for (b = patbuf; b < eb && *h; *b++ = *h++)
continue;
-
+
/* Append the rest of the pattern */
- while ((*b++ = *p++) != EOS)
+ while (b < eb && (*b++ = *p++) != EOS)
continue;
+ *b = EOS;
return patbuf;
}
-
+
/*
* The main glob() routine: compiles the pattern (optionally processing
@@ -403,7 +407,8 @@ glob0(pattern, pglob)
int c, err, oldpathc;
Char *bufnext, patbuf[MAXPATHLEN+1];
- qpatnext = globtilde(pattern, patbuf, pglob);
+ qpatnext = globtilde(pattern, patbuf, sizeof(patbuf) / sizeof(Char),
+ pglob);
oldpathc = pglob->gl_pathc;
bufnext = patbuf;
@@ -443,7 +448,7 @@ glob0(pattern, pglob)
break;
case STAR:
pglob->gl_flags |= GLOB_MAGCHAR;
- /* collapse adjacent stars to one,
+ /* collapse adjacent stars to one,
* to avoid exponential behavior
*/
if (bufnext == patbuf || bufnext[-1] != M_ALL)
@@ -463,17 +468,17 @@ glob0(pattern, pglob)
return(err);
/*
- * If there was no match we are going to append the pattern
+ * If there was no match we are going to append the pattern
* if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was specified
* and the pattern did not contain any magic characters
* GLOB_NOMAGIC is there just for compatibility with csh.
*/
- if (pglob->gl_pathc == oldpathc &&
- ((pglob->gl_flags & GLOB_NOCHECK) ||
+ if (pglob->gl_pathc == oldpathc &&
+ ((pglob->gl_flags & GLOB_NOCHECK) ||
((pglob->gl_flags & GLOB_NOMAGIC) &&
!(pglob->gl_flags & GLOB_MAGCHAR))))
return(globextend(pattern, pglob));
- else if (!(pglob->gl_flags & GLOB_NOSORT))
+ else if (!(pglob->gl_flags & GLOB_NOSORT))
qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc,
pglob->gl_pathc - oldpathc, sizeof(char *), compare);
return(0);
@@ -522,7 +527,7 @@ glob2(pathbuf, pathend, pattern, pglob)
*pathend = EOS;
if (g_lstat(pathbuf, &sb, pglob))
return(0);
-
+
if (((pglob->gl_flags & GLOB_MARK) &&
pathend[-1] != SEP) && (S_ISDIR(sb.st_mode)
|| (S_ISLNK(sb.st_mode) &&
@@ -575,7 +580,7 @@ glob3(pathbuf, pathend, pattern, restpattern, pglob)
*pathend = EOS;
errno = 0;
-
+
if ((dirp = g_opendir(pathbuf, pglob)) == NULL) {
/* TODO: don't call for ENOENT or ENOTDIR? */
if (pglob->gl_errfunc) {
@@ -601,7 +606,7 @@ glob3(pathbuf, pathend, pattern, restpattern, pglob)
/* Initial DOT must be matched literally. */
if (dp->d_name[0] == DOT && *pattern != DOT)
continue;
- for (sc = (u_char *) dp->d_name, dc = pathend;
+ for (sc = (u_char *) dp->d_name, dc = pathend;
(*dc++ = *sc++) != EOS;)
continue;
if (!match(pathend, pattern, restpattern)) {
@@ -647,7 +652,7 @@ globextend(path, pglob)
const Char *p;
newsize = sizeof(*pathv) * (2 + pglob->gl_pathc + pglob->gl_offs);
- pathv = pglob->gl_pathv ?
+ pathv = pglob->gl_pathv ?
realloc((char *)pglob->gl_pathv, newsize) :
malloc(newsize);
if (pathv == NULL)
@@ -671,7 +676,6 @@ globextend(path, pglob)
return(copy == NULL ? GLOB_NOSPACE : 0);
}
-
/*
* pattern matching function for filenames. Each occurrence of the *
* pattern causes a recursion level.
@@ -689,7 +693,7 @@ match(name, pat, patend)
case M_ALL:
if (pat == patend)
return(1);
- do
+ do
if (match(name, pat, patend))
return(1);
while (*name++ != EOS);
@@ -828,7 +832,7 @@ g_Ctoc(str, buf)
}
#ifdef DEBUG
-static void
+static void
qprintf(str, s)
const char *str;
register Char *s;