• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) 2012 Linux Test Project.  All Rights Reserved.
4  * Author: Jan Kara, November 2013
5  */
6 
7 #ifndef	__FANOTIFY_H__
8 #define	__FANOTIFY_H__
9 
10 #include "config.h"
11 #include <sys/statfs.h>
12 #include <sys/types.h>
13 #include <sys/stat.h>
14 #include <errno.h>
15 #include <fcntl.h>
16 
17 #if defined(HAVE_SYS_FANOTIFY_H)
18 
19 #include <sys/fanotify.h>
20 
21 #else /* HAVE_SYS_FANOTIFY_H */
22 
23 /* fanotify(7) wrappers */
24 
25 #include <stdint.h>
26 #include "lapi/syscalls.h"
27 
fanotify_init(unsigned int flags,unsigned int event_f_flags)28 static int fanotify_init(unsigned int flags, unsigned int event_f_flags)
29 {
30 	return syscall(__NR_fanotify_init, flags, event_f_flags);
31 }
32 
fanotify_mark(int fd,unsigned int flags,uint64_t mask,int dfd,const char * pathname)33 static long fanotify_mark(int fd, unsigned int flags, uint64_t mask,
34                      int dfd, const char *pathname)
35 {
36 	return syscall(__NR_fanotify_mark, fd, flags, mask, dfd, pathname);
37 }
38 
39 #endif /* HAVE_SYS_FANOTIFY_H */
40 
41 #ifndef FAN_REPORT_TID
42 #define FAN_REPORT_TID		0x00000100
43 #endif
44 #ifndef FAN_REPORT_FID
45 #define FAN_REPORT_FID		0x00000200
46 #endif
47 
48 #ifndef FAN_MARK_INODE
49 #define FAN_MARK_INODE		0
50 #endif
51 #ifndef FAN_MARK_FILESYSTEM
52 #define FAN_MARK_FILESYSTEM	0x00000100
53 #endif
54 /* New dirent event masks */
55 #ifndef FAN_ATTRIB
56 #define FAN_ATTRIB		0x00000004
57 #endif
58 #ifndef FAN_MOVED_FROM
59 #define FAN_MOVED_FROM		0x00000040
60 #endif
61 #ifndef FAN_MOVED_TO
62 #define FAN_MOVED_TO		0x00000080
63 #endif
64 #ifndef FAN_CREATE
65 #define FAN_CREATE		0x00000100
66 #endif
67 #ifndef FAN_DELETE
68 #define FAN_DELETE		0x00000200
69 #endif
70 #ifndef FAN_DELETE_SELF
71 #define FAN_DELETE_SELF		0x00000400
72 #endif
73 #ifndef FAN_MOVE_SELF
74 #define FAN_MOVE_SELF		0x00000800
75 #endif
76 #ifndef FAN_MOVE
77 #define FAN_MOVE		(FAN_MOVED_FROM | FAN_MOVED_TO)
78 #endif
79 #ifndef FAN_OPEN_EXEC
80 #define FAN_OPEN_EXEC		0x00001000
81 #endif
82 #ifndef FAN_OPEN_EXEC_PERM
83 #define FAN_OPEN_EXEC_PERM	0x00040000
84 #endif
85 #ifndef FAN_DIR_MODIFY
86 #define FAN_DIR_MODIFY		0x00080000
87 #endif
88 
89 /*
90  * FAN_ALL_PERM_EVENTS has been deprecated, so any new permission events
91  * are not to be added to it. To cover the instance where a new permission
92  * event is defined, we create a new macro that is to include all
93  * permission events. Any new permission events should be added to this
94  * macro.
95  */
96 #define LTP_ALL_PERM_EVENTS	(FAN_OPEN_PERM | FAN_OPEN_EXEC_PERM | \
97 				 FAN_ACCESS_PERM)
98 
99 struct fanotify_mark_type {
100 	unsigned int flag;
101 	const char * name;
102 };
103 
104 #ifndef __kernel_fsid_t
105 typedef struct {
106 	int	val[2];
107 } lapi_fsid_t;
108 #define __kernel_fsid_t lapi_fsid_t
109 #endif /* __kernel_fsid_t */
110 
111 #ifndef FAN_EVENT_INFO_TYPE_FID
112 #define FAN_EVENT_INFO_TYPE_FID		1
113 #endif
114 #ifndef FAN_EVENT_INFO_TYPE_DFID_NAME
115 #define FAN_EVENT_INFO_TYPE_DFID_NAME	2
116 #endif
117 
118 #ifndef HAVE_STRUCT_FANOTIFY_EVENT_INFO_HEADER
119 struct fanotify_event_info_header {
120 	uint8_t info_type;
121 	uint8_t pad;
122 	uint16_t len;
123 };
124 #endif /* HAVE_STRUCT_FANOTIFY_EVENT_INFO_HEADER */
125 
126 #ifndef HAVE_STRUCT_FANOTIFY_EVENT_INFO_FID
127 struct fanotify_event_info_fid {
128 	struct fanotify_event_info_header hdr;
129 	__kernel_fsid_t fsid;
130 	unsigned char handle[0];
131 };
132 #endif /* HAVE_STRUCT_FANOTIFY_EVENT_INFO_FID */
133 
134 /* NOTE: only for struct fanotify_event_info_fid */
135 #ifdef HAVE_STRUCT_FANOTIFY_EVENT_INFO_FID_FSID___VAL
136 # define FSID_VAL_MEMBER(fsid, i) (fsid.__val[i])
137 #else
138 # define FSID_VAL_MEMBER(fsid, i) (fsid.val[i])
139 #endif /* HAVE_STRUCT_FANOTIFY_EVENT_INFO_FID_FSID___VAL */
140 
141 #ifdef HAVE_NAME_TO_HANDLE_AT
142 /*
143  * Helper function used to obtain fsid and file_handle for a given path.
144  * Used by test files correlated to FAN_REPORT_FID functionality.
145  */
fanotify_get_fid(const char * path,__kernel_fsid_t * fsid,struct file_handle * handle)146 static inline void fanotify_get_fid(const char *path, __kernel_fsid_t *fsid,
147 				    struct file_handle *handle)
148 {
149 	int mount_id;
150 	struct statfs stats;
151 
152 	if (statfs(path, &stats) == -1)
153 		tst_brk(TBROK | TERRNO,
154 			"statfs(%s, ...) failed", path);
155 	memcpy(fsid, &stats.f_fsid, sizeof(stats.f_fsid));
156 
157 	if (name_to_handle_at(AT_FDCWD, path, handle, &mount_id, 0) == -1) {
158 		if (errno == EOPNOTSUPP) {
159 			tst_brk(TCONF,
160 				"filesystem %s does not support file handles",
161 				tst_device->fs_type);
162 		}
163 		tst_brk(TBROK | TERRNO,
164 			"name_to_handle_at(AT_FDCWD, %s, ...) failed", path);
165 	}
166 }
167 
168 struct fanotify_fid_t {
169 	__kernel_fsid_t fsid;
170 	struct file_handle handle;
171 	char buf[MAX_HANDLE_SZ];
172 };
173 
fanotify_save_fid(const char * path,struct fanotify_fid_t * fid)174 static inline void fanotify_save_fid(const char *path,
175 				     struct fanotify_fid_t *fid)
176 {
177 	int *fh = (int *)(fid->handle.f_handle);
178 
179 	fh[0] = fh[1] = fh[2] = 0;
180 	fid->handle.handle_bytes = MAX_HANDLE_SZ;
181 	fanotify_get_fid(path, &fid->fsid, &fid->handle);
182 
183 	tst_res(TINFO,
184 		"fid(%s) = %x.%x.%x.%x.%x...", path, fid->fsid.val[0],
185 		fid->fsid.val[1], fh[0], fh[1], fh[2]);
186 }
187 #endif /* HAVE_NAME_TO_HANDLE_AT */
188 
189 #define INIT_FANOTIFY_MARK_TYPE(t) \
190 	{ FAN_MARK_ ## t, "FAN_MARK_" #t }
191 
192 #endif /* __FANOTIFY_H__ */
193