aboutsummaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/device_if.m10
-rw-r--r--sys/kern/init_sysent.c8
-rw-r--r--sys/kern/kern_exit.c2
-rw-r--r--sys/kern/kern_jail.c15
-rw-r--r--sys/kern/kern_prot.c185
-rw-r--r--sys/kern/sys_timerfd.c1
-rw-r--r--sys/kern/syscalls.c8
-rw-r--r--sys/kern/syscalls.conf1
-rw-r--r--sys/kern/syscalls.master21
-rw-r--r--sys/kern/systrace_args.c112
-rw-r--r--sys/kern/uipc_shm.c3
-rw-r--r--sys/kern/vfs_bio.c2
-rw-r--r--sys/kern/vfs_default.c1
-rw-r--r--sys/kern/vfs_inotify.c1
-rw-r--r--sys/kern/vfs_syscalls.c21
-rw-r--r--sys/kern/vfs_vnops.c5
16 files changed, 264 insertions, 132 deletions
diff --git a/sys/kern/device_if.m b/sys/kern/device_if.m
index c02e5a46f326..ed94b2ccbe1b 100644
--- a/sys/kern/device_if.m
+++ b/sys/kern/device_if.m
@@ -49,25 +49,25 @@ HEADER {
CODE {
static int null_shutdown(device_t dev)
{
- return 0;
+ return (0);
}
static int null_suspend(device_t dev)
{
- return 0;
+ return (0);
}
static int null_resume(device_t dev)
{
- return 0;
+ return (0);
}
static int null_quiesce(device_t dev)
{
- return 0;
+ return (0);
}
- static void * null_register(device_t dev)
+ static void *null_register(device_t dev)
{
return NULL;
}
diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c
index 91792430d24c..fcd232cde21e 100644
--- a/sys/kern/init_sysent.c
+++ b/sys/kern/init_sysent.c
@@ -67,7 +67,7 @@
/* The casts are bogus but will do for now. */
struct sysent sysent[] = {
{ .sy_narg = 0, .sy_call = (sy_call_t *)nosys, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 0 = syscall */
- { .sy_narg = AS(exit_args), .sy_call = (sy_call_t *)sys_exit, .sy_auevent = AUE_EXIT, .sy_flags = SYF_CAPENABLED, .sy_thrcnt = SY_THR_STATIC }, /* 1 = exit */
+ { .sy_narg = AS(_exit_args), .sy_call = (sy_call_t *)sys__exit, .sy_auevent = AUE_EXIT, .sy_flags = SYF_CAPENABLED, .sy_thrcnt = SY_THR_STATIC }, /* 1 = _exit */
{ .sy_narg = 0, .sy_call = (sy_call_t *)sys_fork, .sy_auevent = AUE_FORK, .sy_flags = SYF_CAPENABLED, .sy_thrcnt = SY_THR_STATIC }, /* 2 = fork */
{ .sy_narg = AS(read_args), .sy_call = (sy_call_t *)sys_read, .sy_auevent = AUE_READ, .sy_flags = SYF_CAPENABLED, .sy_thrcnt = SY_THR_STATIC }, /* 3 = read */
{ .sy_narg = AS(write_args), .sy_call = (sy_call_t *)sys_write, .sy_auevent = AUE_WRITE, .sy_flags = SYF_CAPENABLED, .sy_thrcnt = SY_THR_STATIC }, /* 4 = write */
@@ -145,8 +145,8 @@ struct sysent sysent[] = {
{ .sy_narg = 0, .sy_call = (sy_call_t *)nosys, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_ABSENT }, /* 76 = obsolete vhangup */
{ .sy_narg = 0, .sy_call = (sy_call_t *)nosys, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_ABSENT }, /* 77 = obsolete vlimit */
{ .sy_narg = AS(mincore_args), .sy_call = (sy_call_t *)sys_mincore, .sy_auevent = AUE_MINCORE, .sy_flags = SYF_CAPENABLED, .sy_thrcnt = SY_THR_STATIC }, /* 78 = mincore */
- { .sy_narg = AS(getgroups_args), .sy_call = (sy_call_t *)sys_getgroups, .sy_auevent = AUE_GETGROUPS, .sy_flags = SYF_CAPENABLED, .sy_thrcnt = SY_THR_STATIC }, /* 79 = getgroups */
- { .sy_narg = AS(setgroups_args), .sy_call = (sy_call_t *)sys_setgroups, .sy_auevent = AUE_SETGROUPS, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 80 = setgroups */
+ { compat14(AS(freebsd14_getgroups_args),getgroups), .sy_auevent = AUE_GETGROUPS, .sy_flags = SYF_CAPENABLED, .sy_thrcnt = SY_THR_STATIC }, /* 79 = freebsd14 getgroups */
+ { compat14(AS(freebsd14_setgroups_args),setgroups), .sy_auevent = AUE_SETGROUPS, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 80 = freebsd14 setgroups */
{ .sy_narg = 0, .sy_call = (sy_call_t *)sys_getpgrp, .sy_auevent = AUE_GETPGRP, .sy_flags = SYF_CAPENABLED, .sy_thrcnt = SY_THR_STATIC }, /* 81 = getpgrp */
{ .sy_narg = AS(setpgid_args), .sy_call = (sy_call_t *)sys_setpgid, .sy_auevent = AUE_SETPGRP, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 82 = setpgid */
{ .sy_narg = AS(setitimer_args), .sy_call = (sy_call_t *)sys_setitimer, .sy_auevent = AUE_SETITIMER, .sy_flags = SYF_CAPENABLED, .sy_thrcnt = SY_THR_STATIC }, /* 83 = setitimer */
@@ -661,4 +661,6 @@ struct sysent sysent[] = {
{ .sy_narg = AS(exterrctl_args), .sy_call = (sy_call_t *)sys_exterrctl, .sy_auevent = AUE_NULL, .sy_flags = SYF_CAPENABLED, .sy_thrcnt = SY_THR_STATIC }, /* 592 = exterrctl */
{ .sy_narg = AS(inotify_add_watch_at_args), .sy_call = (sy_call_t *)sys_inotify_add_watch_at, .sy_auevent = AUE_INOTIFY, .sy_flags = SYF_CAPENABLED, .sy_thrcnt = SY_THR_STATIC }, /* 593 = inotify_add_watch_at */
{ .sy_narg = AS(inotify_rm_watch_args), .sy_call = (sy_call_t *)sys_inotify_rm_watch, .sy_auevent = AUE_INOTIFY, .sy_flags = SYF_CAPENABLED, .sy_thrcnt = SY_THR_STATIC }, /* 594 = inotify_rm_watch */
+ { .sy_narg = AS(getgroups_args), .sy_call = (sy_call_t *)sys_getgroups, .sy_auevent = AUE_GETGROUPS, .sy_flags = SYF_CAPENABLED, .sy_thrcnt = SY_THR_STATIC }, /* 595 = getgroups */
+ { .sy_narg = AS(setgroups_args), .sy_call = (sy_call_t *)sys_setgroups, .sy_auevent = AUE_SETGROUPS, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 596 = setgroups */
};
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index 54e3044ab093..a32b5a1b3354 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -202,7 +202,7 @@ exit_onexit(struct proc *p)
* exit -- death of process.
*/
int
-sys_exit(struct thread *td, struct exit_args *uap)
+sys__exit(struct thread *td, struct _exit_args *uap)
{
exit1(td, uap->rval, 0);
diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c
index 7ef1d19f0ea8..7c9a15ae18f3 100644
--- a/sys/kern/kern_jail.c
+++ b/sys/kern/kern_jail.c
@@ -115,8 +115,11 @@ struct prison prison0 = {
#else
.pr_flags = PR_HOST|_PR_IP_SADDRSEL,
#endif
- .pr_allow = PR_ALLOW_ALL_STATIC,
+ .pr_allow = PR_ALLOW_PRISON0,
};
+_Static_assert((PR_ALLOW_PRISON0 & ~PR_ALLOW_ALL_STATIC) == 0,
+ "Bits enabled in PR_ALLOW_PRISON0 that are not statically reserved");
+
MTX_SYSINIT(prison0, &prison0.pr_mtx, "jail mutex", MTX_DEF);
struct bool_flags {
@@ -232,6 +235,9 @@ static struct bool_flags pr_flag_allow[NBBY * NBPW] = {
{"allow.adjtime", "allow.noadjtime", PR_ALLOW_ADJTIME},
{"allow.settime", "allow.nosettime", PR_ALLOW_SETTIME},
{"allow.routing", "allow.norouting", PR_ALLOW_ROUTING},
+ {"allow.unprivileged_parent_tampering",
+ "allow.nounprivileged_parent_tampering",
+ PR_ALLOW_UNPRIV_PARENT_TAMPER},
};
static unsigned pr_allow_all = PR_ALLOW_ALL_STATIC;
const size_t pr_flag_allow_size = sizeof(pr_flag_allow);
@@ -4006,6 +4012,7 @@ prison_priv_check(struct ucred *cred, int priv)
case PRIV_DEBUG_DIFFCRED:
case PRIV_DEBUG_SUGID:
case PRIV_DEBUG_UNPRIV:
+ case PRIV_DEBUG_DIFFJAIL:
/*
* Allow jail to set various resource limits and login
@@ -4043,8 +4050,10 @@ prison_priv_check(struct ucred *cred, int priv)
*/
case PRIV_SCHED_DIFFCRED:
case PRIV_SCHED_CPUSET:
+ case PRIV_SCHED_DIFFJAIL:
case PRIV_SIGNAL_DIFFCRED:
case PRIV_SIGNAL_SUGID:
+ case PRIV_SIGNAL_DIFFJAIL:
/*
* Allow jailed processes to write to sysctls marked as jail
@@ -4688,6 +4697,10 @@ SYSCTL_JAIL_PARAM(_allow, read_msgbuf, CTLTYPE_INT | CTLFLAG_RW,
"B", "Jail may read the kernel message buffer");
SYSCTL_JAIL_PARAM(_allow, unprivileged_proc_debug, CTLTYPE_INT | CTLFLAG_RW,
"B", "Unprivileged processes may use process debugging facilities");
+SYSCTL_JAIL_PARAM(_allow, unprivileged_parent_tampering,
+ CTLTYPE_INT | CTLFLAG_RW, "B",
+ "Unprivileged parent jail processes may tamper with same-uid processes"
+ " (signal/debug/cpuset)");
SYSCTL_JAIL_PARAM(_allow, suser, CTLTYPE_INT | CTLFLAG_RW,
"B", "Processes in jail with uid 0 have privilege");
#ifdef VIMAGE
diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c
index bbb622547598..0ca42d640767 100644
--- a/sys/kern/kern_prot.c
+++ b/sys/kern/kern_prot.c
@@ -310,6 +310,39 @@ sys_getegid(struct thread *td, struct getegid_args *uap)
return (0);
}
+#ifdef COMPAT_FREEBSD14
+int
+freebsd14_getgroups(struct thread *td, struct freebsd14_getgroups_args *uap)
+{
+ struct ucred *cred;
+ int ngrp, error;
+
+ cred = td->td_ucred;
+
+ /*
+ * For FreeBSD < 15.0, we account for the egid being placed at the
+ * beginning of the group list prior to all supplementary groups.
+ */
+ ngrp = cred->cr_ngroups + 1;
+ if (uap->gidsetsize == 0) {
+ error = 0;
+ goto out;
+ } else if (uap->gidsetsize < ngrp) {
+ return (EINVAL);
+ }
+
+ error = copyout(&cred->cr_gid, uap->gidset, sizeof(gid_t));
+ if (error == 0)
+ error = copyout(cred->cr_groups, uap->gidset + 1,
+ (ngrp - 1) * sizeof(gid_t));
+
+out:
+ td->td_retval[0] = ngrp;
+ return (error);
+
+}
+#endif /* COMPAT_FREEBSD14 */
+
#ifndef _SYS_SYSPROTO_H_
struct getgroups_args {
int gidsetsize;
@@ -320,18 +353,11 @@ int
sys_getgroups(struct thread *td, struct getgroups_args *uap)
{
struct ucred *cred;
- gid_t *ugidset;
int ngrp, error;
cred = td->td_ucred;
- /*
- * cr_gid has been moved out of cr_groups, but we'll continue exporting
- * the egid as groups[0] for the time being until we audit userland for
- * any surprises.
- */
- ngrp = cred->cr_ngroups + 1;
-
+ ngrp = cred->cr_ngroups;
if (uap->gidsetsize == 0) {
error = 0;
goto out;
@@ -339,14 +365,7 @@ sys_getgroups(struct thread *td, struct getgroups_args *uap)
if (uap->gidsetsize < ngrp)
return (EINVAL);
- ugidset = uap->gidset;
- error = copyout(&cred->cr_gid, ugidset, sizeof(*ugidset));
- if (error != 0)
- goto out;
-
- if (ngrp > 1)
- error = copyout(cred->cr_groups, ugidset + 1,
- (ngrp - 1) * sizeof(*ugidset));
+ error = copyout(cred->cr_groups, uap->gidset, ngrp * sizeof(gid_t));
out:
td->td_retval[0] = ngrp;
return (error);
@@ -1186,6 +1205,44 @@ fail:
return (error);
}
+#ifdef COMPAT_FREEBSD14
+int
+freebsd14_setgroups(struct thread *td, struct freebsd14_setgroups_args *uap)
+{
+ gid_t smallgroups[CRED_SMALLGROUPS_NB];
+ gid_t *groups;
+ int gidsetsize, error;
+
+ /*
+ * Before FreeBSD 15.0, we allow one more group to be supplied to
+ * account for the egid appearing before the supplementary groups. This
+ * may technically allow one more supplementary group for systems that
+ * did use the default NGROUPS_MAX if we round it back up to 1024.
+ */
+ gidsetsize = uap->gidsetsize;
+ if (gidsetsize > ngroups_max + 1 || gidsetsize < 0)
+ return (EINVAL);
+
+ if (gidsetsize > CRED_SMALLGROUPS_NB)
+ groups = malloc(gidsetsize * sizeof(gid_t), M_TEMP, M_WAITOK);
+ else
+ groups = smallgroups;
+
+ error = copyin(uap->gidset, groups, gidsetsize * sizeof(gid_t));
+ if (error == 0) {
+ int ngroups = gidsetsize > 0 ? gidsetsize - 1 /* egid */ : 0;
+
+ error = kern_setgroups(td, &ngroups, groups + 1);
+ if (error == 0 && gidsetsize > 0)
+ td->td_proc->p_ucred->cr_gid = groups[0];
+ }
+
+ if (groups != smallgroups)
+ free(groups, M_TEMP);
+ return (error);
+}
+#endif /* COMPAT_FREEBSD14 */
+
#ifndef _SYS_SYSPROTO_H_
struct setgroups_args {
int gidsetsize;
@@ -1210,8 +1267,7 @@ sys_setgroups(struct thread *td, struct setgroups_args *uap)
* setgroups() differ.
*/
gidsetsize = uap->gidsetsize;
- /* XXXKE Limit to ngroups_max when we change the userland interface. */
- if (gidsetsize > ngroups_max + 1 || gidsetsize < 0)
+ if (gidsetsize > ngroups_max || gidsetsize < 0)
return (EINVAL);
if (gidsetsize > CRED_SMALLGROUPS_NB)
@@ -1238,35 +1294,17 @@ kern_setgroups(struct thread *td, int *ngrpp, gid_t *groups)
struct proc *p = td->td_proc;
struct ucred *newcred, *oldcred;
int ngrp, error;
- gid_t egid;
ngrp = *ngrpp;
/* Sanity check size. */
- /* XXXKE Limit to ngroups_max when we change the userland interface. */
- if (ngrp < 0 || ngrp > ngroups_max + 1)
+ if (ngrp < 0 || ngrp > ngroups_max)
return (EINVAL);
AUDIT_ARG_GROUPSET(groups, ngrp);
- /*
- * setgroups(0, NULL) is a legitimate way of clearing the groups vector
- * on non-BSD systems (which generally do not have the egid in the
- * groups[0]). We risk security holes when running non-BSD software if
- * we do not do the same. So we allow and treat 0 for 'ngrp' specially
- * below (twice).
- */
- if (ngrp != 0) {
- /*
- * To maintain userland compat for now, we use the first group
- * as our egid and we'll use the rest as our supplemental
- * groups.
- */
- egid = groups[0];
- ngrp--;
- groups++;
- groups_normalize(&ngrp, groups);
- *ngrpp = ngrp;
- }
+ groups_normalize(&ngrp, groups);
+ *ngrpp = ngrp;
+
newcred = crget();
crextend(newcred, ngrp);
PROC_LOCK(p);
@@ -1289,15 +1327,7 @@ kern_setgroups(struct thread *td, int *ngrpp, gid_t *groups)
if (error)
goto fail;
- /*
- * If some groups were passed, the first one is currently the desired
- * egid. This code is to be removed (along with some commented block
- * above) when setgroups() is changed to take only supplementary groups.
- */
- if (ngrp != 0)
- newcred->cr_gid = egid;
crsetgroups_internal(newcred, ngrp, groups);
-
setsugid(p);
proc_set_cred(p, newcred);
PROC_UNLOCK(p);
@@ -1914,6 +1944,38 @@ cr_canseejailproc(struct ucred *u1, struct ucred *u2)
}
/*
+ * Determine if u1 can tamper with the subject specified by u2, if they are in
+ * different jails and 'unprivileged_parent_tampering' jail policy allows it.
+ *
+ * May be called if u1 and u2 are in the same jail, but it is expected that the
+ * caller has already done a prison_check() prior to calling it.
+ *
+ * Returns: 0 for permitted, EPERM otherwise
+ */
+static int
+cr_can_tamper_with_subjail(struct ucred *u1, struct ucred *u2, int priv)
+{
+
+ MPASS(prison_check(u1, u2) == 0);
+ if (u1->cr_prison == u2->cr_prison)
+ return (0);
+
+ if (priv_check_cred(u1, priv) == 0)
+ return (0);
+
+ /*
+ * Jails do not maintain a distinct UID space, so process visibility is
+ * all that would control an unprivileged process' ability to tamper
+ * with a process in a subjail by default if we did not have the
+ * allow.unprivileged_parent_tampering knob to restrict it by default.
+ */
+ if (prison_allow(u2, PR_ALLOW_UNPRIV_PARENT_TAMPER))
+ return (0);
+
+ return (EPERM);
+}
+
+/*
* Helper for cr_cansee*() functions to abide by system-wide security.bsd.see_*
* policies. Determines if u1 "can see" u2 according to these policies.
* Returns: 0 for permitted, ESRCH otherwise
@@ -2062,6 +2124,19 @@ cr_cansignal(struct ucred *cred, struct proc *proc, int signum)
return (error);
}
+ /*
+ * At this point, the target may be in a different jail than the
+ * subject -- the subject must be in a parent jail to the target,
+ * whether it is prison0 or a subordinate of prison0 that has
+ * children. Additional privileges are required to allow this, as
+ * whether the creds are truly equivalent or not must be determined on
+ * a case-by-case basis.
+ */
+ error = cr_can_tamper_with_subjail(cred, proc->p_ucred,
+ PRIV_SIGNAL_DIFFJAIL);
+ if (error)
+ return (error);
+
return (0);
}
@@ -2138,6 +2213,12 @@ p_cansched(struct thread *td, struct proc *p)
if (error)
return (error);
}
+
+ error = cr_can_tamper_with_subjail(td->td_ucred, p->p_ucred,
+ PRIV_SCHED_DIFFJAIL);
+ if (error)
+ return (error);
+
return (0);
}
@@ -2258,6 +2339,11 @@ p_candebug(struct thread *td, struct proc *p)
return (error);
}
+ error = cr_can_tamper_with_subjail(td->td_ucred, p->p_ucred,
+ PRIV_DEBUG_DIFFJAIL);
+ if (error)
+ return (error);
+
/* Can't trace init when securelevel > 0. */
if (p == initproc) {
error = securelevel_gt(td->td_ucred, 0);
@@ -2835,7 +2921,8 @@ crextend(struct ucred *cr, int n)
* Normalizes a set of groups to be applied to a 'struct ucred'.
*
* Normalization ensures that the supplementary groups are sorted in ascending
- * order and do not contain duplicates.
+ * order and do not contain duplicates. This allows group_is_supplementary
+ * to do a binary search.
*/
static void
groups_normalize(int *ngrp, gid_t *groups)
diff --git a/sys/kern/sys_timerfd.c b/sys/kern/sys_timerfd.c
index ab7e048a2ab1..565ab3ad6ee6 100644
--- a/sys/kern/sys_timerfd.c
+++ b/sys/kern/sys_timerfd.c
@@ -206,7 +206,6 @@ retry:
mtx_unlock(&tfd->tfd_lock);
return (EAGAIN);
}
- td->td_rtcgen = atomic_load_acq_int(&rtc_generation);
error = mtx_sleep(&tfd->tfd_count, &tfd->tfd_lock,
PCATCH, "tfdrd", 0);
if (error == 0) {
diff --git a/sys/kern/syscalls.c b/sys/kern/syscalls.c
index 90a4f3a7dad8..4122f9261871 100644
--- a/sys/kern/syscalls.c
+++ b/sys/kern/syscalls.c
@@ -6,7 +6,7 @@
const char *syscallnames[] = {
"syscall", /* 0 = syscall */
- "exit", /* 1 = exit */
+ "_exit", /* 1 = _exit */
"fork", /* 2 = fork */
"read", /* 3 = read */
"write", /* 4 = write */
@@ -84,8 +84,8 @@ const char *syscallnames[] = {
"obs_vhangup", /* 76 = obsolete vhangup */
"obs_vlimit", /* 77 = obsolete vlimit */
"mincore", /* 78 = mincore */
- "getgroups", /* 79 = getgroups */
- "setgroups", /* 80 = setgroups */
+ "compat14.getgroups", /* 79 = freebsd14 getgroups */
+ "compat14.setgroups", /* 80 = freebsd14 setgroups */
"getpgrp", /* 81 = getpgrp */
"setpgid", /* 82 = setpgid */
"setitimer", /* 83 = setitimer */
@@ -600,4 +600,6 @@ const char *syscallnames[] = {
"exterrctl", /* 592 = exterrctl */
"inotify_add_watch_at", /* 593 = inotify_add_watch_at */
"inotify_rm_watch", /* 594 = inotify_rm_watch */
+ "getgroups", /* 595 = getgroups */
+ "setgroups", /* 596 = setgroups */
};
diff --git a/sys/kern/syscalls.conf b/sys/kern/syscalls.conf
index a98d52659832..ae7bd1f87612 100644
--- a/sys/kern/syscalls.conf
+++ b/sys/kern/syscalls.conf
@@ -1,3 +1,4 @@
libsysmap="../../lib/libsys/syscalls.map"
libsys_h="../../lib/libsys/_libsys.h"
sysmk="../sys/syscall.mk"
+syshdr_extra="#define SYS_exit SYS__exit"
diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master
index a8815afee866..fa64597d14a5 100644
--- a/sys/kern/syscalls.master
+++ b/sys/kern/syscalls.master
@@ -51,6 +51,7 @@
; SYSMUX syscall multiplexer. No prototype, argument struct, or
; handler is declared or used. Handled in MD syscall code.
; CAPENABLED syscall is allowed in capability mode
+; NORETURN the syscall does not return
;
; To support programmatic generation of both the default ABI and 32-bit compat
; (freebsd32) we impose a number of restrictions on the types of system calls.
@@ -124,8 +125,8 @@
...
);
}
-1 AUE_EXIT STD|CAPENABLED {
- void exit(
+1 AUE_EXIT STD|CAPENABLED|NORETURN {
+ void _exit(
int rval
);
}
@@ -551,13 +552,13 @@
_Out_writes_bytes_(len/PAGE_SIZE) char *vec
);
}
-79 AUE_GETGROUPS STD|CAPENABLED {
+79 AUE_GETGROUPS STD|CAPENABLED|COMPAT14 {
int getgroups(
int gidsetsize,
_Out_writes_opt_(gidsetsize) gid_t *gidset
);
}
-80 AUE_SETGROUPS STD {
+80 AUE_SETGROUPS STD|COMPAT14 {
int setgroups(
int gidsetsize,
_In_reads_(gidsetsize) const gid_t *gidset
@@ -3370,5 +3371,17 @@
int wd
);
}
+595 AUE_GETGROUPS STD|CAPENABLED {
+ int getgroups(
+ int gidsetsize,
+ _Out_writes_opt_(gidsetsize) gid_t *gidset
+ );
+ }
+596 AUE_SETGROUPS STD {
+ int setgroups(
+ int gidsetsize,
+ _In_reads_(gidsetsize) const gid_t *gidset
+ );
+ }
; vim: syntax=off
diff --git a/sys/kern/systrace_args.c b/sys/kern/systrace_args.c
index 467caa71f20d..2b1ea9eed8d4 100644
--- a/sys/kern/systrace_args.c
+++ b/sys/kern/systrace_args.c
@@ -17,9 +17,9 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
*n_args = 0;
break;
}
- /* exit */
+ /* _exit */
case 1: {
- struct exit_args *p = params;
+ struct _exit_args *p = params;
iarg[a++] = p->rval; /* int */
*n_args = 1;
break;
@@ -454,22 +454,6 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
*n_args = 3;
break;
}
- /* getgroups */
- case 79: {
- struct getgroups_args *p = params;
- iarg[a++] = p->gidsetsize; /* int */
- uarg[a++] = (intptr_t)p->gidset; /* gid_t * */
- *n_args = 2;
- break;
- }
- /* setgroups */
- case 80: {
- struct setgroups_args *p = params;
- iarg[a++] = p->gidsetsize; /* int */
- uarg[a++] = (intptr_t)p->gidset; /* const gid_t * */
- *n_args = 2;
- break;
- }
/* getpgrp */
case 81: {
*n_args = 0;
@@ -3500,6 +3484,22 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
*n_args = 2;
break;
}
+ /* getgroups */
+ case 595: {
+ struct getgroups_args *p = params;
+ iarg[a++] = p->gidsetsize; /* int */
+ uarg[a++] = (intptr_t)p->gidset; /* gid_t * */
+ *n_args = 2;
+ break;
+ }
+ /* setgroups */
+ case 596: {
+ struct setgroups_args *p = params;
+ iarg[a++] = p->gidsetsize; /* int */
+ uarg[a++] = (intptr_t)p->gidset; /* const gid_t * */
+ *n_args = 2;
+ break;
+ }
default:
*n_args = 0;
break;
@@ -3513,7 +3513,7 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
/* syscall */
case 0:
break;
- /* exit */
+ /* _exit */
case 1:
switch (ndx) {
case 0:
@@ -4199,32 +4199,6 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
break;
};
break;
- /* getgroups */
- case 79:
- switch (ndx) {
- case 0:
- p = "int";
- break;
- case 1:
- p = "userland gid_t *";
- break;
- default:
- break;
- };
- break;
- /* setgroups */
- case 80:
- switch (ndx) {
- case 0:
- p = "int";
- break;
- case 1:
- p = "userland const gid_t *";
- break;
- default:
- break;
- };
- break;
/* getpgrp */
case 81:
break;
@@ -9367,6 +9341,32 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
break;
};
break;
+ /* getgroups */
+ case 595:
+ switch (ndx) {
+ case 0:
+ p = "int";
+ break;
+ case 1:
+ p = "userland gid_t *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* setgroups */
+ case 596:
+ switch (ndx) {
+ case 0:
+ p = "int";
+ break;
+ case 1:
+ p = "userland const gid_t *";
+ break;
+ default:
+ break;
+ };
+ break;
default:
break;
};
@@ -9380,7 +9380,7 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
switch (sysnum) {
/* syscall */
case 0:
- /* exit */
+ /* _exit */
case 1:
if (ndx == 0 || ndx == 1)
p = "void";
@@ -9633,16 +9633,6 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
if (ndx == 0 || ndx == 1)
p = "int";
break;
- /* getgroups */
- case 79:
- if (ndx == 0 || ndx == 1)
- p = "int";
- break;
- /* setgroups */
- case 80:
- if (ndx == 0 || ndx == 1)
- p = "int";
- break;
/* getpgrp */
case 81:
/* setpgid */
@@ -11365,6 +11355,16 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
if (ndx == 0 || ndx == 1)
p = "int";
break;
+ /* getgroups */
+ case 595:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* setgroups */
+ case 596:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
default:
break;
};
diff --git a/sys/kern/uipc_shm.c b/sys/kern/uipc_shm.c
index 85fe48ddd466..eb1327f7f2de 100644
--- a/sys/kern/uipc_shm.c
+++ b/sys/kern/uipc_shm.c
@@ -1160,7 +1160,8 @@ kern_shm_open2(struct thread *td, const char *userpath, int flags, mode_t mode,
if ((flags & O_ACCMODE) != O_RDONLY && (flags & O_ACCMODE) != O_RDWR)
return (EINVAL);
- if ((flags & ~(O_ACCMODE | O_CREAT | O_EXCL | O_TRUNC | O_CLOEXEC)) != 0)
+ if ((flags & ~(O_ACCMODE | O_CREAT | O_EXCL | O_TRUNC | O_CLOEXEC |
+ O_CLOFORK)) != 0)
return (EINVAL);
largepage = (shmflags & SHM_LARGEPAGE) != 0;
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c
index fa655c43d155..19c39e42bafa 100644
--- a/sys/kern/vfs_bio.c
+++ b/sys/kern/vfs_bio.c
@@ -5170,7 +5170,7 @@ bufstrategy(struct bufobj *bo, struct buf *bp)
vp = bp->b_vp;
KASSERT(vp == bo->bo_private, ("Inconsistent vnode bufstrategy"));
- KASSERT(vp->v_type != VCHR && vp->v_type != VBLK,
+ KASSERT(!VN_ISDEV(vp),
("Wrong vnode in bufstrategy(bp=%p, vp=%p)", bp, vp));
i = VOP_STRATEGY(vp, bp);
KASSERT(i == 0, ("VOP_STRATEGY failed bp=%p vp=%p", bp, bp->b_vp));
diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c
index fd6202a1424c..85f67731e1cc 100644
--- a/sys/kern/vfs_default.c
+++ b/sys/kern/vfs_default.c
@@ -457,6 +457,7 @@ vop_stdpathconf(struct vop_pathconf_args *ap)
case _PC_NAMEDATTR_ENABLED:
case _PC_HAS_NAMEDATTR:
case _PC_HAS_HIDDENSYSTEM:
+ case _PC_CLONE_BLKSIZE:
*ap->a_retval = 0;
return (0);
default:
diff --git a/sys/kern/vfs_inotify.c b/sys/kern/vfs_inotify.c
index 746a5a39208e..b265a5ff3a62 100644
--- a/sys/kern/vfs_inotify.c
+++ b/sys/kern/vfs_inotify.c
@@ -801,6 +801,7 @@ vn_inotify_add_watch(struct vnode *vp, struct inotify_softc *sc, uint32_t mask,
vn_lock(vp, LK_SHARED | LK_RETRY);
if (error != 0)
break;
+ NDFREE_PNBUF(&nd);
vn_irflag_set_cond(nd.ni_vp, VIRF_INOTIFY_PARENT);
vrele(nd.ni_vp);
}
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 9704e9c160a8..bf3ed9d515dc 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -2839,7 +2839,7 @@ setfflags(struct thread *td, struct vnode *vp, u_long flags)
* if they are allowed to set flags and programs assume that
* chown can't fail when done as root.
*/
- if (vp->v_type == VCHR || vp->v_type == VBLK) {
+ if (VN_ISDEV(vp)) {
error = priv_check(td, PRIV_VFS_CHFLAGS_DEV);
if (error != 0)
return (error);
@@ -5050,15 +5050,16 @@ kern_copy_file_range(struct thread *td, int infd, off_t *inoffp, int outfd,
size_t retlen;
void *rl_rcookie, *rl_wcookie;
off_t inoff, outoff, savinoff, savoutoff;
- bool foffsets_locked;
+ bool foffsets_locked, foffsets_set;
infp = outfp = NULL;
rl_rcookie = rl_wcookie = NULL;
foffsets_locked = false;
+ foffsets_set = false;
error = 0;
retlen = 0;
- if (flags != 0) {
+ if ((flags & ~COPY_FILE_RANGE_USERFLAGS) != 0) {
error = EINVAL;
goto out;
}
@@ -5122,6 +5123,8 @@ kern_copy_file_range(struct thread *td, int infd, off_t *inoffp, int outfd,
}
foffset_lock_pair(infp1, &inoff, outfp1, &outoff, 0);
foffsets_locked = true;
+ } else {
+ foffsets_set = true;
}
savinoff = inoff;
savoutoff = outoff;
@@ -5180,11 +5183,12 @@ out:
vn_rangelock_unlock(invp, rl_rcookie);
if (rl_wcookie != NULL)
vn_rangelock_unlock(outvp, rl_wcookie);
+ if ((foffsets_locked || foffsets_set) &&
+ (error == EINTR || error == ERESTART)) {
+ inoff = savinoff;
+ outoff = savoutoff;
+ }
if (foffsets_locked) {
- if (error == EINTR || error == ERESTART) {
- inoff = savinoff;
- outoff = savoutoff;
- }
if (inoffp == NULL)
foffset_unlock(infp, inoff, 0);
else
@@ -5193,6 +5197,9 @@ out:
foffset_unlock(outfp, outoff, 0);
else
*outoffp = outoff;
+ } else if (foffsets_set) {
+ *inoffp = inoff;
+ *outoffp = outoff;
}
if (outfp != NULL)
fdrop(outfp, td);
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
index 6451c9e07a60..93f87ddae4de 100644
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -3443,6 +3443,11 @@ vn_generic_copy_file_range(struct vnode *invp, off_t *inoffp,
interrupted = 0;
dat = NULL;
+ if ((flags & COPY_FILE_RANGE_CLONE) != 0) {
+ error = ENOSYS;
+ goto out;
+ }
+
error = vn_lock(invp, LK_SHARED);
if (error != 0)
goto out;