]> granicus.if.org Git - strace/blob - prctl.c
build: fix -I options
[strace] / prctl.c
1 #include "defs.h"
2
3 #include <sys/prctl.h>
4
5 #include "xlat/prctl_options.h"
6 #include "xlat/pr_unalign_flags.h"
7 #include "xlat/pr_mce_kill.h"
8 #include "xlat/pr_mce_kill_policy.h"
9 #include "xlat/pr_set_mm.h"
10 #include "xlat/pr_tsc.h"
11
12 #ifndef TASK_COMM_LEN
13 # define TASK_COMM_LEN 16
14 #endif
15
16 #ifdef HAVE_LINUX_SECCOMP_H
17 # include <linux/seccomp.h>
18 #endif
19 #include "xlat/seccomp_mode.h"
20
21 #ifdef HAVE_LINUX_SECUREBITS_H
22 # include <linux/securebits.h>
23 #endif
24 #include "xlat/secbits.h"
25
26 /* these constants are the same as in <linux/capability.h> */
27 enum {
28 #include "caps0.h"
29 #include "caps1.h"
30 };
31
32 #include "xlat/cap.h"
33
34 static void
35 print_prctl_args(struct tcb *tcp, const unsigned int first)
36 {
37         unsigned int i;
38
39         for (i = first; i < tcp->s_ent->nargs; ++i)
40                 tprintf(", %#lx", tcp->u_arg[i]);
41 }
42
43 SYS_FUNC(prctl)
44 {
45         unsigned int i;
46
47         if (entering(tcp))
48                 printxval(prctl_options, tcp->u_arg[0], "PR_???");
49
50         switch (tcp->u_arg[0]) {
51         case PR_GET_DUMPABLE:
52         case PR_GET_KEEPCAPS:
53         case PR_GET_SECCOMP:
54         case PR_GET_TIMERSLACK:
55         case PR_GET_TIMING:
56                 if (entering(tcp))
57                         break;
58                 return syserror(tcp) ? 0 : RVAL_UDECIMAL;
59
60         case PR_GET_CHILD_SUBREAPER:
61         case PR_GET_ENDIAN:
62         case PR_GET_FPEMU:
63         case PR_GET_FPEXC:
64                 if (entering(tcp))
65                         tprints(", ");
66                 else
67                         printnum_int(tcp, tcp->u_arg[1], "%u");
68                 break;
69
70         case PR_GET_NAME:
71                 if (entering(tcp))
72                         tprints(", ");
73                 else {
74                         if (syserror(tcp))
75                                 printaddr(tcp->u_arg[1]);
76                         else
77                                 printstr(tcp, tcp->u_arg[1], -1);
78                 }
79                 break;
80
81         case PR_GET_PDEATHSIG:
82                 if (entering(tcp))
83                         tprints(", ");
84                 else if (!umove_or_printaddr(tcp, tcp->u_arg[1], &i)) {
85                         tprints("[");
86                         tprints(signame(i));
87                         tprints("]");
88                 }
89                 break;
90
91         case PR_GET_SECUREBITS:
92                 if (entering(tcp))
93                         break;
94                 if (syserror(tcp) || tcp->u_rval == 0)
95                         return 0;
96                 tcp->auxstr = sprintflags("", secbits, tcp->u_rval);
97                 return RVAL_STR;
98
99         case PR_GET_TID_ADDRESS:
100                 if (entering(tcp))
101                         tprints(", ");
102                 else
103                         printnum_ptr(tcp, tcp->u_arg[1]);
104                 break;
105
106         case PR_GET_TSC:
107                 if (entering(tcp))
108                         tprints(", ");
109                 else if (!umove_or_printaddr(tcp, tcp->u_arg[1], &i)) {
110                         tprints("[");
111                         printxval(pr_tsc, i, "PR_TSC_???");
112                         tprints("]");
113                 }
114                 break;
115
116         case PR_GET_UNALIGN:
117                 if (entering(tcp))
118                         tprints(", ");
119                 else if (!umove_or_printaddr(tcp, tcp->u_arg[1], &i)) {
120                         tprints("[");
121                         printflags(pr_unalign_flags, i, "PR_UNALIGN_???");
122                         tprints("]");
123                 }
124                 break;
125
126         /* PR_TASK_PERF_EVENTS_* take no arguments. */
127         case PR_TASK_PERF_EVENTS_DISABLE:
128         case PR_TASK_PERF_EVENTS_ENABLE:
129                 return RVAL_DECODED;
130
131         case PR_SET_CHILD_SUBREAPER:
132         case PR_SET_DUMPABLE:
133         case PR_SET_ENDIAN:
134         case PR_SET_FPEMU:
135         case PR_SET_FPEXC:
136         case PR_SET_KEEPCAPS:
137         case PR_SET_TIMING:
138                 tprintf(", %lu", tcp->u_arg[1]);
139                 return RVAL_DECODED;
140
141         case PR_CAPBSET_DROP:
142                 tprints(", ");
143                 printxval(cap, tcp->u_arg[1], "CAP_???");
144                 return RVAL_DECODED;
145
146         case PR_CAPBSET_READ:
147                 if (entering(tcp)) {
148                         tprints(", ");
149                         printxval(cap, tcp->u_arg[1], "CAP_???");
150                         break;
151                 }
152                 return syserror(tcp) ? 0 : RVAL_UDECIMAL;
153
154         case PR_MCE_KILL:
155                 tprints(", ");
156                 printxval(pr_mce_kill, tcp->u_arg[1], "PR_MCE_KILL_???");
157                 tprints(", ");
158                 if (PR_MCE_KILL_SET == tcp->u_arg[1])
159                         printxval(pr_mce_kill_policy, tcp->u_arg[2],
160                                    "PR_MCE_KILL_???");
161                 else
162                         tprintf("%#lx", tcp->u_arg[2]);
163                 print_prctl_args(tcp, 3);
164                 return RVAL_DECODED;
165
166         case PR_SET_NAME:
167                 tprints(", ");
168                 printstr(tcp, tcp->u_arg[1], TASK_COMM_LEN);
169                 return RVAL_DECODED;
170
171 #ifdef __ANDROID__
172 # ifndef PR_SET_VMA
173 #  define PR_SET_VMA   0x53564d41
174 # endif
175 # ifndef PR_SET_VMA_ANON_NAME
176 #  define PR_SET_VMA_ANON_NAME    0
177 # endif
178         case PR_SET_VMA:
179                 if (tcp->u_arg[1] == PR_SET_VMA_ANON_NAME) {
180                         tprintf(", %lu", tcp->u_arg[1]);
181                         tprintf(", %#lx", tcp->u_arg[2]);
182                         tprintf(", %lu, ", tcp->u_arg[3]);
183                         printstr(tcp, tcp->u_arg[4], -1);
184                 } else {
185                         /* There are no other sub-options now, but there
186                          * might be in future... */
187                         print_prctl_args(tcp, 1);
188                 }
189                 return RVAL_DECODED;
190 #endif
191
192         case PR_SET_MM:
193                 tprints(", ");
194                 printxval(pr_set_mm, tcp->u_arg[1], "PR_SET_MM_???");
195                 print_prctl_args(tcp, 2);
196                 return RVAL_DECODED;
197
198         case PR_SET_PDEATHSIG:
199                 tprints(", ");
200                 if ((unsigned long) tcp->u_arg[1] > 128)
201                         tprintf("%lu", tcp->u_arg[1]);
202                 else
203                         tprints(signame(tcp->u_arg[1]));
204                 return RVAL_DECODED;
205
206         case PR_SET_PTRACER:
207                 tprints(", ");
208                 if (tcp->u_arg[1] == -1)
209                         tprints("PR_SET_PTRACER_ANY");
210                 else
211                         tprintf("%lu", tcp->u_arg[1]);
212                 return RVAL_DECODED;
213
214         case PR_SET_SECCOMP:
215                 tprints(", ");
216                 printxval(seccomp_mode, tcp->u_arg[1],
217                           "SECCOMP_MODE_???");
218                 if (SECCOMP_MODE_STRICT == tcp->u_arg[1])
219                         return RVAL_DECODED;
220                 if (SECCOMP_MODE_FILTER == tcp->u_arg[1]) {
221                         tprints(", ");
222                         print_seccomp_filter(tcp, tcp->u_arg[2]);
223                         return RVAL_DECODED;
224                 }
225                 print_prctl_args(tcp, 2);
226                 return RVAL_DECODED;
227
228         case PR_SET_SECUREBITS:
229                 tprints(", ");
230                 printflags(secbits, tcp->u_arg[1], "SECBIT_???");
231                 return RVAL_DECODED;
232
233         case PR_SET_TIMERSLACK:
234                 tprintf(", %ld", tcp->u_arg[1]);
235                 return RVAL_DECODED;
236
237         case PR_SET_TSC:
238                 tprints(", ");
239                 printxval(pr_tsc, tcp->u_arg[1], "PR_TSC_???");
240                 return RVAL_DECODED;
241
242         case PR_SET_UNALIGN:
243                 tprints(", ");
244                 printflags(pr_unalign_flags, tcp->u_arg[1], "PR_UNALIGN_???");
245                 return RVAL_DECODED;
246
247         case PR_SET_NO_NEW_PRIVS:
248         case PR_SET_THP_DISABLE:
249                 tprintf(", %lu", tcp->u_arg[1]);
250                 print_prctl_args(tcp, 2);
251                 return RVAL_DECODED;
252
253         case PR_GET_NO_NEW_PRIVS:
254         case PR_GET_THP_DISABLE:
255                 if (entering(tcp)) {
256                         print_prctl_args(tcp, 1);
257                         return 0;
258                 }
259                 return syserror(tcp) ? 0 : RVAL_UDECIMAL;
260
261         case PR_MCE_KILL_GET:
262                 if (entering(tcp)) {
263                         print_prctl_args(tcp, 1);
264                         return 0;
265                 }
266                 if (syserror(tcp))
267                         return 0;
268                 tcp->auxstr = xlookup(pr_mce_kill_policy, tcp->u_rval);
269                 return tcp->auxstr ? RVAL_STR : RVAL_UDECIMAL;
270
271         case PR_MPX_DISABLE_MANAGEMENT:
272         case PR_MPX_ENABLE_MANAGEMENT:
273         default:
274                 print_prctl_args(tcp, 1);
275                 return RVAL_DECODED;
276         }
277         return 0;
278 }
279
280 #if defined X86_64 || defined X32
281 # include <asm/prctl.h>
282 # include "xlat/archvals.h"
283
284 SYS_FUNC(arch_prctl)
285 {
286         if (entering(tcp))
287                 printxval(archvals, tcp->u_arg[0], "ARCH_???");
288
289         switch (tcp->u_arg[0]) {
290         case ARCH_GET_GS:
291         case ARCH_GET_FS:
292                 if (entering(tcp))
293                         tprints(", ");
294                 else
295                         printnum_ptr(tcp, tcp->u_arg[1]);
296                 return 0;
297         }
298
299         tprintf(", %#lx", tcp->u_arg[1]);
300         return RVAL_DECODED;
301 }
302 #endif /* X86_64 || X32 */