(root)/
strace-6.5/
tests-m32/
fchmodat2.c
       1  /*
       2   * Check decoding of fchmodat2 syscall.
       3   *
       4   * Copyright (c) 2016-2023 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 "secontext.h"
      13  
      14  #include <fcntl.h>
      15  #include <stdio.h>
      16  #include <unistd.h>
      17  
      18  #ifndef AT_SYMLINK_NOFOLLOW
      19  # define AT_SYMLINK_NOFOLLOW	0x100
      20  #endif
      21  #ifndef AT_EMPTY_PATH
      22  # define AT_EMPTY_PATH		0x1000
      23  #endif
      24  
      25  static const char *errstr;
      26  
      27  static long
      28  k_fchmodat2(const unsigned int dfd, const void *path,
      29  	    const unsigned short mode, const unsigned int flags)
      30  {
      31  	const kernel_ulong_t fill = (kernel_ulong_t) 0xbadc0ded00000000ULL;
      32  	const kernel_ulong_t fill_short = fill | 0xdead0000ULL;
      33  	const kernel_ulong_t arg1 = fill | dfd;
      34  	const kernel_ulong_t arg2 = (uintptr_t) path;
      35  	const kernel_ulong_t arg3 = fill_short | mode;
      36  	const kernel_ulong_t arg4 = fill | flags;
      37  	const kernel_ulong_t arg5 = fill | 0xdecaffed;
      38  	const kernel_ulong_t arg6 = fill | 0xdeefaced;
      39  	const long rc = syscall(__NR_fchmodat2,
      40  				arg1, arg2, arg3, arg4, arg5, arg6);
      41  	errstr = sprintrc(rc);
      42  	return rc;
      43  }
      44  
      45  int
      46  main(void)
      47  {
      48  	/*
      49  	 * Make sure the current workdir of the tracee
      50  	 * is different from the current workdir of the tracer.
      51  	 */
      52  	create_and_enter_subdir("fchmodat2_subdir");
      53  
      54  	char *my_secontext = SECONTEXT_PID_MY();
      55  
      56  	static const char sample[] = "fchmodat2_sample_file";
      57  	if (open(sample, O_RDONLY | O_CREAT, 0400) < 0)
      58  		perror_msg_and_fail("open");
      59  
      60  	char *sample_secontext = SECONTEXT_FILE(sample);
      61  
      62  	/*
      63  	 * Tests with AT_FDCWD.
      64  	 */
      65  
      66  	k_fchmodat2(-100, sample, 0600, 0);
      67  	printf("%s%s(%s, \"%s\"%s, 0600, 0) = %s\n",
      68  	       my_secontext, "fchmodat2", "AT_FDCWD",
      69  	       sample, sample_secontext, errstr);
      70  
      71  	if (unlink(sample))
      72  		perror_msg_and_fail("unlink");
      73  
      74  	k_fchmodat2(-100, sample, 051, AT_SYMLINK_NOFOLLOW);
      75  	printf("%s%s(%s, \"%s\", 051, AT_SYMLINK_NOFOLLOW) = %s\n",
      76  	       my_secontext, "fchmodat2", "AT_FDCWD", sample, errstr);
      77  
      78  	k_fchmodat2(-100, sample, 0700, AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH);
      79  	printf("%s%s(%s, \"%s\", 0700, AT_SYMLINK_NOFOLLOW|AT_EMPTY_PATH)"
      80  	       " = %s\n",
      81  	       my_secontext, "fchmodat2", "AT_FDCWD", sample, errstr);
      82  
      83  	k_fchmodat2(-100, sample, 004,
      84  		    -1U & ~(AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH));
      85  	printf("%s%s(%s, \"%s\", 004, 0xffffeeff /* AT_??? */) = %s\n",
      86  	       my_secontext, "fchmodat2", "AT_FDCWD", sample, errstr);
      87  
      88  	/*
      89  	 * Tests with dirfd.
      90  	 */
      91  
      92  	int cwd_fd = get_dir_fd(".");
      93  	char *cwd = get_fd_path(cwd_fd);
      94  	char *cwd_secontext = SECONTEXT_FILE(".");
      95  	char *sample_realpath = xasprintf("%s/%s", cwd, sample);
      96  
      97  	/* no file */
      98  	k_fchmodat2(cwd_fd, sample, 0400, 0);
      99  	printf("%s%s(%d%s, \"%s\", 0400, 0) = %s\n",
     100  	       my_secontext, "fchmodat2",
     101  	       cwd_fd, cwd_secontext, sample, errstr);
     102  
     103  	if (open(sample, O_RDONLY | O_CREAT, 0400) < 0)
     104  		perror_msg_and_fail("open");
     105  
     106  	k_fchmodat2(cwd_fd, sample, 0400, AT_SYMLINK_NOFOLLOW);
     107  	printf("%s%s(%d%s, \"%s\"%s, 0400, AT_SYMLINK_NOFOLLOW) = %s\n",
     108  	       my_secontext, "fchmodat2",
     109  	       cwd_fd, cwd_secontext, sample, sample_secontext, errstr);
     110  
     111  	/* cwd_fd ignored when path is absolute */
     112  	if (chdir("../.."))
     113  		perror_msg_and_fail("chdir");
     114  
     115  	k_fchmodat2(cwd_fd, sample_realpath, 0700, AT_EMPTY_PATH);
     116  	printf("%s%s(%d%s, \"%s\"%s, 0700, AT_EMPTY_PATH) = %s\n",
     117  	       my_secontext, "fchmodat2",
     118  	       cwd_fd, cwd_secontext,
     119  	       sample_realpath, sample_secontext, errstr);
     120  
     121  	if (fchdir(cwd_fd))
     122  		perror_msg_and_fail("fchdir");
     123  
     124  	if (unlink(sample))
     125  		perror_msg_and_fail("unlink");
     126  
     127  	leave_and_remove_subdir();
     128  
     129  	puts("+++ exited with 0 +++");
     130  	return 0;
     131  }