diff options
Diffstat (limited to 'sys/kern/kern_descrip.c')
-rw-r--r-- | sys/kern/kern_descrip.c | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index 26e0cfc..84864a1 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -40,6 +40,7 @@ */ #include "opt_compat.h" +#include "opt_dontuse.h" #include <sys/param.h> #include <sys/systm.h> #include <sys/sysproto.h> @@ -937,6 +938,64 @@ fdfree(p) } /* + * For setuid/setgid programs we don't want to people to use that setuidness + * to generate error messages which write to a file which otherwise would + * otherwise be off limits to the proces. + * + * This is a gross hack to plug the hole. A better solution would involve + * a special vop or other form of generalized access control mechanism. We + * go ahead and just reject all procfs file systems accesses as dangerous. + * + * Since setugidsafety calls this only for fd 0, 1 and 2, this check is + * sufficient. We also don't for setugidness since we know we are. + */ +static int +is_unsafe(struct file *fp) +{ +#if PROCFS + if (fp->f_type == DTYPE_VNODE && + ((struct vnode *)(fp->f_data))->v_tag == VT_PROCFS) + return (1); +#endif + return (0); +} + +/* + * Make this setguid thing safe, if at all possible. + */ +void +setugidsafety(p) + struct proc *p; +{ + struct filedesc *fdp = p->p_fd; + struct file **fpp; + char *fdfp; + register int i; + + /* Certain daemons might not have file descriptors. */ + if (fdp == NULL) + return; + + fpp = fdp->fd_ofiles; + fdfp = fdp->fd_ofileflags; + for (i = 0; i <= fdp->fd_lastfile; i++, fpp++, fdfp++) { + if (i > 2) + break; + if (*fpp != NULL && is_unsafe(*fpp)) { + if (*fdfp & UF_MAPPED) + (void) munmapfd(p, i); + (void) closef(*fpp, p); + *fpp = NULL; + *fdfp = 0; + if (i < fdp->fd_freefile) + fdp->fd_freefile = i; + } + } + while (fdp->fd_lastfile > 0 && fdp->fd_ofiles[fdp->fd_lastfile] == NULL) + fdp->fd_lastfile--; +} + +/* * Close any files on exec? */ void |