Home | History | Annotate | Download | only in strace
      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