]> granicus.if.org Git - strace/blob - tests/prctl-spec-inject.c
strace: terminate itself if interrupted by a signal
[strace] / tests / prctl-spec-inject.c
1 /*
2  * Check decoding of PR_SET_SPECULATION_CTRL and PR_GET_SPECULATION_CTRL
3  * prctl operations.
4  *
5  * Copyright (c) 2018 The strace developers.
6  * All rights reserved.
7  *
8  * SPDX-License-Identifier: GPL-2.0-or-later
9  */
10
11 #include "tests.h"
12 #include <asm/unistd.h>
13
14 #ifdef __NR_prctl
15
16 # include <stdio.h>
17 # include <stdlib.h>
18 # include <unistd.h>
19 # include <linux/prctl.h>
20
21 static long injected_val;
22
23 long
24 do_prctl(kernel_ulong_t cmd, kernel_ulong_t arg2, kernel_ulong_t arg3)
25 {
26         long rc = syscall(__NR_prctl, cmd, arg2, arg3);
27
28         if (rc != injected_val)
29                 error_msg_and_fail("Return value (%ld) differs from expected "
30                                    "injected value (%ld)",
31                                    rc, injected_val);
32
33         return rc;
34 }
35
36 int
37 main(int argc, char **argv)
38 {
39         static const kernel_ulong_t bogus_arg2 =
40                 (kernel_ulong_t) 0xdeadfacebadc0dedULL;
41         static const kernel_ulong_t bogus_arg3 =
42                 (kernel_ulong_t) 0xdecafeedbeefda7eULL;
43         static const struct {
44                 long arg;
45                 const char *str;
46         } get_strs[] = {
47                 { -1, "" },
48                 { 0, " (PR_SPEC_NOT_AFFECTED)" },
49                 { 1, " (PR_SPEC_PRCTL)" },
50                 { 3, " (PR_SPEC_PRCTL|PR_SPEC_ENABLE)" },
51                 { 8, " (PR_SPEC_FORCE_DISABLE)" },
52                 { 16, " (0x10)" },
53                 { 42, " (PR_SPEC_ENABLE|PR_SPEC_FORCE_DISABLE|0x20)" },
54         };
55         static const struct {
56                 kernel_ulong_t arg;
57                 const char *str;
58         } set_strs[] = {
59                 { 0, "0 /* PR_SPEC_??? */" },
60                 { 1, "0x1 /* PR_SPEC_??? */" },
61                 { 2, "PR_SPEC_ENABLE" },
62                 { 3, "0x3 /* PR_SPEC_??? */" },
63                 { 8, "PR_SPEC_FORCE_DISABLE" },
64                 { 16, "0x10 /* PR_SPEC_??? */" },
65                 { (kernel_ulong_t) 0xdecafeedbeefda7eULL, "0x"
66 # if SIZEOF_KERNEL_LONG_T == 8
67                         "decafeed"
68 # endif
69                         "beefda7e /* PR_SPEC_??? */" },
70         };
71
72         long rc;
73         const char *str = NULL;
74
75         if (argc < 2)
76                 error_msg_and_fail("Usage: %s INJECTED_VAL", argv[0]);
77
78         injected_val = strtol(argv[1], NULL, 0);
79
80         /* PR_GET_SPECULATION_CTRL */
81         rc = do_prctl(52, 1, bogus_arg3);
82         printf("prctl(PR_GET_SPECULATION_CTRL, 0x1 /* PR_SPEC_??? */) "
83                "= %s (INJECTED)\n", sprintrc(rc));
84
85         rc = do_prctl(52, bogus_arg2, bogus_arg3);
86         printf("prctl(PR_GET_SPECULATION_CTRL, %#llx /* PR_SPEC_??? */) "
87                "= %s (INJECTED)\n",
88                (unsigned long long) bogus_arg2, sprintrc(rc));
89
90         rc = do_prctl(52, 0, bogus_arg3);
91
92         for (unsigned i = 0; i < ARRAY_SIZE(get_strs); i++) {
93                 if (get_strs[i].arg == rc) {
94                         str = get_strs[i].str;
95                         break;
96                 }
97         }
98         if (!str)
99                 error_msg_and_fail("Unknown return value: %ld", rc);
100
101         printf("prctl(PR_GET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS) "
102                "= %s%s (INJECTED)\n", sprintrc(rc), str);
103
104
105         /* PR_SET_SPECULATION_CTRL*/
106         rc = do_prctl(53, 1, bogus_arg3);
107         printf("prctl(PR_SET_SPECULATION_CTRL, 0x1 /* PR_SPEC_??? */, %#llx) "
108                "= %s (INJECTED)\n",
109                (unsigned long long) bogus_arg3, sprintrc(rc));
110
111         rc = do_prctl(53, bogus_arg2, bogus_arg3);
112         printf("prctl(PR_SET_SPECULATION_CTRL, %#llx /* PR_SPEC_??? */, %#llx) "
113                "= %s (INJECTED)\n",
114                (unsigned long long) bogus_arg2,
115                (unsigned long long) bogus_arg3,
116                sprintrc(rc));
117
118         for (unsigned i = 0; i < ARRAY_SIZE(set_strs); i++) {
119                 rc = do_prctl(53, 0, set_strs[i].arg);
120                 printf("prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS"
121                        ", %s) = %s (INJECTED)\n",
122                        set_strs[i].str, sprintrc(rc));
123         }
124
125         puts("+++ exited with 0 +++");
126         return 0;
127 }
128
129 #else
130
131 SKIP_MAIN_UNDEFINED("__NR_prctl")
132
133 #endif