summaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/kern_jail.c1
-rw-r--r--sys/kern/kern_mbuf.c8
-rw-r--r--sys/kern/kern_umtx.c2
-rw-r--r--sys/kern/syscalls.master2
-rw-r--r--sys/kern/sysv_shm.c9
-rw-r--r--sys/kern/vfs_lookup.c57
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);
}