(root)/
strace-6.5/
tests-m32/
fanotify_mark.c
       1  /*
       2   * Check decoding of fanotify_mark syscall.
       3   *
       4   * Copyright (c) 2015-2016 Dmitry V. Levin <ldv@strace.io>
       5   * Copyright (c) 2016 Eugene Syromyatnikov <evgsyr@gmail.com>
       6   * Copyright (c) 2015-2023 The strace developers.
       7   * All rights reserved.
       8   *
       9   * SPDX-License-Identifier: GPL-2.0-or-later
      10   */
      11  
      12  #include "tests.h"
      13  #include "scno.h"
      14  
      15  #if defined HAVE_SYS_FANOTIFY_H && defined HAVE_FANOTIFY_MARK
      16  
      17  # include <limits.h>
      18  # include <stdint.h>
      19  # include <stdio.h>
      20  # include <unistd.h>
      21  # include <sys/fanotify.h>
      22  
      23  # include "secontext.h"
      24  
      25  # if XLAT_RAW
      26  #  define str_fan_mark_add	"0x1"
      27  #  define str_fan_modify_ondir	"0x40000002"
      28  #  define str_at_fdcwd		"-100"
      29  # elif XLAT_VERBOSE
      30  #  define str_fan_mark_add	"0x1 /* FAN_MARK_ADD */"
      31  #  define str_fan_modify_ondir	"0x40000002 /* FAN_MODIFY|FAN_ONDIR */"
      32  #  define str_at_fdcwd		"-100 /* AT_FDCWD */"
      33  # else
      34  #  define str_fan_mark_add	"FAN_MARK_ADD"
      35  #  define str_fan_modify_ondir	"FAN_MODIFY|FAN_ONDIR"
      36  #  define str_at_fdcwd		"AT_FDCWD"
      37  # endif
      38  
      39  # ifndef TEST_SECONTEXT
      40  /* Performs fanotify_mark call via the syscall interface. */
      41  static void
      42  do_call(kernel_ulong_t fd, kernel_ulong_t flags, const char *flags_str,
      43  	uint64_t mask, const char *mask_str, kernel_ulong_t dirfd,
      44  	const char *dirfd_str, kernel_ulong_t path, const char *path_str)
      45  {
      46  	long rc;
      47  
      48  	rc = syscall(__NR_fanotify_mark, fd, flags,
      49  #  if (LONG_MAX > INT_MAX) \
      50     || (defined __x86_64__ && defined __ILP32__) \
      51     || defined LINUX_MIPSN32
      52  		mask,
      53  #  else
      54  		LL_VAL_TO_PAIR(mask),
      55  #  endif
      56  		dirfd, path);
      57  
      58  	printf("fanotify_mark(%d, %s, %s, %s, %s) = %s\n",
      59  	       (int) fd, flags_str, mask_str, dirfd_str, path_str,
      60  	       sprintrc(rc));
      61  }
      62  
      63  struct strval {
      64  	kernel_ulong_t val;
      65  	const char *str;
      66  };
      67  
      68  #  define STR16 "0123456789abcdef"
      69  #  define STR64 STR16 STR16 STR16 STR16
      70  # endif /* !TEST_SECONTEXT */
      71  
      72  int
      73  main(void)
      74  {
      75  # ifndef TEST_SECONTEXT
      76  	enum {
      77  		PATH1_SIZE = 64,
      78  	};
      79  
      80  	static const kernel_ulong_t fds[] = {
      81  		(kernel_ulong_t) 0xdeadfeed12345678ULL,
      82  		F8ILL_KULONG_MASK,
      83  		(kernel_ulong_t) 0xdeb0d1edffffffffULL,
      84  	};
      85  	static const struct strval flags[] = {
      86  		{ F8ILL_KULONG_MASK, "0" },
      87  		{ (kernel_ulong_t) 0xdec0deddeface800ULL,
      88  			"0xeface800"
      89  #  if !XLAT_RAW
      90  			" /* FAN_MARK_??? */"
      91  #  endif
      92  			},
      93  		{ (kernel_ulong_t) 0xda7a105700000040ULL,
      94  #  if XLAT_RAW
      95  			"0x40"
      96  #  elif XLAT_VERBOSE
      97  			"0x40 /* FAN_MARK_IGNORED_SURV_MODIFY */"
      98  #  else
      99  			"FAN_MARK_IGNORED_SURV_MODIFY"
     100  #  endif
     101  			},
     102  		{ (kernel_ulong_t) 0xbadc0deddeadffffULL,
     103  #  if XLAT_RAW || XLAT_VERBOSE
     104  			"0xdeadffff"
     105  #  endif
     106  #  if XLAT_VERBOSE
     107  			" /* "
     108  #  endif
     109  #  if !XLAT_RAW
     110  			"FAN_MARK_ADD|FAN_MARK_REMOVE|FAN_MARK_DONT_FOLLOW|"
     111  			"FAN_MARK_ONLYDIR|FAN_MARK_MOUNT|FAN_MARK_IGNORED_MASK|"
     112  			"FAN_MARK_IGNORED_SURV_MODIFY|FAN_MARK_FLUSH|"
     113  			"FAN_MARK_FILESYSTEM|FAN_MARK_EVICTABLE|"
     114  			"FAN_MARK_IGNORE|0xdeadf800"
     115  #  endif
     116  #  if XLAT_VERBOSE
     117  			" */"
     118  #  endif
     119  			},
     120  	};
     121  	static const struct strval64 masks[] = {
     122  		{ ARG_ULL_STR(0) },
     123  		{ 0xdeadfeedffffffffULL,
     124  #  if XLAT_RAW || XLAT_VERBOSE
     125  			"0xdeadfeedffffffff"
     126  #  endif
     127  #  if XLAT_VERBOSE
     128  			" /* "
     129  #  endif
     130  #  if !XLAT_RAW
     131  			"FAN_ACCESS|"
     132  			"FAN_MODIFY|"
     133  			"FAN_ATTRIB|"
     134  			"FAN_CLOSE_WRITE|"
     135  			"FAN_CLOSE_NOWRITE|"
     136  			"FAN_OPEN|"
     137  			"FAN_MOVED_FROM|"
     138  			"FAN_MOVED_TO|"
     139  			"FAN_CREATE|"
     140  			"FAN_DELETE|"
     141  			"FAN_DELETE_SELF|"
     142  			"FAN_MOVE_SELF|"
     143  			"FAN_OPEN_EXEC|"
     144  			"FAN_Q_OVERFLOW|"
     145  			"FAN_FS_ERROR|"
     146  			"FAN_OPEN_PERM|"
     147  			"FAN_ACCESS_PERM|"
     148  			"FAN_OPEN_EXEC_PERM|"
     149  			"FAN_DIR_MODIFY|"
     150  			"FAN_ONDIR|"
     151  			"FAN_EVENT_ON_CHILD|"
     152  			"FAN_RENAME|"
     153  			"0xdeadfeeda7f02000"
     154  #  endif
     155  #  if XLAT_VERBOSE
     156  			" */"
     157  #  endif
     158  			},
     159  		{ ARG_ULL_STR(0xffffffffa7f02000)
     160  #  if !XLAT_RAW
     161  			" /* FAN_??? */"
     162  #  endif
     163  			},
     164  	};
     165  	static const struct strval dirfds[] = {
     166  		{ (kernel_ulong_t) 0xfacefeed00000001ULL, "1" },
     167  		{ (kernel_ulong_t) 0xdec0ded0ffffffffULL,
     168  #  if XLAT_RAW
     169  			"-1"
     170  #  elif XLAT_VERBOSE
     171  			"-1 /* FAN_NOFD */"
     172  #  else
     173  			"FAN_NOFD"
     174  #  endif
     175  			},
     176  		{ (kernel_ulong_t) 0xbadfacedffffff9cULL, str_at_fdcwd },
     177  		{ (kernel_ulong_t) 0xdefaced1beeff00dULL, "-1091571699" },
     178  	};
     179  	static const char str64[] = STR64;
     180  
     181  	static char bogus_path1_addr[sizeof("0x") + sizeof(void *) * 2];
     182  	static char bogus_path1_after_addr[sizeof("0x") + sizeof(void *) * 2];
     183  
     184  	char *bogus_path1 = tail_memdup(str64, PATH1_SIZE);
     185  	char *bogus_path2 = tail_memdup(str64, sizeof(str64));
     186  
     187  	struct strval paths[] = {
     188  		{ (kernel_ulong_t) 0, "NULL" },
     189  		{ (kernel_ulong_t) (uintptr_t) (bogus_path1 + PATH1_SIZE),
     190  			bogus_path1_after_addr },
     191  		{ (kernel_ulong_t) (uintptr_t) bogus_path1, bogus_path1_addr },
     192  		{ (kernel_ulong_t) (uintptr_t) bogus_path2, "\"" STR64 "\"" },
     193  	};
     194  
     195  	snprintf(bogus_path1_addr, sizeof(bogus_path1_addr), "%p", bogus_path1);
     196  	snprintf(bogus_path1_after_addr, sizeof(bogus_path1_after_addr), "%p",
     197  		bogus_path1 + PATH1_SIZE);
     198  
     199  	for (unsigned int i = 0;
     200  	     i < ARRAY_SIZE(fds); ++i) {
     201  		for (unsigned int j = 0;
     202  		     j < ARRAY_SIZE(flags); ++j) {
     203  			for (unsigned int k = 0;
     204  			     k < ARRAY_SIZE(masks); ++k) {
     205  				for (unsigned int l = 0;
     206  				     l < ARRAY_SIZE(dirfds); ++l) {
     207  					for (unsigned int m = 0;
     208  					     m < ARRAY_SIZE(paths); ++m)
     209  						do_call(fds[i],
     210  							flags[j].val,
     211  							flags[j].str,
     212  							masks[k].val,
     213  							masks[k].str,
     214  							dirfds[l].val,
     215  							dirfds[l].str,
     216  							paths[m].val,
     217  							paths[m].str);
     218  				}
     219  			}
     220  		}
     221  	}
     222  # endif
     223  	/*
     224  	 * Test with AT_FDCWD.
     225  	 */
     226  
     227  	char *my_secontext = SECONTEXT_PID_MY();
     228  	char path[] = ".";
     229  	char *path_secontext = SECONTEXT_FILE(path);
     230  
     231  	int rc = fanotify_mark(-1, FAN_MARK_ADD, FAN_MODIFY | FAN_ONDIR,
     232  			   -100, path);
     233  	printf("%s%s(-1, %s, %s, %s, \"%s\"%s) = %s\n",
     234  	       my_secontext, "fanotify_mark",
     235  	       str_fan_mark_add, str_fan_modify_ondir, str_at_fdcwd,
     236  	       path, path_secontext,
     237  	       sprintrc(rc));
     238  
     239  	/*
     240  	 * Test with dirfd.
     241  	 */
     242  
     243  	int cwd_fd = get_dir_fd(".");
     244  	char *cwd_secontext = SECONTEXT_FILE(".");
     245  
     246  	rc = fanotify_mark(-1, FAN_MARK_ADD, FAN_MODIFY | FAN_ONDIR,
     247  			   cwd_fd, path);
     248  	printf("%s%s(-1, %s, %s, %d%s, \"%s\"%s) = %s\n",
     249  	       my_secontext, "fanotify_mark",
     250  	       str_fan_mark_add, str_fan_modify_ondir,
     251  	       cwd_fd, cwd_secontext,
     252  	       path, path_secontext,
     253  	       sprintrc(rc));
     254  
     255  	puts("+++ exited with 0 +++");
     256  	return 0;
     257  }
     258  
     259  #else
     260  
     261  SKIP_MAIN_UNDEFINED("HAVE_SYS_FANOTIFY_H && HAVE_FANOTIFY_MARK")
     262  
     263  #endif