Linux-libre 5.3.12-gnu
[librecmc/linux-libre.git] / fs / notify / fanotify / fanotify.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #include <linux/fsnotify_backend.h>
3 #include <linux/path.h>
4 #include <linux/slab.h>
5 #include <linux/exportfs.h>
6
7 extern struct kmem_cache *fanotify_mark_cache;
8 extern struct kmem_cache *fanotify_event_cachep;
9 extern struct kmem_cache *fanotify_perm_event_cachep;
10
11 /* Possible states of the permission event */
12 enum {
13         FAN_EVENT_INIT,
14         FAN_EVENT_REPORTED,
15         FAN_EVENT_ANSWERED,
16         FAN_EVENT_CANCELED,
17 };
18
19 /*
20  * 3 dwords are sufficient for most local fs (64bit ino, 32bit generation).
21  * For 32bit arch, fid increases the size of fanotify_event by 12 bytes and
22  * fh_* fields increase the size of fanotify_event by another 4 bytes.
23  * For 64bit arch, fid increases the size of fanotify_fid by 8 bytes and
24  * fh_* fields are packed in a hole after mask.
25  */
26 #if BITS_PER_LONG == 32
27 #define FANOTIFY_INLINE_FH_LEN  (3 << 2)
28 #else
29 #define FANOTIFY_INLINE_FH_LEN  (4 << 2)
30 #endif
31
32 struct fanotify_fid {
33         __kernel_fsid_t fsid;
34         union {
35                 unsigned char fh[FANOTIFY_INLINE_FH_LEN];
36                 unsigned char *ext_fh;
37         };
38 };
39
40 static inline void *fanotify_fid_fh(struct fanotify_fid *fid,
41                                     unsigned int fh_len)
42 {
43         return fh_len <= FANOTIFY_INLINE_FH_LEN ? fid->fh : fid->ext_fh;
44 }
45
46 static inline bool fanotify_fid_equal(struct fanotify_fid *fid1,
47                                       struct fanotify_fid *fid2,
48                                       unsigned int fh_len)
49 {
50         return fid1->fsid.val[0] == fid2->fsid.val[0] &&
51                 fid1->fsid.val[1] == fid2->fsid.val[1] &&
52                 !memcmp(fanotify_fid_fh(fid1, fh_len),
53                         fanotify_fid_fh(fid2, fh_len), fh_len);
54 }
55
56 /*
57  * Structure for normal fanotify events. It gets allocated in
58  * fanotify_handle_event() and freed when the information is retrieved by
59  * userspace
60  */
61 struct fanotify_event {
62         struct fsnotify_event fse;
63         u32 mask;
64         /*
65          * Those fields are outside fanotify_fid to pack fanotify_event nicely
66          * on 64bit arch and to use fh_type as an indication of whether path
67          * or fid are used in the union:
68          * FILEID_ROOT (0) for path, > 0 for fid, FILEID_INVALID for neither.
69          */
70         u8 fh_type;
71         u8 fh_len;
72         u16 pad;
73         union {
74                 /*
75                  * We hold ref to this path so it may be dereferenced at any
76                  * point during this object's lifetime
77                  */
78                 struct path path;
79                 /*
80                  * With FAN_REPORT_FID, we do not hold any reference on the
81                  * victim object. Instead we store its NFS file handle and its
82                  * filesystem's fsid as a unique identifier.
83                  */
84                 struct fanotify_fid fid;
85         };
86         struct pid *pid;
87 };
88
89 static inline bool fanotify_event_has_path(struct fanotify_event *event)
90 {
91         return event->fh_type == FILEID_ROOT;
92 }
93
94 static inline bool fanotify_event_has_fid(struct fanotify_event *event)
95 {
96         return event->fh_type != FILEID_ROOT &&
97                 event->fh_type != FILEID_INVALID;
98 }
99
100 static inline bool fanotify_event_has_ext_fh(struct fanotify_event *event)
101 {
102         return fanotify_event_has_fid(event) &&
103                 event->fh_len > FANOTIFY_INLINE_FH_LEN;
104 }
105
106 static inline void *fanotify_event_fh(struct fanotify_event *event)
107 {
108         return fanotify_fid_fh(&event->fid, event->fh_len);
109 }
110
111 /*
112  * Structure for permission fanotify events. It gets allocated and freed in
113  * fanotify_handle_event() since we wait there for user response. When the
114  * information is retrieved by userspace the structure is moved from
115  * group->notification_list to group->fanotify_data.access_list to wait for
116  * user response.
117  */
118 struct fanotify_perm_event {
119         struct fanotify_event fae;
120         unsigned short response;        /* userspace answer to the event */
121         unsigned short state;           /* state of the event */
122         int fd;         /* fd we passed to userspace for this event */
123 };
124
125 static inline struct fanotify_perm_event *
126 FANOTIFY_PE(struct fsnotify_event *fse)
127 {
128         return container_of(fse, struct fanotify_perm_event, fae.fse);
129 }
130
131 static inline bool fanotify_is_perm_event(u32 mask)
132 {
133         return IS_ENABLED(CONFIG_FANOTIFY_ACCESS_PERMISSIONS) &&
134                 mask & FANOTIFY_PERM_EVENTS;
135 }
136
137 static inline struct fanotify_event *FANOTIFY_E(struct fsnotify_event *fse)
138 {
139         return container_of(fse, struct fanotify_event, fse);
140 }
141
142 struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group,
143                                             struct inode *inode, u32 mask,
144                                             const void *data, int data_type,
145                                             __kernel_fsid_t *fsid);