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