(root)/
strace-6.5/
tests/
modify_ldt.c
       1  /*
       2   * Check decoding of modify_ldt syscall.
       3   *
       4   * Copyright (c) 2018-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  
      12  #include "scno.h"
      13  
      14  #if defined __NR_modify_ldt && defined HAVE_STRUCT_USER_DESC
      15  
      16  # include <errno.h>
      17  # include <stdio.h>
      18  # include <unistd.h>
      19  
      20  # include "print_user_desc.c"
      21  
      22  static void
      23  printrc(long rc)
      24  {
      25  # ifdef __x86_64__
      26  	/*
      27  	 * Hopefully, we don't expect EPERM to be returned,
      28  	 * otherwise we can't distinguish it on x32.
      29  	 */
      30  	if (rc != -1) {
      31  		int err = -rc;
      32  
      33  		/* Thanks, long return type of syscall(2) */
      34  		printf("%lld", zero_extend_signed_to_ull(rc));
      35  
      36  		if (err > 0 && err < 0x1000) {
      37  			errno = err;
      38  			printf(" %s (%m)", errno2name());
      39  		}
      40  	}
      41  	else
      42  # endif
      43  	{
      44  		printf("%s", sprintrc(rc));
      45  	}
      46  
      47  	puts("");
      48  }
      49  
      50  int
      51  main(void)
      52  {
      53  	static const kernel_ulong_t bogus_func =
      54  		(kernel_ulong_t) 0xbadc0dedda7a1057ULL;
      55  	static const kernel_ulong_t bogus_bytecount =
      56  		(kernel_ulong_t) 0xdeadfacefa57beefULL;
      57  
      58  	TAIL_ALLOC_OBJECT_CONST_PTR(struct user_desc, us);
      59  	TAIL_ALLOC_OBJECT_CONST_PTR(unsigned int, bogus_int);
      60  	long rc;
      61  
      62  	fill_memory(us, sizeof(*us));
      63  
      64  	rc = syscall(__NR_modify_ldt, 0, 0, 0);
      65  	printf("modify_ldt(0, NULL, 0) = ");
      66  	printrc(rc);
      67  
      68  	rc = syscall(__NR_modify_ldt, bogus_func, (kernel_long_t) -1,
      69  		     bogus_bytecount);
      70  	printf("modify_ldt(%d, %#llx, %llu) = ",
      71  	       (int) bogus_func,
      72  	       zero_extend_signed_to_ull((kernel_long_t) -1),
      73  	       (unsigned long long) bogus_bytecount);
      74  	printrc(rc);
      75  
      76  	rc = syscall(__NR_modify_ldt, bogus_func, us + 1, 0);
      77  	printf("modify_ldt(%d, %p, 0) = ", (int) bogus_func, us + 1);
      78  	printrc(rc);
      79  
      80  	rc = syscall(__NR_modify_ldt, bogus_func, us, 42);
      81  	printf("modify_ldt(%d, %p, 42) = ", (int) bogus_func, us);
      82  	printrc(rc);
      83  
      84  	rc = syscall(__NR_modify_ldt, bogus_func, us + 1, sizeof(*us));
      85  	printf("modify_ldt(%d, %p, %zu) = ",
      86  	       (int) bogus_func, us + 1, sizeof(*us));
      87  	printrc(rc);
      88  
      89  	/*
      90  	 * print_user_desc handles entry_number field in a special way for
      91  	 * get_thread_area syscall, so let's also check here that we don't
      92  	 * retrieve it accidentally.
      93  	 */
      94  	rc = syscall(__NR_modify_ldt, bogus_func, bogus_int, sizeof(*us));
      95  	printf("modify_ldt(%d, %p, %zu) = ",
      96  	       (int) bogus_func, bogus_int, sizeof(*us));
      97  	printrc(rc);
      98  
      99  	rc = syscall(__NR_modify_ldt, bogus_func, us, sizeof(*us));
     100  	printf("modify_ldt(%d, ", (int) bogus_func);
     101  	print_user_desc(us, NULL);
     102  	printf(", %zu) = ", sizeof(*us));
     103  	printrc(rc);
     104  
     105  	fill_memory_ex(us, sizeof(*us), 0x55, 80);
     106  	us->entry_number = -1;
     107  	us->base_addr = 0;
     108  	us->limit = 0;
     109  
     110  	rc = syscall(__NR_modify_ldt, bogus_func, us, sizeof(*us));
     111  	printf("modify_ldt(%d, ", (int) bogus_func);
     112  	print_user_desc(us, "-1");
     113  	printf(", %zu) = ", sizeof(*us));
     114  	printrc(rc);
     115  
     116  	puts("+++ exited with 0 +++");
     117  
     118  	return 0;
     119  }
     120  
     121  #else
     122  
     123  SKIP_MAIN_UNDEFINED("__NR_modify_ldt && HAVE_STRUCT_USER_DESC");
     124  
     125  #endif