1 /*
2 * Check decoding of prctl PR_GET_SECUREBITS/PR_SET_SECUREBITS operations.
3 *
4 * Copyright (c) 2016 Eugene Syromyatnikov <evgsyr@gmail.com>
5 * Copyright (c) 2016 Dmitry V. Levin <ldv@strace.io>
6 * Copyright (c) 2016-2021 The strace developers.
7 * All rights reserved.
8 *
9 * SPDX-License-Identifier: GPL-2.0-or-later
10 */
11
12 #include "tests.h"
13 #include "scno.h"
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <unistd.h>
17 #include <linux/prctl.h>
18 #include <linux/securebits.h>
19
20 #include "xlat.h"
21 #include "xlat/secbits.h"
22
23 #ifdef INJECT_RETVAL
24 # define INJ_STR " (INJECTED)"
25 #else
26 # define INJ_STR ""
27 #endif
28
29 static const char *errstr;
30
31 static long
32 prctl(kernel_ulong_t arg1, kernel_ulong_t arg2)
33 {
34 static const kernel_ulong_t bogus_arg =
35 (kernel_ulong_t) 0xdeadbeefbadc0dedULL;
36 long rc = syscall(__NR_prctl, arg1, arg2, bogus_arg);
37 errstr = sprintrc(rc);
38 return rc;
39 }
40
41 int
42 main(int argc, char *argv[])
43 {
44 prctl_marker();
45
46 #ifdef INJECT_RETVAL
47 unsigned long num_skip;
48 bool locked = false;
49
50 if (argc < 2)
51 error_msg_and_fail("Usage: %s NUM_SKIP", argv[0]);
52
53 num_skip = strtoul(argv[1], NULL, 0);
54
55 for (size_t i = 0; i < num_skip; i++) {
56 if (prctl_marker() < 0)
57 continue;
58
59 locked = true;
60 break;
61 }
62
63 if (!locked)
64 error_msg_and_fail("Have not locked on prctl(-1, -2, -3, -4"
65 ", -5) returning non-error value");
66 #endif /* INJECT_RETVAL */
67
68 static const kernel_ulong_t bits1 =
69 (kernel_ulong_t) 0xdeadc0defacebeefULL;
70 static const kernel_ulong_t bits2 =
71 (kernel_ulong_t) 0xbadc0ded00000000ULL;
72 static const kernel_ulong_t bits3 =
73 (kernel_ulong_t) 0xffULL;
74
75 prctl(PR_SET_SECUREBITS, 0);
76 printf("prctl(" XLAT_KNOWN(0x1c, "PR_SET_SECUREBITS") ", 0) = %s"
77 INJ_STR "\n", errstr);
78
79 prctl(PR_SET_SECUREBITS, bits1);
80 printf("prctl(" XLAT_KNOWN(0x1c, "PR_SET_SECUREBITS") ", "
81 NABBR("%#llx") VERB(" /* ") NRAW("SECBIT_NOROOT|"
82 "SECBIT_NOROOT_LOCKED|SECBIT_NO_SETUID_FIXUP|"
83 "SECBIT_NO_SETUID_FIXUP_LOCKED|SECBIT_KEEP_CAPS_LOCKED|"
84 "SECBIT_NO_CAP_AMBIENT_RAISE|SECBIT_NO_CAP_AMBIENT_RAISE_LOCKED|"
85 "%#llx") VERB(" */") ") = %s" INJ_STR "\n",
86 XLAT_SEL((unsigned long long) bits1,
87 (unsigned long long) bits1 & ~0xffULL), errstr);
88
89 if (bits2) {
90 prctl(PR_SET_SECUREBITS, bits2);
91 printf("prctl(" XLAT_KNOWN(0x1c, "PR_SET_SECUREBITS") ", %#llx"
92 NRAW(" /* SECBIT_??? */") ") = %s" INJ_STR "\n",
93 (unsigned long long) bits2, errstr);
94 }
95
96 prctl(PR_SET_SECUREBITS, bits3);
97 printf("prctl(" XLAT_KNOWN(0x1c, "PR_SET_SECUREBITS") ", "
98 XLAT_KNOWN(0xff, "SECBIT_NOROOT|SECBIT_NOROOT_LOCKED|"
99 "SECBIT_NO_SETUID_FIXUP|SECBIT_NO_SETUID_FIXUP_LOCKED|"
100 "SECBIT_KEEP_CAPS|SECBIT_KEEP_CAPS_LOCKED|"
101 "SECBIT_NO_CAP_AMBIENT_RAISE|SECBIT_NO_CAP_AMBIENT_RAISE_LOCKED")
102 ") = %s" INJ_STR "\n", errstr);
103
104 long rc = prctl(PR_GET_SECUREBITS, bits1);
105 printf("prctl(" XLAT_KNOWN(0x1b, "PR_GET_SECUREBITS") ") = ");
106 if (rc > 0) {
107 printf("%#lx", rc);
108 if ((rc & 0xff) && !XLAT_RAW) {
109 printf(" (");
110 printflags(secbits, rc, NULL);
111 printf(")");
112 }
113 puts(INJ_STR);
114 } else {
115 printf("%s" INJ_STR "\n", errstr);
116 }
117
118 puts("+++ exited with 0 +++");
119 return 0;
120 }