(root)/
strace-6.5/
tests-mx32/
openat.c
       1  /*
       2   * Copyright (c) 2016 Katerina Koukiou <k.koukiou@gmail.com>
       3   * Copyright (c) 2016-2021 The strace developers.
       4   * All rights reserved.
       5   *
       6   * SPDX-License-Identifier: GPL-2.0-or-later
       7   */
       8  
       9  #include "tests.h"
      10  #include "scno.h"
      11  
      12  #ifdef __NR_openat
      13  
      14  # include <asm/fcntl.h>
      15  # include <stdio.h>
      16  # include <unistd.h>
      17  
      18  # include "secontext.h"
      19  
      20  # ifdef O_TMPFILE
      21  /* The kernel & C libraries often inline O_DIRECTORY. */
      22  #  define STRACE_O_TMPFILE (O_TMPFILE & ~O_DIRECTORY)
      23  # else
      24  #  define STRACE_O_TMPFILE 0
      25  # endif
      26  
      27  static const char sample[] = "openat.sample";
      28  
      29  static void
      30  test_mode_flag(unsigned int mode_val, const char *mode_str,
      31  	       unsigned int flag_val, const char *flag_str,
      32  	       const char *my_secontext)
      33  {
      34  	long rc = syscall(__NR_openat, -1, sample, mode_val | flag_val, 0);
      35  	printf("%s%s(-1, \"%s\", %s%s%s%s) = %s\n",
      36  	       my_secontext, "openat",
      37  	       sample, mode_str,
      38  	       flag_val ? "|" : "", flag_str,
      39  	       flag_val & (O_CREAT | STRACE_O_TMPFILE) ? ", 000" : "",
      40  	       sprintrc(rc));
      41  }
      42  
      43  int
      44  main(void)
      45  {
      46  	/*
      47  	 * Make sure the current workdir of the tracee
      48  	 * is different from the current workdir of the tracer.
      49  	 */
      50  	create_and_enter_subdir("openat_subdir");
      51  
      52  	char *my_secontext = SECONTEXT_PID_MY();
      53  	struct {
      54  		unsigned int val;
      55  		const char *str;
      56  	} modes[] = {
      57  		{ ARG_STR(O_RDONLY) },
      58  		{ ARG_STR(O_WRONLY) },
      59  		{ ARG_STR(O_RDWR) },
      60  		{ ARG_STR(O_ACCMODE) }
      61  	}, flags[] = {
      62  		{ ARG_STR(O_APPEND) },
      63  		{ ARG_STR(O_DIRECT) },
      64  		{ ARG_STR(O_DIRECTORY) },
      65  		{ ARG_STR(O_EXCL) },
      66  		{ ARG_STR(O_LARGEFILE) },
      67  		{ ARG_STR(O_NOATIME) },
      68  		{ ARG_STR(O_NOCTTY) },
      69  		{ ARG_STR(O_NOFOLLOW) },
      70  		{ ARG_STR(O_NONBLOCK) },
      71  		{ ARG_STR(O_SYNC) },
      72  		{ ARG_STR(O_TRUNC) },
      73  		{ ARG_STR(O_CREAT) },
      74  # ifdef O_CLOEXEC
      75  		{ ARG_STR(O_CLOEXEC) },
      76  # endif
      77  # ifdef O_DSYNC
      78  		{ ARG_STR(O_DSYNC) },
      79  # endif
      80  # ifdef __O_SYNC
      81  		{ ARG_STR(__O_SYNC) },
      82  # endif
      83  # ifdef O_PATH
      84  		{ ARG_STR(O_PATH) },
      85  # endif
      86  # ifdef O_TMPFILE
      87  		{ ARG_STR(O_TMPFILE) },
      88  # endif
      89  # ifdef __O_TMPFILE
      90  		{ ARG_STR(__O_TMPFILE) },
      91  # endif
      92  		{ ARG_STR(0x80000000) },
      93  		{ 0, "" }
      94  	};
      95  
      96  	for (unsigned int m = 0; m < ARRAY_SIZE(modes); ++m)
      97  		for (unsigned int f = 0; f < ARRAY_SIZE(flags); ++f)
      98  			test_mode_flag(modes[m].val, modes[m].str,
      99  				       flags[f].val, flags[f].str,
     100  				       my_secontext);
     101  
     102  	/*
     103  	 * Tests with AT_FDCWD.
     104  	 */
     105  
     106  	(void) unlink(sample);
     107  	long fd = syscall(__NR_openat, -100, sample, O_RDONLY|O_CREAT, 0400);
     108  
     109  	char *sample_secontext = SECONTEXT_FILE(sample);
     110  
     111  	/*
     112  	 * File context in openat() is not displayed because file doesn't exist
     113  	 * yet, but is displayed in return value since the file got created.
     114  	 */
     115  	printf("%s%s(AT_FDCWD, \"%s\", O_RDONLY|O_CREAT, 0400) = %s%s\n",
     116  	       my_secontext, "openat",
     117  	       sample,
     118  	       sprintrc(fd), sample_secontext);
     119  
     120  	close(fd);
     121  
     122  	fd = syscall(__NR_openat, -100, sample, O_RDONLY);
     123  	printf("%s%s(AT_FDCWD, \"%s\"%s, O_RDONLY) = %s%s\n",
     124  	       my_secontext, "openat",
     125  	       sample, sample_secontext,
     126  	       sprintrc(fd), sample_secontext);
     127  	if (fd != -1) {
     128  		close(fd);
     129  		if (unlink(sample))
     130  			perror_msg_and_fail("unlink");
     131  	}
     132  
     133  	/*
     134  	 * Tests with dirfd.
     135  	 */
     136  
     137  	int cwd_fd = get_dir_fd(".");
     138  	char *cwd_secontext = SECONTEXT_FILE(".");
     139  
     140  	fd = syscall(__NR_openat, cwd_fd, sample, O_RDONLY|O_CREAT, 0400);
     141  	if (fd == -1)
     142  		perror_msg_and_fail("openat");
     143  	close(fd);
     144  
     145  	/*
     146  	 * File context in openat() is not displayed because file doesn't exist
     147  	 * yet, but is displayed in return value since the file got created.
     148  	 */
     149  	printf("%s%s(%d%s, \"%s\", O_RDONLY|O_CREAT, 0400) = %s%s\n",
     150  	       my_secontext, "openat",
     151  	       cwd_fd, cwd_secontext,
     152  	       sample,
     153  	       sprintrc(fd), sample_secontext);
     154  
     155  	fd = syscall(__NR_openat, cwd_fd, sample, O_RDONLY);
     156  	printf("%s%s(%d%s, \"%s\"%s, O_RDONLY) = %s%s\n",
     157  	       my_secontext, "openat",
     158  	       cwd_fd, cwd_secontext,
     159  	       sample, sample_secontext,
     160  	       sprintrc(fd), sample_secontext);
     161  	if (fd != -1) {
     162  		close(fd);
     163  		if (unlink(sample))
     164  			perror_msg_and_fail("unlink");
     165  	}
     166  
     167  	leave_and_remove_subdir();
     168  
     169  	puts("+++ exited with 0 +++");
     170  	return 0;
     171  }
     172  
     173  #else
     174  
     175  SKIP_MAIN_UNDEFINED("__NR_openat")
     176  
     177  #endif