(root)/
strace-6.5/
tests-m32/
setresugid.c
       1  /*
       2   * Check decoding of setresuid/setresgid/setresuid32/setresgid32 syscalls.
       3   *
       4   * Copyright (c) 2016-2021 Dmitry V. Levin <ldv@strace.io>
       5   * All rights reserved.
       6   *
       7   * SPDX-License-Identifier: GPL-2.0-or-later
       8   */
       9  
      10  #include <errno.h>
      11  #include <stdio.h>
      12  #include <unistd.h>
      13  
      14  static int
      15  ugid2int(const unsigned UGID_TYPE ugid)
      16  {
      17  	if ((unsigned UGID_TYPE) -1U == ugid)
      18  		return -1;
      19  	else
      20  		return ugid;
      21  }
      22  
      23  static void
      24  print_int(const unsigned int num)
      25  {
      26  	if (num == -1U)
      27  		printf("-1");
      28  	else
      29  		printf("%u", num);
      30  }
      31  
      32  static int
      33  num_matches_id(const unsigned int num, const unsigned int ugid)
      34  {
      35  	return num == ugid || num == -1U;
      36  }
      37  
      38  #define TRIPLE(val)	\
      39  	{ val, ugid, ugid }, { ugid, val, ugid }, { ugid, ugid, val }
      40  
      41  int
      42  main(void)
      43  {
      44  	unsigned int ugid = GETUGID;
      45  	CHECK_OVERFLOWUGID(ugid);
      46  
      47  	const struct {
      48  		const long r, e, s;
      49  	} tests[] = {
      50  		{ ugid, ugid, ugid },
      51  		TRIPLE((unsigned long) 0xffffffff00000000ULL | ugid),
      52  		TRIPLE(-1U),
      53  		TRIPLE(-1L),
      54  		TRIPLE(0xffff0000U | ugid),
      55  		TRIPLE(0xffff),
      56  		TRIPLE(0xc0deffffU)
      57  	};
      58  
      59  	for (unsigned int i = 0; i < ARRAY_SIZE(tests); ++i) {
      60  		const unsigned int rn = ugid2int(tests[i].r);
      61  		const unsigned int en = ugid2int(tests[i].e);
      62  		const unsigned int sn = ugid2int(tests[i].s);
      63  
      64  		if (!num_matches_id(rn, ugid) ||
      65  		    !num_matches_id(en, ugid) ||
      66  		    !num_matches_id(sn, ugid))
      67  			continue;
      68  
      69  		if (syscall(SYSCALL_NR, tests[i].r, tests[i].e, tests[i].s)) {
      70  			if (!i && ENOSYS == errno) {
      71  				printf("%s(%u, %u, %u) = -1 ENOSYS (%m)\n",
      72  				       SYSCALL_NAME, ugid, ugid, ugid);
      73  				break;
      74  			}
      75  			perror_msg_and_fail("%s(%#lx, %#lx, %#lx)",
      76  					    SYSCALL_NAME,
      77  					    tests[i].r, tests[i].e, tests[i].s);
      78  		}
      79  
      80  		printf("%s(", SYSCALL_NAME);
      81  		print_int(rn);
      82  		printf(", ");
      83  		print_int(en);
      84  		printf(", ");
      85  		print_int(sn);
      86  		printf(") = 0\n");
      87  	}
      88  
      89  	puts("+++ exited with 0 +++");
      90  	return 0;
      91  }