(root)/
strace-6.5/
tests-mx32/
prctl-securebits.c
       1  /*
       2   * Check decoding of prctl PR_GET_SECUREBITS/PR_SET_SECUREBITS operations.
       3   *
       4   * Copyright (c) 2016 Eugene Syromyatnikov <evgsyr@gmail.com>
       5   * Copyright (c) 2016 Dmitry V. Levin <ldv@strace.io>
       6   * Copyright (c) 2016-2021 The strace developers.
       7   * All rights reserved.
       8   *
       9   * SPDX-License-Identifier: GPL-2.0-or-later
      10   */
      11  
      12  #include "tests.h"
      13  #include "scno.h"
      14  #include <stdio.h>
      15  #include <stdlib.h>
      16  #include <unistd.h>
      17  #include <linux/prctl.h>
      18  #include <linux/securebits.h>
      19  
      20  #include "xlat.h"
      21  #include "xlat/secbits.h"
      22  
      23  #ifdef INJECT_RETVAL
      24  # define INJ_STR " (INJECTED)"
      25  #else
      26  # define INJ_STR ""
      27  #endif
      28  
      29  static const char *errstr;
      30  
      31  static long
      32  prctl(kernel_ulong_t arg1, kernel_ulong_t arg2)
      33  {
      34  	static const kernel_ulong_t bogus_arg =
      35  		(kernel_ulong_t) 0xdeadbeefbadc0dedULL;
      36  	long rc = syscall(__NR_prctl, arg1, arg2, bogus_arg);
      37  	errstr = sprintrc(rc);
      38  	return rc;
      39  }
      40  
      41  int
      42  main(int argc, char *argv[])
      43  {
      44  	prctl_marker();
      45  
      46  #ifdef INJECT_RETVAL
      47  	unsigned long num_skip;
      48  	bool locked = false;
      49  
      50  	if (argc < 2)
      51  		error_msg_and_fail("Usage: %s NUM_SKIP", argv[0]);
      52  
      53  	num_skip = strtoul(argv[1], NULL, 0);
      54  
      55  	for (size_t i = 0; i < num_skip; i++) {
      56  		if (prctl_marker() < 0)
      57  			continue;
      58  
      59  		locked = true;
      60  		break;
      61  	}
      62  
      63  	if (!locked)
      64  		error_msg_and_fail("Have not locked on prctl(-1, -2, -3, -4"
      65  				   ", -5) returning non-error value");
      66  #endif /* INJECT_RETVAL */
      67  
      68  	static const kernel_ulong_t bits1 =
      69  		(kernel_ulong_t) 0xdeadc0defacebeefULL;
      70  	static const kernel_ulong_t bits2 =
      71  		(kernel_ulong_t) 0xbadc0ded00000000ULL;
      72  	static const kernel_ulong_t bits3 =
      73  		(kernel_ulong_t) 0xffULL;
      74  
      75  	prctl(PR_SET_SECUREBITS, 0);
      76  	printf("prctl(" XLAT_KNOWN(0x1c, "PR_SET_SECUREBITS") ", 0) = %s"
      77  	       INJ_STR "\n", errstr);
      78  
      79  	prctl(PR_SET_SECUREBITS, bits1);
      80  	printf("prctl(" XLAT_KNOWN(0x1c, "PR_SET_SECUREBITS") ", "
      81  	       NABBR("%#llx") VERB(" /* ") NRAW("SECBIT_NOROOT|"
      82  	       "SECBIT_NOROOT_LOCKED|SECBIT_NO_SETUID_FIXUP|"
      83  	       "SECBIT_NO_SETUID_FIXUP_LOCKED|SECBIT_KEEP_CAPS_LOCKED|"
      84  	       "SECBIT_NO_CAP_AMBIENT_RAISE|SECBIT_NO_CAP_AMBIENT_RAISE_LOCKED|"
      85  	       "%#llx") VERB(" */") ") = %s" INJ_STR "\n",
      86  	       XLAT_SEL((unsigned long long) bits1,
      87  	       (unsigned long long) bits1 & ~0xffULL), errstr);
      88  
      89  	if (bits2) {
      90  		prctl(PR_SET_SECUREBITS, bits2);
      91  		printf("prctl(" XLAT_KNOWN(0x1c, "PR_SET_SECUREBITS") ", %#llx"
      92  		       NRAW(" /* SECBIT_??? */") ") = %s" INJ_STR "\n",
      93  		       (unsigned long long) bits2, errstr);
      94  	}
      95  
      96  	prctl(PR_SET_SECUREBITS, bits3);
      97  	printf("prctl(" XLAT_KNOWN(0x1c, "PR_SET_SECUREBITS") ", "
      98  	       XLAT_KNOWN(0xff, "SECBIT_NOROOT|SECBIT_NOROOT_LOCKED|"
      99  	       "SECBIT_NO_SETUID_FIXUP|SECBIT_NO_SETUID_FIXUP_LOCKED|"
     100  	       "SECBIT_KEEP_CAPS|SECBIT_KEEP_CAPS_LOCKED|"
     101  	       "SECBIT_NO_CAP_AMBIENT_RAISE|SECBIT_NO_CAP_AMBIENT_RAISE_LOCKED")
     102  	       ") = %s" INJ_STR "\n", errstr);
     103  
     104  	long rc = prctl(PR_GET_SECUREBITS, bits1);
     105  	printf("prctl(" XLAT_KNOWN(0x1b, "PR_GET_SECUREBITS") ") = ");
     106  	if (rc > 0) {
     107  		printf("%#lx", rc);
     108  		if ((rc & 0xff) && !XLAT_RAW) {
     109  			printf(" (");
     110  			printflags(secbits, rc, NULL);
     111  			printf(")");
     112  		}
     113  		puts(INJ_STR);
     114  	} else {
     115  		printf("%s" INJ_STR "\n", errstr);
     116  	}
     117  
     118  	puts("+++ exited with 0 +++");
     119  	return 0;
     120  }