strace/0188-linux-s390-get_scno.c-use-NT_S390_SYSTEM_CALL-if-gpr.patch
Eugene Syromiatnikov bf36fdf2da Fix incorrect syscall name reporting in restart_syscall() on attach
* 0183-syscall-do-not-use-uninitialized-parts-of-struct-ptr.patch: New
file.
* 0184-startup_tcb-add-a-comment.patch: Likewise.
* 0185-tests-add-another-test-of-restart_syscall-decoding.patch:
Likewise.
* 0186-tests-workaround-net-yy-inet-for-new-kernels.patch: Rename
from 0001-tests-workaround-net-yy-inet-for-new-kernels.patch
to be in sync with RHEL 9, add tests-m32 and tests-mx32 hunks.
* 0187-tests-avoid-linkat-secontext_mismatch-failures-on-se.patch: New
file.
* 0188-linux-s390-get_scno.c-use-NT_S390_SYSTEM_CALL-if-gpr.patch:
Likewise.
* 0189-tests-move-k_setsockopt-definition-into-a-separate-f.patch:
Likewise.
* 0190-tests-sockopt-timestamp.c-use-k_getsockopt-and-k_set.patch:
Likewise.
* strace.spec (Patch183, Patch184, Patch185, Patch186, Patch187,
Patch188, Patch189, Patch190): New patches.
(Patch0001): Remove.
(%prep): Apply them.
(%changelog): Add a record.

Resolves: RHEL-65108
Signed-off-by: Eugene Syromiatnikov <esyr@redhat.com>
2024-11-01 13:50:48 +01:00

77 lines
2.6 KiB
Diff

From d08dfdebb381427cbd8565994868926ba9bc4b40 Mon Sep 17 00:00:00 2001
From: Eugene Syromyatnikov <evgsyr@gmail.com>
Date: Wed, 30 Oct 2024 15:16:47 +0100
Subject: [PATCH 188/190] linux/s390/get_scno.c: use NT_S390_SYSTEM_CALL if
gprs[2] is clobbered
The way the syscall number is retrieved currently relies on the kernel
propagating it properly into gprs[2], which is not however always the case;
apart of the situation where scno > NR_syscalls, there is also an issue
of inspecting it during syscall restart (as it happens on attach, for
example), when it is already clobbered by a ERESTART* errno. Luckily
for strace, this issue has been already foreseen by the kernel
developers, and support for retrieving syscall number on s390
via a separate ptrace regset has been added by the Linux commit
v3.2-rc1~109^2~34; 13 years later, it is time for it to fulfill
its purpose and finally get utilised.
* src/linux/s390/get_scno.c (arch_get_scno): Try to retrieve the syscall
number by querying NT_S390_SYSTEM_CALL regset if gprs[2] contains an errno.
Complements: v6.11-21-gc7e0ea6d712e "syscall: do not use uninitialized parts of struct ptrace_syscall_info"
---
src/linux/s390/get_scno.c | 34 ++++++++++++++++++++++++++++++++--
1 file changed, 32 insertions(+), 2 deletions(-)
diff --git a/src/linux/s390/get_scno.c b/src/linux/s390/get_scno.c
index f0863e26d701..fdc94d025280 100644
--- a/src/linux/s390/get_scno.c
+++ b/src/linux/s390/get_scno.c
@@ -9,11 +9,41 @@
# define ARCH_REGSET s390_regset
#endif
+#ifndef NT_ARM_SYSTEM_CALL
+# define NT_S390_SYSTEM_CALL 0x307
+#endif
+
/* Return codes: 1 - ok, 0 - ignore, other - error. */
static int
arch_get_scno(struct tcb *tcp)
{
- tcp->scno = ARCH_REGSET.gprs[2] ?
- ARCH_REGSET.gprs[2] : ARCH_REGSET.gprs[1];
+ typeof(ARCH_REGSET.gprs[2]) gpr2 = ARCH_REGSET.gprs[2];
+
+ if (gpr2 > (typeof(gpr2)) (-4095ULL)) {
+ /*
+ * We are in restart_syscall and gprs[2] is clobbered
+ * by the errno, using pulling the syscall number
+ * via NT_S390_SYSTEM_CALL regset.
+ */
+ unsigned int scno;
+ const struct iovec io = {
+ .iov_base = &scno,
+ .iov_len = sizeof(scno)
+ };
+ int rc = ptrace(PTRACE_GETREGSET, tcp->pid, NT_S390_SYSTEM_CALL,
+ &io);
+ if (rc && errno != ESRCH) {
+ perror_func_msg("NT_S390_SYSTEM_CALL pid:%d", tcp->pid);
+ return -1;
+ }
+ /*
+ * The ptrace call returns thread.system_call, that stores raw
+ * int_code, and the syscall number part is the lowest 16 bits
+ * of it.
+ */
+ tcp->scno = scno & 0xffff;
+ } else {
+ tcp->scno = gpr2 ?: ARCH_REGSET.gprs[1];
+ }
return 1;
}
--
2.28.0