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