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 info leak, we do a blunt copy of struct ...



details:   https://anonhg.NetBSD.org/src/rev/d7ea3cdf545c
branches:  trunk
changeset: 446125:d7ea3cdf545c
user:      maxv <maxv%NetBSD.org@localhost>
date:      Sat Nov 24 16:18:36 2018 +0000

description:
Fix kernel info leak, we do a blunt copy of struct proc, but it has
padding. So zero out the structure on each allocation. And copy field by
field while here, because many fields should be hidden by COND_SET_VALUE.

diffstat:

 sys/kern/kern_proc.c |  105 +++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 102 insertions(+), 3 deletions(-)

diffs (147 lines):

diff -r 4a0b30a813a0 -r d7ea3cdf545c sys/kern/kern_proc.c
--- a/sys/kern/kern_proc.c      Sat Nov 24 15:44:13 2018 +0000
+++ b/sys/kern/kern_proc.c      Sat Nov 24 16:18:36 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_proc.c,v 1.219 2018/11/12 06:55:03 maxv Exp $     */
+/*     $NetBSD: kern_proc.c,v 1.220 2018/11/24 16:18:36 maxv Exp $     */
 
 /*-
  * Copyright (c) 1999, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_proc.c,v 1.219 2018/11/12 06:55:03 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_proc.c,v 1.220 2018/11/24 16:18:36 maxv Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_kstack.h"
@@ -241,6 +241,7 @@
 
 static kauth_listener_t proc_listener;
 
+static void fill_proc(const struct proc *, struct proc *);
 static int fill_pathname(struct lwp *, pid_t, void *, size_t *);
 
 static int
@@ -746,6 +747,7 @@
        struct proc *p;
 
        p = pool_cache_get(proc_cache, PR_WAITOK);
+       memset(p, 0, sizeof(*p));
        p->p_stat = SIDL;                       /* protect against others */
        proc_initspecific(p);
        kdtrace_proc_ctor(NULL, p);
@@ -1791,7 +1793,7 @@
                if (buflen >= elem_size &&
                    (type == KERN_PROC || elem_count > 0)) {
                        if (type == KERN_PROC) {
-                               kbuf->kproc.kp_proc = *p;
+                               fill_proc(p, &kbuf->kproc.kp_proc);
                                fill_eproc(p, &kbuf->kproc.kp_eproc, zombie);
                        } else {
                                fill_kproc2(p, &kbuf->kproc2, zombie);
@@ -2161,6 +2163,103 @@
 }
 
 /*
+ * Fill in a proc structure for the specified process.
+ */
+static void
+fill_proc(const struct proc *psrc, struct proc *p)
+{
+       const bool allowaddr = get_expose_address(curproc);
+
+       memset(p, 0, sizeof(*p));
+
+       COND_SET_VALUE(p->p_list, psrc->p_list, allowaddr);
+       COND_SET_VALUE(p->p_auxlock, psrc->p_auxlock, allowaddr);
+       COND_SET_VALUE(p->p_lock, psrc->p_lock, allowaddr);
+       COND_SET_VALUE(p->p_stmutex, psrc->p_stmutex, allowaddr);
+       COND_SET_VALUE(p->p_reflock, psrc->p_reflock, allowaddr);
+       COND_SET_VALUE(p->p_waitcv, psrc->p_waitcv, allowaddr);
+       COND_SET_VALUE(p->p_lwpcv, psrc->p_lwpcv, allowaddr);
+       COND_SET_VALUE(p->p_cred, psrc->p_cred, allowaddr);
+       COND_SET_VALUE(p->p_fd, psrc->p_fd, allowaddr);
+       COND_SET_VALUE(p->p_cwdi, psrc->p_cwdi, allowaddr);
+       COND_SET_VALUE(p->p_stats, psrc->p_stats, allowaddr);
+       COND_SET_VALUE(p->p_limit, psrc->p_limit, allowaddr);
+       COND_SET_VALUE(p->p_vmspace, psrc->p_vmspace, allowaddr);
+       COND_SET_VALUE(p->p_sigacts, psrc->p_sigacts, allowaddr);
+       COND_SET_VALUE(p->p_aio, psrc->p_aio, allowaddr);
+       p->p_mqueue_cnt = psrc->p_mqueue_cnt;
+       COND_SET_VALUE(p->p_specdataref, psrc->p_specdataref, allowaddr);
+       p->p_exitsig = psrc->p_exitsig;
+       p->p_flag = psrc->p_flag;
+       p->p_sflag = psrc->p_sflag;
+       p->p_slflag = psrc->p_slflag;
+       p->p_lflag = psrc->p_lflag;
+       p->p_stflag = psrc->p_stflag;
+       p->p_stat = psrc->p_stat;
+       p->p_trace_enabled = psrc->p_trace_enabled;
+       p->p_pid = psrc->p_pid;
+       COND_SET_VALUE(p->p_pglist, psrc->p_pglist, allowaddr);
+       COND_SET_VALUE(p->p_pptr, psrc->p_pptr, allowaddr);
+       COND_SET_VALUE(p->p_sibling, psrc->p_sibling, allowaddr);
+       COND_SET_VALUE(p->p_children, psrc->p_children, allowaddr);
+       COND_SET_VALUE(p->p_lwps, psrc->p_lwps, allowaddr);
+       COND_SET_VALUE(p->p_raslist, psrc->p_raslist, allowaddr);
+       p->p_nlwps = psrc->p_nlwps;
+       p->p_nzlwps = psrc->p_nzlwps;
+       p->p_nrlwps = psrc->p_nrlwps;
+       p->p_nlwpwait = psrc->p_nlwpwait;
+       p->p_ndlwps = psrc->p_ndlwps;
+       p->p_nlwpid = psrc->p_nlwpid;
+       p->p_nstopchild = psrc->p_nstopchild;
+       p->p_waited = psrc->p_waited;
+       COND_SET_VALUE(p->p_zomblwp, psrc->p_zomblwp, allowaddr);
+       COND_SET_VALUE(p->p_vforklwp, psrc->p_vforklwp, allowaddr);
+       COND_SET_VALUE(p->p_sched_info, psrc->p_sched_info, allowaddr);
+       p->p_estcpu = psrc->p_estcpu;
+       p->p_estcpu_inherited = psrc->p_estcpu_inherited;
+       p->p_forktime = psrc->p_forktime;
+       p->p_pctcpu = psrc->p_pctcpu;
+       COND_SET_VALUE(p->p_opptr, psrc->p_opptr, allowaddr);
+       COND_SET_VALUE(p->p_timers, psrc->p_timers, allowaddr);
+       p->p_rtime = psrc->p_rtime;
+       p->p_uticks = psrc->p_uticks;
+       p->p_sticks = psrc->p_sticks;
+       p->p_iticks = psrc->p_iticks;
+       p->p_xutime = psrc->p_xutime;
+       p->p_xstime = psrc->p_xstime;
+       p->p_traceflag = psrc->p_traceflag;
+       COND_SET_VALUE(p->p_tracep, psrc->p_tracep, allowaddr);
+       COND_SET_VALUE(p->p_textvp, psrc->p_textvp, allowaddr);
+       COND_SET_VALUE(p->p_emul, psrc->p_emul, allowaddr);
+       COND_SET_VALUE(p->p_emuldata, psrc->p_emuldata, allowaddr);
+       COND_SET_VALUE(p->p_execsw, psrc->p_execsw, allowaddr);
+       COND_SET_VALUE(p->p_klist, psrc->p_klist, allowaddr);
+       COND_SET_VALUE(p->p_sigwaiters, psrc->p_sigwaiters, allowaddr);
+       COND_SET_VALUE(p->p_sigpend, psrc->p_sigpend, allowaddr);
+       COND_SET_VALUE(p->p_lwpctl, psrc->p_lwpctl, allowaddr);
+       p->p_ppid = psrc->p_ppid;
+       p->p_fpid = psrc->p_fpid;
+       p->p_vfpid = psrc->p_vfpid;
+       p->p_vfpid_done = psrc->p_vfpid_done;
+       p->p_lwp_created = psrc->p_lwp_created;
+       p->p_lwp_exited = psrc->p_lwp_exited;
+       p->p_nsems = psrc->p_nsems;
+       COND_SET_VALUE(p->p_path, psrc->p_path, allowaddr);
+       COND_SET_VALUE(p->p_sigctx, psrc->p_sigctx, allowaddr);
+       p->p_nice = psrc->p_nice;
+       memcpy(p->p_comm, psrc->p_comm, sizeof(p->p_comm));
+       COND_SET_VALUE(p->p_pgrp, psrc->p_pgrp, allowaddr);
+       COND_SET_VALUE(p->p_psstrp, psrc->p_psstrp, allowaddr);
+       p->p_pax = psrc->p_pax;
+       p->p_xexit = psrc->p_xexit;
+       p->p_xsig = psrc->p_xsig;
+       p->p_acflag = psrc->p_acflag;
+       COND_SET_VALUE(p->p_md, psrc->p_md, allowaddr);
+       p->p_stackbase = psrc->p_stackbase;
+       COND_SET_VALUE(p->p_dtrace, psrc->p_dtrace, allowaddr);
+}
+
+/*
  * Fill in an eproc structure for the specified process.
  */
 void



Home | Main Index | Thread Index | Old Index