(root)/
strace-6.5/
tests/
prctl-pac-enabled-keys.c
       1  /*
       2   * Check decoding of prctl PR_PAC_RESET_KEYS operation.
       3   *
       4   * Copyright (c) 2021 The strace developers.
       5   * All rights reserved.
       6   *
       7   * SPDX-License-Identifier: GPL-2.0-or-later
       8   */
       9  
      10  #include "tests.h"
      11  #include "scno.h"
      12  #include <stdio.h>
      13  #include <stdlib.h>
      14  #include <unistd.h>
      15  #include <linux/prctl.h>
      16  
      17  #include "xlat.h"
      18  #include "xlat/pr_pac_enabled_keys.h"
      19  
      20  #ifdef INJECT_RETVAL
      21  # define INJ_STR " (INJECTED)"
      22  #else
      23  # define INJ_STR ""
      24  #endif
      25  
      26  #define PR_PAC_ENABLE_FLAGS_MASK \
      27  	(PR_PAC_APIAKEY|PR_PAC_APIBKEY|PR_PAC_APDAKEY|PR_PAC_APDBKEY)
      28  
      29  int
      30  main(int argc, char *argv[])
      31  {
      32  	prctl_marker();
      33  
      34  #ifdef INJECT_RETVAL
      35  	unsigned long num_skip;
      36  	long inject_retval;
      37  	bool locked = false;
      38  
      39  	if (argc < 3)
      40  		error_msg_and_fail("Usage: %s NUM_SKIP INJECT_RETVAL", argv[0]);
      41  
      42  	num_skip = strtoul(argv[1], NULL, 0);
      43  	inject_retval = strtol(argv[2], NULL, 0);
      44  
      45  	for (size_t i = 0; i < num_skip; i++) {
      46  		if (prctl_marker() != inject_retval)
      47  			continue;
      48  
      49  		locked = true;
      50  		break;
      51  	}
      52  
      53  	if (!locked)
      54  		error_msg_and_fail("Have not locked on prctl(-1, -2, -3, -4"
      55  				   ", -5) returning %ld", inject_retval);
      56  #endif /* INJECT_RETVAL */
      57  
      58  	static const struct {
      59  		kernel_ulong_t val;
      60  		const char *str;
      61  	} args[] = {
      62  		{ ARG_STR(0) },
      63  		{ ARG_STR(PR_PAC_APIAKEY) },
      64  		{ ARG_STR(PR_PAC_APIBKEY|PR_PAC_APDAKEY|PR_PAC_APDBKEY|0x10) },
      65  		{ 0x7ffffff0, NVERB("0x7ffffff0 /* ") "PR_PAC_???" NVERB(" */") },
      66  	};
      67  	long rc;
      68  	const char *errstr;
      69  	size_t i = 0;
      70  
      71  	for (i = 0; i < ARRAY_SIZE(args); i++) {
      72  		for (size_t j = 0; j < ARRAY_SIZE(args); j++) {
      73  			rc = syscall(__NR_prctl, PR_PAC_SET_ENABLED_KEYS,
      74  				     args[i].val, args[j].val, 0, 1);
      75  			errstr = sprintrc(rc);
      76  			printf("prctl("
      77  			       XLAT_KNOWN(0x3c, "PR_PAC_SET_ENABLED_KEYS"));
      78  			if (args[i].val) {
      79  				printf(", " XLAT_FMT_LL,
      80  				       XLAT_SEL((unsigned long long) args[i].val,
      81  						args[i].str));
      82  			} else {
      83  				printf(", 0");
      84  			}
      85  			if (args[j].val) {
      86  				printf(", " XLAT_FMT_LL,
      87  				       XLAT_SEL((unsigned long long) args[j].val,
      88  						args[j].str));
      89  			} else {
      90  				printf(", 0");
      91  			}
      92  			printf(", 0, 0x1) = %s" INJ_STR "\n", errstr);
      93  		}
      94  	}
      95  
      96  	rc = syscall(__NR_prctl, PR_PAC_GET_ENABLED_KEYS, 0, 0, 0, 0);
      97  	errstr = sprintrc(rc);
      98  	printf("prctl(" XLAT_KNOWN(0x3d, "PR_PAC_GET_ENABLED_KEYS")
      99  	       ", 0, 0, 0, 0) = ");
     100  
     101  	if (rc > 0) {
     102  		printf("%#lx", rc);
     103  #if !XLAT_RAW
     104  		for (i = 0; i < ARRAY_SIZE(args); i++) {
     105  			if (!(rc & PR_PAC_ENABLE_FLAGS_MASK))
     106  				break;
     107  
     108  			if (args[i].val == (unsigned long) rc) {
     109  				printf(" (%s)", args[i].str);
     110  				break;
     111  			}
     112  		}
     113  
     114  		if (i == ARRAY_SIZE(args)) {
     115  			printf(" (");
     116  			printflags(pr_pac_enabled_keys, rc, "PR_PAC_???");
     117  			printf(")");
     118  		}
     119  #endif /* !XLAT_RAW */
     120  		puts(INJ_STR);
     121  	} else {
     122  		printf("%s" INJ_STR "\n", errstr);
     123  	}
     124  
     125  
     126  	puts("+++ exited with 0 +++");
     127  	return 0;
     128  }