Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/lib/libkvm Set the close-on-exec bit on all file descriptors...



details:   https://anonhg.NetBSD.org/src/rev/59e7661f1e4e
branches:  trunk
changeset: 536470:59e7661f1e4e
user:      christos <christos%NetBSD.org@localhost>
date:      Mon Sep 16 17:20:45 2002 +0000

description:
Set the close-on-exec bit on all file descriptors we open. Inspired by a
FreeBSD security advisory.

Reviewed by thorpej

diffstat:

 lib/libkvm/kvm.c |  51 ++++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 44 insertions(+), 7 deletions(-)

diffs (122 lines):

diff -r 4c16a643e71d -r 59e7661f1e4e lib/libkvm/kvm.c
--- a/lib/libkvm/kvm.c  Mon Sep 16 17:12:08 2002 +0000
+++ b/lib/libkvm/kvm.c  Mon Sep 16 17:20:45 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kvm.c,v 1.72 2002/08/08 01:30:09 soren Exp $   */
+/*     $NetBSD: kvm.c,v 1.73 2002/09/16 17:20:45 christos Exp $        */
 
 /*-
  * Copyright (c) 1989, 1992, 1993
@@ -42,7 +42,7 @@
 #if 0
 static char sccsid[] = "@(#)kvm.c      8.2 (Berkeley) 2/13/94";
 #else
-__RCSID("$NetBSD: kvm.c,v 1.72 2002/08/08 01:30:09 soren Exp $");
+__RCSID("$NetBSD: kvm.c,v 1.73 2002/09/16 17:20:45 christos Exp $");
 #endif
 #endif /* LIBC_SCCS and not lint */
 
@@ -79,6 +79,7 @@
 static kvm_t   *_kvm_open __P((kvm_t *, const char *, const char *,
                    const char *, int, char *));
 static int     clear_gap __P((kvm_t *, FILE *, int));
+static int     open_cloexec  __P((const char *, int, int));
 static off_t   Lseek __P((kvm_t *, int, off_t, int));
 static ssize_t Pread __P((kvm_t *, int, void *, size_t, off_t));
 
@@ -147,6 +148,31 @@
 }
 
 /*
+ * Open a file setting the close on exec bit.
+ */
+static int
+open_cloexec(fname, flags, mode)
+       const char *fname;
+       int flags, mode;
+{
+       int fd;
+
+       if ((fd = open(fname, flags, mode)) == -1)
+               return fd;
+       if ((flags = fcntl(fd, F_GETFL, 0)) == -1)
+               goto error;
+       if (fcntl(fd, F_SETFL, flags | 1) == -1)
+               goto error;
+
+       return fd;
+error:
+       flags = errno;
+       (void)close(fd);
+       errno = flags;
+       return -1;
+}
+
+/*
  * Wrapper around the lseek(2) system call; calls _kvm_syserr() for us
  * in the event of emergency.
  */
@@ -253,7 +279,7 @@
        if (sf == 0)
                sf = _PATH_DRUM;
 
-       if ((kd->pmfd = open(mf, flag, 0)) < 0) {
+       if ((kd->pmfd = open_cloexec(mf, flag, 0)) < 0) {
                _kvm_syserr(kd, kd->program, "%s", mf);
                goto failed;
        }
@@ -273,12 +299,12 @@
                                 "%s: not physical memory device", mf);
                        goto failed;
                }
-               if ((kd->vmfd = open(_PATH_KMEM, flag, 0)) < 0) {
+               if ((kd->vmfd = open_cloexec(_PATH_KMEM, flag, 0)) < 0) {
                        _kvm_syserr(kd, kd->program, "%s", _PATH_KMEM);
                        goto failed;
                }
                kd->alive = KVM_ALIVE_FILES;
-               if ((kd->swfd = open(sf, flag, 0)) < 0) {
+               if ((kd->swfd = open_cloexec(sf, flag, 0)) < 0) {
                        _kvm_syserr(kd, kd->program, "%s", sf);
                        goto failed;
                }
@@ -290,7 +316,7 @@
                 * revert to slow nlist() calls.
                 */
                if ((ufgiven || kvm_dbopen(kd) < 0) &&
-                   (kd->nlfd = open(uf, O_RDONLY, 0)) < 0) {
+                   (kd->nlfd = open_cloexec(uf, O_RDONLY, 0)) < 0) {
                        _kvm_syserr(kd, kd->program, "%s", uf);
                        goto failed;
                }
@@ -300,7 +326,7 @@
                 * Initialize the virtual address translation machinery,
                 * but first setup the namelist fd.
                 */
-               if ((kd->nlfd = open(uf, O_RDONLY, 0)) < 0) {
+               if ((kd->nlfd = open_cloexec(uf, O_RDONLY, 0)) < 0) {
                        _kvm_syserr(kd, kd->program, "%s", uf);
                        goto failed;
                }
@@ -699,10 +725,21 @@
        struct nlist nitem;
        char dbversion[_POSIX2_LINE_MAX];
        char kversion[_POSIX2_LINE_MAX];
+       int fd, flags;
 
        kd->db = dbopen(_PATH_KVMDB, O_RDONLY, 0, DB_HASH, NULL);
        if (kd->db == 0)
                return (-1);
+       if ((fd = (*kd->db->fd)(kd->db)) >= 0) {
+               if ((flags = fcntl(fd, F_GETFL, 0)) == -1) {
+                      (*kd->db->close)(kd->db);
+                      return (-1);
+               }
+               if (fcntl(fd, F_SETFL, flags | 1) == -1) {
+                      (*kd->db->close)(kd->db);
+                      return (-1);
+               }
+       }
        /*
         * read version out of database
         */



Home | Main Index | Thread Index | Old Index