2 * Check decoding of prctl operations which use arg2 as pointer to an integer
3 * value: PR_GET_CHILD_SUBREAPER, PR_GET_ENDIAN, PR_GET_FPEMU, and PR_GET_FPEXC.
5 * Copyright (c) 2016 Eugene Syromyatnikov <evgsyr@gmail.com>
6 * Copyright (c) 2016 Dmitry V. Levin <ldv@altlinux.org>
7 * Copyright (c) 2016-2017 The strace developers.
10 * SPDX-License-Identifier: GPL-2.0-or-later
14 #include <asm/unistd.h>
16 #if defined __NR_prctl
21 # include <linux/prctl.h>
23 static const char *errstr;
26 prctl(kernel_ulong_t arg1, kernel_ulong_t arg2)
28 static const kernel_ulong_t bogus_arg =
29 (kernel_ulong_t) 0xdeadbeefbadc0dedULL;
30 long rc = syscall(__NR_prctl, arg1, arg2, bogus_arg);
31 errstr = sprintrc(rc);
38 static const kernel_ulong_t bogus_addr1 =
39 (kernel_ulong_t) 0x1e55c0de00000000ULL;
40 static const kernel_ulong_t bogus_addr2 =
41 (kernel_ulong_t) 0xfffffffffffffffdULL;
42 static const kernel_ulong_t bogus_op_bits =
43 (kernel_ulong_t) 0xbadc0ded00000000ULL;
48 { 37, "PR_GET_CHILD_SUBREAPER" },
49 { 19, "PR_GET_ENDIAN" },
50 { 9, "PR_GET_FPEMU" },
51 { 11, "PR_GET_FPEXC" },
54 TAIL_ALLOC_OBJECT_CONST_PTR(unsigned int, ptr);
58 for (i = 0; i < ARRAY_SIZE(options); ++i) {
59 prctl(options[i].val | bogus_op_bits, 0);
60 printf("prctl(%s, NULL) = %s\n", options[i].str, errstr);
63 prctl(options[i].val | bogus_op_bits, bogus_addr1);
64 printf("prctl(%s, %#llx) = %s\n", options[i].str,
65 (unsigned long long) bogus_addr1, errstr);
68 prctl(options[i].val | bogus_op_bits, bogus_addr2);
69 printf("prctl(%s, %#llx) = %s\n", options[i].str,
70 (unsigned long long) bogus_addr2, errstr);
72 prctl(options[i].val | bogus_op_bits, (uintptr_t) (ptr + 1));
73 printf("prctl(%s, %p) = %s\n", options[i].str,
76 rc = prctl(options[i].val | bogus_op_bits, (uintptr_t) ptr);
78 printf("prctl(%s, [%u]) = %s\n",
79 options[i].str, *ptr, errstr);
81 printf("prctl(%s, %p) = %s\n",
82 options[i].str, ptr, errstr);
85 if (F8ILL_KULONG_SUPPORTED) {
86 kernel_ulong_t bogus_addr3 = f8ill_ptr_to_kulong(ptr);
87 prctl(options[i].val | bogus_op_bits, bogus_addr3);
88 printf("prctl(%s, %#llx) = %s\n", options[i].str,
89 (unsigned long long) bogus_addr3, errstr);
93 puts("+++ exited with 0 +++");
99 SKIP_MAIN_UNDEFINED("__NR_prctl")