103 lines
3.0 KiB
Diff
103 lines
3.0 KiB
Diff
|
From c7e0ea6d712eb214dafe7e9eae57661d9a427ea7 Mon Sep 17 00:00:00 2001
|
||
|
From: "Dmitry V. Levin" <ldv@strace.io>
|
||
|
Date: Mon, 28 Oct 2024 08:00:00 +0000
|
||
|
Subject: [PATCH 183/185] syscall: do not use uninitialized parts of struct
|
||
|
ptrace_syscall_info
|
||
|
|
||
|
* src/syscall.c (ptrace_syscall_info_is_entry,
|
||
|
ptrace_syscall_info_is_exit): New functions.
|
||
|
(get_scno): Replace ptrace_syscall_info_is_valid() with
|
||
|
ptrace_syscall_info_is_entry().
|
||
|
(get_error): Replace ptrace_syscall_info_is_valid() with
|
||
|
ptrace_syscall_info_is_exit().
|
||
|
(get_syscall_regs): Fall back to get_regs() if strace_get_syscall_info()
|
||
|
succeeded but couldn't obtain the necessary data.
|
||
|
|
||
|
Resolves: https://github.com/strace/strace/issues/322
|
||
|
---
|
||
|
src/syscall.c | 40 +++++++++++++++++++++++++++++++++++-----
|
||
|
1 file changed, 35 insertions(+), 5 deletions(-)
|
||
|
|
||
|
diff --git a/src/syscall.c b/src/syscall.c
|
||
|
index a6692721a..1f4d86dc1 100644
|
||
|
--- a/src/syscall.c
|
||
|
+++ b/src/syscall.c
|
||
|
@@ -1082,6 +1082,21 @@ ptrace_syscall_info_is_valid(void)
|
||
|
ptrace_sci.op <= PTRACE_SYSCALL_INFO_SECCOMP;
|
||
|
}
|
||
|
|
||
|
+static bool
|
||
|
+ptrace_syscall_info_is_entry(void)
|
||
|
+{
|
||
|
+ return ptrace_get_syscall_info_supported &&
|
||
|
+ (ptrace_sci.op == PTRACE_SYSCALL_INFO_ENTRY ||
|
||
|
+ ptrace_sci.op == PTRACE_SYSCALL_INFO_SECCOMP);
|
||
|
+}
|
||
|
+
|
||
|
+static bool
|
||
|
+ptrace_syscall_info_is_exit(void)
|
||
|
+{
|
||
|
+ return ptrace_get_syscall_info_supported &&
|
||
|
+ ptrace_sci.op == PTRACE_SYSCALL_INFO_EXIT;
|
||
|
+}
|
||
|
+
|
||
|
#define XLAT_MACROS_ONLY
|
||
|
#include "xlat/nt_descriptor_types.h"
|
||
|
#undef XLAT_MACROS_ONLY
|
||
|
@@ -1376,8 +1391,23 @@ get_syscall_regs(struct tcb *tcp)
|
||
|
if (get_regs_error != -1)
|
||
|
return get_regs_error;
|
||
|
|
||
|
- if (ptrace_get_syscall_info_supported)
|
||
|
- return strace_get_syscall_info(tcp) ? 0 : get_regs_error;
|
||
|
+ if (ptrace_get_syscall_info_supported) {
|
||
|
+ if (!strace_get_syscall_info(tcp))
|
||
|
+ return get_regs_error;
|
||
|
+
|
||
|
+ if ((entering(tcp) && ptrace_syscall_info_is_entry()) ||
|
||
|
+ (exiting(tcp) && ptrace_syscall_info_is_exit()))
|
||
|
+ return 0;
|
||
|
+
|
||
|
+ /*
|
||
|
+ * PTRACE_GET_SYSCALL_INFO succeeded but didn't help,
|
||
|
+ * falling back to get_regs().
|
||
|
+ *
|
||
|
+ * This can happen when get_syscall_regs() is called
|
||
|
+ * from startup_tcb() via get_scno().
|
||
|
+ */
|
||
|
+ debug_func_msg("ptrace_sci.op = %d", ptrace_sci.op);
|
||
|
+ }
|
||
|
|
||
|
return get_regs(tcp);
|
||
|
}
|
||
|
@@ -1408,7 +1438,7 @@ get_scno(struct tcb *tcp)
|
||
|
if (get_syscall_regs(tcp) < 0)
|
||
|
return -1;
|
||
|
|
||
|
- if (ptrace_syscall_info_is_valid()) {
|
||
|
+ if (ptrace_syscall_info_is_entry()) {
|
||
|
/* Apply arch-specific workarounds. */
|
||
|
int rc = arch_check_scno(tcp);
|
||
|
if (rc != 1)
|
||
|
@@ -1456,7 +1486,7 @@ get_scno(struct tcb *tcp)
|
||
|
static int
|
||
|
get_syscall_args(struct tcb *tcp)
|
||
|
{
|
||
|
- if (ptrace_syscall_info_is_valid()) {
|
||
|
+ if (ptrace_syscall_info_is_entry()) {
|
||
|
const unsigned int n =
|
||
|
MIN(ARRAY_SIZE(tcp->u_arg),
|
||
|
ARRAY_SIZE(ptrace_sci.entry.args));
|
||
|
@@ -1507,7 +1537,7 @@ get_syscall_result(struct tcb *tcp)
|
||
|
static void
|
||
|
get_error(struct tcb *tcp, const bool check_errno)
|
||
|
{
|
||
|
- if (ptrace_syscall_info_is_valid()) {
|
||
|
+ if (ptrace_syscall_info_is_exit()) {
|
||
|
if (ptrace_sci.exit.is_error) {
|
||
|
tcp->u_rval = -1;
|
||
|
tcp->u_error = -ptrace_sci.exit.rval;
|
||
|
--
|
||
|
2.13.6
|
||
|
|