diff options
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/kern_jail.c | 1 | ||||
-rw-r--r-- | sys/kern/kern_mbuf.c | 8 | ||||
-rw-r--r-- | sys/kern/kern_umtx.c | 2 | ||||
-rw-r--r-- | sys/kern/syscalls.master | 2 | ||||
-rw-r--r-- | sys/kern/sysv_shm.c | 9 | ||||
-rw-r--r-- | sys/kern/vfs_lookup.c | 57 |
6 files changed, 59 insertions, 20 deletions
diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c index dfb2a7a4f9fba..35564477f002d 100644 --- a/sys/kern/kern_jail.c +++ b/sys/kern/kern_jail.c @@ -3062,6 +3062,7 @@ prison_priv_check(struct ucred *cred, int priv) case PRIV_NET_SETIFMETRIC: case PRIV_NET_SETIFPHYS: case PRIV_NET_SETIFMAC: + case PRIV_NET_SETLANPCP: case PRIV_NET_ADDMULTI: case PRIV_NET_DELMULTI: case PRIV_NET_HWIOCTL: diff --git a/sys/kern/kern_mbuf.c b/sys/kern/kern_mbuf.c index 100e01a4a069e..af1fe9e5de043 100644 --- a/sys/kern/kern_mbuf.c +++ b/sys/kern/kern_mbuf.c @@ -410,8 +410,6 @@ nd_buf_import(void *arg, void **store, int count, int domain __unused, struct mbuf *m; int i; - KASSERT(!dumping, ("%s: ran out of pre-allocated mbufs", __func__)); - q = arg; for (i = 0; i < count; i++) { @@ -421,6 +419,8 @@ nd_buf_import(void *arg, void **store, int count, int domain __unused, trash_init(m, q == &nd_mbufq ? MSIZE : nd_clsize, flags); store[i] = m; } + KASSERT((flags & M_WAITOK) == 0 || i == count, + ("%s: ran out of pre-allocated mbufs", __func__)); return (i); } @@ -447,8 +447,6 @@ nd_pack_import(void *arg __unused, void **store, int count, int domain __unused, void *clust; int i; - KASSERT(!dumping, ("%s: ran out of pre-allocated mbufs", __func__)); - for (i = 0; i < count; i++) { m = m_get(MT_DATA, M_NOWAIT); if (m == NULL) @@ -461,6 +459,8 @@ nd_pack_import(void *arg __unused, void **store, int count, int domain __unused, mb_ctor_clust(clust, nd_clsize, m, 0); store[i] = m; } + KASSERT((flags & M_WAITOK) == 0 || i == count, + ("%s: ran out of pre-allocated mbufs", __func__)); return (i); } diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c index 8beea32666a6c..c704cbb1d6bc1 100644 --- a/sys/kern/kern_umtx.c +++ b/sys/kern/kern_umtx.c @@ -4351,7 +4351,7 @@ static const _umtx_op_func op_table_compat32[] = { }; int -freebsd32_umtx_op(struct thread *td, struct freebsd32_umtx_op_args *uap) +freebsd32__umtx_op(struct thread *td, struct freebsd32__umtx_op_args *uap) { if ((unsigned)uap->op < nitems(op_table_compat32)) { diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master index 3756bf5c797ca..384f297dac27c 100644 --- a/sys/kern/syscalls.master +++ b/sys/kern/syscalls.master @@ -163,7 +163,7 @@ int mknod( _In_z_ const char *path, int mode, - int dev + uint32_t dev ); } 15 AUE_CHMOD STD { diff --git a/sys/kern/sysv_shm.c b/sys/kern/sysv_shm.c index 0d9b561d03b54..999a95738de4b 100644 --- a/sys/kern/sysv_shm.c +++ b/sys/kern/sysv_shm.c @@ -332,9 +332,6 @@ kern_shmdt_locked(struct thread *td, const void *shmaddr) { struct proc *p = td->td_proc; struct shmmap_state *shmmap_s; -#if defined(AUDIT) || defined(MAC) - struct shmid_kernel *shmsegptr; -#endif #ifdef MAC int error; #endif @@ -355,11 +352,9 @@ kern_shmdt_locked(struct thread *td, const void *shmaddr) } if (i == shminfo.shmseg) return (EINVAL); -#if (defined(AUDIT) && defined(KDTRACE_HOOKS)) || defined(MAC) - shmsegptr = &shmsegs[IPCID_TO_IX(shmmap_s->shmid)]; -#endif #ifdef MAC - error = mac_sysvshm_check_shmdt(td->td_ucred, shmsegptr); + error = mac_sysvshm_check_shmdt(td->td_ucred, + &shmsegs[IPCID_TO_IX(shmmap_s->shmid)]); if (error != 0) return (error); #endif diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c index 496a4e6f5a68e..78893c4f2bd3d 100644 --- a/sys/kern/vfs_lookup.c +++ b/sys/kern/vfs_lookup.c @@ -177,6 +177,13 @@ nameicap_tracker_add(struct nameidata *ndp, struct vnode *dp) if ((ndp->ni_lcf & NI_LCF_CAP_DOTDOT) == 0 || dp->v_type != VDIR) return; + if ((ndp->ni_lcf & (NI_LCF_BENEATH_ABS | NI_LCF_BENEATH_LATCHED)) == + NI_LCF_BENEATH_ABS) { + MPASS((ndp->ni_lcf & NI_LCF_LATCH) != 0); + if (dp != ndp->ni_beneath_latch) + return; + ndp->ni_lcf |= NI_LCF_BENEATH_LATCHED; + } nt = uma_zalloc(nt_zone, M_WAITOK); vhold(dp); nt->dp = dp; @@ -184,7 +191,7 @@ nameicap_tracker_add(struct nameidata *ndp, struct vnode *dp) } static void -nameicap_cleanup(struct nameidata *ndp) +nameicap_cleanup(struct nameidata *ndp, bool clean_latch) { struct nameicap_tracker *nt, *nt1; @@ -195,6 +202,8 @@ nameicap_cleanup(struct nameidata *ndp) vdrop(nt->dp); uma_zfree(nt_zone, nt); } + if (clean_latch && (ndp->ni_lcf & NI_LCF_LATCH) != 0) + vrele(ndp->ni_beneath_latch); } /* @@ -222,6 +231,11 @@ nameicap_check_dotdot(struct nameidata *ndp, struct vnode *dp) if (dp == nt->dp) return (0); } + if ((ndp->ni_lcf & NI_LCF_BENEATH_ABS) != 0) { + ndp->ni_lcf &= ~NI_LCF_BENEATH_LATCHED; + nameicap_cleanup(ndp, false); + return (0); + } return (ENOTCAPABLE); } @@ -242,14 +256,18 @@ namei_handle_root(struct nameidata *ndp, struct vnode **dpp) struct componentname *cnp; cnp = &ndp->ni_cnd; - if ((ndp->ni_lcf & NI_LCF_STRICTRELATIVE) != 0 || - (cnp->cn_flags & BENEATH) != 0) { + if ((ndp->ni_lcf & NI_LCF_STRICTRELATIVE) != 0) { #ifdef KTRACE if (KTRPOINT(curthread, KTR_CAPFAIL)) ktrcapfail(CAPFAIL_LOOKUP, NULL, NULL); #endif return (ENOTCAPABLE); } + if ((cnp->cn_flags & BENEATH) != 0) { + ndp->ni_lcf |= NI_LCF_BENEATH_ABS; + ndp->ni_lcf &= ~NI_LCF_BENEATH_LATCHED; + nameicap_cleanup(ndp, false); + } while (*(cnp->cn_nameptr) == '/') { cnp->cn_nameptr++; ndp->ni_pathlen--; @@ -290,6 +308,7 @@ namei(struct nameidata *ndp) struct thread *td; struct proc *p; cap_rights_t rights; + struct filecaps dirfd_caps; struct uio auio; int error, linklen, startdir_used; @@ -427,6 +446,23 @@ namei(struct nameidata *ndp) if (error == 0 && dp->v_type != VDIR) error = ENOTDIR; } + if (error == 0 && (ndp->ni_lcf & NI_LCF_BENEATH_ABS) != 0) { + if (ndp->ni_dirfd == AT_FDCWD) { + ndp->ni_beneath_latch = fdp->fd_cdir; + vrefact(ndp->ni_beneath_latch); + } else { + rights = ndp->ni_rightsneeded; + cap_rights_set(&rights, CAP_LOOKUP); + error = fgetvp_rights(td, ndp->ni_dirfd, &rights, + &dirfd_caps, &ndp->ni_beneath_latch); + if (error == 0 && dp->v_type != VDIR) { + vrele(ndp->ni_beneath_latch); + error = ENOTDIR; + } + } + if (error == 0) + ndp->ni_lcf |= NI_LCF_LATCH; + } FILEDESC_SUNLOCK(fdp); if (ndp->ni_startdir != NULL && !startdir_used) vrele(ndp->ni_startdir); @@ -456,9 +492,15 @@ namei(struct nameidata *ndp) namei_cleanup_cnp(cnp); } else cnp->cn_flags |= HASBUF; - nameicap_cleanup(ndp); - SDT_PROBE2(vfs, namei, lookup, return, 0, ndp->ni_vp); - return (0); + if ((ndp->ni_lcf & (NI_LCF_BENEATH_ABS | + NI_LCF_BENEATH_LATCHED)) == NI_LCF_BENEATH_ABS) { + NDFREE(ndp, 0); + error = ENOTCAPABLE; + } + nameicap_cleanup(ndp, true); + SDT_PROBE2(vfs, namei, lookup, return, error, + (error == 0 ? ndp->ni_vp : NULL)); + return (error); } if (ndp->ni_loopcnt++ >= MAXSYMLINKS) { error = ELOOP; @@ -529,8 +571,9 @@ namei(struct nameidata *ndp) vrele(ndp->ni_dvp); out: vrele(ndp->ni_rootdir); + MPASS(error != 0); namei_cleanup_cnp(cnp); - nameicap_cleanup(ndp); + nameicap_cleanup(ndp, true); SDT_PROBE2(vfs, namei, lookup, return, error, NULL); return (error); } |