Source-Changes-HG archive

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

[src/trunk]: src/sys/kern Fix kernel pointer leaks in the kern.file sysctl, s...



details:   https://anonhg.NetBSD.org/src/rev/f59b3d1eb6df
branches:  trunk
changeset: 446127:f59b3d1eb6df
user:      maxv <maxv%NetBSD.org@localhost>
date:      Sat Nov 24 16:41:48 2018 +0000

description:
Fix kernel pointer leaks in the kern.file sysctl, same as kern.file2.

diffstat:

 sys/kern/kern_descrip.c |  43 +++++++++++++++++++++++++++++++++++++------
 1 files changed, 37 insertions(+), 6 deletions(-)

diffs (96 lines):

diff -r f4438e7907b0 -r f59b3d1eb6df sys/kern/kern_descrip.c
--- a/sys/kern/kern_descrip.c   Sat Nov 24 16:25:20 2018 +0000
+++ b/sys/kern/kern_descrip.c   Sat Nov 24 16:41:48 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_descrip.c,v 1.240 2018/11/24 16:25:20 maxv Exp $  */
+/*     $NetBSD: kern_descrip.c,v 1.241 2018/11/24 16:41:48 maxv Exp $  */
 
 /*-
  * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -70,7 +70,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_descrip.c,v 1.240 2018/11/24 16:25:20 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_descrip.c,v 1.241 2018/11/24 16:41:48 maxv Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -118,6 +118,7 @@
 
 static int sysctl_kern_file(SYSCTLFN_PROTO);
 static int sysctl_kern_file2(SYSCTLFN_PROTO);
+static void fill_file(struct file *, const struct file *);
 static void fill_file2(struct kinfo_file *, const file_t *, const fdfile_t *,
                      int, pid_t);
 
@@ -1990,6 +1991,8 @@
 static int
 sysctl_kern_file(SYSCTLFN_ARGS)
 {
+       const bool allowaddr = get_expose_address(curproc);
+       struct filelist flist;
        int error;
        size_t buflen;
        struct file *fp, fbuf;
@@ -2016,13 +2019,18 @@
                return 0;
        }
        sysctl_unlock();
-       error = sysctl_copyout(l, &filehead, where, sizeof(filehead));
+       if (allowaddr) {
+               memcpy(&flist, &filehead, sizeof(flist));
+       } else {
+               memset(&flist, 0, sizeof(flist));
+       }
+       error = sysctl_copyout(l, &flist, where, sizeof(flist));
        if (error) {
                sysctl_relock();
                return error;
        }
-       buflen -= sizeof(filehead);
-       where += sizeof(filehead);
+       buflen -= sizeof(flist);
+       where += sizeof(flist);
 
        /*
         * followed by an array of file structures
@@ -2090,7 +2098,7 @@
                                break;
                        }
 
-                       memcpy(&fbuf, fp, sizeof(fbuf));
+                       fill_file(&fbuf, fp);
                        mutex_exit(&fp->f_lock);
                        error = sysctl_copyout(l, &fbuf, where, sizeof(fbuf));
                        if (error) {
@@ -2286,6 +2294,29 @@
 }
 
 static void
+fill_file(struct file *fp, const struct file *fpsrc)
+{
+       const bool allowaddr = get_expose_address(curproc);
+
+       memset(fp, 0, sizeof(*fp));
+
+       fp->f_offset = fpsrc->f_offset;
+       COND_SET_VALUE(fp->f_cred, fpsrc->f_cred, allowaddr);
+       COND_SET_VALUE(fp->f_ops, fpsrc->f_ops, allowaddr);
+       COND_SET_VALUE(fp->f_undata, fpsrc->f_undata, allowaddr);
+       COND_SET_VALUE(fp->f_list, fpsrc->f_list, allowaddr);
+       COND_SET_VALUE(fp->f_lock, fpsrc->f_lock, allowaddr);
+       fp->f_flag = fpsrc->f_flag;
+       fp->f_marker = fpsrc->f_marker;
+       fp->f_type = fpsrc->f_type;
+       fp->f_advice = fpsrc->f_advice;
+       fp->f_count = fpsrc->f_count;
+       fp->f_msgcount = fpsrc->f_msgcount;
+       fp->f_unpcount = fpsrc->f_unpcount;
+       COND_SET_VALUE(fp->f_unplist, fpsrc->f_unplist, allowaddr);
+}
+
+static void
 fill_file2(struct kinfo_file *kp, const file_t *fp, const fdfile_t *ff,
          int i, pid_t pid)
 {



Home | Main Index | Thread Index | Old Index