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