(root)/
strace-6.5/
tests-mx32/
prctl-arg2-intptr.c
       1  /*
       2   * Check decoding of prctl operations which use arg2 as a pointer to an integer
       3   * value: PR_GET_CHILD_SUBREAPER, PR_GET_ENDIAN, PR_GET_FPEMU, and PR_GET_FPEXC.
       4   *
       5   * Copyright (c) 2016 Eugene Syromyatnikov <evgsyr@gmail.com>
       6   * Copyright (c) 2016 Dmitry V. Levin <ldv@strace.io>
       7   * Copyright (c) 2016-2021 The strace developers.
       8   * All rights reserved.
       9   *
      10   * SPDX-License-Identifier: GPL-2.0-or-later
      11   */
      12  
      13  #include "tests.h"
      14  #include "scno.h"
      15  
      16  #include <stdint.h>
      17  #include <stdio.h>
      18  #include <unistd.h>
      19  #include <linux/prctl.h>
      20  
      21  static const char *errstr;
      22  
      23  static long
      24  prctl(kernel_ulong_t arg1, kernel_ulong_t arg2)
      25  {
      26  	static const kernel_ulong_t bogus_arg =
      27  		(kernel_ulong_t) 0xdeadbeefbadc0dedULL;
      28  	long rc = syscall(__NR_prctl, arg1, arg2, bogus_arg);
      29  	errstr = sprintrc(rc);
      30  	return rc;
      31  }
      32  
      33  int
      34  main(void)
      35  {
      36  	static const kernel_ulong_t bogus_addr1 =
      37  		(kernel_ulong_t) 0x1e55c0de00000000ULL;
      38  	static const kernel_ulong_t bogus_addr2 =
      39  		(kernel_ulong_t) 0xfffffffffffffffdULL;
      40  	static const kernel_ulong_t bogus_op_bits =
      41  		(kernel_ulong_t) 0xbadc0ded00000000ULL;
      42  	static const struct {
      43  		kernel_ulong_t val;
      44  		const char *str;
      45  	} options[] = {
      46  		{ 37, "PR_GET_CHILD_SUBREAPER" },
      47  		{ 19, "PR_GET_ENDIAN" },
      48  		{  9, "PR_GET_FPEMU" },
      49  		{ 11, "PR_GET_FPEXC" },
      50  	};
      51  
      52  	TAIL_ALLOC_OBJECT_CONST_PTR(unsigned int, ptr);
      53  	long rc;
      54  
      55  	prctl_marker();
      56  
      57  	for (unsigned int i = 0; i < ARRAY_SIZE(options); ++i) {
      58  		prctl(options[i].val | bogus_op_bits, 0);
      59  		printf("prctl(%s, NULL) = %s\n", options[i].str, errstr);
      60  
      61  		if (bogus_addr1) {
      62  			prctl(options[i].val | bogus_op_bits, bogus_addr1);
      63  			printf("prctl(%s, %#llx) = %s\n", options[i].str,
      64  			       (unsigned long long) bogus_addr1, errstr);
      65  		}
      66  
      67  		prctl(options[i].val | bogus_op_bits, bogus_addr2);
      68  		printf("prctl(%s, %#llx) = %s\n", options[i].str,
      69  		       (unsigned long long) bogus_addr2, errstr);
      70  
      71  		prctl(options[i].val | bogus_op_bits, (uintptr_t) (ptr + 1));
      72  		printf("prctl(%s, %p) = %s\n", options[i].str,
      73  		       ptr + 1, errstr);
      74  
      75  		rc = prctl(options[i].val | bogus_op_bits, (uintptr_t) ptr);
      76  		if (!rc) {
      77  			printf("prctl(%s, [%u]) = %s\n",
      78  			       options[i].str, *ptr, errstr);
      79  		} else {
      80  			printf("prctl(%s, %p) = %s\n",
      81  			       options[i].str, ptr, errstr);
      82  		}
      83  
      84  		if (F8ILL_KULONG_SUPPORTED) {
      85  			kernel_ulong_t bogus_addr3 = f8ill_ptr_to_kulong(ptr);
      86  			prctl(options[i].val | bogus_op_bits, bogus_addr3);
      87  			printf("prctl(%s, %#llx) = %s\n", options[i].str,
      88  			       (unsigned long long) bogus_addr3, errstr);
      89  		}
      90  	}
      91  
      92  	puts("+++ exited with 0 +++");
      93  	return 0;
      94  }