summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry V. Levin <ldv@strace.io>2022-01-30 08:00:00 +0000
committerDmitry V. Levin <ldv@strace.io>2022-01-30 08:00:00 +0000
commit8852bfb4a0fb9cb53b4f24b5d293f36667882a95 (patch)
tree7bf0daec818e60834ed08abb69f2b3355fcfd2f7
parent46929b48711a69569420f98c0fc92a7614314f06 (diff)
downloadstrace-8852bfb4a0fb9cb53b4f24b5d293f36667882a95.tar.gz
prctl: implement PR_SET_VMA decoding for non-Android platforms
PR_SET_VMA used to be specific to Android until Linux kernel commit v5.17-rc1~79^2~89. * NEWS: Mention this change. * src/xlat/prctl_options.in (PR_SET_VMA): Remove __ANDROID__ guard. * src/xlat/pr_set_vma.in: New file. * src/prctl.c [__ANDROID__ && !PR_SET_VMA]: Remove. [__ANDROID__ && !PR_SET_VMA_ANON_NAME]: Likewise. (SYS_FUNC(prctl)) <PR_SET_VMA>: Remove __ANDROID__ guard, enhance decoding. * tests/prctl-set_vma.c: New file. * tests/gen_tests.in (prctl-set_vma): New test. * tests/pure_executables.list: Add prctl-set_vma. * tests/.gitignore: Likewise.
-rw-r--r--NEWS1
-rw-r--r--src/prctl.c23
-rw-r--r--src/xlat/pr_set_vma.in3
-rw-r--r--src/xlat/prctl_options.in2
-rw-r--r--tests/.gitignore1
-rw-r--r--tests/gen_tests.in1
-rw-r--r--tests/prctl-set_vma.c82
-rwxr-xr-xtests/pure_executables.list1
8 files changed, 95 insertions, 19 deletions
diff --git a/NEWS b/NEWS
index 4a4c20b3b..6c8f859db 100644
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,7 @@ Noteworthy changes in release ?.?? (????-??-??)
expressions.
* Implemented decoding of IFLA_GRO_MAX_SIZE and TCA_ACT_IN_HW_COUNT netlink
attributes.
+ * Implemented decoding of PR_SET_VMA operation of prctl syscall.
* Updated lists of FAN_*, IORING_*, IOSQE_*, KVM_*, MODULE_INIT_*, TCA_ACT_*,
and *_MAGIC constants.
diff --git a/src/prctl.c b/src/prctl.c
index 4275e5f70..d4b0ca622 100644
--- a/src/prctl.c
+++ b/src/prctl.c
@@ -10,17 +10,10 @@
*/
#include "defs.h"
+#include "xstring.h"
#include <linux/prctl.h>
-#ifdef __ANDROID__
-# ifndef PR_SET_VMA
-# define PR_SET_VMA 0x53564d41 /* "SVMA" */
-# endif
-#endif
-
-#include "xstring.h"
-
#include "xlat/prctl_options.h"
#include "xlat/pr_cap_ambient.h"
#include "xlat/pr_dumpable.h"
@@ -32,6 +25,7 @@
#include "xlat/pr_sched_core_cmds.h"
#include "xlat/pr_sched_core_pidtypes.h"
#include "xlat/pr_set_mm.h"
+#include "xlat/pr_set_vma.h"
#include "xlat/pr_spec_cmds.h"
#include "xlat/pr_spec_get_store_bypass_flags.h"
#include "xlat/pr_spec_set_store_bypass_flags.h"
@@ -353,16 +347,12 @@ SYS_FUNC(prctl)
QUOTE_0_TERMINATED);
return RVAL_DECODED;
-#ifdef __ANDROID__
-# ifndef PR_SET_VMA_ANON_NAME
-# define PR_SET_VMA_ANON_NAME 0
-# endif
case PR_SET_VMA:
+ tprint_arg_next();
+ printxval64(pr_set_vma, arg2, "PR_SET_VMA_???");
if (arg2 == PR_SET_VMA_ANON_NAME) {
tprint_arg_next();
- print_xlat(PR_SET_VMA_ANON_NAME);
- tprint_arg_next();
- PRINT_VAL_X(arg3);
+ printaddr(arg3);
tprint_arg_next();
PRINT_VAL_U(arg4);
tprint_arg_next();
@@ -370,10 +360,9 @@ SYS_FUNC(prctl)
} else {
/* There are no other sub-options now, but there
* might be in future... */
- print_prctl_args(tcp, 1);
+ print_prctl_args(tcp, 2);
}
return RVAL_DECODED;
-#endif
case PR_SET_MM:
tprint_arg_next();
diff --git a/src/xlat/pr_set_vma.in b/src/xlat/pr_set_vma.in
new file mode 100644
index 000000000..5936351fd
--- /dev/null
+++ b/src/xlat/pr_set_vma.in
@@ -0,0 +1,3 @@
+#unconditional
+#value_indexed
+PR_SET_VMA_ANON_NAME
diff --git a/src/xlat/prctl_options.in b/src/xlat/prctl_options.in
index 38823d51b..dffff49b2 100644
--- a/src/xlat/prctl_options.in
+++ b/src/xlat/prctl_options.in
@@ -58,7 +58,5 @@ PR_SET_SYSCALL_USER_DISPATCH
PR_PAC_SET_ENABLED_KEYS
PR_PAC_GET_ENABLED_KEYS
PR_SCHED_CORE
-#ifdef __ANDROID__
PR_SET_VMA
-#endif
PR_SET_PTRACER
diff --git a/tests/.gitignore b/tests/.gitignore
index 128d9a076..a636eceb3 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -724,6 +724,7 @@ prctl-set-ptracer-success-Xraw
prctl-set-ptracer-success-Xraw--pidns-translation
prctl-set-ptracer-success-Xverbose
prctl-set-ptracer-success-Xverbose--pidns-translation
+prctl-set_vma
prctl-spec-inject
prctl-sve
prctl-syscall-user-dispatch
diff --git a/tests/gen_tests.in b/tests/gen_tests.in
index 4b16f9bff..23b9bce1d 100644
--- a/tests/gen_tests.in
+++ b/tests/gen_tests.in
@@ -719,6 +719,7 @@ prctl-set-ptracer-success-Xraw +prctl-success.sh PRCTL_INJECT_RETVALS=0 -a20 -X
prctl-set-ptracer-success-Xraw--pidns-translation check_scno_tampering; test_pidns -einject=prctl:when=256+:retval=0 -etrace=prctl -a27 "QUIRK:START-OF-TEST-OUTPUT:prctl(0xffffffff, 0xfffffffe, 0xfffffffd, 0xfffffffc, 0xfffffffb)" -Xraw
prctl-set-ptracer-success-Xverbose +prctl-success.sh PRCTL_INJECT_RETVALS=0 -a42 -Xverbose
prctl-set-ptracer-success-Xverbose--pidns-translation check_scno_tampering; test_pidns -einject=prctl:when=256+:retval=0 -etrace=prctl -a48 "QUIRK:START-OF-TEST-OUTPUT:prctl(0xffffffff /* PR_??? */, 0xfffffffe, 0xfffffffd, 0xfffffffc, 0xfffffffb)" -Xverbose
+prctl-set_vma +prctl.sh
prctl-spec-inject +prctl-success.sh PRCTL_INJECT_RETVALS="error=ENOTTY 0 1 3 8 16 32 42" -a50
prctl-sve +prctl.sh -a21
prctl-syscall-user-dispatch +prctl.sh -a68
diff --git a/tests/prctl-set_vma.c b/tests/prctl-set_vma.c
new file mode 100644
index 000000000..0929565f9
--- /dev/null
+++ b/tests/prctl-set_vma.c
@@ -0,0 +1,82 @@
+/*
+ * Check decoding of prctl PR_SET_VMA operation.
+ *
+ * Copyright (c) 2019-2022 Dmitry V. Levin <ldv@strace.io>
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "tests.h"
+#include "scno.h"
+#include <stdio.h>
+#include <unistd.h>
+#include <linux/prctl.h>
+
+static const kernel_ulong_t fill = (kernel_ulong_t) 0xdefaced00000000ULL;
+static const char *errstr;
+
+static long
+pr_set_vma(const kernel_ulong_t op, const void *const addr,
+ const kernel_ulong_t size, const void *const arg)
+{
+ const kernel_ulong_t bad = (kernel_ulong_t) 0xbadc0dedbadc0dedULL;
+ const kernel_ulong_t arg1 = fill | PR_SET_VMA;
+ const kernel_ulong_t arg2 = op;
+ const kernel_ulong_t arg3 = (uintptr_t) addr;
+ const kernel_ulong_t arg4 = size;
+ const kernel_ulong_t arg5 = (uintptr_t) arg;
+ const long rc = syscall(__NR_prctl, arg1, arg2, arg3, arg4, arg5, bad);
+ errstr = sprintrc(rc);
+ return rc;
+}
+
+int
+main(void)
+{
+ prctl_marker();
+
+ char *const name1 = tail_alloc(DEFAULT_STRLEN + 2);
+ char *const name = name1 + 1;
+ const void *const efault = name + DEFAULT_STRLEN + 1;
+ const char *const empty = efault - 1;
+ fill_memory_ex(name1, DEFAULT_STRLEN + 1, '0', 10);
+ name1[DEFAULT_STRLEN + 1] = '\0';
+
+ pr_set_vma(0, 0, 1, name);
+ printf("prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, NULL, 1, \"%s\")"
+ " = %s\n",
+ name, errstr);
+
+ pr_set_vma(0, empty, 2, name1);
+ printf("prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, %p, 2, \"%.*s\"...)"
+ " = %s\n",
+ empty, DEFAULT_STRLEN, name1, errstr);
+
+ pr_set_vma(0, empty, 3, efault);
+ printf("prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, %p, 3, %p)"
+ " = %s\n",
+ empty, efault, errstr);
+
+ pr_set_vma(0, empty, 4, 0);
+ printf("prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, %p, 4, NULL)"
+ " = %s\n",
+ empty, errstr);
+
+ pr_set_vma(0, efault, 5, empty);
+ printf("prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, %p, 5, \"\")"
+ " = %s\n",
+ efault, errstr);
+
+ const kernel_ulong_t bad_op = fill | 0xface1fed;
+ const kernel_ulong_t bad_size = fill | 0xface2fed;
+
+ pr_set_vma(bad_op, efault, bad_size, empty);
+ printf("prctl(PR_SET_VMA, %#llx /* PR_SET_VMA_??? */, %p, %#llx, %p)"
+ " = %s\n",
+ (unsigned long long) bad_op, efault,
+ (unsigned long long) bad_size, empty, errstr);
+
+ puts("+++ exited with 0 +++");
+ return 0;
+}
diff --git a/tests/pure_executables.list b/tests/pure_executables.list
index 296e22359..4ee581692 100755
--- a/tests/pure_executables.list
+++ b/tests/pure_executables.list
@@ -514,6 +514,7 @@ prctl-sched-core-Xabbrev
prctl-sched-core-Xraw
prctl-sched-core-Xverbose
prctl-securebits
+prctl-set_vma
prctl-sve
prctl-syscall-user-dispatch
prctl-tagged-addr