* [PATCH v3 0/2] ptrace: reject out of range error values in PTRACE_SET_SYSCALL_INFO
@ 2026-11-15 15:26 Renzo Davoli
2026-11-15 15:26 ` [PATCH v3 1/2] " Renzo Davoli
2026-11-15 15:27 ` [PATCH v3 2/2] selftests/ptrace: check that PTRACE_SET_SYSCALL_INFO rejects invalid error values Renzo Davoli
0 siblings, 2 replies; 4+ messages in thread
From: Renzo Davoli @ 2026-11-15 15:26 UTC (permalink / raw)
To: linux-kernel
Cc: Renzo Davoli, Oleg Nesterov, Andrew Morton, Dmitry V . Levin,
Alexey Gladkov, Eugene Syromyatnikov, Charlie Jenkins,
Bradley Morgan, Shuah Khan, strace-devel, linux-api,
linux-kselftest
With is_error set, PTRACE_SET_SYSCALL_INFO passes info.exit.rval to
syscall_set_return_value() as an "int" error without checking it: a
positive value, or on 64-bit one outside the "int" range, turns the
error into a success or is truncated.
Patch 1 rejects with -ERANGE any error value outside [-MAX_ERRNO, -1].
Patch 2 adds a test case for this to the set_syscall_info selftest.
This series is independent of the PTRACE_SET_SYSCALL_INFO seccomp skip
and SET_IP series: they apply on top of each other in either order.
Changes in v3:
* added Reviewed-by of Dmitry V. Levin and Bradley Morgan to patch 1
* new patch 2: selftest, as suggested by Dmitry V. Levin
Changes in v2:
* shorter commit message and comment, dropped Assisted-by
(Bradley Morgan)
v2: https://lore.kernel.org/lkml/20261115082540.385386-1-renzo@cs.unibo.it/
v1: https://lore.kernel.org/lkml/20261114184842.373304-1-renzo@cs.unibo.it/
Renzo Davoli (2):
ptrace: reject out of range error values in PTRACE_SET_SYSCALL_INFO
selftests/ptrace: check that PTRACE_SET_SYSCALL_INFO rejects invalid
error values
kernel/ptrace.c | 4 ++
.../selftests/ptrace/set_syscall_info.c | 51 +++++++++++++++++++
2 files changed, 55 insertions(+)
base-commit: 7e1392a42ea288d70a266f6553fe06f57f8647ea
--
2.47.3
^ permalink raw reply [flat|nested] 4+ messages in thread* [PATCH v3 1/2] ptrace: reject out of range error values in PTRACE_SET_SYSCALL_INFO 2026-11-15 15:26 [PATCH v3 0/2] ptrace: reject out of range error values in PTRACE_SET_SYSCALL_INFO Renzo Davoli @ 2026-11-15 15:26 ` Renzo Davoli 2026-11-15 15:27 ` [PATCH v3 2/2] selftests/ptrace: check that PTRACE_SET_SYSCALL_INFO rejects invalid error values Renzo Davoli 1 sibling, 0 replies; 4+ messages in thread From: Renzo Davoli @ 2026-11-15 15:26 UTC (permalink / raw) To: linux-kernel Cc: Renzo Davoli, Oleg Nesterov, Andrew Morton, Dmitry V . Levin, Alexey Gladkov, Eugene Syromyatnikov, Charlie Jenkins, Bradley Morgan, Shuah Khan, strace-devel, linux-api, linux-kselftest With is_error set, PTRACE_SET_SYSCALL_INFO passes info.exit.rval to syscall_set_return_value() as an "int" error without checking it: a positive value, or on 64-bit one outside the "int" range, turns the error into a success or is truncated. Reject with -ERANGE any error value outside [-MAX_ERRNO, -1]. Fixes: 26bb32768fe6 ("ptrace: introduce PTRACE_SET_SYSCALL_INFO request") Reviewed-by: Dmitry V. Levin <ldv@strace.io> Reviewed-by: Bradley Morgan <bradley.morgan@linux.dev> Signed-off-by: Renzo Davoli <renzo@cs.unibo.it> --- kernel/ptrace.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 3f2fe68ccb14..1ffacfcef8d4 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -1111,6 +1111,10 @@ ptrace_set_syscall_info_exit(struct task_struct *child, struct pt_regs *regs, if (rval != info->exit.rval) return -ERANGE; + /* An error must be a negative errno value. */ + if (info->exit.is_error && (rval < -MAX_ERRNO || rval >= 0)) + return -ERANGE; + if (info->exit.is_error) syscall_set_return_value(child, regs, rval, 0); else -- 2.47.3 ^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v3 2/2] selftests/ptrace: check that PTRACE_SET_SYSCALL_INFO rejects invalid error values 2026-11-15 15:26 [PATCH v3 0/2] ptrace: reject out of range error values in PTRACE_SET_SYSCALL_INFO Renzo Davoli 2026-11-15 15:26 ` [PATCH v3 1/2] " Renzo Davoli @ 2026-11-15 15:27 ` Renzo Davoli 2026-11-15 16:17 ` Bradley Morgan 1 sibling, 1 reply; 4+ messages in thread From: Renzo Davoli @ 2026-11-15 15:27 UTC (permalink / raw) To: linux-kernel Cc: Renzo Davoli, Oleg Nesterov, Andrew Morton, Dmitry V . Levin, Alexey Gladkov, Eugene Syromyatnikov, Charlie Jenkins, Bradley Morgan, Shuah Khan, strace-devel, linux-api, linux-kselftest At every exit stop of the set_syscall_info test, try to set with is_error set a few values outside [-MAX_ERRNO, -1], check that PTRACE_SET_SYSCALL_INFO fails with ERANGE and that the return value of the system call is left untouched. Signed-off-by: Renzo Davoli <renzo@cs.unibo.it> --- .../selftests/ptrace/set_syscall_info.c | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/tools/testing/selftests/ptrace/set_syscall_info.c b/tools/testing/selftests/ptrace/set_syscall_info.c index 1cc411a41cd6..366ef0ec228f 100644 --- a/tools/testing/selftests/ptrace/set_syscall_info.c +++ b/tools/testing/selftests/ptrace/set_syscall_info.c @@ -126,6 +126,54 @@ check_psi_exit(struct __test_metadata *_metadata, } } +/* Error values that PTRACE_SET_SYSCALL_INFO must reject with ERANGE. */ +static const long long bad_error_rval[] = { + 0, + 1, + ESRCH, + -4095 - 1, /* -MAX_ERRNO - 1 */ + -2147483647LL - 1, +#if __SIZEOF_LONG__ > 4 + 0x100000000LL, + -0x100000000LL - ESRCH, +#endif +}; + +static void +check_psi_exit_bad_rval(struct __test_metadata *_metadata, + const struct ptrace_syscall_info *orig, + const struct si_exit *exp_exit) +{ + struct ptrace_syscall_info info; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(bad_error_rval); ++i) { + info = *orig; + info.exit.is_error = 1; + info.exit.rval = bad_error_rval[i]; + ASSERT_EQ(-1, sys_ptrace(PTRACE_SET_SYSCALL_INFO, + tracee_pid, sizeof(info), + (uintptr_t) &info)) { + LOG_KILL_TRACEE("PTRACE_SET_SYSCALL_INFO: error rval %lld accepted", + bad_error_rval[i]); + } + ASSERT_EQ(ERANGE, errno) { + LOG_KILL_TRACEE("PTRACE_SET_SYSCALL_INFO: error rval %lld: %m", + bad_error_rval[i]); + } + + /* the return value must be left untouched */ + memset(&info, 0, sizeof(info)); + info.op = 0xff; + ASSERT_LT(0, sys_ptrace(PTRACE_GET_SYSCALL_INFO, tracee_pid, + sizeof(info), (uintptr_t) &info)) { + LOG_KILL_TRACEE("PTRACE_GET_SYSCALL_INFO: %m"); + } + check_psi_exit(_metadata, &info, exp_exit, + "PTRACE_SET_SYSCALL_INFO with bad error rval"); + } +} + TEST(set_syscall_info) { const pid_t tracer_pid = getpid(); @@ -476,6 +524,9 @@ TEST(set_syscall_info) check_psi_exit(_metadata, &info, exp_exit, "PTRACE_GET_SYSCALL_INFO #1"); + /* invalid error values must be rejected */ + check_psi_exit_bad_rval(_metadata, &info, exp_exit); + /* apply the changes */ info.exit.is_error = set_exit->is_error; info.exit.rval = set_exit->rval; -- 2.47.3 ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH v3 2/2] selftests/ptrace: check that PTRACE_SET_SYSCALL_INFO rejects invalid error values 2026-11-15 15:27 ` [PATCH v3 2/2] selftests/ptrace: check that PTRACE_SET_SYSCALL_INFO rejects invalid error values Renzo Davoli @ 2026-11-15 16:17 ` Bradley Morgan 0 siblings, 0 replies; 4+ messages in thread From: Bradley Morgan @ 2026-11-15 16:17 UTC (permalink / raw) To: Renzo Davoli, linux-kernel Cc: Oleg Nesterov, Andrew Morton, Dmitry V . Levin, Alexey Gladkov, Eugene Syromyatnikov, Charlie Jenkins, Shuah Khan, strace-devel, linux-api, linux-kselftest On 15 November 2026 15:27:00 GMT, Renzo Davoli <renzo@cs.unibo.it> wrote: >At every exit stop of the set_syscall_info test, try to set with >is_error set a few values outside [-MAX_ERRNO, -1], check that >PTRACE_SET_SYSCALL_INFO fails with ERANGE and that the return value >of the system call is left untouched. > >Signed-off-by: Renzo Davoli <renzo@cs.unibo.it> >--- > .../selftests/ptrace/set_syscall_info.c | 51 +++++++++++++++++++ > 1 file changed, 51 insertions(+) > >diff --git a/tools/testing/selftests/ptrace/set_syscall_info.c b/tools/testing/selftests/ptrace/set_syscall_info.c >index 1cc411a41cd6..366ef0ec228f 100644 >--- a/tools/testing/selftests/ptrace/set_syscall_info.c >+++ b/tools/testing/selftests/ptrace/set_syscall_info.c >@@ -126,6 +126,54 @@ check_psi_exit(struct __test_metadata *_metadata, > } > } > >+/* Error values that PTRACE_SET_SYSCALL_INFO must reject with ERANGE. */ >+static const long long bad_error_rval[] = { >+ 0, >+ 1, >+ ESRCH, >+ -4095 - 1, /* -MAX_ERRNO - 1 */ >+ -2147483647LL - 1, >+#if __SIZEOF_LONG__ > 4 >+ 0x100000000LL, >+ -0x100000000LL - ESRCH, >+#endif >+}; yeah sure. Bit of a odd way to show error codes but okie dokie. >+ >+static void >+check_psi_exit_bad_rval(struct __test_metadata *_metadata, >+ const struct ptrace_syscall_info *orig, >+ const struct si_exit *exp_exit) >+{ >+ struct ptrace_syscall_info info; >+ unsigned int i; >+ >+ for (i = 0; i < ARRAY_SIZE(bad_error_rval); ++i) { >+ info = *orig; >+ info.exit.is_error = 1; >+ info.exit.rval = bad_error_rval[i]; >+ ASSERT_EQ(-1, sys_ptrace(PTRACE_SET_SYSCALL_INFO, >+ tracee_pid, sizeof(info), >+ (uintptr_t) &info)) { >+ LOG_KILL_TRACEE("PTRACE_SET_SYSCALL_INFO: error rval %lld accepted", >+ bad_error_rval[i]); >+ } >+ ASSERT_EQ(ERANGE, errno) { >+ LOG_KILL_TRACEE("PTRACE_SET_SYSCALL_INFO: error rval %lld: %m", >+ bad_error_rval[i]); >+ } >+ >+ /* the return value must be left untouched */ >+ memset(&info, 0, sizeof(info)); >+ info.op = 0xff; >+ ASSERT_LT(0, sys_ptrace(PTRACE_GET_SYSCALL_INFO, tracee_pid, >+ sizeof(info), (uintptr_t) &info)) { >+ LOG_KILL_TRACEE("PTRACE_GET_SYSCALL_INFO: %m"); >+ } >+ check_psi_exit(_metadata, &info, exp_exit, >+ "PTRACE_SET_SYSCALL_INFO with bad error rval"); >+ } >+} >+ > TEST(set_syscall_info) > { > const pid_t tracer_pid = getpid(); >@@ -476,6 +524,9 @@ TEST(set_syscall_info) > check_psi_exit(_metadata, &info, exp_exit, > "PTRACE_GET_SYSCALL_INFO #1"); > >+ /* invalid error values must be rejected */ >+ check_psi_exit_bad_rval(_metadata, &info, exp_exit); >+ Reviewed-by: Bradley Morgan <bradley.morgan@linux.dev> A feature suggestion on the table here is that you can modify the bad_error_rval[] parameter thru sysfs so you'd provide custom addresses or custom whatever. E.g: Echoing 0 to the sysfs directory. Then checking dmesg to see if it passed or if a hole happened. > /* apply the changes */ > info.exit.is_error = set_exit->is_error; > info.exit.rval = set_exit->rval; > --- Thanks! ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-11-15 16:17 UTC | newest] Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2026-11-15 15:26 [PATCH v3 0/2] ptrace: reject out of range error values in PTRACE_SET_SYSCALL_INFO Renzo Davoli 2026-11-15 15:26 ` [PATCH v3 1/2] " Renzo Davoli 2026-11-15 15:27 ` [PATCH v3 2/2] selftests/ptrace: check that PTRACE_SET_SYSCALL_INFO rejects invalid error values Renzo Davoli 2026-11-15 16:17 ` Bradley Morgan
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®