tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: KAUTH_GENERIC_CANSEE
Hi,
Attached is a patch to do what David suggested for one of the two
instances. It's abusing the f_unused1 field to do the marking, and
uses a static "seq" variable... I'm sure someone will come up with
a better way of doing the same thing.
Once we've agreed on the approach I'll adjust the other instance
and post a complete diff.
Please review. FWIW, I've written a kernel module using both methods
to test the changes and they seem fine. I'm also running with this
change locally and pstat seems fine as well.
Thanks,
-e.
Index: init_sysctl.c
===================================================================
RCS file: /cvsroot/src/sys/kern/init_sysctl.c,v
retrieving revision 1.168
diff -u -p -r1.168 init_sysctl.c
--- init_sysctl.c 21 Oct 2009 21:12:06 -0000 1.168
+++ init_sysctl.c 15 Nov 2009 08:17:43 -0000
@@ -1877,7 +1877,7 @@ static int
sysctl_kern_file2(SYSCTLFN_ARGS)
{
struct proc *p;
- struct file *fp, *tp, *np;
+ struct file *fp;
struct filedesc *fd;
struct kinfo_file kf;
char *dp;
@@ -1886,6 +1886,7 @@ sysctl_kern_file2(SYSCTLFN_ARGS)
int error, arg, elem_count;
fdfile_t *ff;
fdtab_t *dt;
+ static u_int seq = 0;
if (namelen == 1 && name[0] == CTL_QUERY)
return (sysctl_query(SYSCTLFN_CALL(rnode)));
@@ -1908,65 +1909,21 @@ sysctl_kern_file2(SYSCTLFN_ARGS)
switch (op) {
case KERN_FILE_BYFILE:
+ case KERN_FILE_BYPID:
/*
- * doesn't use arg so it must be zero
- */
- if (arg != 0)
- return (EINVAL);
- sysctl_unlock();
- /*
- * allocate dummy file descriptor to make position in list
+ * We're traversing the process list in both cases; the BYFILE
+ * case does additional work of keeping track of files already
+ * looked at.
*/
- if ((tp = fgetdummy()) == NULL) {
- sysctl_relock();
- return ENOMEM;
- }
- mutex_enter(&filelist_lock);
- for (fp = LIST_FIRST(&filehead); fp != NULL; fp = np) {
- np = LIST_NEXT(fp, f_list);
- mutex_enter(&fp->f_lock);
- if (fp->f_count == 0) {
- mutex_exit(&fp->f_lock);
- continue;
- }
- /*
- * XXX Need to prevent that from being an alternative
- * XXX way for getting process information.
- */
- if (kauth_authorize_generic(l->l_cred,
- KAUTH_GENERIC_CANSEE, fp->f_cred) != 0) {
- mutex_exit(&fp->f_lock);
- continue;
- }
- if (len >= elem_size && elem_count > 0) {
- fill_file(&kf, fp, NULL, 0, 0);
- LIST_INSERT_AFTER(fp, tp, f_list);
- mutex_exit(&fp->f_lock);
- mutex_exit(&filelist_lock);
- error = dcopyout(l, &kf, dp, out_size);
- mutex_enter(&filelist_lock);
- np = LIST_NEXT(tp, f_list);
- LIST_REMOVE(tp, f_list);
- if (error) {
- break;
- }
- dp += elem_size;
- len -= elem_size;
- } else {
- mutex_exit(&fp->f_lock);
- }
- needed += elem_size;
- if (elem_count > 0 && elem_count != INT_MAX)
- elem_count--;
- }
- mutex_exit(&filelist_lock);
- fputdummy(tp);
- sysctl_relock();
- break;
- case KERN_FILE_BYPID:
- if (arg < -1)
+
+ /* doesn't use arg so it must be zero */
+ if ((op == KERN_FILE_BYFILE) && (arg != 0))
+ return EINVAL;
+
+ if ((op == KERN_FILE_BYPID) && (arg < -1))
/* -1 means all processes */
return (EINVAL);
+
sysctl_unlock();
mutex_enter(proc_lock);
PROCLIST_FOREACH(p, &allproc) {
@@ -2013,6 +1970,10 @@ sysctl_kern_file2(SYSCTLFN_ARGS)
if ((fp = ff->ff_file) == NULL) {
continue;
}
+ if ((op == KERN_FILE_BYFILE) &&
+ (fp->f_unused1 == seq)) {
+ continue;
+ }
if (len >= elem_size && elem_count > 0) {
mutex_enter(&fp->f_lock);
fill_file(&kf, fp, ff, i, p->p_pid);
@@ -2025,6 +1986,8 @@ sysctl_kern_file2(SYSCTLFN_ARGS)
dp += elem_size;
len -= elem_size;
}
+ if (op == KERN_FILE_BYFILE)
+ fp->f_unused1 = seq;
needed += elem_size;
if (elem_count > 0 && elem_count != INT_MAX)
elem_count--;
@@ -2037,6 +2000,8 @@ sysctl_kern_file2(SYSCTLFN_ARGS)
mutex_enter(proc_lock);
rw_exit(&p->p_reflock);
}
+ if (op == KERN_FILE_BYFILE)
+ seq++;
mutex_exit(proc_lock);
sysctl_relock();
break;
Home |
Main Index |
Thread Index |
Old Index