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,