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