this hides more kernel pointers in the kinfo proc struct and
introduces a backdoor for the kmem group. also hoist the permission
test up out of the loops.

Index: sys/sysctl.h
===================================================================
RCS file: /cvs/src/sys/sys/sysctl.h,v
retrieving revision 1.129
diff -u -p -r1.129 sysctl.h
--- sys/sysctl.h        20 Mar 2013 04:26:11 -0000      1.129
+++ sys/sysctl.h        23 Mar 2013 10:47:11 -0000
@@ -467,19 +467,16 @@ struct kinfo_proc {
 do {                                                                   \
        memset((kp), 0, sizeof(*(kp)));                                 \
                                                                        \
-       if (show_addresses)                                             \
+       if (show_addresses) {                                           \
                (kp)->p_paddr = PTRTOINT64(paddr);                      \
-       (kp)->p_fd = PTRTOINT64((p)->p_fd);                             \
-       (kp)->p_stats = 0;                                              \
-       (kp)->p_limit = PTRTOINT64((pr)->ps_limit);                     \
-       (kp)->p_vmspace = PTRTOINT64((p)->p_vmspace);                   \
-       if (show_addresses)                                             \
+               (kp)->p_fd = PTRTOINT64((p)->p_fd);                     \
+               (kp)->p_stats = 0;                                      \
+               (kp)->p_limit = PTRTOINT64((pr)->ps_limit);             \
+               (kp)->p_vmspace = PTRTOINT64((p)->p_vmspace);           \
                (kp)->p_sigacts = PTRTOINT64((p)->p_sigacts);           \
-       if (show_addresses)                                             \
                (kp)->p_sess = PTRTOINT64((pg)->pg_session);            \
-       if (show_addresses)                                             \
                (kp)->p_ru = PTRTOINT64((pr)->ps_ru);                   \
-                                                                       \
+       }                                                               \
        (kp)->p_exitsig = (p)->p_exitsig;                               \
        (kp)->p_flag = (p)->p_flag | (pr)->ps_flags | P_INMEM;          \
                                                                        \
@@ -940,11 +937,6 @@ int sysctl_vnode(char *, size_t *, struc
 int sysctl_doprof(int *, u_int, void *, size_t *, void *, size_t);
 #endif
 int sysctl_dopool(int *, u_int, char *, size_t *);
-
-void fill_file2(struct kinfo_file2 *, struct file *, struct filedesc *,
-    int, struct vnode *, struct proc *, struct proc *);
-
-void fill_kproc(struct proc *, struct kinfo_proc *, int);
 
 int kern_sysctl(int *, u_int, void *, size_t *, void *, size_t,
                     struct proc *);
Index: kern/kern_sysctl.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_sysctl.c,v
retrieving revision 1.232
diff -u -p -r1.232 kern_sysctl.c
--- kern/kern_sysctl.c  20 Mar 2013 03:43:08 -0000      1.232
+++ kern/kern_sysctl.c  23 Mar 2013 10:51:44 -0000
@@ -121,6 +121,13 @@ int sysctl_sensors(int *, u_int, void *,
 int sysctl_emul(int *, u_int, void *, size_t *, void *, size_t);
 int sysctl_cptime2(int *, u_int, void *, size_t *, void *, size_t);
 
+void fill_file2(struct kinfo_file2 *, struct file *, struct filedesc *,
+    int, struct vnode *, struct proc *, struct proc *, int);
+void fill_kproc(struct proc *, struct kinfo_proc *, int, int);
+
+/* let's hope this doesn't change */
+#define KMEM_GROUP 2
+
 int (*cpu_cpuspeed)(int *);
 void (*cpu_setperf)(int);
 int perflevel = 100;
@@ -1058,10 +1065,10 @@ sysctl_file(char *where, size_t *sizep, 
 #ifndef SMALL_KERNEL
 void
 fill_file2(struct kinfo_file2 *kf, struct file *fp, struct filedesc *fdp,
-         int fd, struct vnode *vp, struct proc *pp, struct proc *p)
+         int fd, struct vnode *vp, struct proc *pp, struct proc *p,
+         int show_pointers)
 {
        struct vattr va;
-       int show_pointers = suser(curproc, 0) == 0;
 
        memset(kf, 0, sizeof(*kf));
 
@@ -1240,6 +1247,7 @@ sysctl_file2(int *name, u_int namelen, c
        char *dp = where;
        int arg, i, error = 0, needed = 0;
        u_int op;
+       int show_pointers;
 
        if (namelen > 4)
                return (ENOTDIR);
@@ -1256,11 +1264,14 @@ sysctl_file2(int *name, u_int namelen, c
        if (elem_size < 1)
                return (EINVAL);
 
+       show_pointers = suser(curproc, 0) == 0 ||
+           curproc->p_ucred->cr_gid == KMEM_GROUP;
+
        kf = malloc(sizeof(*kf), M_TEMP, M_WAITOK);
 
 #define FILLIT(fp, fdp, i, vp, pp) do {                                \
        if (buflen >= elem_size && elem_count > 0) {            \
-               fill_file2(kf, fp, fdp, i, vp, pp, p);          \
+               fill_file2(kf, fp, fdp, i, vp, pp, p, show_pointers);   \
                error = copyout(kf, dp, outsize);               \
                if (error)                                      \
                        break;                                  \
@@ -1383,6 +1394,7 @@ sysctl_doproc(int *name, u_int namelen, 
        int arg, buflen, doingzomb, elem_size, elem_count;
        int error, needed, op;
        int dothreads = 0;
+       int show_pointers;
 
        dp = where;
        buflen = where != NULL ? *sizep : 0;
@@ -1399,6 +1411,9 @@ sysctl_doproc(int *name, u_int namelen, 
        dothreads = op & KERN_PROC_SHOW_THREADS;
        op &= ~KERN_PROC_SHOW_THREADS;
 
+       show_pointers = suser(curproc, 0) == 0 ||
+           curproc->p_ucred->cr_gid == KMEM_GROUP;
+
        if (where != NULL)
                kproc = malloc(sizeof(*kproc), M_TEMP, M_WAITOK);
 
@@ -1473,7 +1488,7 @@ again:
 
                if ((p->p_flag & P_THREAD) == 0) {
                        if (buflen >= elem_size && elem_count > 0) {
-                               fill_kproc(p, kproc, 0);
+                               fill_kproc(p, kproc, 0, show_pointers);
                                /* Update %cpu for all threads */
                                if (!dothreads) {
                                        TAILQ_FOREACH(pp, &pr->ps_threads,
@@ -1497,7 +1512,7 @@ again:
                        continue;
 
                if (buflen >= elem_size && elem_count > 0) {
-                       fill_kproc(p, kproc, 1);
+                       fill_kproc(p, kproc, 1, show_pointers);
                        error = copyout(kproc, dp, elem_size);
                        if (error)
                                goto err;
@@ -1532,13 +1547,13 @@ err:
  * Fill in a kproc structure for the specified process.
  */
 void
-fill_kproc(struct proc *p, struct kinfo_proc *ki, int isthread)
+fill_kproc(struct proc *p, struct kinfo_proc *ki, int isthread,
+    int show_pointers)
 {
        struct process *pr = p->p_p;
        struct session *s = pr->ps_session;
        struct tty *tp;
        struct timeval ut, st;
-       int show_pointers = suser(curproc, 0) == 0;
 
        FILL_KPROC(ki, strlcpy, p, pr, p->p_cred, p->p_ucred, pr->ps_pgrp,
            p, pr, s, p->p_vmspace, pr->ps_limit, p->p_sigacts, isthread,

Reply via email to