summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorkris <kris@FreeBSD.org>2001-06-01 21:53:50 +0000
committerkris <kris@FreeBSD.org>2001-06-01 21:53:50 +0000
commitb4dd259ff3571482d58dc9542d43c18fae0b32e0 (patch)
tree587eb2b9a8b57a7ebe31e202613c7fefecadca0d /lib
parent42275c0786a6b35b2809d34cad55e9fe46cd39e5 (diff)
downloadFreeBSD-src-b4dd259ff3571482d58dc9542d43c18fae0b32e0.zip
FreeBSD-src-b4dd259ff3571482d58dc9542d43c18fae0b32e0.tar.gz
Fix another unprotected instance of chdir() by extending the
fts_safe_changedir() function and using that instead for both of the chdir()s. Partially submitted by: Todd Miller <millert@OpenBSD.org>, bde
Diffstat (limited to 'lib')
-rw-r--r--lib/libc/gen/fts-compat.c36
-rw-r--r--lib/libc/gen/fts.c36
2 files changed, 24 insertions, 48 deletions
diff --git a/lib/libc/gen/fts-compat.c b/lib/libc/gen/fts-compat.c
index 72e0c4d..f874d44 100644
--- a/lib/libc/gen/fts-compat.c
+++ b/lib/libc/gen/fts-compat.c
@@ -66,7 +66,7 @@ static void fts_padjust __P((FTS *, FTSENT *));
static int fts_palloc __P((FTS *, size_t));
static FTSENT *fts_sort __P((FTS *, FTSENT *, int));
static u_short fts_stat __P((FTS *, FTSENT *, int));
-static int fts_safe_changedir __P((FTS *, FTSENT *, int));
+static int fts_safe_changedir __P((FTS *, FTSENT *, int, char *));
#define ISDOT(a) (a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2])))
@@ -74,7 +74,6 @@ static int fts_safe_changedir __P((FTS *, FTSENT *, int));
#define ISSET(opt) (sp->fts_options & (opt))
#define SET(opt) (sp->fts_options |= (opt))
-#define CHDIR(sp, path) (!ISSET(FTS_NOCHDIR) && chdir(path))
#define FCHDIR(sp, fd) (!ISSET(FTS_NOCHDIR) && fchdir(fd))
/* fts_build flags */
@@ -278,8 +277,8 @@ FTSENT *
fts_read(sp)
register FTS *sp;
{
- register FTSENT *p, *tmp;
struct stat sb;
+ register FTSENT *p, *tmp;
register int instr;
register char *t;
int saved_errno;
@@ -355,7 +354,7 @@ fts_read(sp)
* FTS_STOP or the fts_info field of the node.
*/
if (sp->fts_child != NULL) {
- if (fts_safe_changedir(sp, p, -1)) {
+ if (fts_safe_changedir(sp, p, -1, p->fts_accpath)) {
p->fts_errno = errno;
p->fts_flags |= FTS_DONTCHDIR;
for (p = sp->fts_child; p != NULL;
@@ -454,22 +453,9 @@ name: t = sp->fts_path + NAPPEND(p->fts_parent);
}
(void)_close(p->fts_symfd);
} else if (!(p->fts_flags & FTS_DONTCHDIR) &&
- !ISSET(FTS_NOCHDIR)) {
- if (chdir("..")) {
- SET(FTS_STOP);
- return (NULL);
- }
- if (stat(".", &sb) == -1) {
- SET(FTS_STOP);
- return (NULL);
- } else {
- if (sb.st_ino != p->fts_parent->fts_ino ||
- sb.st_dev != p->fts_parent->fts_dev) {
- errno = ENOENT;
- SET(FTS_STOP);
- return (NULL);
- }
- }
+ fts_safe_changedir(sp, p->fts_parent, -1, "..")) {
+ SET(FTS_STOP);
+ return (NULL);
}
p->fts_info = p->fts_errno ? FTS_ERR : FTS_DP;
return (sp->fts_cur = p);
@@ -656,7 +642,7 @@ fts_build(sp, type)
*/
cderrno = 0;
if (nlinks || type == BREAD) {
- if (fts_safe_changedir(sp, cur, dirfd(dirp))) {
+ if (fts_safe_changedir(sp, cur, dirfd(dirp), NULL)) {
if (nlinks && type == BREAD)
cur->fts_errno = errno;
cur->fts_flags |= FTS_DONTCHDIR;
@@ -822,7 +808,8 @@ mem1: saved_errno = errno;
*/
if (descend && (type == BCHILD || !nitems) &&
(cur->fts_level == FTS_ROOTLEVEL ?
- FCHDIR(sp, sp->fts_rfd) : CHDIR(sp, ".."))) {
+ FCHDIR(sp, sp->fts_rfd) :
+ fts_safe_changedir(sp, cur->fts_parent, -1, ".."))) {
cur->fts_info = FTS_ERR;
SET(FTS_STOP);
return (NULL);
@@ -1085,10 +1072,11 @@ fts_maxarglen(argv)
* Assumes p->fts_dev and p->fts_ino are filled in.
*/
static int
-fts_safe_changedir(sp, p, fd)
+fts_safe_changedir(sp, p, fd, path)
FTS *sp;
FTSENT *p;
int fd;
+ char *path;
{
int ret, oerrno, newfd;
struct stat sb;
@@ -1096,7 +1084,7 @@ fts_safe_changedir(sp, p, fd)
newfd = fd;
if (ISSET(FTS_NOCHDIR))
return (0);
- if (fd < 0 && (newfd = _open(p->fts_accpath, O_RDONLY, 0)) < 0)
+ if (fd < 0 && (newfd = _open(path, O_RDONLY, 0)) < 0)
return (-1);
if (_fstat(newfd, &sb)) {
ret = -1;
diff --git a/lib/libc/gen/fts.c b/lib/libc/gen/fts.c
index 72e0c4d..f874d44 100644
--- a/lib/libc/gen/fts.c
+++ b/lib/libc/gen/fts.c
@@ -66,7 +66,7 @@ static void fts_padjust __P((FTS *, FTSENT *));
static int fts_palloc __P((FTS *, size_t));
static FTSENT *fts_sort __P((FTS *, FTSENT *, int));
static u_short fts_stat __P((FTS *, FTSENT *, int));
-static int fts_safe_changedir __P((FTS *, FTSENT *, int));
+static int fts_safe_changedir __P((FTS *, FTSENT *, int, char *));
#define ISDOT(a) (a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2])))
@@ -74,7 +74,6 @@ static int fts_safe_changedir __P((FTS *, FTSENT *, int));
#define ISSET(opt) (sp->fts_options & (opt))
#define SET(opt) (sp->fts_options |= (opt))
-#define CHDIR(sp, path) (!ISSET(FTS_NOCHDIR) && chdir(path))
#define FCHDIR(sp, fd) (!ISSET(FTS_NOCHDIR) && fchdir(fd))
/* fts_build flags */
@@ -278,8 +277,8 @@ FTSENT *
fts_read(sp)
register FTS *sp;
{
- register FTSENT *p, *tmp;
struct stat sb;
+ register FTSENT *p, *tmp;
register int instr;
register char *t;
int saved_errno;
@@ -355,7 +354,7 @@ fts_read(sp)
* FTS_STOP or the fts_info field of the node.
*/
if (sp->fts_child != NULL) {
- if (fts_safe_changedir(sp, p, -1)) {
+ if (fts_safe_changedir(sp, p, -1, p->fts_accpath)) {
p->fts_errno = errno;
p->fts_flags |= FTS_DONTCHDIR;
for (p = sp->fts_child; p != NULL;
@@ -454,22 +453,9 @@ name: t = sp->fts_path + NAPPEND(p->fts_parent);
}
(void)_close(p->fts_symfd);
} else if (!(p->fts_flags & FTS_DONTCHDIR) &&
- !ISSET(FTS_NOCHDIR)) {
- if (chdir("..")) {
- SET(FTS_STOP);
- return (NULL);
- }
- if (stat(".", &sb) == -1) {
- SET(FTS_STOP);
- return (NULL);
- } else {
- if (sb.st_ino != p->fts_parent->fts_ino ||
- sb.st_dev != p->fts_parent->fts_dev) {
- errno = ENOENT;
- SET(FTS_STOP);
- return (NULL);
- }
- }
+ fts_safe_changedir(sp, p->fts_parent, -1, "..")) {
+ SET(FTS_STOP);
+ return (NULL);
}
p->fts_info = p->fts_errno ? FTS_ERR : FTS_DP;
return (sp->fts_cur = p);
@@ -656,7 +642,7 @@ fts_build(sp, type)
*/
cderrno = 0;
if (nlinks || type == BREAD) {
- if (fts_safe_changedir(sp, cur, dirfd(dirp))) {
+ if (fts_safe_changedir(sp, cur, dirfd(dirp), NULL)) {
if (nlinks && type == BREAD)
cur->fts_errno = errno;
cur->fts_flags |= FTS_DONTCHDIR;
@@ -822,7 +808,8 @@ mem1: saved_errno = errno;
*/
if (descend && (type == BCHILD || !nitems) &&
(cur->fts_level == FTS_ROOTLEVEL ?
- FCHDIR(sp, sp->fts_rfd) : CHDIR(sp, ".."))) {
+ FCHDIR(sp, sp->fts_rfd) :
+ fts_safe_changedir(sp, cur->fts_parent, -1, ".."))) {
cur->fts_info = FTS_ERR;
SET(FTS_STOP);
return (NULL);
@@ -1085,10 +1072,11 @@ fts_maxarglen(argv)
* Assumes p->fts_dev and p->fts_ino are filled in.
*/
static int
-fts_safe_changedir(sp, p, fd)
+fts_safe_changedir(sp, p, fd, path)
FTS *sp;
FTSENT *p;
int fd;
+ char *path;
{
int ret, oerrno, newfd;
struct stat sb;
@@ -1096,7 +1084,7 @@ fts_safe_changedir(sp, p, fd)
newfd = fd;
if (ISSET(FTS_NOCHDIR))
return (0);
- if (fd < 0 && (newfd = _open(p->fts_accpath, O_RDONLY, 0)) < 0)
+ if (fd < 0 && (newfd = _open(path, O_RDONLY, 0)) < 0)
return (-1);
if (_fstat(newfd, &sb)) {
ret = -1;
OpenPOWER on IntegriCloud