(root)/
strace-6.5/
tests-mx32/
prctl-sched-core.c
       1  /*
       2   * Check decoding of prctl PR_SCHED_CORE operation.
       3   *
       4   * Copyright (c) 2021 Eugene Syromyatnikov <evgsyr@gmail.com>.
       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 <inttypes.h>
      13  #include <stdint.h>
      14  #include <stdio.h>
      15  #include <stdlib.h>
      16  #include <unistd.h>
      17  #include <linux/prctl.h>
      18  
      19  #include "pidns.h"
      20  
      21  struct op_str {
      22  	unsigned int op;
      23  	const char *str;
      24  };
      25  
      26  #ifdef INJECT_RETVAL
      27  # define NUM_SKIP 256
      28  # define INJ_STR " (INJECTED)"
      29  #else
      30  # define NUM_SKIP 1
      31  # define INJ_STR ""
      32  #endif
      33  
      34  int
      35  main(int argc, char *argv[])
      36  {
      37  	PIDNS_TEST_INIT;
      38  
      39  	long rc;
      40  
      41  	unsigned long num_skip = NUM_SKIP;
      42  
      43  	if (argc >= 2)
      44  		num_skip = strtoul(argv[1], NULL, 0);
      45  
      46  	for (size_t i = 0; i < num_skip; i++) {
      47  		rc = prctl_marker();
      48  #ifdef PIDNS_TRANSLATION
      49  		const char *errstr = sprintrc(rc);
      50  		pidns_print_leader();
      51  		printf("prctl(" XLAT_UNKNOWN(0xffffffff, "PR_???")
      52  		       ", 0xfffffffe, 0xfffffffd, 0xfffffffc, 0xfffffffb) = ");
      53  
      54  		if (rc < 0) {
      55  			puts(errstr);
      56  		} else {
      57  			printf("%ld (INJECTED)\n", rc);
      58  		}
      59  #endif
      60  
      61  		if (rc < 0)
      62  			continue;
      63  
      64  		break;
      65  	}
      66  
      67  	static const struct {
      68  		unsigned int decode_ptr:1,
      69  			     valid:1;
      70  		unsigned int op;
      71  		const char *str;
      72  	} ops[] = {
      73  		{ true,  true,  ARG_STR(PR_SCHED_CORE_GET) },
      74  		{ false, true,  ARG_STR(PR_SCHED_CORE_CREATE) },
      75  		{ false, true,  ARG_STR(PR_SCHED_CORE_SHARE_TO) },
      76  		{ false, true,  ARG_STR(PR_SCHED_CORE_SHARE_FROM) },
      77  		{ false, false, 4, "PR_SCHED_CORE_???" },
      78  	};
      79  	static const struct {
      80  		unsigned int val;
      81  		const char *str;
      82  	} pidtypes[] = {
      83  		{ 0, "PIDTYPE_PID" },
      84  		{ 1, "PIDTYPE_TGID" },
      85  		{ 2, "PIDTYPE_PGID" },
      86  		{ 3, "PIDTYPE_SID" },
      87  		{ 4, "PIDTYPE_???" },
      88  		{ -1U, "PIDTYPE_???" },
      89  	};
      90  
      91  	int ids[5];
      92  	ids[0] = syscall(__NR_gettid);
      93  	ids[1] = getpid();
      94  	ids[2] = getpgid(0);
      95  	ids[3] = getsid(0);
      96  	ids[4] = -1;
      97  
      98  	TAIL_ALLOC_OBJECT_VAR_PTR(uint64_t, uptr);
      99  	uint64_t *uptrs[] = { NULL, uptr + 1, uptr };
     100  
     101  	for (size_t i = 0; i < ARRAY_SIZE(ops); i++) {
     102  		for (size_t j = 0; j < ARRAY_SIZE(pidtypes); j++) {
     103  			for (size_t k = 0; k < ARRAY_SIZE(uptrs); k++) {
     104  				*uptr = 0xdeadc0debadc0dedULL;
     105  				rc = syscall(__NR_prctl, PR_SCHED_CORE,
     106  						  ops[i].op | F8ILL_KULONG_MASK,
     107  						  ids[MIN(pidtypes[j].val, 4)]
     108  							| F8ILL_KULONG_MASK,
     109  						  pidtypes[j].val
     110  							| F8ILL_KULONG_MASK,
     111  						  uptrs[k]);
     112  				const char *errstr = sprintrc(rc);
     113  
     114  				pidns_print_leader();
     115  				printf("prctl("
     116  				       XLAT_KNOWN(0x3e, "PR_SCHED_CORE") ", ");
     117  				if (ops[i].valid) {
     118  					printf(XLAT_FMT,
     119  					       XLAT_SEL(ops[i].op, ops[i].str));
     120  				} else {
     121  					printf("%#x"
     122  					       NRAW(" /* PR_SCHED_CORE_??? */"),
     123  					       ops[i].op);
     124  				}
     125  				printf(", %d%s, %#x" NRAW(" /* %s */") ", ",
     126  				       ids[MIN(pidtypes[j].val, 4)],
     127  				       pidns_pid2str(pidtypes[j].val),
     128  				       pidtypes[j].val
     129  #if !XLAT_RAW
     130  				       , pidtypes[j].str
     131  #endif
     132  				       );
     133  
     134  				if (uptrs[k]) {
     135  					if (uptrs[k] == uptr
     136  					    && ops[i].decode_ptr && rc >= 0)
     137  #ifdef INJECT_RETVAL
     138  						printf("[0xdeadc0debadc0ded]");
     139  #else
     140  						printf("[%#" PRIx64 "]", *uptr);
     141  #endif
     142  					else
     143  						printf("%p", uptrs[k]);
     144  				} else {
     145  					printf("NULL");
     146  				}
     147  
     148  				printf(") = %s" INJ_STR "\n", errstr);
     149  			}
     150  		}
     151  	}
     152  
     153  	pidns_print_leader();
     154  	puts("+++ exited with 0 +++");
     155  	return 0;
     156  }