diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -1110,20 +1110,27 @@ uap->mode)); } -int -kern_openat(struct thread *td, int fd, const char *path, enum uio_seg pathseg, - int flags, int mode) +/* + * If fpp != NULL, opened file is not installed into the file + * descriptors table, instead it is returned in *fpp. This is + * incompatible with fdopen(), in which case we return EINVAL. + */ +static int +openatfp(struct thread *td, int dirfd, const char *path, + enum uio_seg pathseg, int flags, int mode, struct file **fpp) { - struct proc *p = td->td_proc; + struct proc *p; struct filedesc *fdp; struct pwddesc *pdp; struct file *fp; struct vnode *vp; + struct filecaps *fcaps; struct nameidata nd; cap_rights_t rights; int cmode, error, indx; indx = -1; + p = td->td_proc; fdp = p->p_fd; pdp = p->p_pd; @@ -1159,7 +1166,7 @@ fp->f_flag = flags & FMASK; cmode = ((mode & ~pdp->pd_cmask) & ALLPERMS) & ~S_ISTXT; NDINIT_ATRIGHTS(&nd, LOOKUP, FOLLOW | AUDITVNODE1 | WANTIOCTLCAPS, - pathseg, path, fd, &rights); + pathseg, path, dirfd, &rights); td->td_dupfd = -1; /* XXX check for fdopen */ error = vn_open_cred(&nd, &flags, cmode, VN_OPEN_WANTIOCTLCAPS, td->td_ucred, fp); @@ -1184,6 +1191,7 @@ if ((nd.ni_resflags & NIRES_STRICTREL) == 0 && (error == ENODEV || error == ENXIO) && td->td_dupfd >= 0) { + MPASS(fpp == NULL); error = dupfdopen(td, fdp, td->td_dupfd, flags, error, &indx); if (error == 0) @@ -1225,12 +1233,17 @@ goto bad; } success: + if (fpp != NULL) { + MPASS(error == 0); + NDFREE_IOCTLCAPS(&nd); + *fpp = fp; + return (0); + } + /* * If we haven't already installed the FD (for dupfdopen), do so now. */ if (indx == -1) { - struct filecaps *fcaps; - #ifdef CAPABILITIES if ((nd.ni_resflags & NIRES_STRICTREL) != 0) fcaps = &nd.ni_filecaps; @@ -1256,6 +1269,26 @@ return (error); } +int +kern_openat(struct thread *td, int dirfd, const char *path, + enum uio_seg pathseg, int flags, int mode) +{ + return (openatfp(td, dirfd, path, pathseg, flags, mode, NULL)); +} + +int +kern_openatfp(struct thread *td, int dirfd, const char *path, + enum uio_seg pathseg, int flags, int mode, struct file **fpp) +{ + int error, old_dupfd; + + old_dupfd = td->td_dupfd; + td->td_dupfd = -1; + error = openatfp(td, dirfd, path, pathseg, flags, mode, fpp); + td->td_dupfd = old_dupfd; + return (error); +} + #ifdef COMPAT_43 /* * Create a file. diff --git a/sys/modules/ipsec/Makefile b/sys/modules/ipsec/Makefile --- a/sys/modules/ipsec/Makefile +++ b/sys/modules/ipsec/Makefile @@ -5,8 +5,6 @@ SRCS= if_ipsec.c ipsec.c ipsec_input.c ipsec_mbuf.c ipsec_mod.c \ ipsec_output.c xform_ah.c xform_esp.c xform_ipcomp.c \ opt_inet.h opt_inet6.h opt_ipsec.h opt_kern_tls.h opt_sctp.h -.if "${MK_INET}" != "no" || "${MK_INET6}" != "no" -SRCS+= udpencap.c -.endif +SRCS.INET= udpencap.c .include diff --git a/sys/netipsec/ipsec_support.h b/sys/netipsec/ipsec_support.h --- a/sys/netipsec/ipsec_support.h +++ b/sys/netipsec/ipsec_support.h @@ -49,11 +49,9 @@ int ipsec_delete_pcbpolicy(struct inpcb *); int ipsec_copy_pcbpolicy(struct inpcb *, struct inpcb *); -#if defined(INET) || defined(INET6) +#ifdef INET int udp_ipsec_input(struct mbuf *, int, int); int udp_ipsec_pcbctl(struct inpcb *, struct sockopt *); -#endif -#ifdef INET int ipsec4_in_reject(const struct mbuf *, struct inpcb *); int ipsec4_input(struct mbuf *, int, int); int ipsec4_forward(struct mbuf *); diff --git a/sys/sys/syscallsubr.h b/sys/sys/syscallsubr.h --- a/sys/sys/syscallsubr.h +++ b/sys/sys/syscallsubr.h @@ -249,8 +249,10 @@ long *ploff); int kern_ommap(struct thread *td, uintptr_t hint, int len, int oprot, int oflags, int fd, long pos); -int kern_openat(struct thread *td, int fd, const char *path, +int kern_openat(struct thread *td, int dirfd, const char *path, enum uio_seg pathseg, int flags, int mode); +int kern_openatfp(struct thread *td, int dirfd, const char *path, + enum uio_seg pathseg, int flags, int mode, struct file **fpp); int kern_pathconf(struct thread *td, const char *path, enum uio_seg pathseg, int name, u_long flags, long *valuep); int kern_pipe(struct thread *td, int fildes[2], int flags,