>Number:         169800
>Category:       misc
>Synopsis:       A merged patch to
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Thu Jul 12 09:50:01 UTC 2012
>Closed-Date:
>Last-Modified:
>Originator:     Jukka Ukkonen
>Release:        FreeBSD 9.1-BETA1
>Organization:
-----
>Environment:
FreeBSD sleipnir 9.1-BETA1 FreeBSD 9.1-BETA1 #0: Thu Jul 12 11:23:31 EEST 2012  
   root@sleipnir:/usr/obj/usr/src/sys/Sleipnir  amd64
>Description:
The attached patch changes a number of system library functions to set
the O_CLOEXEC flag immediately while the file is being opened.
This will assure that there will be no time window between opening the file
and setting the close-on-exec flag.
Esp. in a threaded program even the small time window could cause the file
descriptors being leaked to a child program, if another independent library
module decides to call exec() inside another thread while the new file has
been opened but the close-on-exec flag has not been set yet.

NOTICE!
This patch requires as a precondition the second enhanced version of
the patch to

http://www.freebsd.org/cgi/query-pr.cgi?pr=kern/169320


>How-To-Repeat:
See full description above.

>Fix:
Find the patch attached.

Patch attached with submission follows:

--- lib/libc/gen/getcap.c.orig  2011-09-23 03:51:37.000000000 +0300
+++ lib/libc/gen/getcap.c       2012-07-12 10:21:29.000000000 +0300
@@ -654,7 +654,7 @@
        if (dbp == NULL)
                dbp = db_array;
 
-       if (pfp == NULL && (pfp = fopen(*dbp, "r")) == NULL) {
+       if (pfp == NULL && (pfp = fopen(*dbp, "re")) == NULL) {
                (void)cgetclose();
                return (-1);
        }
@@ -679,7 +679,7 @@
                                                (void)cgetclose();
                                                return (0);
                                        } else if ((pfp =
-                                           fopen(*dbp, "r")) == NULL) {
+                                                 fopen(*dbp, "re")) == NULL) {
                                                (void)cgetclose();
                                                return (-1);
                                        } else
--- lib/libc/gen/getttyent.c.orig       2011-09-23 03:51:37.000000000 +0300
+++ lib/libc/gen/getttyent.c    2012-07-12 10:18:06.000000000 +0300
@@ -211,7 +211,7 @@
        if (tf) {
                rewind(tf);
                return (1);
-       } else if ( (tf = fopen(_PATH_TTYS, "r")) )
+       } else if ( (tf = fopen(_PATH_TTYS, "re")) )
                return (1);
        return (0);
 }
--- lib/libc/gen/getusershell.c.orig    2011-09-23 03:51:37.000000000 +0300
+++ lib/libc/gen/getusershell.c 2012-07-12 10:24:29.000000000 +0300
@@ -121,7 +121,7 @@
                sl_free(sl, 1);
        sl = sl_init();
 
-       if ((fp = fopen(_PATH_SHELLS, "r")) == NULL)
+       if ((fp = fopen(_PATH_SHELLS, "re")) == NULL)
                return NS_UNAVAIL;
 
        cp = line;
--- lib/libc/gen/getutxent.c.orig       2012-03-02 23:38:27.000000000 +0200
+++ lib/libc/gen/getutxent.c    2012-07-12 10:27:07.000000000 +0300
@@ -66,7 +66,7 @@
 
        if (uf != NULL)
                fclose(uf);
-       uf = fopen(file, "r");
+       uf = fopen(file, "re");
        if (uf == NULL)
                return (-1);
 
--- cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c.orig        
2012-06-14 22:27:17.000000000 +0300
+++ cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c     2012-06-14 
22:27:30.000000000 +0300
@@ -1061,13 +1061,20 @@
         */
        dt_provmod_open(&provmod, &df);
 
-       dtfd = open("/dev/dtrace/dtrace", O_RDWR);
+/*
+ *  In case it is not defined, we define it temporarily to harmless 0.
+ */
+#if !defined(O_CLOEXEC)
+#  define O_CLOEXEC    0
+#endif
+
+       dtfd = open("/dev/dtrace/dtrace", O_RDWR | O_CLOEXEC);
        err = errno; /* save errno from opening dtfd */
 
 #if defined(sun)
        ftfd = open("/dev/dtrace/provider/fasttrap", O_RDWR);
 #else
-       ftfd = open("/dev/dtrace/fasttrap", O_RDWR);
+       ftfd = open("/dev/dtrace/fasttrap", O_RDWR | O_CLOEXEC);
 #endif
        fterr = ftfd == -1 ? errno : 0; /* save errno from open ftfd */
 
@@ -1097,8 +1104,11 @@
                return (set_open_errno(dtp, errp, err));
        }
 
+#if (O_CLOEXEC == 0)
        (void) fcntl(dtfd, F_SETFD, FD_CLOEXEC);
        (void) fcntl(ftfd, F_SETFD, FD_CLOEXEC);
+#  undef O_CLOEXEC
+#endif
 
 alloc:
        if ((dtp = malloc(sizeof (dtrace_hdl_t))) == NULL)
--- lib/libfetch/file.c.orig    2012-05-26 19:34:39.000000000 +0300
+++ lib/libfetch/file.c 2012-07-12 10:30:20.000000000 +0300
@@ -48,7 +48,7 @@
        if (us && fetchStatFile(u, us, flags) == -1)
                return (NULL);
 
-       f = fopen(u->doc, "r");
+       f = fopen(u->doc, "re");
 
        if (f == NULL)
                fetch_syserr();
@@ -58,7 +58,6 @@
                fetch_syserr();
        }
 
-       fcntl(fileno(f), F_SETFD, FD_CLOEXEC);
        return (f);
 }
 
@@ -74,9 +73,9 @@
        FILE *f;
 
        if (CHECK_FLAG('a'))
-               f = fopen(u->doc, "a");
+               f = fopen(u->doc, "ae");
        else
-               f = fopen(u->doc, "w+");
+               f = fopen(u->doc, "w+e");
 
        if (f == NULL)
                fetch_syserr();
@@ -86,7 +85,6 @@
                fetch_syserr();
        }
 
-       fcntl(fileno(f), F_SETFD, FD_CLOEXEC);
        return (f);
 }
 
--- lib/libkvm/kvm.c.orig       2012-06-17 17:48:21.000000000 +0300
+++ lib/libkvm/kvm.c    2012-06-17 17:55:25.000000000 +0300
@@ -166,7 +166,7 @@
        if (mf == 0)
                mf = _PATH_MEM;
 
-       if ((kd->pmfd = open(mf, flag, 0)) < 0) {
+       if ((kd->pmfd = open(mf, (flag | O_CLOEXEC), 0)) < 0) {
                _kvm_syserr(kd, kd->program, "%s", mf);
                goto failed;
        }
@@ -179,10 +179,7 @@
                _kvm_syserr(kd, kd->program, "empty file");
                goto failed;
        }
-       if (fcntl(kd->pmfd, F_SETFD, FD_CLOEXEC) < 0) {
-               _kvm_syserr(kd, kd->program, "%s", mf);
-               goto failed;
-       }
+
        if (S_ISCHR(st.st_mode)) {
                /*
                 * If this is a character special device, then check that
@@ -191,17 +188,16 @@
                 * case you're working with a live kernel.)
                 */
                if (strcmp(mf, _PATH_DEVNULL) == 0) {
-                       kd->vmfd = open(_PATH_DEVNULL, O_RDONLY);
+                       kd->vmfd = open(_PATH_DEVNULL,
+                                       (O_RDONLY | O_CLOEXEC));
                        return (kd);
                } else if (strcmp(mf, _PATH_MEM) == 0) {
-                       if ((kd->vmfd = open(_PATH_KMEM, flag)) < 0) {
-                               _kvm_syserr(kd, kd->program, "%s", _PATH_KMEM);
-                               goto failed;
-                       }
-                       if (fcntl(kd->vmfd, F_SETFD, FD_CLOEXEC) < 0) {
+                       if ((kd->vmfd = open(_PATH_KMEM, 
+                                            (flag | O_CLOEXEC))) < 0) {
                                _kvm_syserr(kd, kd->program, "%s", _PATH_KMEM);
                                goto failed;
                        }
+
                        return (kd);
                }
        }
@@ -210,14 +206,11 @@
         * Initialize the virtual address translation machinery,
         * but first setup the namelist fd.
         */
-       if ((kd->nlfd = open(uf, O_RDONLY, 0)) < 0) {
-               _kvm_syserr(kd, kd->program, "%s", uf);
-               goto failed;
-       }
-       if (fcntl(kd->nlfd, F_SETFD, FD_CLOEXEC) < 0) {
+       if ((kd->nlfd = open(uf, (O_RDONLY | O_CLOEXEC), 0)) < 0) {
                _kvm_syserr(kd, kd->program, "%s", uf);
                goto failed;
        }
+
        if (strncmp(mf, _PATH_FWMEM, strlen(_PATH_FWMEM)) == 0)
                kd->rawdump = 1;
        if (_kvm_initvtop(kd) < 0)


>Release-Note:
>Audit-Trail:
>Unformatted:
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-bugs
To unsubscribe, send any mail to "[email protected]"

Reply via email to