> There has been developer pressure to permit an increasing number of
> ioctl's to pledged programs. The problem is that providing a specific
> ioctl under a promise to one program, means it becomes supplied to all
> other programs that make that promise. There is no discrete method
> to differentiate further, until now.
>
> This proposal annotates file descriptors allocated before the first
> pledge(2) call in a process, with a marker. Such file descriptors can
> be dup'd; the mark is retained. They can fdpassed, which also retains
> the mark in the receiver (therefore, a non-pledged process can feed a
> pledged process). Execve clears this flag.
>
> That is the proposed semantic. There are still a few glitches.
>
> Once that mark exists, I feel more comfortable adding additional ioctl's
> which demand early-open fd's. Specifically in privsep daemons.
>
> 5 programs have been discovered in the tree which needed small changes
> (csh, ksh, less, tmux, dhclient).
>
> less and tmux fixes are not commited, be cautious about tmux.
New version.
Index: sys/filedesc.h
===================================================================
RCS file: /cvs/src/sys/sys/filedesc.h,v
retrieving revision 1.30
diff -u -p -u -r1.30 filedesc.h
--- sys/filedesc.h 6 May 2015 08:52:17 -0000 1.30
+++ sys/filedesc.h 23 Jan 2017 16:00:14 -0000
@@ -105,6 +105,7 @@ struct filedesc0 {
* Per-process open flags.
*/
#define UF_EXCLOSE 0x01 /* auto-close on exec */
+#define UF_PLEDGED 0x02 /* opened after pledge(2) */
/*
* Flags on the file descriptor table.
@@ -121,7 +122,7 @@ struct filedesc0 {
* Kernel global variables and routines.
*/
void filedesc_init(void);
-int dupfdopen(struct filedesc *, int, int, int);
+int dupfdopen(struct proc *p, struct filedesc *, int, int);
int fdalloc(struct proc *p, int want, int *result);
void fdexpand(struct proc *);
int falloc(struct proc *p, struct file **resultfp, int *resultfd);
Index: sys/pledge.h
===================================================================
RCS file: /cvs/src/sys/sys/pledge.h,v
retrieving revision 1.30
diff -u -p -u -r1.30 pledge.h
--- sys/pledge.h 23 Jan 2017 04:25:05 -0000 1.30
+++ sys/pledge.h 23 Jan 2017 11:40:58 -0000
@@ -126,7 +126,7 @@ int pledge_adjtime(struct proc *p, const
int pledge_sendit(struct proc *p, const void *to);
int pledge_sockopt(struct proc *p, int set, int level, int optname);
int pledge_socket(struct proc *p, int domain, int state);
-int pledge_ioctl(struct proc *p, long com, struct file *);
+int pledge_ioctl(struct proc *p, long com, struct file *, int, int);
int pledge_ioctl_drm(struct proc *p, long com, dev_t device);
int pledge_ioctl_vmm(struct proc *p, long com);
int pledge_flock(struct proc *p);
Index: sys/unpcb.h
===================================================================
RCS file: /cvs/src/sys/sys/unpcb.h,v
retrieving revision 1.12
diff -u -p -u -r1.12 unpcb.h
--- sys/unpcb.h 28 Aug 2015 04:38:47 -0000 1.12
+++ sys/unpcb.h 22 Jan 2017 09:19:54 -0000
@@ -86,17 +86,22 @@ struct unpcb {
#define sotounpcb(so) ((struct unpcb *)((so)->so_pcb))
#ifdef _KERNEL
+struct fdpass {
+ struct file *fp;
+ int flags;
+};
+
int unp_attach(struct socket *);
int unp_bind(struct unpcb *, struct mbuf *, struct proc *);
int unp_connect(struct socket *, struct mbuf *, struct proc *);
int unp_connect2(struct socket *, struct socket *);
void unp_detach(struct unpcb *);
-void unp_discard(struct file **, int);
+void unp_discard(struct fdpass *, int);
void unp_disconnect(struct unpcb *);
void unp_drop(struct unpcb *, int);
void unp_gc(void *);
-void unp_mark(struct file **, int);
-void unp_scan(struct mbuf *, void (*)(struct file **, int));
+void unp_mark(struct fdpass *, int);
+void unp_scan(struct mbuf *, void (*)(struct fdpass *, int));
void unp_shutdown(struct unpcb *);
int unp_externalize(struct mbuf *, socklen_t, int);
int unp_internalize(struct mbuf *, struct proc *);
Index: kern/kern_descrip.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_descrip.c,v
retrieving revision 1.136
diff -u -p -u -r1.136 kern_descrip.c
--- kern/kern_descrip.c 24 Sep 2016 18:39:17 -0000 1.136
+++ kern/kern_descrip.c 23 Jan 2017 16:01:59 -0000
@@ -611,7 +611,7 @@ finishdup(struct proc *p, struct file *f
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);
}
}
@@ -1253,7 +1256,7 @@ filedescopen(dev_t dev, int mode, int ty
* Duplicate the specified descriptor to a free descriptor.
*/
int
-dupfdopen(struct filedesc *fdp, int indx, int dfd, int mode)
+dupfdopen(struct proc *p, struct filedesc *fdp, int indx, int mode)
{
struct file *wfp;
@@ -1263,10 +1266,10 @@ dupfdopen(struct filedesc *fdp, int indx
* Assume that the filename was user-specified; applications do
* not tend to open /dev/fd/# when they can just call dup()
*/
- if ((curproc->p_p->ps_flags & (PS_SUGIDEXEC | PS_SUGID))) {
- if (curproc->p_descfd == 255)
+ if ((p->p_p->ps_flags & (PS_SUGIDEXEC | PS_SUGID))) {
+ if (p->p_descfd == 255)
return (EPERM);
- if (curproc->p_descfd != curproc->p_dupfd)
+ if (p->p_descfd != p->p_dupfd)
return (EPERM);
}
@@ -1277,7 +1280,7 @@ dupfdopen(struct filedesc *fdp, int indx
* because fd_getfile will return NULL if the file at indx is
* newly created by falloc (FIF_LARVAL).
*/
- if ((wfp = fd_getfile(fdp, dfd)) == NULL)
+ if ((wfp = fd_getfile(fdp, p->p_dupfd)) == NULL)
return (EBADF);
/*
@@ -1291,7 +1294,9 @@ dupfdopen(struct filedesc *fdp, int indx
fdp->fd_ofiles[indx] = wfp;
fdp->fd_ofileflags[indx] = (fdp->fd_ofileflags[indx] & UF_EXCLOSE) |
- (fdp->fd_ofileflags[dfd] & ~UF_EXCLOSE);
+ (fdp->fd_ofileflags[p->p_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);
@@ -1307,9 +1312,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);
}
Index: kern/kern_pledge.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_pledge.c,v
retrieving revision 1.192
diff -u -p -u -r1.192 kern_pledge.c
--- kern/kern_pledge.c 23 Jan 2017 05:49:24 -0000 1.192
+++ kern/kern_pledge.c 23 Jan 2017 14:39:51 -0000
@@ -66,6 +66,7 @@
#include "audio.h"
#include "pf.h"
+#include "bpfilter.h"
#include "pty.h"
#if defined(__amd64__) || defined(__i386__)
@@ -401,8 +402,9 @@ sys_pledge(struct proc *p, void *v, regi
syscallarg(const char **)paths;
} */ *uap = v;
struct process *pr = p->p_p;
+ struct filedesc *fdp = p->p_fd;
uint64_t flags = 0;
- int error;
+ int error, fd;
if (SCARG(uap, request)) {
size_t rbuflen;
@@ -538,6 +540,19 @@ sys_pledge(struct proc *p, void *v, regi
}
if (SCARG(uap, request)) {
+#ifdef DIAGNOSTIC
+ if (!ISSET(pr->ps_flags, PS_PLEDGE)) {
+ fdplock(fdp);
+ for (fd = 0; fd <= fdp->fd_lastfile; fd++) {
+ if (fdp->fd_ofiles[fd] &&
+ (fdp->fd_ofileflags[fd] & UF_PLEDGED))
+ printf("%s: fd %d was set!\n",
+ pr->ps_comm, fd);
+ fdp->fd_ofileflags[fd] &= ~UF_PLEDGED;
+ }
+ fdpunlock(fdp);
+ }
+#endif
pr->ps_pledge = flags;
pr->ps_flags |= PS_PLEDGE;
}
@@ -1102,7 +1117,7 @@ pledge_sendit(struct proc *p, const void
}
int
-pledge_ioctl(struct proc *p, long com, struct file *fp)
+pledge_ioctl(struct proc *p, long com, struct file *fp, int fd, int fdpledged)
{
struct vnode *vp = NULL;
int error = EPERM;
@@ -1130,6 +1145,7 @@ pledge_ioctl(struct proc *p, long com, s
if ((p->p_p->ps_pledge & PLEDGE_INET)) {
switch (com) {
+ case SIOCGIFDATA:
case SIOCGIFGROUP:
if (fp->f_type == DTYPE_SOCKET)
return (0);
@@ -1139,19 +1155,22 @@ pledge_ioctl(struct proc *p, long com, s
if ((p->p_p->ps_pledge & PLEDGE_BPF)) {
switch (com) {
- case BIOCGSTATS: /* bpf: tcpdump privsep on ^C */
- if (fp->f_type == DTYPE_VNODE &&
- fp->f_ops->fo_ioctl == vn_ioctl)
+#if NBPFILTER > 0
+ case BIOCGSTATS: /* tcpdump, pflogd */
+ if (!fdpledged &&
+ fp->f_type == DTYPE_VNODE &&
+ vp->v_type == VCHR &&
+ cdevsw[major(vp->v_rdev)].d_open == bpfopen)
return (0);
break;
+#endif
}
}
if ((p->p_p->ps_pledge & PLEDGE_TAPE)) {
switch (com) {
- case MTIOCGET:
+ case MTIOCGET: /* pax */
case MTIOCTOP:
- /* for pax(1) and such, checking tapes... */
if (fp->f_type == DTYPE_VNODE &&
(vp->v_type == VCHR || vp->v_type == VBLK))
return (0);
@@ -1189,14 +1208,17 @@ pledge_ioctl(struct proc *p, long com, s
if ((p->p_p->ps_pledge & PLEDGE_DISKLABEL)) {
switch (com) {
- case DIOCGDINFO:
- case DIOCGPDINFO:
- case DIOCRLDINFO:
+ case DIOCRLDINFO: /* change operations, etc. */
case DIOCWDINFO:
case BIOCDISK:
case BIOCINQ:
case BIOCINSTALLBOOT:
case BIOCVOL:
+ if (fdpledged)
+ break;
+ /* FALLTHROUGH */
+ case DIOCGDINFO: /* read operations, etc. */
+ case DIOCGPDINFO:
if (fp->f_type == DTYPE_VNODE &&
((vp->v_type == VCHR &&
cdevsw[major(vp->v_rdev)].d_type == D_DISK) ||
@@ -1216,7 +1238,7 @@ pledge_ioctl(struct proc *p, long com, s
if ((p->p_p->ps_pledge & PLEDGE_PF)) {
#if NPF > 0
switch (com) {
- case DIOCADDRULE:
+ case DIOCADDRULE: /* relayd */
case DIOCGETSTATUS:
case DIOCNATLOOK:
case DIOCRADDTABLES:
@@ -1225,10 +1247,14 @@ pledge_ioctl(struct proc *p, long com, s
case DIOCRCLRTSTATS:
case DIOCRGETTSTATS:
case DIOCRSETADDRS:
- case DIOCXBEGIN:
+ case DIOCXBEGIN: /* relayd, proxies */
case DIOCXCOMMIT:
case DIOCKILLSRCNODES:
- if ((fp->f_type == DTYPE_VNODE) &&
+ case DIOCRGETASTATS: /* bgpd */
+ case DIOCRDELADDRS:
+ case DIOCRADDADDRS:
+ if (!fdpledged &&
+ (fp->f_type == DTYPE_VNODE) &&
(vp->v_type == VCHR) &&
(cdevsw[major(vp->v_rdev)].d_open == pfopen))
return (0);
@@ -1240,26 +1266,27 @@ pledge_ioctl(struct proc *p, long com, s
if ((p->p_p->ps_pledge & PLEDGE_TTY)) {
switch (com) {
#if NPTY > 0
- case PTMGET:
- if ((p->p_p->ps_pledge & PLEDGE_RPATH) == 0)
- break;
- if ((p->p_p->ps_pledge & PLEDGE_WPATH) == 0)
- break;
- if (fp->f_type != DTYPE_VNODE || vp->v_type != VCHR)
- break;
- if (cdevsw[major(vp->v_rdev)].d_open != ptmopen)
- break;
- return (0);
+ case PTMGET: /* tmux */
+ if (!fdpledged &&
+ (p->p_p->ps_pledge & PLEDGE_RPATH) &&
+ (p->p_p->ps_pledge & PLEDGE_WPATH) &&
+ fp->f_type == DTYPE_VNODE && vp->v_type == VCHR &&
+ cdevsw[major(vp->v_rdev)].d_open == ptmopen)
+ return (0);
+ break;
#endif /* NPTY > 0 */
- case TIOCSTI: /* ksh? csh? */
- if ((p->p_p->ps_pledge & PLEDGE_PROC) &&
+ case TIOCSTI: /* csh */
+ if (!fdpledged &&
+ (p->p_p->ps_pledge & PLEDGE_PROC) &&
fp->f_type == DTYPE_VNODE && (vp->v_flag & VISTTY))
return (0);
break;
case TIOCSPGRP:
- if ((p->p_p->ps_pledge & PLEDGE_PROC) == 0)
- break;
- /* FALLTHROUGH */
+ /* cannot do !fdpledged test */
+ if ((p->p_p->ps_pledge & PLEDGE_PROC) &&
+ fp->f_type == DTYPE_VNODE && (vp->v_flag & VISTTY))
+ return (0);
+ break;
case TIOCFLUSH: /* getty, telnet */
case TIOCGPGRP:
case TIOCGETA:
@@ -1267,7 +1294,7 @@ pledge_ioctl(struct proc *p, long com, s
if (fp->f_type == DTYPE_VNODE && (vp->v_flag & VISTTY))
return (0);
return (ENOTTY);
- case TIOCSWINSZ:
+ case TIOCSWINSZ: /* tmux, script */
case TIOCEXT: /* mail, libedit .. */
case TIOCCBRK: /* cu */
case TIOCSBRK: /* cu */
@@ -1275,7 +1302,7 @@ pledge_ioctl(struct proc *p, long com, s
case TIOCSDTR: /* cu */
case TIOCEXCL: /* cu */
case TIOCSETA: /* cu, ... */
- case TIOCSETAW: /* cu, ... */
+ case TIOCSETAW: /* tmux, cu, ksh ... */
case TIOCSETAF: /* tcsetattr TCSAFLUSH, script */
case TIOCSCTTY: /* forkpty(3), login_tty(3), ... */
if (fp->f_type == DTYPE_VNODE && (vp->v_flag & VISTTY))
@@ -1296,7 +1323,7 @@ pledge_ioctl(struct proc *p, long com, s
case SIOCGNBRINFO_IN6:
case SIOCGIFINFO_IN6:
case SIOCGIFMEDIA:
- if (fp->f_type == DTYPE_SOCKET)
+ if (!fdpledged && fp->f_type == DTYPE_SOCKET)
return (0);
break;
}
@@ -1314,6 +1341,8 @@ pledge_ioctl(struct proc *p, long com, s
#endif
}
+ if (fdpledged)
+ printf("%s: ioctl %08lx post-pledge fd %d\n", p->p_p->ps_comm,
com, fd);
return pledge_fail(p, error, PLEDGE_TTY);
}
Index: kern/sys_generic.c
===================================================================
RCS file: /cvs/src/sys/kern/sys_generic.c,v
retrieving revision 1.113
diff -u -p -u -r1.113 sys_generic.c
--- kern/sys_generic.c 7 Nov 2016 00:26:33 -0000 1.113
+++ kern/sys_generic.c 23 Jan 2017 13:34:18 -0000
@@ -390,17 +390,20 @@ sys_ioctl(struct proc *p, void *v, regis
syscallarg(void *) data;
} */ *uap = v;
struct file *fp;
- struct filedesc *fdp;
+ struct filedesc *fdp = p->p_fd;
u_long com = SCARG(uap, com);
int error;
u_int size;
caddr_t data, memp;
- int tmp;
+ int tmp, pl;
#define STK_PARAMS 128
long long stkbuf[STK_PARAMS / sizeof(long long)];
- fdp = p->p_fd;
+ fdplock(fdp);
fp = fd_getfile_mode(fdp, SCARG(uap, fd), FREAD|FWRITE);
+ if (fp)
+ pl = fdp->fd_ofileflags[SCARG(uap, fd)] & UF_PLEDGED;
+ fdpunlock(fdp);
if (fp == NULL)
return (EBADF);
@@ -412,7 +415,7 @@ sys_ioctl(struct proc *p, void *v, regis
return (EINVAL);
}
- error = pledge_ioctl(p, com, fp);
+ error = pledge_ioctl(p, com, fp, SCARG(uap, fd), pl);
if (error)
return (error);
Index: kern/uipc_usrreq.c
===================================================================
RCS file: /cvs/src/sys/kern/uipc_usrreq.c,v
retrieving revision 1.109
diff -u -p -u -r1.109 uipc_usrreq.c
--- kern/uipc_usrreq.c 29 Dec 2016 12:12:43 -0000 1.109
+++ kern/uipc_usrreq.c 23 Jan 2017 16:17:00 -0000
@@ -63,8 +63,8 @@ LIST_HEAD(unp_head, unpcb) unp_head = LI
struct unp_deferral {
SLIST_ENTRY(unp_deferral) ud_link;
int ud_n;
- /* followed by ud_n struct file * pointers */
- struct file *ud_fp[];
+ /* followed by ud_n struct fdpass */
+ struct fdpass ud_fp[];
};
/* list of sets of files that were sent over sockets that are now closed */
@@ -664,12 +664,12 @@ unp_externalize(struct mbuf *rights, soc
struct proc *p = curproc; /* XXX */
struct cmsghdr *cm = mtod(rights, struct cmsghdr *);
int i, *fdp = NULL;
- struct file **rp;
+ struct fdpass *rp;
struct file *fp;
int nfds, error = 0;
nfds = (cm->cmsg_len - CMSG_ALIGN(sizeof(*cm))) /
- sizeof(struct file *);
+ sizeof(struct fdpass);
if (controllen < CMSG_ALIGN(sizeof(struct cmsghdr)))
controllen = 0;
else
@@ -680,9 +680,10 @@ unp_externalize(struct mbuf *rights, soc
}
/* Make sure the recipient should be able to see the descriptors.. */
- rp = (struct file **)CMSG_DATA(cm);
+ rp = (struct fdpass *)CMSG_DATA(cm);
for (i = 0; i < nfds; i++) {
- fp = *rp++;
+ fp = rp->fp;
+ rp++;
error = pledge_recvfd(p, fp);
if (error)
break;
@@ -709,7 +710,7 @@ restart:
fdplock(p->p_fd);
if (error != 0) {
if (nfds > 0) {
- rp = ((struct file **)CMSG_DATA(cm));
+ rp = ((struct fdpass *)CMSG_DATA(cm));
unp_discard(rp, nfds);
}
goto out;
@@ -719,7 +720,7 @@ restart:
* First loop -- allocate file descriptor table slots for the
* new descriptors.
*/
- rp = ((struct file **)CMSG_DATA(cm));
+ rp = ((struct fdpass *)CMSG_DATA(cm));
for (i = 0; i < nfds; i++) {
if ((error = fdalloc(p, 0, &fdp[i])) != 0) {
/*
@@ -748,7 +749,9 @@ restart:
* fdalloc() works properly.. We finalize it all
* in the loop below.
*/
- p->p_fd->fd_ofiles[fdp[i]] = *rp++;
+ 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)
p->p_fd->fd_ofileflags[fdp[i]] |= UF_EXCLOSE;
@@ -758,11 +761,12 @@ restart:
* Now that adding them has succeeded, update all of the
* descriptor passing state.
*/
- rp = (struct file **)CMSG_DATA(cm);
+ rp = (struct fdpass *)CMSG_DATA(cm);
for (i = 0; i < nfds; i++) {
struct unpcb *unp;
- fp = *rp++;
+ fp = rp->fp;
+ rp++;
if ((unp = fptounp(fp)) != NULL)
unp->unp_msgcount--;
unp_rights--;
@@ -787,7 +791,8 @@ unp_internalize(struct mbuf *control, st
{
struct filedesc *fdp = p->p_fd;
struct cmsghdr *cm = mtod(control, struct cmsghdr *);
- struct file **rp, *fp;
+ struct fdpass *rp;
+ struct file *fp;
struct unpcb *unp;
int i, error;
int nfds, *ip, fd, neededspace;
@@ -807,7 +812,7 @@ unp_internalize(struct mbuf *control, st
/* Make sure we have room for the struct file pointers */
morespace:
- neededspace = CMSG_SPACE(nfds * sizeof(struct file *)) -
+ neededspace = CMSG_SPACE(nfds * sizeof(struct fdpass)) -
control->m_len;
if (neededspace > M_TRAILINGSPACE(control)) {
char *tmp;
@@ -834,11 +839,11 @@ morespace:
}
/* adjust message & mbuf to note amount of space actually used. */
- cm->cmsg_len = CMSG_LEN(nfds * sizeof(struct file *));
- control->m_len = CMSG_SPACE(nfds * sizeof(struct file *));
+ cm->cmsg_len = CMSG_LEN(nfds * sizeof(struct fdpass));
+ control->m_len = CMSG_SPACE(nfds * sizeof(struct fdpass));
ip = ((int *)CMSG_DATA(cm)) + nfds - 1;
- rp = ((struct file **)CMSG_DATA(cm)) + nfds - 1;
+ rp = ((struct fdpass *)CMSG_DATA(cm)) + nfds - 1;
for (i = 0; i < nfds; i++) {
memcpy(&fd, ip, sizeof fd);
ip--;
@@ -859,7 +864,8 @@ morespace:
error = EINVAL;
goto fail;
}
- memcpy(rp, &fp, sizeof fp);
+ rp->fp = fp;
+ rp->flags = fdp->fd_ofileflags[fd] & UF_PLEDGED;
rp--;
fp->f_count++;
if ((unp = fptounp(fp)) != NULL) {
@@ -873,7 +879,7 @@ fail:
/* Back out what we just did. */
for ( ; i > 0; i--) {
rp++;
- memcpy(&fp, rp, sizeof(fp));
+ fp = rp->fp;
fp->f_count--;
if ((unp = fptounp(fp)) != NULL)
unp->unp_msgcount--;
@@ -902,7 +908,7 @@ unp_gc(void *arg __unused)
while ((defer = SLIST_FIRST(&unp_deferred)) != NULL) {
SLIST_REMOVE_HEAD(&unp_deferred, ud_link);
for (i = 0; i < defer->ud_n; i++) {
- fp = defer->ud_fp[i];
+ fp = defer->ud_fp[i].fp;
if (fp == NULL)
continue;
FREF(fp);
@@ -911,7 +917,7 @@ unp_gc(void *arg __unused)
unp_rights--;
(void) closef(fp, NULL);
}
- free(defer, M_TEMP, sizeof(*defer) + sizeof(fp) * defer->ud_n);
+ free(defer, M_TEMP, sizeof(*defer) + sizeof(struct fdpass) *
defer->ud_n);
}
unp_defer = 0;
@@ -1005,10 +1011,10 @@ unp_dispose(struct mbuf *m)
}
void
-unp_scan(struct mbuf *m0, void (*op)(struct file **, int))
+unp_scan(struct mbuf *m0, void (*op)(struct fdpass *, int))
{
struct mbuf *m;
- struct file **rp;
+ struct fdpass *rp;
struct cmsghdr *cm;
int qfds;
@@ -1021,9 +1027,9 @@ unp_scan(struct mbuf *m0, void (*op)(str
cm->cmsg_type != SCM_RIGHTS)
continue;
qfds = (cm->cmsg_len - CMSG_ALIGN(sizeof *cm))
- / sizeof(struct file *);
+ / sizeof(struct fdpass);
if (qfds > 0) {
- rp = (struct file **)CMSG_DATA(cm);
+ rp = (struct fdpass *)CMSG_DATA(cm);
op(rp, qfds);
}
break; /* XXX, but saves time */
@@ -1034,16 +1040,16 @@ unp_scan(struct mbuf *m0, void (*op)(str
}
void
-unp_mark(struct file **rp, int nfds)
+unp_mark(struct fdpass *rp, int nfds)
{
struct unpcb *unp;
int i;
for (i = 0; i < nfds; i++) {
- if (rp[i] == NULL)
+ if (rp[i].fp == NULL)
continue;
- unp = fptounp(rp[i]);
+ unp = fptounp(rp[i].fp);
if (unp == NULL)
continue;
@@ -1057,7 +1063,7 @@ unp_mark(struct file **rp, int nfds)
}
void
-unp_discard(struct file **rp, int nfds)
+unp_discard(struct fdpass *rp, int nfds)
{
struct unp_deferral *defer;
Index: kern/vfs_syscalls.c
===================================================================
RCS file: /cvs/src/sys/kern/vfs_syscalls.c,v
retrieving revision 1.268
diff -u -p -u -r1.268 vfs_syscalls.c
--- kern/vfs_syscalls.c 15 Jan 2017 23:18:05 -0000 1.268
+++ kern/vfs_syscalls.c 23 Jan 2017 15:59:48 -0000
@@ -829,7 +829,7 @@ doopenat(struct proc *p, int fd, const c
if (error == ENODEV &&
p->p_dupfd >= 0 && /* XXX from fdopen */
(error =
- dupfdopen(fdp, indx, p->p_dupfd, flags)) == 0) {
+ dupfdopen(p, fdp, indx, flags)) == 0) {
closef(fp, p);
*retval = indx;
goto out;