git: 62a8639f7012 - stable/13 - syscalls: fix missing SIGSYS for several ENOSYS errors
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 09 Oct 2023 03:43:05 UTC
The branch stable/13 has been updated by kib:
URL: https://cgit.FreeBSD.org/src/commit/?id=62a8639f7012603b3b525409b89c7b6a197c6dd3
commit 62a8639f7012603b3b525409b89c7b6a197c6dd3
Author: Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2023-09-25 16:32:52 +0000
Commit: Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2023-10-09 03:42:17 +0000
syscalls: fix missing SIGSYS for several ENOSYS errors
(cherry picked from commit 39024a89146902ca9aba250130b828ad9aced99d)
---
sys/amd64/amd64/trap.c | 2 +-
sys/amd64/ia32/ia32_syscall.c | 2 +-
sys/arm/arm/syscall.c | 2 +-
sys/arm64/arm64/elf32_machdep.c | 2 +-
sys/arm64/arm64/trap.c | 2 +-
sys/arm64/linux/linux_sysvec.c | 2 +-
sys/i386/i386/trap.c | 2 +-
sys/i386/linux/linux_sysvec.c | 2 +-
sys/kern/kern_sig.c | 3 ++-
sys/kern/kern_syscalls.c | 25 +++++++++++++++++++------
sys/kern/subr_syscall.c | 3 ++-
sys/powerpc/powerpc/trap.c | 2 +-
sys/riscv/riscv/trap.c | 2 +-
sys/sys/sysent.h | 3 ++-
14 files changed, 35 insertions(+), 19 deletions(-)
diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c
index 8534e1e5b063..9f50de795ca5 100644
--- a/sys/amd64/amd64/trap.c
+++ b/sys/amd64/amd64/trap.c
@@ -1020,7 +1020,7 @@ cpu_fetch_syscall_args_fallback(struct thread *td, struct syscall_args *sa)
}
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/ia32/ia32_syscall.c b/sys/amd64/ia32/ia32_syscall.c
index 9d8afa960abd..20a7b1cadb60 100644
--- a/sys/amd64/ia32/ia32_syscall.c
+++ b/sys/amd64/ia32/ia32_syscall.c
@@ -181,7 +181,7 @@ ia32_fetch_syscall_args(struct thread *td)
params += sizeof(quad_t);
}
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/arm/arm/syscall.c b/sys/arm/arm/syscall.c
index d2799123138a..99ce83ebce5f 100644
--- a/sys/arm/arm/syscall.c
+++ b/sys/arm/arm/syscall.c
@@ -117,7 +117,7 @@ cpu_fetch_syscall_args(struct thread *td)
}
p = td->td_proc;
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];
error = 0;
diff --git a/sys/arm64/arm64/elf32_machdep.c b/sys/arm64/arm64/elf32_machdep.c
index 30561ded9376..edd285d8b482 100644
--- a/sys/arm64/arm64/elf32_machdep.c
+++ b/sys/arm64/arm64/elf32_machdep.c
@@ -192,7 +192,7 @@ freebsd32_fetch_syscall_args(struct thread *td)
}
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/arm64/arm64/trap.c b/sys/arm64/arm64/trap.c
index 7906bd94d470..d62ebba3debd 100644
--- a/sys/arm64/arm64/trap.c
+++ b/sys/arm64/arm64/trap.c
@@ -149,7 +149,7 @@ cpu_fetch_syscall_args(struct thread *td)
}
if (__predict_false(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/arm64/linux/linux_sysvec.c b/sys/arm64/linux/linux_sysvec.c
index 8f142e0d8069..4ceee760d80b 100644
--- a/sys/arm64/linux/linux_sysvec.c
+++ b/sys/arm64/linux/linux_sysvec.c
@@ -132,7 +132,7 @@ linux_fetch_syscall_args(struct thread *td)
sa->code = td->td_frame->tf_x[8];
/* LINUXTODO: generic syscall? */
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/i386/i386/trap.c b/sys/i386/i386/trap.c
index aa33418c34b8..67bd0ba015e5 100644
--- a/sys/i386/i386/trap.c
+++ b/sys/i386/i386/trap.c
@@ -1114,7 +1114,7 @@ cpu_fetch_syscall_args(struct thread *td)
}
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/i386/linux/linux_sysvec.c b/sys/i386/linux/linux_sysvec.c
index de2e65fb2191..ab29da91f64a 100644
--- a/sys/i386/linux/linux_sysvec.c
+++ b/sys/i386/linux/linux_sysvec.c
@@ -522,7 +522,7 @@ linux_fetch_syscall_args(struct thread *td)
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];
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index 7601385677d2..04ca12cc5d84 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -2610,7 +2610,8 @@ ptrace_syscallreq(struct thread *td, struct proc *p,
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;
diff --git a/sys/kern/kern_syscalls.c b/sys/kern/kern_syscalls.c
index c596fca98d6c..0adb55ce80d0 100644
--- a/sys/kern/kern_syscalls.c
+++ b/sys/kern/kern_syscalls.c
@@ -61,6 +61,17 @@ lkmressys(struct thread *td, struct nosys_args *args)
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 @@ syscall_thread_drain(struct sysent *se)
}
int
-syscall_thread_enter(struct thread *td, struct sysent *se)
+syscall_thread_enter(struct thread *td, struct sysent **se)
{
u_int32_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
index 464f91e04206..67ec87d2d563 100644
--- a/sys/kern/subr_syscall.c
+++ b/sys/kern/subr_syscall.c
@@ -144,7 +144,8 @@ syscallenter(struct thread *td)
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/powerpc/powerpc/trap.c b/sys/powerpc/powerpc/trap.c
index e1bc7aee1be9..202a83c4683f 100644
--- a/sys/powerpc/powerpc/trap.c
+++ b/sys/powerpc/powerpc/trap.c
@@ -693,7 +693,7 @@ cpu_fetch_syscall_args(struct thread *td)
}
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/riscv/riscv/trap.c b/sys/riscv/riscv/trap.c
index 8a5e340442c7..ecf6b043d606 100644
--- a/sys/riscv/riscv/trap.c
+++ b/sys/riscv/riscv/trap.c
@@ -109,7 +109,7 @@ cpu_fetch_syscall_args(struct thread *td)
}
if (__predict_false(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/sys/sysent.h b/sys/sys/sysent.h
index f895f2cd894a..2d8631b94113 100644
--- a/sys/sys/sysent.h
+++ b/sys/sys/sysent.h
@@ -193,6 +193,7 @@ struct sysentvec {
extern struct sysentvec aout_sysvec;
extern struct sysent sysent[];
extern const char *syscallnames[];
+extern struct sysent nosys_sysent;
#define NO_SYSCALL (-1)
@@ -315,7 +316,7 @@ struct nosys_args;
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);