summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2001-05-15 21:14:40 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2001-05-15 21:14:40 +0000
commit702c312cb2831ffe553edec88356e10045e393dc (patch)
tree4a2502c33d39858af039f48178358183b02c5015
parent58f7e38be96df800e8b4421a044937182e3679b5 (diff)
Make path length variables size_t. This fixes the problem where
things like rm can't remove files with ridiculously long path names that were created by some script kiddie trying in vain to exploit something. Previously, the length was effectively constrained to USHRT_MAX due to one of the internal structs. Also, nuke FTS_CHDIRROOT since it never worked correctly and hasn't been documented for a long time.
-rw-r--r--include/fts.h11
-rw-r--r--lib/libc/gen/fts.36
-rw-r--r--lib/libc/gen/fts.c120
-rw-r--r--lib/libc/shlib_version4
-rw-r--r--lib/libc_r/shlib_version4
5 files changed, 64 insertions, 81 deletions
diff --git a/include/fts.h b/include/fts.h
index fdb89c58c1e..eb40c7a14d9 100644
--- a/include/fts.h
+++ b/include/fts.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: fts.h,v 1.5 1999/10/03 20:39:52 millert Exp $ */
+/* $OpenBSD: fts.h,v 1.6 2001/05/15 21:14:37 millert Exp $ */
/* $NetBSD: fts.h,v 1.5 1994/12/28 01:41:50 mycroft Exp $ */
/*
@@ -46,7 +46,7 @@ typedef struct {
dev_t fts_dev; /* starting device # */
char *fts_path; /* path for this descent */
int fts_rfd; /* fd for root */
- int fts_pathlen; /* sizeof(path) */
+ size_t fts_pathlen; /* sizeof(path) */
int fts_nitems; /* elements in the sort array */
int (*fts_compar)(); /* compare function */
@@ -58,8 +58,7 @@ typedef struct {
#define FTS_SEEDOT 0x0020 /* return dot and dot-dot */
#define FTS_XDEV 0x0040 /* don't cross devices */
#define FTS_WHITEOUT 0x0080 /* return whiteout information */
-#define FTS_CHDIRROOT 0x0100 /* chdir to root of tree not orig cwd */
-#define FTS_OPTIONMASK 0x0fff /* valid user option mask */
+#define FTS_OPTIONMASK 0x00ff /* valid user option mask */
#define FTS_NAMEONLY 0x1000 /* (private) child names only */
#define FTS_STOP 0x2000 /* (private) unrecoverable error */
@@ -76,8 +75,8 @@ typedef struct _ftsent {
char *fts_path; /* root path */
int fts_errno; /* errno for this node */
int fts_symfd; /* fd for symlink */
- u_short fts_pathlen; /* strlen(fts_path) */
- u_short fts_namelen; /* strlen(fts_name) */
+ size_t fts_pathlen; /* strlen(fts_path) */
+ size_t fts_namelen; /* strlen(fts_name) */
ino_t fts_ino; /* inode */
dev_t fts_dev; /* device */
diff --git a/lib/libc/gen/fts.3 b/lib/libc/gen/fts.3
index a050fb3d8b4..77ea5dbb355 100644
--- a/lib/libc/gen/fts.3
+++ b/lib/libc/gen/fts.3
@@ -1,4 +1,4 @@
-.\" $OpenBSD: fts.3,v 1.17 2000/12/24 00:30:47 aaron Exp $
+.\" $OpenBSD: fts.3,v 1.18 2001/05/15 21:14:38 millert Exp $
.\"
.\" Copyright (c) 1989, 1991, 1993, 1994
.\" The Regents of the University of California. All rights reserved.
@@ -115,9 +115,9 @@ typedef struct _ftsent {
u_short fts_info; /* flags for FTSENT structure */
char *fts_accpath; /* access path */
char *fts_path; /* root path */
- u_short fts_pathlen; /* strlen(fts_path) */
+ size_t fts_pathlen; /* strlen(fts_path) */
char *fts_name; /* file name */
- u_short fts_namelen; /* strlen(fts_name) */
+ size_t fts_namelen; /* strlen(fts_name) */
short fts_level; /* depth (-1 to N) */
int fts_errno; /* file errno */
long fts_number; /* local numeric value */
diff --git a/lib/libc/gen/fts.c b/lib/libc/gen/fts.c
index e28cf9bbd94..5d9c8aae5be 100644
--- a/lib/libc/gen/fts.c
+++ b/lib/libc/gen/fts.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fts.c,v 1.24 2000/08/24 17:04:12 deraadt Exp $ */
+/* $OpenBSD: fts.c,v 1.25 2001/05/15 21:14:39 millert Exp $ */
/*-
* Copyright (c) 1990, 1993, 1994
@@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)fts.c 8.6 (Berkeley) 8/14/94";
#else
-static char rcsid[] = "$OpenBSD: fts.c,v 1.24 2000/08/24 17:04:12 deraadt Exp $";
+static char rcsid[] = "$OpenBSD: fts.c,v 1.25 2001/05/15 21:14:39 millert Exp $";
#endif
#endif /* LIBC_SCCS and not lint */
@@ -52,7 +52,7 @@ static char rcsid[] = "$OpenBSD: fts.c,v 1.24 2000/08/24 17:04:12 deraadt Exp $"
#include <string.h>
#include <unistd.h>
-static FTSENT *fts_alloc __P((FTS *, char *, int));
+static FTSENT *fts_alloc __P((FTS *, char *, size_t));
static FTSENT *fts_build __P((FTS *, int));
static void fts_lfree __P((FTSENT *));
static void fts_load __P((FTS *, FTSENT *));
@@ -80,14 +80,14 @@ static int fts_safe_changedir __P((FTS *, FTSENT *, int));
FTS *
fts_open(argv, options, compar)
char * const *argv;
- register int options;
+ int options;
int (*compar) __P((const FTSENT **, const FTSENT **));
{
- register FTS *sp;
- register FTSENT *p, *root;
- register int nitems;
+ FTS *sp;
+ FTSENT *p, *root;
+ int nitems;
FTSENT *parent, *tmp;
- int len;
+ size_t len;
/* Options check. */
if (options & ~FTS_OPTIONMASK) {
@@ -188,10 +188,10 @@ mem1: free(sp);
static void
fts_load(sp, p)
FTS *sp;
- register FTSENT *p;
+ FTSENT *p;
{
- register int len;
- register char *cp;
+ size_t len;
+ char *cp;
/*
* Load the stream structure for the next traversal. Since we don't
@@ -215,7 +215,7 @@ int
fts_close(sp)
FTS *sp;
{
- register FTSENT *freep, *p;
+ FTSENT *freep, *p;
int saved_errno = 0;
/*
@@ -268,11 +268,11 @@ fts_close(sp)
FTSENT *
fts_read(sp)
- register FTS *sp;
+ FTS *sp;
{
- register FTSENT *p, *tmp;
- register int instr;
- register char *t;
+ FTSENT *p, *tmp;
+ int instr;
+ char *t;
int saved_errno;
/* If finished or unrecoverable error, return NULL. */
@@ -373,16 +373,9 @@ next: tmp = p;
* the root of the tree), and load the paths for the next root.
*/
if (p->fts_level == FTS_ROOTLEVEL) {
- if ((sp->fts_options & FTS_CHDIRROOT)) {
- if (chdir(p->fts_accpath)) {
- SET(FTS_STOP);
- return (NULL);
- }
- } else {
- if (FCHDIR(sp, sp->fts_rfd)) {
- SET(FTS_STOP);
- return (NULL);
- }
+ if (FCHDIR(sp, sp->fts_rfd)) {
+ SET(FTS_STOP);
+ return (NULL);
}
fts_load(sp, p);
return (sp->fts_cur = p);
@@ -437,16 +430,9 @@ name: t = sp->fts_path + NAPPEND(p->fts_parent);
* one directory.
*/
if (p->fts_level == FTS_ROOTLEVEL) {
- if ((sp->fts_options & FTS_CHDIRROOT)) {
- if (chdir(p->fts_accpath)) {
- SET(FTS_STOP);
- return (NULL);
- }
- } else {
- if (FCHDIR(sp, sp->fts_rfd)) {
- SET(FTS_STOP);
- return (NULL);
- }
+ if (FCHDIR(sp, sp->fts_rfd)) {
+ SET(FTS_STOP);
+ return (NULL);
}
} else if (p->fts_flags & FTS_SYMFOLLOW) {
if (FCHDIR(sp, p->fts_symfd)) {
@@ -491,10 +477,10 @@ fts_set(sp, p, instr)
FTSENT *
fts_children(sp, instr)
- register FTS *sp;
+ FTS *sp;
int instr;
{
- register FTSENT *p;
+ FTSENT *p;
int fd;
if (instr && instr != FTS_NAMEONLY) {
@@ -573,17 +559,17 @@ fts_children(sp, instr)
*/
static FTSENT *
fts_build(sp, type)
- register FTS *sp;
+ FTS *sp;
int type;
{
- register struct dirent *dp;
- register FTSENT *p, *head;
- register int nitems;
+ struct dirent *dp;
+ FTSENT *p, *head;
FTSENT *cur, *tail;
DIR *dirp;
void *oldaddr;
- int cderrno, descend, len, level, maxlen, nlinks, oflag, saved_errno,
- nostat, doadjust;
+ size_t len, maxlen;
+ int nitems, cderrno, descend, level, nlinks, oflag, nostat, doadjust;
+ int saved_errno;
char *cp;
/* Set current node pointer. */
@@ -685,7 +671,7 @@ fts_build(sp, type)
if (!ISSET(FTS_SEEDOT) && ISDOT(dp->d_name))
continue;
- if ((p = fts_alloc(sp, dp->d_name, (int)dp->d_namlen)) == NULL)
+ if (!(p = fts_alloc(sp, dp->d_name, (size_t)dp->d_namlen)))
goto mem1;
if (dp->d_namlen >= maxlen) { /* include space for NUL */
oldaddr = sp->fts_path;
@@ -714,12 +700,14 @@ mem1: saved_errno = errno;
maxlen = sp->fts_pathlen - len;
}
- if (len + dp->d_namlen >= USHRT_MAX) {
+ p->fts_level = level;
+ p->fts_parent = sp->fts_cur;
+ p->fts_pathlen = len + dp->d_namlen;
+ if (p->fts_pathlen < len) {
/*
- * In an FTSENT, fts_pathlen is a u_short so it is
- * possible to wraparound here. If we do, free up
- * the current structure and the structures already
- * allocated, then error out with ENAMETOOLONG.
+ * If we wrap, free up the current structure and
+ * the structures already allocated, then error
+ * out with ENAMETOOLONG.
*/
free(p);
fts_lfree(head);
@@ -729,9 +717,6 @@ mem1: saved_errno = errno;
errno = ENAMETOOLONG;
return (NULL);
}
- p->fts_level = level;
- p->fts_parent = sp->fts_cur;
- p->fts_pathlen = len + dp->d_namlen;
#ifdef FTS_WHITEOUT
if (dp->d_type == DT_WHT)
@@ -831,12 +816,12 @@ mem1: saved_errno = errno;
static u_short
fts_stat(sp, p, follow)
FTS *sp;
- register FTSENT *p;
+ FTSENT *p;
int follow;
{
- register FTSENT *t;
- register dev_t dev;
- register ino_t ino;
+ FTSENT *t;
+ dev_t dev;
+ ino_t ino;
struct stat *sbp, sb;
int saved_errno;
@@ -915,9 +900,9 @@ static FTSENT *
fts_sort(sp, head, nitems)
FTS *sp;
FTSENT *head;
- register int nitems;
+ int nitems;
{
- register FTSENT **ap, *p;
+ FTSENT **ap, *p;
/*
* Construct an array of pointers to the structures and call qsort(3).
@@ -953,9 +938,9 @@ static FTSENT *
fts_alloc(sp, name, namelen)
FTS *sp;
char *name;
- register int namelen;
+ size_t namelen;
{
- register FTSENT *p;
+ FTSENT *p;
size_t len;
/*
@@ -990,9 +975,9 @@ fts_alloc(sp, name, namelen)
static void
fts_lfree(head)
- register FTSENT *head;
+ FTSENT *head;
{
- register FTSENT *p;
+ FTSENT *p;
/* Free a linked list of structures. */
while ((p = head)) {
@@ -1014,19 +999,18 @@ fts_palloc(sp, more)
{
char *p;
- sp->fts_pathlen += more + 256;
/*
- * Check for possible wraparound. In an FTS, fts_pathlen is
- * a signed int but in an FTSENT it is an unsigned short.
- * We limit fts_pathlen to USHRT_MAX to be safe in both cases.
+ * Check for possible wraparound.
*/
- if (sp->fts_pathlen < 0 || sp->fts_pathlen >= USHRT_MAX) {
+ more += 256;
+ if (sp->fts_pathlen + more < sp->fts_pathlen) {
if (sp->fts_path)
free(sp->fts_path);
sp->fts_path = NULL;
errno = ENAMETOOLONG;
return (1);
}
+ sp->fts_pathlen += more;
p = realloc(sp->fts_path, sp->fts_pathlen);
if (p == NULL) {
if (sp->fts_path)
diff --git a/lib/libc/shlib_version b/lib/libc/shlib_version
index 34aa186fe47..54ef0c4cc0c 100644
--- a/lib/libc/shlib_version
+++ b/lib/libc/shlib_version
@@ -1,2 +1,2 @@
-major=26
-minor=2
+major=27
+minor=0
diff --git a/lib/libc_r/shlib_version b/lib/libc_r/shlib_version
index f89dbabf714..3066b9771e7 100644
--- a/lib/libc_r/shlib_version
+++ b/lib/libc_r/shlib_version
@@ -1,2 +1,2 @@
-major=4
-minor=2
+major=5
+minor=0