]> granicus.if.org Git - strace/blob - prctl.c
netlink_sock_diag: print inet_diag_sockid.idiag_if as an interface index
[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-2017 The strace developers.
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. The name of the author may not be used to endorse or promote products
18  *    derived from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31
32 #include "defs.h"
33
34 #include <linux/prctl.h>
35
36 #include "xlat/prctl_options.h"
37 #include "xlat/pr_cap_ambient.h"
38 #include "xlat/pr_dumpable.h"
39 #include "xlat/pr_fp_mode.h"
40 #include "xlat/pr_mce_kill.h"
41 #include "xlat/pr_mce_kill_policy.h"
42 #include "xlat/pr_set_mm.h"
43 #include "xlat/pr_tsc.h"
44 #include "xlat/pr_unalign_flags.h"
45
46 #ifndef TASK_COMM_LEN
47 # define TASK_COMM_LEN 16
48 #endif
49
50 #ifdef HAVE_LINUX_SECCOMP_H
51 # include <linux/seccomp.h>
52 #endif
53 #include "xlat/seccomp_mode.h"
54
55 #ifdef HAVE_LINUX_SECUREBITS_H
56 # include <linux/securebits.h>
57 #endif
58 #include "xlat/secbits.h"
59
60 /* these constants are the same as in <linux/capability.h> */
61 enum {
62 #include "caps0.h"
63 #include "caps1.h"
64 };
65
66 #include "xlat/cap.h"
67
68 static void
69 print_prctl_args(struct tcb *tcp, const unsigned int first)
70 {
71         unsigned int i;
72
73         for (i = first; i < tcp->s_ent->nargs; ++i)
74                 tprintf(", %#" PRI_klx, tcp->u_arg[i]);
75 }
76
77 SYS_FUNC(prctl)
78 {
79         const unsigned int option = tcp->u_arg[0];
80         const kernel_ulong_t arg2 = tcp->u_arg[1];
81         const kernel_ulong_t arg3 = tcp->u_arg[2];
82         /*
83          * PR_SET_VMA is the only command which actually uses these arguments
84          * currently, and it is available only on Android for now.
85          */
86 #ifdef __ANDROID__
87         const kernel_ulong_t arg4 = tcp->u_arg[3];
88         const kernel_ulong_t arg5 = tcp->u_arg[4];
89 #endif
90         unsigned int i;
91
92         if (entering(tcp))
93                 printxval(prctl_options, option, "PR_???");
94
95         switch (option) {
96         case PR_GET_KEEPCAPS:
97         case PR_GET_SECCOMP:
98         case PR_GET_TIMERSLACK:
99         case PR_GET_TIMING:
100                 return RVAL_DECODED;
101
102         case PR_GET_CHILD_SUBREAPER:
103         case PR_GET_ENDIAN:
104         case PR_GET_FPEMU:
105         case PR_GET_FPEXC:
106                 if (entering(tcp))
107                         tprints(", ");
108                 else
109                         printnum_int(tcp, arg2, "%u");
110                 break;
111
112         case PR_GET_DUMPABLE:
113                 if (entering(tcp))
114                         break;
115                 if (syserror(tcp))
116                         return 0;
117                 tcp->auxstr = xlookup(pr_dumpable, (kernel_ulong_t) tcp->u_rval);
118                 return RVAL_STR;
119
120         case PR_GET_NAME:
121                 if (entering(tcp)) {
122                         tprints(", ");
123                 } else {
124                         if (syserror(tcp))
125                                 printaddr(arg2);
126                         else
127                                 printstr_ex(tcp, arg2, TASK_COMM_LEN,
128                                             QUOTE_0_TERMINATED);
129                 }
130                 break;
131
132         case PR_GET_PDEATHSIG:
133                 if (entering(tcp)) {
134                         tprints(", ");
135                 } else if (!umove_or_printaddr(tcp, arg2, &i)) {
136                         tprints("[");
137                         tprints(signame(i));
138                         tprints("]");
139                 }
140                 break;
141
142         case PR_GET_SECUREBITS:
143                 if (entering(tcp))
144                         break;
145                 if (syserror(tcp) || tcp->u_rval == 0)
146                         return 0;
147                 tcp->auxstr = sprintflags("", secbits,
148                                           (kernel_ulong_t) tcp->u_rval);
149                 return RVAL_STR;
150
151         case PR_GET_TID_ADDRESS:
152                 if (entering(tcp))
153                         tprints(", ");
154                 else
155                         printnum_kptr(tcp, arg2);
156                 break;
157
158         case PR_GET_TSC:
159                 if (entering(tcp)) {
160                         tprints(", ");
161                 } else if (!umove_or_printaddr(tcp, arg2, &i)) {
162                         tprints("[");
163                         printxval(pr_tsc, i, "PR_TSC_???");
164                         tprints("]");
165                 }
166                 break;
167
168         case PR_GET_UNALIGN:
169                 if (entering(tcp)) {
170                         tprints(", ");
171                 } else if (!umove_or_printaddr(tcp, arg2, &i)) {
172                         tprints("[");
173                         printflags(pr_unalign_flags, i, "PR_UNALIGN_???");
174                         tprints("]");
175                 }
176                 break;
177
178         case PR_GET_FP_MODE:
179                 if (entering(tcp))
180                         break;
181                 if (syserror(tcp) || tcp->u_rval == 0)
182                         return 0;
183                 tcp->auxstr = sprintflags("", pr_fp_mode,
184                                           (kernel_ulong_t) tcp->u_rval);
185                 return RVAL_STR;
186
187         /* PR_TASK_PERF_EVENTS_* take no arguments. */
188         case PR_TASK_PERF_EVENTS_DISABLE:
189         case PR_TASK_PERF_EVENTS_ENABLE:
190                 return RVAL_DECODED;
191
192         case PR_SET_CHILD_SUBREAPER:
193         case PR_SET_ENDIAN:
194         case PR_SET_FPEMU:
195         case PR_SET_FPEXC:
196         case PR_SET_KEEPCAPS:
197         case PR_SET_TIMING:
198                 tprintf(", %" PRI_klu, arg2);
199                 return RVAL_DECODED;
200
201         case PR_SET_DUMPABLE:
202                 tprints(", ");
203                 printxval64(pr_dumpable, arg2, "SUID_DUMP_???");
204                 return RVAL_DECODED;
205
206         case PR_CAPBSET_DROP:
207         case PR_CAPBSET_READ:
208                 tprints(", ");
209                 printxval64(cap, arg2, "CAP_???");
210                 return RVAL_DECODED;
211
212         case PR_CAP_AMBIENT:
213                 tprints(", ");
214                 printxval64(pr_cap_ambient, arg2,
215                                "PR_CAP_AMBIENT_???");
216                 switch (arg2) {
217                 case PR_CAP_AMBIENT_RAISE:
218                 case PR_CAP_AMBIENT_LOWER:
219                 case PR_CAP_AMBIENT_IS_SET:
220                         tprints(", ");
221                         printxval64(cap, arg3, "CAP_???");
222                         print_prctl_args(tcp, 3);
223                         break;
224                 default:
225                         print_prctl_args(tcp, 2);
226                         break;
227                 }
228                 return RVAL_DECODED;
229
230         case PR_MCE_KILL:
231                 tprints(", ");
232                 printxval64(pr_mce_kill, arg2, "PR_MCE_KILL_???");
233                 tprints(", ");
234                 if (PR_MCE_KILL_SET == arg2)
235                         printxval64(pr_mce_kill_policy, arg3,
236                                     "PR_MCE_KILL_???");
237                 else
238                         tprintf("%#" PRI_klx, arg3);
239                 print_prctl_args(tcp, 3);
240                 return RVAL_DECODED;
241
242         case PR_SET_NAME:
243                 tprints(", ");
244                 printstr_ex(tcp, arg2, TASK_COMM_LEN - 1,
245                             QUOTE_0_TERMINATED);
246                 return RVAL_DECODED;
247
248 #ifdef __ANDROID__
249 # ifndef PR_SET_VMA_ANON_NAME
250 #  define PR_SET_VMA_ANON_NAME    0
251 # endif
252         case PR_SET_VMA:
253                 if (arg2 == PR_SET_VMA_ANON_NAME) {
254                         tprintf(", PR_SET_VMA_ANON_NAME, %#" PRI_klx, arg3);
255                         tprintf(", %" PRI_klu ", ", arg4);
256                         printstr(tcp, arg5);
257                 } else {
258                         /* There are no other sub-options now, but there
259                          * might be in future... */
260                         print_prctl_args(tcp, 1);
261                 }
262                 return RVAL_DECODED;
263 #endif
264
265         case PR_SET_MM:
266                 tprints(", ");
267                 printxval(pr_set_mm, arg2, "PR_SET_MM_???");
268                 print_prctl_args(tcp, 2);
269                 return RVAL_DECODED;
270
271         case PR_SET_PDEATHSIG:
272                 tprints(", ");
273                 if (arg2 > 128)
274                         tprintf("%" PRI_klu, arg2);
275                 else
276                         tprints(signame(arg2));
277                 return RVAL_DECODED;
278
279         case PR_SET_PTRACER:
280                 tprints(", ");
281                 if ((int) arg2 == -1)
282                         tprints("PR_SET_PTRACER_ANY");
283                 else
284                         tprintf("%" PRI_klu, arg2);
285                 return RVAL_DECODED;
286
287         case PR_SET_SECCOMP:
288                 tprints(", ");
289                 printxval64(seccomp_mode, arg2,
290                             "SECCOMP_MODE_???");
291                 if (SECCOMP_MODE_STRICT == arg2)
292                         return RVAL_DECODED;
293                 if (SECCOMP_MODE_FILTER == arg2) {
294                         tprints(", ");
295                         print_seccomp_filter(tcp, arg3);
296                         return RVAL_DECODED;
297                 }
298                 print_prctl_args(tcp, 2);
299                 return RVAL_DECODED;
300
301         case PR_SET_SECUREBITS:
302                 tprints(", ");
303                 printflags64(secbits, arg2, "SECBIT_???");
304                 return RVAL_DECODED;
305
306         case PR_SET_TIMERSLACK:
307                 tprintf(", %" PRI_kld, arg2);
308                 return RVAL_DECODED;
309
310         case PR_SET_TSC:
311                 tprints(", ");
312                 printxval(pr_tsc, arg2, "PR_TSC_???");
313                 return RVAL_DECODED;
314
315         case PR_SET_UNALIGN:
316                 tprints(", ");
317                 printflags(pr_unalign_flags, arg2, "PR_UNALIGN_???");
318                 return RVAL_DECODED;
319
320         case PR_SET_NO_NEW_PRIVS:
321         case PR_SET_THP_DISABLE:
322                 tprintf(", %" PRI_klu, arg2);
323                 print_prctl_args(tcp, 2);
324                 return RVAL_DECODED;
325
326         case PR_MCE_KILL_GET:
327                 if (entering(tcp)) {
328                         print_prctl_args(tcp, 1);
329                         return 0;
330                 }
331                 if (syserror(tcp))
332                         return 0;
333                 tcp->auxstr = xlookup(pr_mce_kill_policy,
334                                       (kernel_ulong_t) tcp->u_rval);
335                 return tcp->auxstr ? RVAL_STR : RVAL_UDECIMAL;
336
337         case PR_SET_FP_MODE:
338                 tprints(", ");
339                 printflags(pr_fp_mode, arg2, "PR_FP_MODE_???");
340                 return RVAL_DECODED;
341
342         case PR_GET_NO_NEW_PRIVS:
343         case PR_GET_THP_DISABLE:
344         case PR_MPX_DISABLE_MANAGEMENT:
345         case PR_MPX_ENABLE_MANAGEMENT:
346         default:
347                 print_prctl_args(tcp, 1);
348                 return RVAL_DECODED;
349         }
350         return 0;
351 }
352
353 #if defined X86_64 || defined X32
354 # include <asm/prctl.h>
355 # include "xlat/archvals.h"
356
357 SYS_FUNC(arch_prctl)
358 {
359         const unsigned int option = tcp->u_arg[0];
360         const kernel_ulong_t addr = tcp->u_arg[1];
361
362         if (entering(tcp))
363                 printxval(archvals, option, "ARCH_???");
364
365         switch (option) {
366         case ARCH_GET_GS:
367         case ARCH_GET_FS:
368                 if (entering(tcp))
369                         tprints(", ");
370                 else
371                         printnum_ptr(tcp, addr);
372                 return 0;
373         }
374
375         tprintf(", %#" PRI_klx, addr);
376         return RVAL_DECODED;
377 }
378 #endif /* X86_64 || X32 */