]> granicus.if.org Git - strace/blob - prctl.c
tests: add ioctl_evdev-success* test binaries to .gitignore
[strace] / prctl.c
1 /*
2  * Copyright (c) 1994-1996 Rick Sladkey <jrs@world.std.com>
3  * Copyright (c) 1996-2000 Wichert Akkerman <wichert@cistron.nl>
4  * Copyright (c) 2005-2007 Roland McGrath <roland@redhat.com>
5  * Copyright (c) 2008-2015 Dmitry V. Levin <ldv@altlinux.org>
6  * Copyright (c) 2014-2019 The strace developers.
7  * All rights reserved.
8  *
9  * SPDX-License-Identifier: LGPL-2.1-or-later
10  */
11
12 #include "defs.h"
13
14 #include <linux/prctl.h>
15
16 #include "xstring.h"
17
18 #include "xlat/prctl_options.h"
19 #include "xlat/pr_cap_ambient.h"
20 #include "xlat/pr_dumpable.h"
21 #include "xlat/pr_fp_mode.h"
22 #include "xlat/pr_mce_kill.h"
23 #include "xlat/pr_mce_kill_policy.h"
24 #include "xlat/pr_set_mm.h"
25 #include "xlat/pr_spec_cmds.h"
26 #include "xlat/pr_spec_get_store_bypass_flags.h"
27 #include "xlat/pr_spec_set_store_bypass_flags.h"
28 #include "xlat/pr_sve_vl_flags.h"
29 #include "xlat/pr_tsc.h"
30 #include "xlat/pr_unalign_flags.h"
31
32 #ifndef TASK_COMM_LEN
33 # define TASK_COMM_LEN 16
34 #endif
35
36 #ifdef HAVE_LINUX_SECCOMP_H
37 # include <linux/seccomp.h>
38 #endif
39 #include "xlat/seccomp_mode.h"
40
41 #ifdef HAVE_LINUX_SECUREBITS_H
42 # include <linux/securebits.h>
43 #endif
44 #include "xlat/secbits.h"
45
46 /* these constants are the same as in <linux/capability.h> */
47 enum {
48 #include "caps0.h"
49 #include "caps1.h"
50 };
51
52 #include "xlat/cap.h"
53
54 #ifndef PR_SVE_VL_LEN_MASK
55 # define PR_SVE_VL_LEN_MASK 0xffff
56 #endif
57
58
59 static void
60 print_prctl_args(struct tcb *tcp, const unsigned int first)
61 {
62         unsigned int i;
63
64         for (i = first; i < n_args(tcp); ++i)
65                 tprintf(", %#" PRI_klx, tcp->u_arg[i]);
66 }
67
68 static char *
69 sprint_sve_val(kernel_ulong_t arg)
70 {
71         static char out[sizeof("PR_SVE_SET_VL_ONEXEC|PR_SVE_VL_INHERIT|0x") +
72                         sizeof(kernel_ulong_t) * 2];
73
74         kernel_ulong_t vl = arg & PR_SVE_VL_LEN_MASK;
75         kernel_ulong_t flags = arg & ~PR_SVE_VL_LEN_MASK;
76         const char *flags_str = sprintflags("", pr_sve_vl_flags, flags);
77
78         xsprintf(out, "%s%s%#" PRI_klx,
79                  flags_str ?: "", flags_str ? "|" : "", vl);
80
81         return out;
82 }
83
84 SYS_FUNC(prctl)
85 {
86         const unsigned int option = tcp->u_arg[0];
87         const kernel_ulong_t arg2 = tcp->u_arg[1];
88         const kernel_ulong_t arg3 = tcp->u_arg[2];
89         /*
90          * PR_SET_VMA is the only command which actually uses these arguments
91          * currently, and it is available only on Android for now.
92          */
93 #ifdef __ANDROID__
94         const kernel_ulong_t arg4 = tcp->u_arg[3];
95         const kernel_ulong_t arg5 = tcp->u_arg[4];
96 #endif
97         unsigned int i;
98
99         if (entering(tcp))
100                 printxval(prctl_options, option, "PR_???");
101
102         switch (option) {
103         case PR_GET_KEEPCAPS:
104         case PR_GET_SECCOMP:
105         case PR_GET_TIMERSLACK:
106         case PR_GET_TIMING:
107                 return RVAL_DECODED;
108
109         case PR_GET_CHILD_SUBREAPER:
110         case PR_GET_ENDIAN:
111         case PR_GET_FPEMU:
112         case PR_GET_FPEXC:
113                 if (entering(tcp))
114                         tprints(", ");
115                 else
116                         printnum_int(tcp, arg2, "%u");
117                 break;
118
119         case PR_GET_DUMPABLE:
120                 if (entering(tcp))
121                         break;
122                 if (syserror(tcp))
123                         return 0;
124                 tcp->auxstr = xlookup(pr_dumpable, (kernel_ulong_t) tcp->u_rval);
125                 return RVAL_STR;
126
127         case PR_GET_NAME:
128                 if (entering(tcp)) {
129                         tprints(", ");
130                 } else {
131                         if (syserror(tcp))
132                                 printaddr(arg2);
133                         else
134                                 printstr_ex(tcp, arg2, TASK_COMM_LEN,
135                                             QUOTE_0_TERMINATED);
136                 }
137                 break;
138
139         case PR_GET_PDEATHSIG:
140                 if (entering(tcp)) {
141                         tprints(", ");
142                 } else if (!umove_or_printaddr(tcp, arg2, &i)) {
143                         tprints("[");
144                         printsignal(i);
145                         tprints("]");
146                 }
147                 break;
148
149         case PR_GET_SECUREBITS:
150                 if (entering(tcp))
151                         break;
152                 if (syserror(tcp) || tcp->u_rval == 0)
153                         return 0;
154                 tcp->auxstr = sprintflags("", secbits,
155                                           (kernel_ulong_t) tcp->u_rval);
156                 return RVAL_STR;
157
158         case PR_GET_TID_ADDRESS:
159                 if (entering(tcp))
160                         tprints(", ");
161                 else
162                         printnum_kptr(tcp, arg2);
163                 break;
164
165         case PR_GET_TSC:
166                 if (entering(tcp)) {
167                         tprints(", ");
168                 } else if (!umove_or_printaddr(tcp, arg2, &i)) {
169                         tprints("[");
170                         printxval(pr_tsc, i, "PR_TSC_???");
171                         tprints("]");
172                 }
173                 break;
174
175         case PR_GET_UNALIGN:
176                 if (entering(tcp)) {
177                         tprints(", ");
178                 } else if (!umove_or_printaddr(tcp, arg2, &i)) {
179                         tprints("[");
180                         printflags(pr_unalign_flags, i, "PR_UNALIGN_???");
181                         tprints("]");
182                 }
183                 break;
184
185         case PR_GET_FP_MODE:
186                 if (entering(tcp))
187                         break;
188                 if (syserror(tcp) || tcp->u_rval == 0)
189                         return 0;
190                 tcp->auxstr = sprintflags("", pr_fp_mode,
191                                           (kernel_ulong_t) tcp->u_rval);
192                 return RVAL_STR;
193
194         case PR_SVE_SET_VL:
195                 if (entering(tcp)) {
196                         tprintf(", %s", sprint_sve_val(arg2));
197                         return 0;
198                 }
199                 ATTRIBUTE_FALLTHROUGH;
200
201         case PR_SVE_GET_VL:
202                 if (entering(tcp))
203                         break;
204                 if (syserror(tcp) || tcp->u_rval == 0)
205                         return 0;
206
207                 tcp->auxstr = sprint_sve_val(tcp->u_rval);
208
209                 return RVAL_STR;
210
211         case PR_GET_SPECULATION_CTRL:
212                 if (entering(tcp)) {
213                         tprints(", ");
214                         printxval64(pr_spec_cmds, arg2, "PR_SPEC_???");
215
216                         break;
217                 }
218
219                 if (syserror(tcp))
220                         return 0;
221
222                 switch (arg2) {
223                 case PR_SPEC_STORE_BYPASS:
224                 case PR_SPEC_INDIRECT_BRANCH:
225                         tcp->auxstr = sprintflags("",
226                                                   pr_spec_get_store_bypass_flags,
227                                                   (kernel_ulong_t) tcp->u_rval);
228                         break;
229                 }
230
231                 return RVAL_STR;
232
233         /* PR_TASK_PERF_EVENTS_* take no arguments. */
234         case PR_TASK_PERF_EVENTS_DISABLE:
235         case PR_TASK_PERF_EVENTS_ENABLE:
236                 return RVAL_DECODED;
237
238         case PR_SET_CHILD_SUBREAPER:
239         case PR_SET_ENDIAN:
240         case PR_SET_FPEMU:
241         case PR_SET_FPEXC:
242         case PR_SET_KEEPCAPS:
243         case PR_SET_TIMING:
244                 tprintf(", %" PRI_klu, arg2);
245                 return RVAL_DECODED;
246
247         case PR_SET_DUMPABLE:
248                 tprints(", ");
249                 printxval64(pr_dumpable, arg2, "SUID_DUMP_???");
250                 return RVAL_DECODED;
251
252         case PR_CAPBSET_DROP:
253         case PR_CAPBSET_READ:
254                 tprints(", ");
255                 printxval64(cap, arg2, "CAP_???");
256                 return RVAL_DECODED;
257
258         case PR_CAP_AMBIENT:
259                 tprints(", ");
260                 printxval64(pr_cap_ambient, arg2,
261                                "PR_CAP_AMBIENT_???");
262                 switch (arg2) {
263                 case PR_CAP_AMBIENT_RAISE:
264                 case PR_CAP_AMBIENT_LOWER:
265                 case PR_CAP_AMBIENT_IS_SET:
266                         tprints(", ");
267                         printxval64(cap, arg3, "CAP_???");
268                         print_prctl_args(tcp, 3);
269                         break;
270                 default:
271                         print_prctl_args(tcp, 2);
272                         break;
273                 }
274                 return RVAL_DECODED;
275
276         case PR_MCE_KILL:
277                 tprints(", ");
278                 printxval64(pr_mce_kill, arg2, "PR_MCE_KILL_???");
279                 tprints(", ");
280                 if (PR_MCE_KILL_SET == arg2)
281                         printxval64(pr_mce_kill_policy, arg3,
282                                     "PR_MCE_KILL_???");
283                 else
284                         tprintf("%#" PRI_klx, arg3);
285                 print_prctl_args(tcp, 3);
286                 return RVAL_DECODED;
287
288         case PR_SET_NAME:
289                 tprints(", ");
290                 printstr_ex(tcp, arg2, TASK_COMM_LEN - 1,
291                             QUOTE_0_TERMINATED);
292                 return RVAL_DECODED;
293
294 #ifdef __ANDROID__
295 # ifndef PR_SET_VMA_ANON_NAME
296 #  define PR_SET_VMA_ANON_NAME    0
297 # endif
298         case PR_SET_VMA:
299                 if (arg2 == PR_SET_VMA_ANON_NAME) {
300                         tprintf(", PR_SET_VMA_ANON_NAME, %#" PRI_klx, arg3);
301                         tprintf(", %" PRI_klu ", ", arg4);
302                         printstr(tcp, arg5);
303                 } else {
304                         /* There are no other sub-options now, but there
305                          * might be in future... */
306                         print_prctl_args(tcp, 1);
307                 }
308                 return RVAL_DECODED;
309 #endif
310
311         case PR_SET_MM:
312                 tprints(", ");
313                 printxval(pr_set_mm, arg2, "PR_SET_MM_???");
314                 print_prctl_args(tcp, 2);
315                 return RVAL_DECODED;
316
317         case PR_SET_PDEATHSIG:
318                 tprints(", ");
319                 if (arg2 > 128)
320                         tprintf("%" PRI_klu, arg2);
321                 else
322                         printsignal(arg2);
323                 return RVAL_DECODED;
324
325         case PR_SET_PTRACER:
326                 tprints(", ");
327                 if ((int) arg2 == -1) {
328                         print_xlat_ex(arg2, "PR_SET_PTRACER_ANY",
329                                       XLAT_STYLE_DEFAULT);
330                 } else {
331                         tprintf("%" PRI_klu, arg2);
332                 }
333                 return RVAL_DECODED;
334
335         case PR_SET_SECCOMP:
336                 tprints(", ");
337                 printxval64(seccomp_mode, arg2,
338                             "SECCOMP_MODE_???");
339                 if (SECCOMP_MODE_STRICT == arg2)
340                         return RVAL_DECODED;
341                 if (SECCOMP_MODE_FILTER == arg2) {
342                         tprints(", ");
343                         decode_seccomp_fprog(tcp, arg3);
344                         return RVAL_DECODED;
345                 }
346                 print_prctl_args(tcp, 2);
347                 return RVAL_DECODED;
348
349         case PR_SET_SECUREBITS:
350                 tprints(", ");
351                 printflags64(secbits, arg2, "SECBIT_???");
352                 return RVAL_DECODED;
353
354         case PR_SET_TIMERSLACK:
355                 tprintf(", %" PRI_kld, arg2);
356                 return RVAL_DECODED;
357
358         case PR_SET_TSC:
359                 tprints(", ");
360                 printxval(pr_tsc, arg2, "PR_TSC_???");
361                 return RVAL_DECODED;
362
363         case PR_SET_UNALIGN:
364                 tprints(", ");
365                 printflags(pr_unalign_flags, arg2, "PR_UNALIGN_???");
366                 return RVAL_DECODED;
367
368         case PR_SET_NO_NEW_PRIVS:
369         case PR_SET_THP_DISABLE:
370                 tprintf(", %" PRI_klu, arg2);
371                 print_prctl_args(tcp, 2);
372                 return RVAL_DECODED;
373
374         case PR_MCE_KILL_GET:
375                 if (entering(tcp)) {
376                         print_prctl_args(tcp, 1);
377                         return 0;
378                 }
379                 if (syserror(tcp))
380                         return 0;
381                 tcp->auxstr = xlookup(pr_mce_kill_policy,
382                                       (kernel_ulong_t) tcp->u_rval);
383                 return RVAL_STR;
384
385         case PR_SET_FP_MODE:
386                 tprints(", ");
387                 printflags(pr_fp_mode, arg2, "PR_FP_MODE_???");
388                 return RVAL_DECODED;
389
390         case PR_SET_SPECULATION_CTRL:
391                 tprints(", ");
392                 printxval64(pr_spec_cmds, arg2, "PR_SPEC_???");
393                 tprints(", ");
394
395                 switch (arg2) {
396                 case PR_SPEC_STORE_BYPASS:
397                 case PR_SPEC_INDIRECT_BRANCH:
398                         printxval64(pr_spec_set_store_bypass_flags, arg3,
399                                     "PR_SPEC_???");
400                         break;
401
402                 default:
403                         tprintf("%#" PRI_klx, arg3);
404                 }
405
406                 return RVAL_DECODED;
407
408         case PR_GET_NO_NEW_PRIVS:
409         case PR_GET_THP_DISABLE:
410         case PR_MPX_DISABLE_MANAGEMENT:
411         case PR_MPX_ENABLE_MANAGEMENT:
412         default:
413                 print_prctl_args(tcp, 1);
414                 return RVAL_DECODED;
415         }
416         return 0;
417 }
418
419 #if defined X86_64 || defined X32 || defined I386
420 # include "xlat/archvals.h"
421
422 SYS_FUNC(arch_prctl)
423 {
424         const unsigned int option = tcp->u_arg[0];
425         const kernel_ulong_t addr = tcp->u_arg[1];
426
427         if (entering(tcp))
428                 printxval(archvals, option, "ARCH_???");
429
430         switch (option) {
431         case ARCH_GET_GS:
432         case ARCH_GET_FS:
433                 if (entering(tcp))
434                         tprints(", ");
435                 else
436                         printnum_ptr(tcp, addr);
437                 return 0;
438         }
439
440         tprintf(", %#" PRI_klx, addr);
441         return RVAL_DECODED;
442 }
443 #endif /* X86_64 || X32 || I386 */