]> sourceware.org Git - newlib-cygwin.git/commitdiff
* libc/bsdlib.cc (forkpty): Close master and slave if fork fails to
authorCorinna Vinschen <corinna@vinschen.de>
Thu, 22 May 2014 09:45:17 +0000 (09:45 +0000)
committerCorinna Vinschen <corinna@vinschen.de>
Thu, 22 May 2014 09:45:17 +0000 (09:45 +0000)
avoid resource leak (CID 59997).
* libc/fts.c: Update to FreeBSD version 1.39 (CID 59947).
* libc/minires.c (minires_get_search): Fix out-of-bounds read from
words array (CID 59937).

winsup/cygwin/ChangeLog
winsup/cygwin/libc/bsdlib.cc
winsup/cygwin/libc/fts.c
winsup/cygwin/libc/minires.c

index d1253916dac98df00acac3a966edb6d746e4fc3d..b89f37467ec32231d384971f90b3c5ad9218d79e 100644 (file)
@@ -1,3 +1,11 @@
+2014-05-20  Corinna Vinschen  <corinna@vinschen.de>
+
+       * libc/bsdlib.cc (forkpty): Close master and slave if fork fails to
+       avoid resource leak (CID 59997).
+       * libc/fts.c: Update to FreeBSD version 1.39 (CID 59947).
+       * libc/minires.c (minires_get_search): Fix out-of-bounds read from
+       words array (CID 59937).
+
 2014-05-20  Corinna Vinschen  <corinna@vinschen.de>
 
        * flock.cc (delete_lock_in_parent): Use LIST_FOREACH_SAFE to avoid
index 66cffc7d31319b6687dbf48aad4cb8238be7cad8..696a9f85660962e199478b9d44d847ad0d0b9894 100644 (file)
@@ -150,6 +150,8 @@ forkpty (int *amaster, char *name, const struct termios *termp,
   switch (pid = fork ())
     {
       case -1:
+       close (master);
+       close (slave);
        return -1;
       case 0:
        close (master);
index e82ec3fd7944140e0a811c03068d77fcf40e8e69..003f8514623ceda3fd3578f76a128369a4651869 100644 (file)
 static char sccsid[] = "@(#)fts.c      8.6 (Berkeley) 8/14/94";
 #endif /* LIBC_SCCS and not lint */
 #endif
-#ifdef __CYGWIN__
-#include "winsup.h"
-#include <sys/statfs.h>
-#define _open open
-#define _close close
-#endif
+
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: /repoman/r/ncvs/src/lib/libc/gen/fts.c,v 1.27 2004/06/08 06:23:23 das Exp $");
+__FBSDID("$FreeBSD: src/lib/libc/gen/fts.c,v 1.39 2013/02/11 02:00:16 svnexp Exp $");
 
 #ifndef __CYGWIN__
 #include "namespace.h"
@@ -57,19 +52,37 @@ __FBSDID("$FreeBSD: /repoman/r/ncvs/src/lib/libc/gen/fts.c,v 1.27 2004/06/08 06:
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
-#ifndef __CYGWIN__
+#ifdef __CYGWIN__
+#include "winsup.h"
+#include <sys/statfs.h>
+#define _open open
+#define _close close
+#define _dirfd dirfd
+#ifdef __x86_64__
+#define _fstat fstat
+#else
+extern int stat64 (const char *path, struct stat *buf);
+extern int fstat64 (int fd, struct stat *buf);
+extern int lstat64 (const char *path, struct stat *buf);
+#define stat(a,b) stat64((a),(b))
+#define _fstat(a,b) fstat64((a),(b))
+#define lstat(a,b) lstat64((a),(b))
+#endif
+#else
 #include "un-namespace.h"
+
+#include "gen-private.h"
 #endif
 
-static FTSENT  *fts_alloc(FTS *, const char *, int);
+static FTSENT  *fts_alloc(FTS *, const char *, size_t);
 static FTSENT  *fts_build(FTS *, int);
 static void     fts_lfree(FTSENT *);
 static void     fts_load(FTS *, FTSENT *);
 static size_t   fts_maxarglen(char * const *);
 static void     fts_padjust(FTS *, FTSENT *);
 static int      fts_palloc(FTS *, size_t);
-static FTSENT  *fts_sort(FTS *, FTSENT *, int);
-static u_short  fts_stat(FTS *, FTSENT *, int);
+static FTSENT  *fts_sort(FTS *, FTSENT *, size_t);
+static int      fts_stat(FTS *, FTSENT *, int);
 static int      fts_safe_changedir(FTS *, FTSENT *, int, const char *);
 static int      fts_ufslinks(FTS *, const FTSENT *);
 
@@ -110,6 +123,7 @@ struct _fts_private {
 #ifndef __CYGWIN__
 static const char *ufslike_filesystems[] = {
        "ufs",
+       "zfs",
        "nfs",
        "nfs4",
        "ext2fs",
@@ -126,9 +140,8 @@ fts_open(argv, options, compar)
        struct _fts_private *priv;
        FTS *sp;
        FTSENT *p, *root;
-       int nitems;
        FTSENT *parent, *tmp;
-       int len;
+       size_t len, nitems;
 
        /* Options check. */
        if (options & ~FTS_OPTIONMASK) {
@@ -136,10 +149,15 @@ fts_open(argv, options, compar)
                return (NULL);
        }
 
+       /* fts_open() requires at least one path */
+       if (*argv == NULL) {
+               errno = EINVAL;
+               return (NULL);
+       }
+
        /* Allocate/initialize the stream. */
-       if ((priv = malloc(sizeof(*priv))) == NULL)
+       if ((priv = calloc(1, sizeof(*priv))) == NULL)
                return (NULL);
-       memset(priv, 0, sizeof(*priv));
        sp = &priv->ftsp_fts;
        sp->fts_compar = compar;
        sp->fts_options = options;
@@ -218,7 +236,8 @@ fts_open(argv, options, compar)
         * and ".." are all fairly nasty problems.  Note, if we can't get the
         * descriptor we run anyway, just more slowly.
         */
-       if (!ISSET(FTS_NOCHDIR) && (sp->fts_rfd = _open(".", O_RDONLY, 0)) < 0)
+       if (!ISSET(FTS_NOCHDIR) &&
+           (sp->fts_rfd = _open(".", O_RDONLY | O_CLOEXEC, 0)) < 0)
                SET(FTS_NOCHDIR);
 
        return (sp);
@@ -231,11 +250,9 @@ mem1:      free(sp);
 }
 
 static void
-fts_load(sp, p)
-       FTS *sp;
-       FTSENT *p;
+fts_load(FTS *sp, FTSENT *p)
 {
-       int len;
+       size_t len;
        char *cp;
 
        /*
@@ -257,8 +274,7 @@ fts_load(sp, p)
 }
 
 int
-fts_close(sp)
-       FTS *sp;
+fts_close(FTS *sp)
 {
        FTSENT *freep, *p;
        int saved_errno;
@@ -312,8 +328,7 @@ fts_close(sp)
            ? p->fts_pathlen - 1 : p->fts_pathlen)
 
 FTSENT *
-fts_read(sp)
-       FTS *sp;
+fts_read(FTS *sp)
 {
        FTSENT *p, *tmp;
        int instr;
@@ -347,7 +362,8 @@ fts_read(sp)
            (p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE)) {
                p->fts_info = fts_stat(sp, p, 1);
                if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) {
-                       if ((p->fts_symfd = _open(".", O_RDONLY, 0)) < 0) {
+                       if ((p->fts_symfd = _open(".", O_RDONLY | O_CLOEXEC,
+                           0)) < 0) {
                                p->fts_errno = errno;
                                p->fts_info = FTS_ERR;
                        } else
@@ -438,7 +454,7 @@ next:       tmp = p;
                        p->fts_info = fts_stat(sp, p, 1);
                        if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) {
                                if ((p->fts_symfd =
-                                   _open(".", O_RDONLY, 0)) < 0) {
+                                   _open(".", O_RDONLY | O_CLOEXEC, 0)) < 0) {
                                        p->fts_errno = errno;
                                        p->fts_info = FTS_ERR;
                                } else
@@ -506,10 +522,7 @@ name:              t = sp->fts_path + NAPPEND(p->fts_parent);
  */
 /* ARGSUSED */
 int
-fts_set(sp, p, instr)
-       FTS *sp __attribute__ ((unused));
-       FTSENT *p;
-       int instr;
+fts_set(FTS *sp, FTSENT *p, int instr)
 {
        if (instr != 0 && instr != FTS_AGAIN && instr != FTS_FOLLOW &&
            instr != FTS_NOINSTR && instr != FTS_SKIP) {
@@ -521,9 +534,7 @@ fts_set(sp, p, instr)
 }
 
 FTSENT *
-fts_children(sp, instr)
-       FTS *sp;
-       int instr;
+fts_children(FTS *sp, int instr)
 {
        FTSENT *p;
        int fd;
@@ -579,11 +590,13 @@ fts_children(sp, instr)
            ISSET(FTS_NOCHDIR))
                return (sp->fts_child = fts_build(sp, instr));
 
-       if ((fd = _open(".", O_RDONLY, 0)) < 0)
+       if ((fd = _open(".", O_RDONLY | O_CLOEXEC, 0)) < 0)
                return (NULL);
        sp->fts_child = fts_build(sp, instr);
-       if (fchdir(fd))
+       if (fchdir(fd)) {
+               (void)_close(fd);
                return (NULL);
+       }
        (void)_close(fd);
        return (sp->fts_child);
 }
@@ -631,20 +644,18 @@ fts_set_clientptr(FTS *sp, void *clientptr)
  * been found, cutting the stat calls by about 2/3.
  */
 static FTSENT *
-fts_build(sp, type)
-       FTS *sp;
-       int type;
+fts_build(FTS *sp, int type)
 {
        struct dirent *dp;
        FTSENT *p, *head;
-       int nitems;
        FTSENT *cur, *tail;
        DIR *dirp;
        void *oldaddr;
-       size_t dnamlen;
-       int cderrno, descend, len, level, maxlen, nlinks, /*oflag,*/ saved_errno,
-           nostat, doadjust;
        char *cp;
+       int cderrno, descend, /* oflag, */ saved_errno, nostat, doadjust;
+       long level;
+       long nlinks;    /* has to be signed because -1 is a magic value */
+       size_t dnamlen, len, maxlen, nitems;
 
        /* Set current node pointer. */
        cur = sp->fts_cur;
@@ -711,7 +722,7 @@ fts_build(sp, type)
         */
        cderrno = 0;
        if (nlinks || type == BREAD) {
-               if (fts_safe_changedir(sp, cur, dirfd(dirp), NULL)) {
+               if (fts_safe_changedir(sp, cur, _dirfd(dirp), NULL)) {
                        if (nlinks && type == BREAD)
                                cur->fts_errno = errno;
                        cur->fts_flags |= FTS_DONTCHDIR;
@@ -756,9 +767,9 @@ fts_build(sp, type)
                if (!ISSET(FTS_SEEDOT) && ISDOT(dp->d_name))
                        continue;
 
-               if ((p = fts_alloc(sp, dp->d_name, (int)dnamlen)) == NULL)
+               if ((p = fts_alloc(sp, dp->d_name, dnamlen)) == NULL)
                        goto mem1;
-               if ((int) dnamlen >= maxlen) {  /* include space for NUL */
+               if (dnamlen >= maxlen) {        /* include space for NUL */
                        oldaddr = sp->fts_path;
                        if (fts_palloc(sp, dnamlen + len + 1)) {
                                /*
@@ -785,21 +796,6 @@ mem1:                              saved_errno = errno;
                        maxlen = sp->fts_pathlen - len;
                }
 
-               if (len + dnamlen >= USHRT_MAX) {
-                       /*
-                        * 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.
-                        */
-                       free(p);
-                       fts_lfree(head);
-                       (void)closedir(dirp);
-                       cur->fts_info = FTS_ERR;
-                       SET(FTS_STOP);
-                       errno = ENAMETOOLONG;
-                       return (NULL);
-               }
                p->fts_level = level;
                p->fts_parent = sp->fts_cur;
                p->fts_pathlen = len + dnamlen;
@@ -817,7 +813,7 @@ mem1:                               saved_errno = errno;
                                p->fts_info = FTS_NSOK;
                        p->fts_accpath = cur->fts_accpath;
                } else if (nlinks == 0
-#if defined(DT_DIR)
+#ifdef DT_DIR
                    || (nostat &&
                    dp->d_type != DT_DIR && dp->d_type != DT_UNKNOWN)
 #endif
@@ -865,11 +861,8 @@ mem1:                              saved_errno = errno;
         * If not changing directories, reset the path back to original
         * state.
         */
-       if (ISSET(FTS_NOCHDIR)) {
-               if (len == sp->fts_pathlen || nitems == 0)
-                       --cp;
-               *cp = '\0';
-       }
+       if (ISSET(FTS_NOCHDIR))
+               sp->fts_path[cur->fts_pathlen] = '\0';
 
        /*
         * If descended after called from fts_children or after called from
@@ -900,11 +893,8 @@ mem1:                              saved_errno = errno;
        return (head);
 }
 
-static u_short
-fts_stat(sp, p, follow)
-       FTS *sp;
-       FTSENT *p;
-       int follow;
+static int
+fts_stat(FTS *sp, FTSENT *p, int follow)
 {
        FTSENT *t;
        dev_t dev;
@@ -932,16 +922,16 @@ fts_stat(sp, p, follow)
         * fail, set the errno from the stat call.
         */
        if (ISSET(FTS_LOGICAL) || follow) {
-               if (stat64(p->fts_accpath, sbp)) {
+               if (stat(p->fts_accpath, sbp)) {
                        saved_errno = errno;
-                       if (!lstat64(p->fts_accpath, sbp)) {
+                       if (!lstat(p->fts_accpath, sbp)) {
                                errno = 0;
                                return (FTS_SLNONE);
                        }
                        p->fts_errno = saved_errno;
                        goto err;
                }
-       } else if (lstat64(p->fts_accpath, sbp)) {
+       } else if (lstat(p->fts_accpath, sbp)) {
                p->fts_errno = errno;
 err:           memset(sbp, 0, sizeof(struct stat));
                return (FTS_NS);
@@ -999,10 +989,7 @@ fts_compar(const void *a, const void *b)
 }
 
 static FTSENT *
-fts_sort(sp, head, nitems)
-       FTS *sp;
-       FTSENT *head;
-       int nitems;
+fts_sort(FTS *sp, FTSENT *head, size_t nitems)
 {
        FTSENT **ap, *p;
 
@@ -1031,10 +1018,7 @@ fts_sort(sp, head, nitems)
 }
 
 static FTSENT *
-fts_alloc(sp, name, namelen)
-       FTS *sp;
-       const char *name;
-       int namelen;
+fts_alloc(FTS *sp, const char *name, size_t namelen)
 {
        FTSENT *p;
        size_t len;
@@ -1081,8 +1065,7 @@ fts_alloc(sp, name, namelen)
 }
 
 static void
-fts_lfree(head)
-       FTSENT *head;
+fts_lfree(FTSENT *head)
 {
        FTSENT *p;
 
@@ -1100,24 +1083,10 @@ fts_lfree(head)
  * plus 256 bytes so don't realloc the path 2 bytes at a time.
  */
 static int
-fts_palloc(sp, more)
-       FTS *sp;
-       size_t more;
+fts_palloc(FTS *sp, size_t more)
 {
 
        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.
-        */
-       if (sp->fts_pathlen < 0 || sp->fts_pathlen >= USHRT_MAX) {
-               if (sp->fts_path)
-                       free(sp->fts_path);
-               sp->fts_path = NULL;
-               errno = ENAMETOOLONG;
-               return (1);
-       }
        sp->fts_path = reallocf(sp->fts_path, sp->fts_pathlen);
        return (sp->fts_path == NULL);
 }
@@ -1127,9 +1096,7 @@ fts_palloc(sp, more)
  * already returned.
  */
 static void
-fts_padjust(sp, head)
-       FTS *sp;
-       FTSENT *head;
+fts_padjust(FTS *sp, FTSENT *head)
 {
        FTSENT *p;
        char *addr = sp->fts_path;
@@ -1170,11 +1137,7 @@ fts_maxarglen(argv)
  * Assumes p->fts_dev and p->fts_ino are filled in.
  */
 static int
-fts_safe_changedir(sp, p, fd, path)
-       FTS *sp;
-       FTSENT *p;
-       int fd;
-       const char *path;
+fts_safe_changedir(FTS *sp, FTSENT *p, int fd, const char *path)
 {
        int ret, oerrno, newfd;
        struct stat sb;
@@ -1182,9 +1145,10 @@ fts_safe_changedir(sp, p, fd, path)
        newfd = fd;
        if (ISSET(FTS_NOCHDIR))
                return (0);
-       if (fd < 0 && (newfd = _open(path, O_RDONLY, 0)) < 0)
+       if (fd < 0 && (newfd = _open(path, O_RDONLY | O_DIRECTORY |
+           O_CLOEXEC, 0)) < 0)
                return (-1);
-       if (fstat64(newfd, &sb)) {
+       if (_fstat(newfd, &sb)) {
                ret = -1;
                goto bail;
        }
index c73ad3c582af64660f2340da9adb50f3dcc6fe22..b25c927c9ee23d730c881e1beef9ece98c34e6ad 100644 (file)
@@ -77,7 +77,7 @@ void minires_get_search(char * string, res_state statp)
       ptr += sizes[j];
       DPRINTF(debug, "search \"%s\"\n", words[j]);
     }
-    else
+    else if (j < MAXDNSRCH + 1)
       DPRINTF(debug, "no space for \"%s\"\n", words[j]);
   }
 }
This page took 0.063715 seconds and 5 git commands to generate.