Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/netbsd-1-4]: src/lib/libc/gen Pull up revisions 1.11-1.20 (requested by ...
details: https://anonhg.NetBSD.org/src/rev/2282bd0dcd0c
branches: netbsd-1-4
changeset: 471277:2282bd0dcd0c
user: he <he%NetBSD.org@localhost>
date: Sun Apr 01 16:07:40 2001 +0000
description:
Pull up revisions 1.11-1.20 (requested by christos):
Fixes buffer overflow problems in glob(3). Adds and uses GLOB_LIMIT
to prevent denial of service attacks.
(syncs to current head of trunk).
diffstat:
lib/libc/gen/__glob13.c | 240 +++++++++++++++++++++++++++++++++--------------
1 files changed, 169 insertions(+), 71 deletions(-)
diffs (truncated from 585 to 300 lines):
diff -r 0ca18ab625df -r 2282bd0dcd0c lib/libc/gen/__glob13.c
--- a/lib/libc/gen/__glob13.c Sun Apr 01 16:07:04 2001 +0000
+++ b/lib/libc/gen/__glob13.c Sun Apr 01 16:07:40 2001 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: __glob13.c,v 1.10 1999/02/07 12:19:37 lukem Exp $ */
+/* $NetBSD: __glob13.c,v 1.10.2.1 2001/04/01 16:07:40 he Exp $ */
/*
* Copyright (c) 1989, 1993
@@ -41,7 +41,7 @@
#if 0
static char sccsid[] = "@(#)glob.c 8.3 (Berkeley) 10/13/93";
#else
-__RCSID("$NetBSD: __glob13.c,v 1.10 1999/02/07 12:19:37 lukem Exp $");
+__RCSID("$NetBSD: __glob13.c,v 1.10.2.1 2001/04/01 16:07:40 he Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
@@ -71,6 +71,7 @@
#include <sys/param.h>
#include <sys/stat.h>
+#include <assert.h>
#include <ctype.h>
#include <dirent.h>
#include <errno.h>
@@ -83,11 +84,18 @@
#ifdef __weak_alias
#ifdef __LIBC12_SOURCE__
-__weak_alias(glob,_glob);
-__weak_alias(globfree,_globfree);
+__weak_alias(glob,_glob)
+__weak_alias(globfree,_globfree)
#endif /* __LIBC12_SOURCE__ */
#endif /* __weak_alias */
+/*
+ * XXX: For NetBSD 1.4.x compatibility. (kill me l8r)
+ */
+#ifndef _DIAGASSERT
+#define _DIAGASSERT(a)
+#endif
+
#ifdef __LIBC12_SOURCE__
#define STAT stat12
#else
@@ -152,20 +160,18 @@
static int compare __P((const void *, const void *));
-static void g_Ctoc __P((const Char *, char *));
+static int g_Ctoc __P((const Char *, char *, size_t));
static int g_lstat __P((Char *, struct STAT *, glob_t *));
static DIR *g_opendir __P((Char *, glob_t *));
static Char *g_strchr __P((const Char *, int));
-#ifdef notdef
-static Char *g_strcat __P((Char *, const Char *));
-#endif
static int g_stat __P((Char *, struct STAT *, glob_t *));
static int glob0 __P((const Char *, glob_t *));
-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 int glob1 __P((Char *, glob_t *, size_t *));
+static int glob2 __P((Char *, Char *, Char *, glob_t *, size_t *));
+static int glob3 __P((Char *, Char *, Char *, Char *, glob_t *,
+ size_t *));
+static int globextend __P((const Char *, glob_t *, size_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 *));
@@ -183,6 +189,8 @@
int c;
Char *bufnext, *bufend, patbuf[MAXPATHLEN+1];
+ _DIAGASSERT(pattern != NULL);
+
patnext = (const u_char *) pattern;
if (!(flags & GLOB_APPEND)) {
pglob->gl_pathc = 0;
@@ -197,8 +205,8 @@
bufnext = patbuf;
bufend = bufnext + MAXPATHLEN;
if (flags & GLOB_NOESCAPE) {
- while (bufnext < bufend && (c = *patnext++) != EOS)
- *bufnext++ = c;
+ while (bufnext < bufend && (c = *patnext++) != EOS)
+ *bufnext++ = c;
} else {
/* Protect the quoted characters. */
while (bufnext < bufend && (c = *patnext++) != EOS)
@@ -225,13 +233,17 @@
* invoke the standard globbing routine to glob the rest of the magic
* characters
*/
-static int globexp1(pattern, pglob)
+static int
+globexp1(pattern, pglob)
const Char *pattern;
glob_t *pglob;
{
const Char* ptr = pattern;
int rv;
+ _DIAGASSERT(pattern != NULL);
+ _DIAGASSERT(pglob != NULL);
+
/* Protect a single {}, for find(1), like csh */
if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS)
return glob0(pattern, pglob);
@@ -249,7 +261,8 @@
* If it succeeds then it invokes globexp1 with the new pattern.
* If it fails then it tries to glob the rest of the pattern and returns.
*/
-static int globexp2(ptr, pattern, pglob, rv)
+static int
+globexp2(ptr, pattern, pglob, rv)
const Char *ptr, *pattern;
glob_t *pglob;
int *rv;
@@ -259,6 +272,11 @@
const Char *pe, *pm, *pl;
Char patbuf[MAXPATHLEN + 1];
+ _DIAGASSERT(ptr != NULL);
+ _DIAGASSERT(pattern != NULL);
+ _DIAGASSERT(pglob != NULL);
+ _DIAGASSERT(rv != NULL);
+
/* copy part up to the brace */
for (lm = patbuf, pm = pattern; pm != ptr; *lm++ = *pm++)
continue;
@@ -292,7 +310,7 @@
return 0;
}
- for (i = 0, pl = pm = ptr; pm <= pe; pm++)
+ for (i = 0, pl = pm = ptr; pm <= pe; pm++) {
switch (*pm) {
case LBRACKET:
/* Ignore everything between [] */
@@ -313,8 +331,8 @@
case RBRACE:
if (i) {
- i--;
- break;
+ i--;
+ break;
}
/* FALLTHROUGH */
case COMMA:
@@ -345,6 +363,7 @@
default:
break;
}
+ }
*rv = 0;
return 0;
}
@@ -355,9 +374,10 @@
* expand tilde from the passwd file.
*/
static const Char *
-globtilde(pattern, patbuf, pglob)
+globtilde(pattern, patbuf, patsize, pglob)
const Char *pattern;
Char *patbuf;
+ size_t patsize;
glob_t *pglob;
{
struct passwd *pwd;
@@ -365,15 +385,26 @@
const Char *p;
Char *b;
char *d;
+ Char *pend = &patbuf[patsize];
+
+ pend--;
+
+ _DIAGASSERT(pattern != NULL);
+ _DIAGASSERT(patbuf != NULL);
+ _DIAGASSERT(pglob != NULL);
if (*pattern != TILDE || !(pglob->gl_flags & GLOB_TILDE))
return pattern;
/* Copy up to the end of the string or / */
- for (p = pattern + 1, d = (char *)(void *)patbuf; *p && *p != SLASH;
+ for (p = pattern + 1, d = (char *)(void *)patbuf;
+ d < (char *)(void *)pend && *p && *p != SLASH;
*d++ = *p++)
continue;
+ if (d == (char *)(void *)pend)
+ return NULL;
+
*d = EOS;
d = (char *)(void *)patbuf;
@@ -400,13 +431,19 @@
}
/* Copy the home directory */
- for (b = patbuf; *h; *b++ = *h++)
+ for (b = patbuf; b < pend && *h; *b++ = *h++)
continue;
+
+ if (b == pend)
+ return NULL;
/* Append the rest of the pattern */
- while ((*b++ = *p++) != EOS)
+ while (b < pend && (*b++ = *p++) != EOS)
continue;
+ if (b == pend)
+ return NULL;
+
return patbuf;
}
@@ -426,8 +463,13 @@
const Char *qpatnext;
int c, err, oldpathc;
Char *bufnext, patbuf[MAXPATHLEN+1];
+ size_t limit = 0;
- qpatnext = globtilde(pattern, patbuf, pglob);
+ _DIAGASSERT(pattern != NULL);
+ _DIAGASSERT(pglob != NULL);
+
+ if ((qpatnext = globtilde(pattern, patbuf, sizeof(patbuf), pglob)) == NULL)
+ return GLOB_ABEND;
oldpathc = pglob->gl_pathc;
bufnext = patbuf;
@@ -471,7 +513,7 @@
* to avoid exponential behavior
*/
if (bufnext == patbuf || bufnext[-1] != M_ALL)
- *bufnext++ = M_ALL;
+ *bufnext++ = M_ALL;
break;
default:
*bufnext++ = CHAR(c);
@@ -483,7 +525,7 @@
qprintf("glob0:", patbuf);
#endif
- if ((err = glob1(patbuf, pglob)) != 0)
+ if ((err = glob1(patbuf, pglob, &limit)) != 0)
return(err);
if (pglob->gl_pathc == oldpathc) {
@@ -497,7 +539,7 @@
if ((pglob->gl_flags & GLOB_NOCHECK) ||
((pglob->gl_flags & (GLOB_NOMAGIC|GLOB_MAGCHAR))
== GLOB_NOMAGIC)) {
- if ((err = globextend(pattern, pglob)) != 0)
+ if ((err = globextend(pattern, pglob, &limit)) != 0)
return (err);
} else {
return (GLOB_NOMATCH);
@@ -515,20 +557,28 @@
compare(p, q)
const void *p, *q;
{
+
+ _DIAGASSERT(p != NULL);
+ _DIAGASSERT(q != NULL);
+
return(strcoll(*(const char * const *)p, *(const char * const *)q));
}
static int
-glob1(pattern, pglob)
+glob1(pattern, pglob, limit)
Char *pattern;
glob_t *pglob;
+ size_t *limit;
{
Char pathbuf[MAXPATHLEN+1];
+ _DIAGASSERT(pattern != NULL);
+ _DIAGASSERT(pglob != NULL);
+
/* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */
if (*pattern == EOS)
return(0);
- return(glob2(pathbuf, pathbuf, pattern, pglob));
+ return(glob2(pathbuf, pathbuf, pattern, pglob, limit));
}
/*
@@ -537,14 +587,20 @@
Home |
Main Index |
Thread Index |
Old Index