Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F107281871
D41976.id127802.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D41976.id127802.diff
View Options
diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c
--- a/sys/amd64/amd64/trap.c
+++ b/sys/amd64/amd64/trap.c
@@ -1033,7 +1033,7 @@
}
if (sa->code >= p->p_sysent->sv_size)
- sa->callp = &p->p_sysent->sv_table[0];
+ sa->callp = &nosys_sysent;
else
sa->callp = &p->p_sysent->sv_table[sa->code];
diff --git a/sys/amd64/linux/linux_sysvec.c b/sys/amd64/linux/linux_sysvec.c
--- a/sys/amd64/linux/linux_sysvec.c
+++ b/sys/amd64/linux/linux_sysvec.c
@@ -159,7 +159,7 @@
if (sa->code >= p->p_sysent->sv_size)
/* nosys */
- sa->callp = &p->p_sysent->sv_table[p->p_sysent->sv_size - 1];
+ sa->callp = &nosys_sysent;
else
sa->callp = &p->p_sysent->sv_table[sa->code];
@@ -701,7 +701,7 @@
.sv_fixlimit = NULL,
.sv_maxssiz = NULL,
.sv_flags = SV_ABI_LINUX | SV_LP64 | SV_SHP | SV_SIG_DISCIGN |
- SV_SIG_WAITNDQ | SV_TIMEKEEP,
+ SV_SIG_WAITNDQ | SV_TIMEKEEP | SV_NOSYS_NOSIG,
.sv_set_syscall_retval = linux_set_syscall_retval,
.sv_fetch_syscall_args = linux_fetch_syscall_args,
.sv_syscallnames = linux_syscallnames,
diff --git a/sys/amd64/linux32/linux32_sysvec.c b/sys/amd64/linux32/linux32_sysvec.c
--- a/sys/amd64/linux32/linux32_sysvec.c
+++ b/sys/amd64/linux32/linux32_sysvec.c
@@ -531,7 +531,7 @@
if (sa->code >= p->p_sysent->sv_size)
/* nosys */
- sa->callp = &p->p_sysent->sv_table[p->p_sysent->sv_size - 1];
+ sa->callp = &nosys_sysent;
else
sa->callp = &p->p_sysent->sv_table[sa->code];
@@ -799,7 +799,7 @@
.sv_fixlimit = linux32_fixlimit,
.sv_maxssiz = &linux32_maxssiz,
.sv_flags = SV_ABI_LINUX | SV_ILP32 | SV_IA32 | SV_SHP |
- SV_SIG_DISCIGN | SV_SIG_WAITNDQ | SV_TIMEKEEP,
+ SV_SIG_DISCIGN | SV_SIG_WAITNDQ | SV_TIMEKEEP | SV_NOSYS_NOSIG,
.sv_set_syscall_retval = linux32_set_syscall_retval,
.sv_fetch_syscall_args = linux32_fetch_syscall_args,
.sv_syscallnames = linux32_syscallnames,
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -159,6 +159,10 @@
SYSCTL_INT(_kern, OID_AUTO, lognosys, CTLFLAG_RWTUN, &kern_lognosys, 0,
"Log invalid syscalls");
+static int kern_signosys = 1;
+SYSCTL_INT(_kern, OID_AUTO, signosys, CTLFLAG_RWTUN, &kern_signosys, 0,
+ "Send SIGSYS on return from invalid syscall");
+
__read_frequently bool sigfastblock_fetch_always = false;
SYSCTL_BOOL(_kern, OID_AUTO, sigfastblock_fetch_always, CTLFLAG_RWTUN,
&sigfastblock_fetch_always, 0,
@@ -2686,7 +2690,8 @@
audited = AUDIT_SYSCALL_ENTER(sc, td) != 0;
if (!sy_thr_static) {
- error = syscall_thread_enter(td, se);
+ error = syscall_thread_enter(td, &se);
+ sy_thr_static = (se->sy_thrcnt & SY_THR_STATIC) != 0;
if (error != 0) {
tsr->ts_ret.sr_error = error;
return;
@@ -4218,9 +4223,11 @@
p = td->td_proc;
- PROC_LOCK(p);
- tdsignal(td, SIGSYS);
- PROC_UNLOCK(p);
+ if (SV_PROC_FLAG(p, SV_NOSYS_NOSIG) == 0 && kern_signosys) {
+ PROC_LOCK(p);
+ tdsignal(td, SIGSYS);
+ PROC_UNLOCK(p);
+ }
if (kern_lognosys == 1 || kern_lognosys == 3) {
uprintf("pid %d comm %s: nosys %d\n", p->p_pid, p->p_comm,
td->td_sa.code);
diff --git a/sys/kern/kern_syscalls.c b/sys/kern/kern_syscalls.c
--- a/sys/kern/kern_syscalls.c
+++ b/sys/kern/kern_syscalls.c
@@ -61,6 +61,17 @@
return (nosys(td, args));
}
+struct sysent nosys_sysent = {
+ .sy_call = (sy_call_t *)nosys,
+ .sy_systrace_args_func = NULL,
+ .sy_narg = 0,
+ .sy_flags = SYF_CAPENABLED,
+ .sy_auevent = AUE_NULL,
+ .sy_entry = 0, /* DTRACE_IDNONE */
+ .sy_return = 0,
+ .sy_thrcnt = SY_THR_STATIC,
+};
+
static void
syscall_thread_drain(struct sysent *se)
{
@@ -78,19 +89,21 @@
}
int
-syscall_thread_enter(struct thread *td, struct sysent *se)
+syscall_thread_enter(struct thread *td, struct sysent **se)
{
uint32_t cnt, oldcnt;
- KASSERT((se->sy_thrcnt & SY_THR_STATIC) == 0,
+ KASSERT(((*se)->sy_thrcnt & SY_THR_STATIC) == 0,
("%s: not a static syscall", __func__));
do {
- oldcnt = se->sy_thrcnt;
- if ((oldcnt & (SY_THR_DRAINING | SY_THR_ABSENT)) != 0)
- return (ENOSYS);
+ oldcnt = (*se)->sy_thrcnt;
+ if ((oldcnt & (SY_THR_DRAINING | SY_THR_ABSENT)) != 0) {
+ *se = &nosys_sysent;
+ return (0);
+ }
cnt = oldcnt + SY_THR_INCR;
- } while (atomic_cmpset_acq_32(&se->sy_thrcnt, oldcnt, cnt) == 0);
+ } while (atomic_cmpset_acq_32(&(*se)->sy_thrcnt, oldcnt, cnt) == 0);
return (0);
}
diff --git a/sys/kern/subr_syscall.c b/sys/kern/subr_syscall.c
--- a/sys/kern/subr_syscall.c
+++ b/sys/kern/subr_syscall.c
@@ -144,7 +144,8 @@
AUDIT_SYSCALL_ENTER(sa->code, td) ||
!sy_thr_static)) {
if (!sy_thr_static) {
- error = syscall_thread_enter(td, se);
+ error = syscall_thread_enter(td, &se);
+ sy_thr_static = (se->sy_thrcnt & SY_THR_STATIC) != 0;
if (error != 0) {
td->td_errno = error;
goto retval;
diff --git a/sys/sys/sysent.h b/sys/sys/sysent.h
--- a/sys/sys/sysent.h
+++ b/sys/sys/sysent.h
@@ -164,7 +164,7 @@
#define SV_IA32 0x004000 /* Intel 32-bit executable. */
#define SV_AOUT 0x008000 /* a.out executable. */
#define SV_SHP 0x010000 /* Shared page. */
-#define SV_AVAIL1 0x020000 /* Unused */
+#define SV_NOSYS_NOSIG 0x020000 /* No SIGSYS for non-existing syscall */
#define SV_TIMEKEEP 0x040000 /* Shared page timehands. */
#define SV_ASLR 0x080000 /* ASLR allowed. */
#define SV_RNG_SEED_VER 0x100000 /* random(4) reseed generation. */
@@ -191,6 +191,7 @@
extern struct sysentvec aout_sysvec;
extern struct sysent sysent[];
extern const char *syscallnames[];
+extern struct sysent nosys_sysent;
struct nosys_args {
register_t dummy;
@@ -319,7 +320,7 @@
int lkmnosys(struct thread *, struct nosys_args *);
int lkmressys(struct thread *, struct nosys_args *);
-int syscall_thread_enter(struct thread *td, struct sysent *se);
+int syscall_thread_enter(struct thread *td, struct sysent **se);
void syscall_thread_exit(struct thread *td, struct sysent *se);
int shared_page_alloc(int size, int align);
diff --git a/tests/sys/kern/Makefile b/tests/sys/kern/Makefile
--- a/tests/sys/kern/Makefile
+++ b/tests/sys/kern/Makefile
@@ -48,6 +48,7 @@
ATF_TESTS_C+= unix_socketpair_test
ATF_TESTS_C+= waitpid_nohang
ATF_TESTS_C+= pdeathsig
+ATF_TESTS_C+= sigsys
ATF_TESTS_SH+= coredump_phnum_test
ATF_TESTS_SH+= sonewconn_overflow
diff --git a/tests/sys/kern/sigsys.c b/tests/sys/kern/sigsys.c
new file mode 100644
--- /dev/null
+++ b/tests/sys/kern/sigsys.c
@@ -0,0 +1,66 @@
+/*-
+ * Copyright (c) 2023 The FreeBSD Foundation
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * This software were developed by Konstantin Belousov <kib@FreeBSD.org>
+ * under sponsorship from the FreeBSD Foundation.
+ */
+
+#include <sys/syscall.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <signal.h>
+#include <stdatomic.h>
+#include <stdbool.h>
+#include <stdlib.h>
+
+int sigsys_cnt;
+
+static void
+sigsys_handler(int signo, siginfo_t *si, void *ucp)
+{
+ sigsys_cnt++;
+}
+
+ATF_TC(sigsys_test);
+
+ATF_TC_HEAD(sigsys_test, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Testing delivery of SIGSYS on invalid syscalls");
+}
+
+ATF_TC_BODY(sigsys_test, tc)
+{
+ struct sigaction sa;
+
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_sigaction = sigsys_handler;
+ sa.sa_flags = SA_SIGINFO;
+ ATF_REQUIRE(sigaction(SIGSYS, &sa, NULL) == 0);
+
+ ATF_REQUIRE(syscall(273) == -1); /* reserved */
+ atomic_signal_fence(memory_order_seq_cst);
+ ATF_REQUIRE(sigsys_cnt == 1);
+
+ ATF_REQUIRE(syscall(440) == -1); /* SYS_kse_switchin */
+ atomic_signal_fence(memory_order_seq_cst);
+ ATF_REQUIRE(sigsys_cnt == 2);
+
+ /* Hope this is enough for say next two months */
+ ATF_REQUIRE(syscall(3000000) == -1);
+ atomic_signal_fence(memory_order_seq_cst);
+ ATF_REQUIRE(sigsys_cnt == 3);
+
+ ATF_REQUIRE(syscall(SYS_afs3_syscall) == -1);
+ atomic_signal_fence(memory_order_seq_cst);
+ ATF_REQUIRE(sigsys_cnt == 4);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, sigsys_test);
+ return (atf_no_error());
+}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Jan 12, 10:47 PM (20 h, 53 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15773458
Default Alt Text
D41976.id127802.diff (7 KB)
Attached To
Mode
D41976: Some fixes for nosys()/SIGSYS
Attached
Detach File
Event Timeline
Log In to Comment