(root)/
strace-6.5/
tests-mx32/
landlock_create_ruleset.c
       1  /*
       2   * Check decoding of landlock_create_ruleset syscall.
       3   *
       4   * Copyright (c) 2021 Eugene Syromyatnikov <evgsyr@gmail.com>
       5   * Copyright (c) 2021-2023 The strace developers.
       6   * All rights reserved.
       7   *
       8   * SPDX-License-Identifier: GPL-2.0-or-later
       9   */
      10  
      11  #include "tests.h"
      12  #include "scno.h"
      13  #include "xmalloc.h"
      14  
      15  #include <inttypes.h>
      16  #include <stdio.h>
      17  #include <stdint.h>
      18  #include <stdlib.h>
      19  #include <unistd.h>
      20  
      21  #include <linux/landlock.h>
      22  
      23  #ifndef RETVAL_INJECTED
      24  # define RETVAL_INJECTED 0
      25  #endif
      26  #ifndef DECODE_FD
      27  # define DECODE_FD 0
      28  #endif
      29  
      30  #ifndef SKIP_IF_PROC_IS_UNAVAILABLE
      31  # define SKIP_IF_PROC_IS_UNAVAILABLE
      32  #endif
      33  #ifndef FD_PATH
      34  # define FD_PATH ""
      35  #endif
      36  
      37  #if RETVAL_INJECTED
      38  # define INJ_STR " (INJECTED)\n"
      39  # define INJ_FD_STR FD_PATH " (INJECTED)\n"
      40  #else /* !RETVAL_INJECTED */
      41  # define INJ_STR "\n"
      42  # define INJ_FD_STR "\n"
      43  #endif /* RETVAL_INJECTED */
      44  
      45  static const char *errstr;
      46  
      47  static long
      48  sys_landlock_create_ruleset(struct landlock_ruleset_attr *attr,
      49  			    kernel_ulong_t size, unsigned int flags)
      50  
      51  {
      52  	static const kernel_ulong_t fill =
      53  		(kernel_ulong_t) 0xd1efaced00000000ULL;
      54  	kernel_ulong_t arg1 = (uintptr_t) attr;
      55  	kernel_ulong_t arg2 = size;
      56  	kernel_ulong_t arg3 = fill | flags;
      57  	kernel_ulong_t arg4 = fill | 0xbadbeefd;
      58  	kernel_ulong_t arg5 = fill | 0xdecaffed;
      59  	kernel_ulong_t arg6 = fill | 0xdeefaced;
      60  
      61  	long rc = syscall(__NR_landlock_create_ruleset,
      62  			  arg1, arg2, arg3, arg4, arg5, arg6);
      63  	errstr = sprintrc(rc);
      64  	return rc;
      65  }
      66  
      67  int
      68  main(void)
      69  {
      70  	static const kernel_ulong_t bogus_size =
      71  		(kernel_ulong_t) 0xbadfaceddecaffee;
      72  
      73  	SKIP_IF_PROC_IS_UNAVAILABLE;
      74  
      75  	TAIL_ALLOC_OBJECT_VAR_PTR(struct landlock_ruleset_attr, attr);
      76  	long rc;
      77  
      78  	/* All zeroes */
      79  	rc = sys_landlock_create_ruleset(NULL, 0, 0);
      80  	printf("landlock_create_ruleset(NULL, 0, 0) = %s" INJ_FD_STR,
      81  	       errstr);
      82  
      83  	/* Get ABI version */
      84  	rc = sys_landlock_create_ruleset(NULL, 0, 1);
      85  	printf("landlock_create_ruleset(NULL, 0"
      86  	       ", LANDLOCK_CREATE_RULESET_VERSION) = %s" INJ_STR, errstr);
      87  
      88  	/* ilp32 check */
      89  	rc = syscall(__NR_landlock_create_ruleset,
      90  		     (kernel_ulong_t) 0xffFFffFF00000000,
      91  		     (kernel_ulong_t) 0xdefeededdeadface,
      92  		     (kernel_ulong_t) 0xbadc0dedbadfaced);
      93  	printf("landlock_create_ruleset("
      94  #if SIZEOF_KERNEL_LONG_T > 4
      95  	       "%#llx"
      96  #else
      97  	       "NULL"
      98  #endif
      99  	       ", %llu, LANDLOCK_CREATE_RULESET_VERSION|%#x) = %s" INJ_STR,
     100  #if SIZEOF_KERNEL_LONG_T > 4
     101  	       (unsigned long long) (kernel_ulong_t) 0xffFFffFF00000000,
     102  #endif
     103  	       (unsigned long long) (kernel_ulong_t) 0xdefeededdeadface,
     104  	       0xbadfacec, sprintrc(rc));
     105  
     106  	/* Bogus addr, size, flags */
     107  	rc = sys_landlock_create_ruleset(attr + 1, bogus_size, 0xbadcaffe);
     108  	printf("landlock_create_ruleset(%p, %llu"
     109  	       ", 0xbadcaffe /* LANDLOCK_CREATE_RULESET_??? */) = %s"
     110  	       INJ_FD_STR,
     111  	       attr + 1, (unsigned long long) bogus_size, errstr);
     112  
     113  	/* Size is too small */
     114  	for (size_t i = 0; i < 8; i++) {
     115  		rc = sys_landlock_create_ruleset(attr, i, 0);
     116  		printf("landlock_create_ruleset(%p, %zu, 0) = %s" INJ_FD_STR,
     117  		       attr, i, errstr);
     118  	}
     119  
     120  	/* Perform syscalls with valid attr ptr */
     121  	static const struct {
     122  		uint64_t val;
     123  		const char *str;
     124  	} attr_vals[] = {
     125  		{ ARG_STR(LANDLOCK_ACCESS_FS_EXECUTE) },
     126  		{ ARG_ULL_STR(LANDLOCK_ACCESS_FS_EXECUTE|LANDLOCK_ACCESS_FS_READ_FILE|LANDLOCK_ACCESS_FS_READ_DIR|LANDLOCK_ACCESS_FS_REMOVE_FILE|LANDLOCK_ACCESS_FS_MAKE_CHAR|LANDLOCK_ACCESS_FS_MAKE_DIR|LANDLOCK_ACCESS_FS_MAKE_SOCK|LANDLOCK_ACCESS_FS_MAKE_FIFO|LANDLOCK_ACCESS_FS_MAKE_BLOCK|LANDLOCK_ACCESS_FS_MAKE_SYM|LANDLOCK_ACCESS_FS_REFER|LANDLOCK_ACCESS_FS_TRUNCATE|0xdebeefeddeca8000) },
     127  		{ ARG_ULL_STR(0xdebeefeddeca8000)
     128  			" /* LANDLOCK_ACCESS_FS_??? */" },
     129  	};
     130  	static const kernel_ulong_t sizes[] = { 8, 12, 16 };
     131  	for (size_t i = 0; i < ARRAY_SIZE(attr_vals); i++) {
     132  		for (size_t j = 0; j < ARRAY_SIZE(sizes); j++) {
     133  			const char *fd_str = FD_PATH;
     134  
     135  			attr->handled_access_fs = attr_vals[i].val;
     136  			rc = sys_landlock_create_ruleset(attr, sizes[j], 0);
     137  
     138  #if DECODE_FD
     139  			/*
     140  			 * The ABI has been broken in commit v5.18-rc1~88^2
     141  			 * by adding brackets to the link value, hence, we can't
     142  			 * rely on a specific name anymore and have to fetch it
     143  			 * ourselves.
     144  			 */
     145  			if (rc >= 0) {
     146  				static char buf[256];
     147  				char *path = xasprintf("/proc/self/fd/%ld", rc);
     148  				ssize_t ret = readlink(path, buf + 1,
     149  						       sizeof(buf) - 3);
     150  				free(path);
     151  
     152  				if (ret >= 0) {
     153  					buf[0] = '<';
     154  					buf[ret + 1] = '>';
     155  					buf[ret + 2] = '\0';
     156  					fd_str = buf;
     157  				}
     158  			}
     159  #endif
     160  
     161  			printf("landlock_create_ruleset({handled_access_fs=%s"
     162  			       "%s}, %llu, 0) = %s%s" INJ_STR,
     163  			       attr_vals[i].str,
     164  			       sizes[j] > sizeof(*attr) ? ", ..." : "",
     165  			       (unsigned long long) sizes[j],
     166  			       errstr, rc >= 0 ? fd_str : "");
     167  		}
     168  	}
     169  
     170  	puts("+++ exited with 0 +++");
     171  	return 0;
     172  }