blob: 90efe16ec0be8f72e9fdbf11977b9370519471c6 [file] [log] [blame]
Dmitry V. Levin53c993d2014-12-11 19:25:02 +00001#include "defs.h"
2
Dmitry V. Levin53c993d2014-12-11 19:25:02 +00003#include <sys/prctl.h>
4
5#include "xlat/prctl_options.h"
Dmitry V. Levin1e880732015-02-14 01:51:03 +00006#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"
Dmitry V. Levin53c993d2014-12-11 19:25:02 +000011
Dmitry V. Levin1e880732015-02-14 01:51:03 +000012#ifndef TASK_COMM_LEN
13# define TASK_COMM_LEN 16
Dmitry V. Levin53c993d2014-12-11 19:25:02 +000014#endif
Dmitry V. Levin53c993d2014-12-11 19:25:02 +000015
Dmitry V. Levin2af69032015-02-04 23:50:50 +000016#ifdef HAVE_LINUX_SECCOMP_H
17# include <linux/seccomp.h>
18#endif
Dmitry V. Levin2af69032015-02-04 23:50:50 +000019#include "xlat/seccomp_mode.h"
20
Dmitry V. Levin1e880732015-02-14 01:51:03 +000021#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> */
27enum {
28#include "caps0.h"
29#include "caps1.h"
30};
31
32#include "xlat/cap.h"
33
Dmitry V. Levin36915622015-07-25 09:43:01 +000034static void
35print_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
Dmitry V. Levin210a6b62015-07-17 21:49:17 +000043SYS_FUNC(prctl)
Dmitry V. Levin1e880732015-02-14 01:51:03 +000044{
45 unsigned int i;
46
Dmitry V. Levin210a6b62015-07-17 21:49:17 +000047 if (entering(tcp))
48 printxval(prctl_options, tcp->u_arg[0], "PR_???");
Dmitry V. Levin1e880732015-02-14 01:51:03 +000049
50 switch (tcp->u_arg[0]) {
Dmitry V. Levin1e880732015-02-14 01:51:03 +000051 case PR_GET_DUMPABLE:
Dmitry V. Levin210a6b62015-07-17 21:49:17 +000052 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:
Dmitry V. Levin1e880732015-02-14 01:51:03 +000061 case PR_GET_ENDIAN:
62 case PR_GET_FPEMU:
63 case PR_GET_FPEXC:
Dmitry V. Levin210a6b62015-07-17 21:49:17 +000064 if (entering(tcp))
65 tprints(", ");
66 else
67 printnum_int(tcp, tcp->u_arg[1], "%u");
68 break;
69
Dmitry V. Levin1e880732015-02-14 01:51:03 +000070 case PR_GET_NAME:
Dmitry V. Levin210a6b62015-07-17 21:49:17 +000071 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
Dmitry V. Levin1e880732015-02-14 01:51:03 +000081 case PR_GET_PDEATHSIG:
Dmitry V. Levin210a6b62015-07-17 21:49:17 +000082 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
Dmitry V. Levin1e880732015-02-14 01:51:03 +000091 case PR_GET_SECUREBITS:
Dmitry V. Levin210a6b62015-07-17 21:49:17 +000092 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
Dmitry V. Levin1e880732015-02-14 01:51:03 +000099 case PR_GET_TID_ADDRESS:
Dmitry V. Levin210a6b62015-07-17 21:49:17 +0000100 if (entering(tcp))
101 tprints(", ");
102 else
103 printnum_long(tcp, tcp->u_arg[1], "%#lx");
104 break;
105
Dmitry V. Levin1e880732015-02-14 01:51:03 +0000106 case PR_GET_TSC:
Dmitry V. Levin210a6b62015-07-17 21:49:17 +0000107 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
Dmitry V. Levin1e880732015-02-14 01:51:03 +0000116 case PR_GET_UNALIGN:
Dmitry V. Levin210a6b62015-07-17 21:49:17 +0000117 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. */
Dmitry V. Levin1e880732015-02-14 01:51:03 +0000127 case PR_TASK_PERF_EVENTS_DISABLE:
128 case PR_TASK_PERF_EVENTS_ENABLE:
Dmitry V. Levin210a6b62015-07-17 21:49:17 +0000129 return RVAL_DECODED;
Dmitry V. Levin1e880732015-02-14 01:51:03 +0000130
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]);
Dmitry V. Levin210a6b62015-07-17 21:49:17 +0000139 return RVAL_DECODED;
Dmitry V. Levin1e880732015-02-14 01:51:03 +0000140
141 case PR_CAPBSET_DROP:
Dmitry V. Levin1e880732015-02-14 01:51:03 +0000142 tprints(", ");
143 printxval(cap, tcp->u_arg[1], "CAP_???");
Dmitry V. Levin210a6b62015-07-17 21:49:17 +0000144 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;
Dmitry V. Levin1e880732015-02-14 01:51:03 +0000153
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]);
Dmitry V. Levin36915622015-07-25 09:43:01 +0000163 print_prctl_args(tcp, 3);
Dmitry V. Levin210a6b62015-07-17 21:49:17 +0000164 return RVAL_DECODED;
Dmitry V. Levin1e880732015-02-14 01:51:03 +0000165
166 case PR_SET_NAME:
167 tprints(", ");
168 printstr(tcp, tcp->u_arg[1], TASK_COMM_LEN);
Dmitry V. Levin210a6b62015-07-17 21:49:17 +0000169 return RVAL_DECODED;
Dmitry V. Levin1e880732015-02-14 01:51:03 +0000170
Elliott Hughes1d246ce2015-07-29 22:49:38 +0000171#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
Dmitry V. Levin1e880732015-02-14 01:51:03 +0000192 case PR_SET_MM:
193 tprints(", ");
194 printxval(pr_set_mm, tcp->u_arg[1], "PR_SET_MM_???");
Dmitry V. Levin36915622015-07-25 09:43:01 +0000195 print_prctl_args(tcp, 2);
Dmitry V. Levin210a6b62015-07-17 21:49:17 +0000196 return RVAL_DECODED;
Dmitry V. Levin1e880732015-02-14 01:51:03 +0000197
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]));
Dmitry V. Levin210a6b62015-07-17 21:49:17 +0000204 return RVAL_DECODED;
Dmitry V. Levin1e880732015-02-14 01:51:03 +0000205
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]);
Dmitry V. Levin210a6b62015-07-17 21:49:17 +0000212 return RVAL_DECODED;
Dmitry V. Levin1e880732015-02-14 01:51:03 +0000213
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])
Dmitry V. Levin210a6b62015-07-17 21:49:17 +0000219 return RVAL_DECODED;
Dmitry V. Levin1e880732015-02-14 01:51:03 +0000220 if (SECCOMP_MODE_FILTER == tcp->u_arg[1]) {
221 tprints(", ");
222 print_seccomp_filter(tcp, tcp->u_arg[2]);
Dmitry V. Levin210a6b62015-07-17 21:49:17 +0000223 return RVAL_DECODED;
Dmitry V. Levin1e880732015-02-14 01:51:03 +0000224 }
Dmitry V. Levin36915622015-07-25 09:43:01 +0000225 print_prctl_args(tcp, 2);
Dmitry V. Levin210a6b62015-07-17 21:49:17 +0000226 return RVAL_DECODED;
Dmitry V. Levin1e880732015-02-14 01:51:03 +0000227
228 case PR_SET_SECUREBITS:
229 tprints(", ");
230 printflags(secbits, tcp->u_arg[1], "SECBIT_???");
Dmitry V. Levin210a6b62015-07-17 21:49:17 +0000231 return RVAL_DECODED;
Dmitry V. Levin1e880732015-02-14 01:51:03 +0000232
233 case PR_SET_TIMERSLACK:
234 tprintf(", %ld", tcp->u_arg[1]);
Dmitry V. Levin210a6b62015-07-17 21:49:17 +0000235 return RVAL_DECODED;
Dmitry V. Levin1e880732015-02-14 01:51:03 +0000236
237 case PR_SET_TSC:
238 tprints(", ");
239 printxval(pr_tsc, tcp->u_arg[1], "PR_TSC_???");
Dmitry V. Levin210a6b62015-07-17 21:49:17 +0000240 return RVAL_DECODED;
Dmitry V. Levin1e880732015-02-14 01:51:03 +0000241
242 case PR_SET_UNALIGN:
243 tprints(", ");
244 printflags(pr_unalign_flags, tcp->u_arg[1], "PR_UNALIGN_???");
Dmitry V. Levin210a6b62015-07-17 21:49:17 +0000245 return RVAL_DECODED;
Dmitry V. Levin1e880732015-02-14 01:51:03 +0000246
247 case PR_SET_NO_NEW_PRIVS:
248 case PR_SET_THP_DISABLE:
249 tprintf(", %lu", tcp->u_arg[1]);
Dmitry V. Levin36915622015-07-25 09:43:01 +0000250 print_prctl_args(tcp, 2);
Dmitry V. Levin210a6b62015-07-17 21:49:17 +0000251 return RVAL_DECODED;
Dmitry V. Levin1e880732015-02-14 01:51:03 +0000252
253 case PR_GET_NO_NEW_PRIVS:
254 case PR_GET_THP_DISABLE:
Dmitry V. Levin36915622015-07-25 09:43:01 +0000255 if (entering(tcp)) {
256 print_prctl_args(tcp, 1);
257 return 0;
258 }
Dmitry V. Levin1e880732015-02-14 01:51:03 +0000259 return syserror(tcp) ? 0 : RVAL_UDECIMAL;
260
Dmitry V. Levin1e880732015-02-14 01:51:03 +0000261 case PR_MCE_KILL_GET:
Dmitry V. Levin36915622015-07-25 09:43:01 +0000262 if (entering(tcp)) {
263 print_prctl_args(tcp, 1);
264 return 0;
265 }
Dmitry V. Levin1e880732015-02-14 01:51:03 +0000266 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
Dmitry V. Levin210a6b62015-07-17 21:49:17 +0000271 case PR_MPX_DISABLE_MANAGEMENT:
272 case PR_MPX_ENABLE_MANAGEMENT:
Dmitry V. Levin1e880732015-02-14 01:51:03 +0000273 default:
Dmitry V. Levin36915622015-07-25 09:43:01 +0000274 print_prctl_args(tcp, 1);
Dmitry V. Levin210a6b62015-07-17 21:49:17 +0000275 return RVAL_DECODED;
Dmitry V. Levin1e880732015-02-14 01:51:03 +0000276 }
277 return 0;
278}
279
Dmitry V. Levin53c993d2014-12-11 19:25:02 +0000280#if defined X86_64 || defined X32
281# include <asm/prctl.h>
282# include "xlat/archvals.h"
283
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000284SYS_FUNC(arch_prctl)
Dmitry V. Levin53c993d2014-12-11 19:25:02 +0000285{
Dmitry V. Levin1e880732015-02-14 01:51:03 +0000286 if (entering(tcp))
Dmitry V. Levin53c993d2014-12-11 19:25:02 +0000287 printxval(archvals, tcp->u_arg[0], "ARCH_???");
Dmitry V. Levin1e880732015-02-14 01:51:03 +0000288
289 switch (tcp->u_arg[0]) {
290 case ARCH_GET_GS:
291 case ARCH_GET_FS:
Dmitry V. Levin210a6b62015-07-17 21:49:17 +0000292 if (entering(tcp))
Dmitry V. Levin1e880732015-02-14 01:51:03 +0000293 tprints(", ");
Dmitry V. Levin210a6b62015-07-17 21:49:17 +0000294 else
Dmitry V. Levin1e880732015-02-14 01:51:03 +0000295 printnum_long(tcp, tcp->u_arg[1], "%#lx");
Dmitry V. Levin1e880732015-02-14 01:51:03 +0000296 return 0;
Dmitry V. Levin53c993d2014-12-11 19:25:02 +0000297 }
Dmitry V. Levin1e880732015-02-14 01:51:03 +0000298
299 tprintf(", %#lx", tcp->u_arg[1]);
Dmitry V. Levin210a6b62015-07-17 21:49:17 +0000300 return RVAL_DECODED;
Dmitry V. Levin53c993d2014-12-11 19:25:02 +0000301}
302#endif /* X86_64 || X32 */