diff options
author | trociny <trociny@FreeBSD.org> | 2012-02-26 14:25:48 +0000 |
---|---|---|
committer | trociny <trociny@FreeBSD.org> | 2012-02-26 14:25:48 +0000 |
commit | a9902044d13d86ba035c143f8484325fc569be5c (patch) | |
tree | bd8f20f1a852febeb3976d27f2d4839a90e8bcd0 /sys/kern/kern_proc.c | |
parent | bb3d17b00a07ca5a59201757d04996502b418744 (diff) | |
download | FreeBSD-src-a9902044d13d86ba035c143f8484325fc569be5c.zip FreeBSD-src-a9902044d13d86ba035c143f8484325fc569be5c.tar.gz |
Add sysctl to retrieve or set umask of another process.
Submitted by: Dmitry Banschikov <me ubique spb ru>
Discussed with: kib, rwatson
Reviewed by: kib
MFC after: 2 weeks
Diffstat (limited to 'sys/kern/kern_proc.c')
-rw-r--r-- | sys/kern/kern_proc.c | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c index 41b6f2b..50e5368 100644 --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -60,6 +60,7 @@ __FBSDID("$FreeBSD$"); #include <sys/sched.h> #include <sys/smp.h> #include <sys/stack.h> +#include <sys/stat.h> #include <sys/sysctl.h> #include <sys/filedesc.h> #include <sys/tty.h> @@ -2471,6 +2472,49 @@ sysctl_kern_proc_ps_strings(SYSCTL_HANDLER_ARGS) return (error); } +/* + * This sysctl allows a process to retrieve or/and set umask of + * another process. + */ +static int +sysctl_kern_proc_umask(SYSCTL_HANDLER_ARGS) +{ + int *name = (int *)arg1; + u_int namelen = arg2; + struct proc *p; + int error; + u_short fd_cmask; + + if (namelen != 1) + return (EINVAL); + + if (req->newptr != NULL && req->newlen != sizeof(fd_cmask)) + return (EINVAL); + + error = pget((pid_t)name[0], PGET_WANTREAD, &p); + if (error != 0) + return (error); + + FILEDESC_SLOCK(p->p_fd); + fd_cmask = p->p_fd->fd_cmask; + FILEDESC_SUNLOCK(p->p_fd); + error = SYSCTL_OUT(req, &fd_cmask, sizeof(fd_cmask)); + if (error != 0) + goto errout; + + if (req->newptr != NULL) { + error = SYSCTL_IN(req, &fd_cmask, sizeof(fd_cmask)); + if (error == 0) { + FILEDESC_XLOCK(p->p_fd); + p->p_fd->fd_cmask = fd_cmask & ALLPERMS; + FILEDESC_XUNLOCK(p->p_fd); + } + } +errout: + PRELE(p); + return (error); +} + SYSCTL_NODE(_kern, KERN_PROC, proc, CTLFLAG_RD, 0, "Process table"); SYSCTL_PROC(_kern_proc, KERN_PROC_ALL, all, CTLFLAG_RD|CTLTYPE_STRUCT| @@ -2572,3 +2616,7 @@ static SYSCTL_NODE(_kern_proc, KERN_PROC_RLIMIT, rlimit, CTLFLAG_RW | static SYSCTL_NODE(_kern_proc, KERN_PROC_PS_STRINGS, ps_strings, CTLFLAG_RD | CTLFLAG_MPSAFE, sysctl_kern_proc_ps_strings, "Process ps_strings location"); + +static SYSCTL_NODE(_kern_proc, KERN_PROC_UMASK, umask, CTLFLAG_RW | + CTLFLAG_ANYBODY | CTLFLAG_MPSAFE, sysctl_kern_proc_umask, + "Process umask"); |