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 
45 #ifndef FAN_MARK_INODE
46 #define FAN_MARK_INODE		0
47 #endif
48 #ifndef FAN_MARK_FILESYSTEM
49 #define FAN_MARK_FILESYSTEM	0x00000100
50 #endif
51 /* New dirent event masks */
52 #ifndef FAN_ATTRIB
53 #define FAN_ATTRIB		0x00000004
54 #endif
55 #ifndef FAN_MOVED_FROM
56 #define FAN_MOVED_FROM		0x00000040
57 #endif
58 #ifndef FAN_MOVED_TO
59 #define FAN_MOVED_TO		0x00000080
60 #endif
61 #ifndef FAN_CREATE
62 #define FAN_CREATE		0x00000100
63 #endif
64 #ifndef FAN_DELETE
65 #define FAN_DELETE		0x00000200
66 #endif
67 #ifndef FAN_DELETE_SELF
68 #define FAN_DELETE_SELF		0x00000400
69 #endif
70 #ifndef FAN_MOVE_SELF
71 #define FAN_MOVE_SELF		0x00000800
72 #endif
73 #ifndef FAN_MOVE
74 #define FAN_MOVE		(FAN_MOVED_FROM | FAN_MOVED_TO)
75 #endif
76 #ifndef FAN_OPEN_EXEC
77 #define FAN_OPEN_EXEC		0x00001000
78 #endif
79 #ifndef FAN_OPEN_EXEC_PERM
80 #define FAN_OPEN_EXEC_PERM	0x00040000
81 #endif
82 
83 #ifndef FAN_REPORT_FID
84 #define FAN_REPORT_FID		0x00000200
85 #endif
86 
87 /*
88  * FAN_ALL_PERM_EVENTS has been deprecated, so any new permission events
89  * are not to be added to it. To cover the instance where a new permission
90  * event is defined, we create a new macro that is to include all
91  * permission events. Any new permission events should be added to this
92  * macro.
93  */
94 #define LTP_ALL_PERM_EVENTS	(FAN_OPEN_PERM | FAN_OPEN_EXEC_PERM | \
95 				 FAN_ACCESS_PERM)
96 
97 struct fanotify_mark_type {
98 	unsigned int flag;
99 	const char * name;
100 };
101 
102 #ifndef __kernel_fsid_t
103 typedef struct {
104 	int	val[2];
105 } lapi_fsid_t;
106 #define __kernel_fsid_t lapi_fsid_t
107 #endif /* __kernel_fsid_t */
108 
109 #ifndef HAVE_STRUCT_FANOTIFY_EVENT_INFO_HEADER
110 struct fanotify_event_info_header {
111 	uint8_t info_type;
112 	uint8_t pad;
113 	uint16_t len;
114 };
115 #endif /* HAVE_STRUCT_FANOTIFY_EVENT_INFO_HEADER */
116 
117 #ifndef HAVE_STRUCT_FANOTIFY_EVENT_INFO_FID
118 struct fanotify_event_info_fid {
119 	struct fanotify_event_info_header hdr;
120 	__kernel_fsid_t fsid;
121 	unsigned char handle[0];
122 };
123 #endif /* HAVE_STRUCT_FANOTIFY_EVENT_INFO_FID */
124 
125 /* NOTE: only for struct fanotify_event_info_fid */
126 #ifdef HAVE_STRUCT_FANOTIFY_EVENT_INFO_FID_FSID___VAL
127 # define FSID_VAL_MEMBER(fsid, i) (fsid.__val[i])
128 #else
129 # define FSID_VAL_MEMBER(fsid, i) (fsid.val[i])
130 #endif /* HAVE_STRUCT_FANOTIFY_EVENT_INFO_FID_FSID___VAL */
131 
132 #ifdef HAVE_NAME_TO_HANDLE_AT
133 /*
134  * Helper function used to obtain fsid and file_handle for a given path.
135  * Used by test files correlated to FAN_REPORT_FID functionality.
136  */
fanotify_get_fid(const char * path,__kernel_fsid_t * fsid,struct file_handle * handle)137 static inline void fanotify_get_fid(const char *path, __kernel_fsid_t *fsid,
138 				    struct file_handle *handle)
139 {
140 	int mount_id;
141 	struct statfs stats;
142 
143 	if (statfs(path, &stats) == -1)
144 		tst_brk(TBROK | TERRNO,
145 			"statfs(%s, ...) failed", path);
146 	memcpy(fsid, &stats.f_fsid, sizeof(stats.f_fsid));
147 
148 	if (name_to_handle_at(AT_FDCWD, path, handle, &mount_id, 0) == -1) {
149 		if (errno == EOPNOTSUPP) {
150 			tst_brk(TCONF,
151 				"filesystem %s does not support file handles",
152 				tst_device->fs_type);
153 		}
154 		tst_brk(TBROK | TERRNO,
155 			"name_to_handle_at(AT_FDCWD, %s, ...) failed", path);
156 	}
157 }
158 #endif /* HAVE_NAME_TO_HANDLE_AT */
159 
160 #define INIT_FANOTIFY_MARK_TYPE(t) \
161 	{ FAN_MARK_ ## t, "FAN_MARK_" #t }
162 
163 #endif /* __FANOTIFY_H__ */
164