summaryrefslogtreecommitdiff
path: root/sys/kern/kern_sysctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern/kern_sysctl.c')
-rw-r--r--sys/kern/kern_sysctl.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c
index 1a0a15f00eb..84584964fd2 100644
--- a/sys/kern/kern_sysctl.c
+++ b/sys/kern/kern_sysctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_sysctl.c,v 1.161 2008/06/09 07:07:16 djm Exp $ */
+/* $OpenBSD: kern_sysctl.c,v 1.162 2008/10/07 02:20:11 deraadt Exp $ */
/* $NetBSD: kern_sysctl.c,v 1.17 1996/05/20 17:49:05 mrg Exp $ */
/*-
@@ -347,7 +347,7 @@ kern_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
p));
#endif
case KERN_FILE:
- return (sysctl_file(oldp, oldlenp));
+ return (sysctl_file(oldp, oldlenp, p));
case KERN_MBSTAT:
return (sysctl_rdstruct(oldp, oldlenp, newp, &mbstat,
sizeof(mbstat)));
@@ -923,11 +923,12 @@ sysctl_rdstruct(void *oldp, size_t *oldlenp, void *newp, const void *sp,
* Get file structures.
*/
int
-sysctl_file(char *where, size_t *sizep)
+sysctl_file(char *where, size_t *sizep, struct proc *p)
{
int buflen, error;
- struct file *fp;
+ struct file *fp, cfile;
char *start = where;
+ struct ucred *cred = p->p_ucred;
buflen = *sizep;
if (where == NULL) {
@@ -959,7 +960,17 @@ sysctl_file(char *where, size_t *sizep)
*sizep = where - start;
return (ENOMEM);
}
- error = copyout((caddr_t)fp, where, sizeof (struct file));
+
+ /* Only let the superuser or the owner see some information */
+ bcopy(fp, &cfile, sizeof (struct file));
+ if (suser(p, 0) != 0 && cred->cr_uid != fp->f_cred->cr_uid) {
+ cfile.f_offset = (off_t)-1;
+ cfile.f_rxfer = 0;
+ cfile.f_wxfer = 0;
+ cfile.f_rbytes = 0;
+ cfile.f_wbytes = 0;
+ }
+ error = copyout(&cfile, where, sizeof (struct file));
if (error)
return (error);
buflen -= sizeof(struct file);