1 // SPDX-License-Identifier: LGPL-2.1 2 /* 3 * trace/beauty/prctl.c 4 * 5 * Copyright (C) 2017, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com> 6 */ 7 8 #include "trace/beauty/beauty.h" 9 #include <linux/kernel.h> 10 #include <uapi/linux/prctl.h> 11 12 #include "trace/beauty/generated/prctl_option_array.c" 13 14 static size_t prctl__scnprintf_option(int option, char *bf, size_t size) 15 { 16 static DEFINE_STRARRAY(prctl_options, "PR_"); 17 return strarray__scnprintf(&strarray__prctl_options, bf, size, "%d", option); 18 } 19 20 static size_t prctl__scnprintf_set_mm(int option, char *bf, size_t size) 21 { 22 static DEFINE_STRARRAY(prctl_set_mm_options, "PR_SET_MM_"); 23 return strarray__scnprintf(&strarray__prctl_set_mm_options, bf, size, "%d", option); 24 } 25 26 size_t syscall_arg__scnprintf_prctl_arg2(char *bf, size_t size, struct syscall_arg *arg) 27 { 28 int option = syscall_arg__val(arg, 0); 29 30 if (option == PR_SET_MM) 31 return prctl__scnprintf_set_mm(arg->val, bf, size); 32 /* 33 * We still don't grab the contents of pointers on entry or exit, 34 * so just print them as hex numbers 35 */ 36 if (option == PR_SET_NAME) 37 return syscall_arg__scnprintf_hex(bf, size, arg); 38 39 return syscall_arg__scnprintf_long(bf, size, arg); 40 } 41 42 size_t syscall_arg__scnprintf_prctl_arg3(char *bf, size_t size, struct syscall_arg *arg) 43 { 44 int option = syscall_arg__val(arg, 0); 45 46 if (option == PR_SET_MM) 47 return syscall_arg__scnprintf_hex(bf, size, arg); 48 49 return syscall_arg__scnprintf_long(bf, size, arg); 50 } 51 52 size_t syscall_arg__scnprintf_prctl_option(char *bf, size_t size, struct syscall_arg *arg) 53 { 54 unsigned long option = arg->val; 55 enum { 56 SPO_ARG2 = (1 << 1), 57 SPO_ARG3 = (1 << 2), 58 SPO_ARG4 = (1 << 3), 59 SPO_ARG5 = (1 << 4), 60 SPO_ARG6 = (1 << 5), 61 }; 62 const u8 all_but2 = SPO_ARG3 | SPO_ARG4 | SPO_ARG5 | SPO_ARG6; 63 const u8 all = SPO_ARG2 | all_but2; 64 const u8 masks[] = { 65 [PR_GET_DUMPABLE] = all, 66 [PR_SET_DUMPABLE] = all_but2, 67 [PR_SET_NAME] = all_but2, 68 [PR_GET_CHILD_SUBREAPER] = all_but2, 69 [PR_SET_CHILD_SUBREAPER] = all_but2, 70 [PR_GET_SECUREBITS] = all, 71 [PR_SET_SECUREBITS] = all_but2, 72 [PR_SET_MM] = SPO_ARG4 | SPO_ARG5 | SPO_ARG6, 73 [PR_GET_PDEATHSIG] = all, 74 [PR_SET_PDEATHSIG] = all_but2, 75 }; 76 77 if (option < ARRAY_SIZE(masks)) 78 arg->mask |= masks[option]; 79 80 return prctl__scnprintf_option(option, bf, size); 81 } 82