(root)/
strace-6.5/
tests-mx32/
openat2.c
       1  /*
       2   * Check decoding of openat2 syscall.
       3   *
       4   * Copyright (c) 2020-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  #include "scno.h"
      12  
      13  #include <errno.h>
      14  #include <stdint.h>
      15  #include <inttypes.h>
      16  #include <stdio.h>
      17  #include <string.h>
      18  #include <unistd.h>
      19  #include <linux/fcntl.h>
      20  
      21  #ifndef VERBOSE
      22  # define VERBOSE 0
      23  #endif
      24  #ifndef FD0_PATH
      25  # define FD0_PATH ""
      26  #else
      27  # define YFLAG
      28  #endif
      29  #ifndef SKIP_IF_PROC_IS_UNAVAILABLE
      30  # define SKIP_IF_PROC_IS_UNAVAILABLE
      31  #endif
      32  
      33  #ifdef YFLAG
      34  # define AT_FDCWD_FMT "<%s>"
      35  # define AT_FDCWD_ARG(arg) arg,
      36  #else
      37  # define AT_FDCWD_FMT
      38  # define AT_FDCWD_ARG(arg)
      39  #endif
      40  
      41  static const char sample[] = "openat2.sample";
      42  
      43  int
      44  main(void)
      45  {
      46  	SKIP_IF_PROC_IS_UNAVAILABLE;
      47  
      48  #ifdef YFLAG
      49  	char *cwd = get_fd_path(get_dir_fd("."));
      50  #endif
      51  	long rc;
      52  	const char *rcstr;
      53  	struct open_how *how = tail_alloc(sizeof(*how));
      54  	struct open_how *how_big = tail_alloc(sizeof(*how_big) + 8);
      55  
      56  	rc = syscall(__NR_openat2, 0, NULL, NULL,
      57  		     (kernel_ulong_t) 0xdeadc0debadc0dedULL);
      58  	printf("openat2(0" FD0_PATH ", NULL, NULL, %llu) = %s\n",
      59  	       (unsigned long long) (kernel_ulong_t) 0xdeadc0debadc0dedULL,
      60  	       sprintrc(rc));
      61  
      62  	rc = syscall(__NR_openat2, -100, "", how + 1, sizeof(*how));
      63  	printf("openat2(%s" AT_FDCWD_FMT ", \"\", %p, %zu) = %s\n",
      64  	       XLAT_KNOWN(-100, "AT_FDCWD"),
      65  	       AT_FDCWD_ARG(cwd)
      66  	       how + 1, sizeof(*how),
      67  	       sprintrc(rc));
      68  
      69  	rc = syscall(__NR_openat2, -1, sample, how, 11);
      70  	printf("openat2(-1, \"%s\", %p, 11) = %s\n", sample, how, sprintrc(rc));
      71  
      72  	static struct strval64 flags[] = {
      73  		{ ARG_STR(O_RDONLY|O_EXCL) },
      74  		{ ARG_STR(O_WRONLY|O_CREAT) },
      75  		{ ARG_STR(O_RDWR|O_LARGEFILE) },
      76  		{ ARG_STR(O_ACCMODE|O_TMPFILE) },
      77  		{ ARG_ULL_STR(O_RDONLY|0xdeadface80000000) },
      78  	};
      79  	static uint64_t modes[] = { 0, 0777, 0xbadc0dedfacebeefULL };
      80  	static struct strval64 resolve[] = {
      81  		{ 0, NULL },
      82  		{ ARG_STR(RESOLVE_NO_XDEV) },
      83  		{ ARG_ULL_STR(RESOLVE_NO_XDEV|RESOLVE_IN_ROOT|RESOLVE_CACHED|0xfeedfacedcaffec0) },
      84  		{ 0xdec0dedbeeffffc0, NULL },
      85  	};
      86  	const size_t iters = MAX(MAX(ARRAY_SIZE(flags), ARRAY_SIZE(modes)),
      87  				 ARRAY_SIZE(resolve));
      88  
      89  
      90  	for (size_t i = 0; i < iters * 4; i++) {
      91  		how->flags = flags[i % ARRAY_SIZE(flags)].val;
      92  		how->mode = modes[i % ARRAY_SIZE(modes)];
      93  		how->resolve = resolve[i % ARRAY_SIZE(resolve)].val;
      94  
      95  		fill_memory(how_big + 1, 8);
      96  		memcpy(how_big, how, sizeof(*how));
      97  
      98  		for (size_t j = 0; j < 4; j++) {
      99  			rc = syscall(__NR_openat2, -1, sample,
     100  				     j > 1 ? how_big : how,
     101  				     j ? sizeof(*how) + 8 : sizeof(*how));
     102  			rcstr = sprintrc(rc);
     103  			printf("openat2(-1, \"%s\", {flags=%s",
     104  			       sample,
     105  			       sprintxlat(flags[i % ARRAY_SIZE(flags)].str,
     106  					  flags[i % ARRAY_SIZE(flags)].val,
     107  					  NULL));
     108  
     109  			if (how->mode || (i % ARRAY_SIZE(flags) == 1)
     110  				      || (i % ARRAY_SIZE(flags) == 3)) {
     111  				printf(", mode=%#03" PRIo64,
     112  				       modes[i % ARRAY_SIZE(modes)]);
     113  			}
     114  
     115  			printf(", resolve=%s",
     116  			       sprintxlat(resolve[i % ARRAY_SIZE(resolve)].str,
     117  					  resolve[i % ARRAY_SIZE(resolve)].val,
     118  					  resolve[i % ARRAY_SIZE(resolve)].val
     119  						? "RESOLVE_???" : NULL));
     120  			if (j == 1)
     121  				printf(", ???");
     122  			if (j == 2) {
     123  				printf(", /* bytes %zu..%zu */ \"\\x80\\x81"
     124  				       "\\x82\\x83\\x84\\x85\\x86\\x87\"",
     125  				       sizeof(*how), sizeof(*how) + 7);
     126  			}
     127  			printf("}, %zu) = %s\n",
     128  			       j ? sizeof(*how) + 8 : sizeof(*how), rcstr);
     129  
     130  			if (j == 2)
     131  				memset(how_big + 1, 0, 8);
     132  		}
     133  	}
     134  
     135  	how->flags = O_RDONLY | O_NOCTTY;
     136  	how->mode = 0;
     137  	how->resolve = 0;
     138  	rc = syscall(__NR_openat2, -100, "/dev/full", how, sizeof(*how));
     139  	printf("openat2(%s" AT_FDCWD_FMT ", \"/dev/full\""
     140  	       ", {flags=%s, resolve=0}, %zu) = %s%s\n",
     141  	       XLAT_KNOWN(-100, "AT_FDCWD"),
     142  	       AT_FDCWD_ARG(cwd)
     143  	       XLAT_STR(O_RDONLY|O_NOCTTY),
     144  	       sizeof(*how), sprintrc(rc), rc >= 0 ? FD0_PATH : "");
     145  
     146  	puts("+++ exited with 0 +++");
     147  	return 0;
     148  }