From 5a0f20a0802ec5698a44512e60b6653ea61db79c Mon Sep 17 00:00:00 2001 From: deraadt Date: Tue, 24 Jan 2017 04:09:59 +0000 Subject: Track a per-fd flag UF_PLEDGED. This indicates the initial open was done by a pledged process. dup(2) and recvmsg(2) retain UF_PLEDGED from the original fd. In pledge "exec" circumstances, exceve clears UF_PLEDGED on all the process's fds. In a pledge'd process, ioctl(2) can use this additional information to grant access to ioctl's which are more sensitive or dive deeply into the kernel. Developers will be encouraged to open such sensitive resources before calling pledge(2), rather than afterwards. That matches the heading of privsep development practices. Future changes will introduce those ioctl(2) changes. Lots of discussions with semarie guenther and benno. --- sys/kern/kern_descrip.c | 13 ++++++++++--- sys/kern/uipc_usrreq.c | 5 ++++- sys/sys/filedesc.h | 3 ++- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index 904f7b43439..8e549968e98 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_descrip.c,v 1.138 2017/01/23 23:22:00 mpi Exp $ */ +/* $OpenBSD: kern_descrip.c,v 1.139 2017/01/24 04:09:59 deraadt Exp $ */ /* $NetBSD: kern_descrip.c,v 1.42 1996/03/30 22:24:38 christos Exp $ */ /* @@ -611,7 +611,7 @@ finishdup(struct proc *p, struct file *fp, int old, int new, FREF(oldfp); fdp->fd_ofiles[new] = fp; - fdp->fd_ofileflags[new] = fdp->fd_ofileflags[old] & ~UF_EXCLOSE; + fdp->fd_ofileflags[new] = fdp->fd_ofileflags[old] & ~(UF_EXCLOSE|UF_PLEDGED); fp->f_count++; FRELE(fp, p); if (dup2 && oldfp == NULL) @@ -632,6 +632,7 @@ fdremove(struct filedesc *fdp, int fd) { fdpassertlocked(fdp); fdp->fd_ofiles[fd] = NULL; + fdp->fd_ofileflags[fd] = 0; fd_unused(fdp, fd); } @@ -805,6 +806,8 @@ restart: fdp->fd_freefile = i; *result = i; fdp->fd_ofileflags[i] = 0; + if (ISSET(p->p_p->ps_flags, PS_PLEDGE)) + fdp->fd_ofileflags[i] |= UF_PLEDGED; return (0); } } @@ -1299,6 +1302,8 @@ dupfdopen(struct proc *p, int indx, int mode) fdp->fd_ofiles[indx] = wfp; fdp->fd_ofileflags[indx] = (fdp->fd_ofileflags[indx] & UF_EXCLOSE) | (fdp->fd_ofileflags[dupfd] & ~UF_EXCLOSE); + if (ISSET(p->p_p->ps_flags, PS_PLEDGE)) + fdp->fd_ofileflags[indx] |= UF_PLEDGED; wfp->f_count++; fd_used(fdp, indx); return (0); @@ -1314,9 +1319,11 @@ fdcloseexec(struct proc *p) int fd; fdplock(fdp); - for (fd = 0; fd <= fdp->fd_lastfile; fd++) + for (fd = 0; fd <= fdp->fd_lastfile; fd++) { + fdp->fd_ofileflags[fd] &= ~UF_PLEDGED; if (fdp->fd_ofileflags[fd] & UF_EXCLOSE) (void) fdrelease(p, fd); + } fdpunlock(fdp); } diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c index ef14e79c4c2..4589f903a24 100644 --- a/sys/kern/uipc_usrreq.c +++ b/sys/kern/uipc_usrreq.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_usrreq.c,v 1.110 2017/01/23 23:44:04 deraadt Exp $ */ +/* $OpenBSD: uipc_usrreq.c,v 1.111 2017/01/24 04:09:59 deraadt Exp $ */ /* $NetBSD: uipc_usrreq.c,v 1.18 1996/02/09 19:00:50 christos Exp $ */ /* @@ -58,6 +58,7 @@ LIST_HEAD(unp_head, unpcb) unp_head = LIST_HEAD_INITIALIZER(unp_head); struct fdpass { struct file *fp; + int flags; }; /* @@ -759,6 +760,7 @@ restart: * in the loop below. */ p->p_fd->fd_ofiles[fdp[i]] = rp->fp; + p->p_fd->fd_ofileflags[fdp[i]] = (rp->flags & UF_PLEDGED); rp++; if (flags & MSG_CMSG_CLOEXEC) @@ -873,6 +875,7 @@ morespace: goto fail; } rp->fp = fp; + rp->flags = fdp->fd_ofileflags[fd] & UF_PLEDGED; rp--; fp->f_count++; if ((unp = fptounp(fp)) != NULL) { diff --git a/sys/sys/filedesc.h b/sys/sys/filedesc.h index 136133189b7..4e8767df955 100644 --- a/sys/sys/filedesc.h +++ b/sys/sys/filedesc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: filedesc.h,v 1.31 2017/01/23 22:34:10 deraadt Exp $ */ +/* $OpenBSD: filedesc.h,v 1.32 2017/01/24 04:09:59 deraadt Exp $ */ /* $NetBSD: filedesc.h,v 1.14 1996/04/09 20:55:28 cgd Exp $ */ /* @@ -105,6 +105,7 @@ struct filedesc0 { * Per-process open flags. */ #define UF_EXCLOSE 0x01 /* auto-close on exec */ +#define UF_PLEDGED 0x02 /* open after pledge(2) */ /* * Flags on the file descriptor table. -- cgit v1.2.3-59-g8ed1b