Module Name: src
Committed By: maxv
Date: Sat Nov 24 16:41:48 UTC 2018
Modified Files:
src/sys/kern: kern_descrip.c
Log Message:
Fix kernel pointer leaks in the kern.file sysctl, same as kern.file2.
To generate a diff of this commit:
cvs rdiff -u -r1.240 -r1.241 src/sys/kern/kern_descrip.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/kern/kern_descrip.c
diff -u src/sys/kern/kern_descrip.c:1.240 src/sys/kern/kern_descrip.c:1.241
--- src/sys/kern/kern_descrip.c:1.240 Sat Nov 24 16:25:20 2018
+++ src/sys/kern/kern_descrip.c Sat Nov 24 16:41:48 2018
@@ -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 filedescopen(dev_t, int, int,
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 @@ sysctl_file_marker_reset(void)
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 @@ sysctl_kern_file(SYSCTLFN_ARGS)
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 @@ sysctl_kern_file(SYSCTLFN_ARGS)
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 @@ sysctl_kern_file2(SYSCTLFN_ARGS)
}
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)
{