^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #include <linux/fsnotify_backend.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #include <linux/path.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/exportfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) extern struct kmem_cache *fanotify_mark_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) extern struct kmem_cache *fanotify_fid_event_cachep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) extern struct kmem_cache *fanotify_path_event_cachep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) extern struct kmem_cache *fanotify_perm_event_cachep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) /* Possible states of the permission event */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) FAN_EVENT_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) FAN_EVENT_REPORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) FAN_EVENT_ANSWERED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) FAN_EVENT_CANCELED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * 3 dwords are sufficient for most local fs (64bit ino, 32bit generation).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * fh buf should be dword aligned. On 64bit arch, the ext_buf pointer is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * stored in either the first or last 2 dwords.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define FANOTIFY_INLINE_FH_LEN (3 << 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define FANOTIFY_FH_HDR_LEN offsetof(struct fanotify_fh, buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) /* Fixed size struct for file handle */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) struct fanotify_fh {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) u8 type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) u8 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define FANOTIFY_FH_FLAG_EXT_BUF 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) u8 flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) u8 pad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) unsigned char buf[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) } __aligned(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) /* Variable size struct for dir file handle + child file handle + name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) struct fanotify_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) /* size of dir_fh/file_fh including fanotify_fh hdr size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) u8 dir_fh_totlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) u8 file_fh_totlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) u8 name_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) u8 pad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) unsigned char buf[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * (struct fanotify_fh) dir_fh starts at buf[0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * (optional) file_fh starts at buf[dir_fh_totlen]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * name starts at buf[dir_fh_totlen + file_fh_totlen]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) } __aligned(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) static inline bool fanotify_fh_has_ext_buf(struct fanotify_fh *fh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) return (fh->flags & FANOTIFY_FH_FLAG_EXT_BUF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) static inline char **fanotify_fh_ext_buf_ptr(struct fanotify_fh *fh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) BUILD_BUG_ON(FANOTIFY_FH_HDR_LEN % 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) BUILD_BUG_ON(__alignof__(char *) - 4 + sizeof(char *) >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) FANOTIFY_INLINE_FH_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) return (char **)ALIGN((unsigned long)(fh->buf), __alignof__(char *));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) static inline void *fanotify_fh_ext_buf(struct fanotify_fh *fh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) return *fanotify_fh_ext_buf_ptr(fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) static inline void *fanotify_fh_buf(struct fanotify_fh *fh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) return fanotify_fh_has_ext_buf(fh) ? fanotify_fh_ext_buf(fh) : fh->buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) static inline int fanotify_info_dir_fh_len(struct fanotify_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) if (!info->dir_fh_totlen ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) WARN_ON_ONCE(info->dir_fh_totlen < FANOTIFY_FH_HDR_LEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) return info->dir_fh_totlen - FANOTIFY_FH_HDR_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) static inline struct fanotify_fh *fanotify_info_dir_fh(struct fanotify_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) BUILD_BUG_ON(offsetof(struct fanotify_info, buf) % 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) return (struct fanotify_fh *)info->buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) static inline int fanotify_info_file_fh_len(struct fanotify_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) if (!info->file_fh_totlen ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) WARN_ON_ONCE(info->file_fh_totlen < FANOTIFY_FH_HDR_LEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) return info->file_fh_totlen - FANOTIFY_FH_HDR_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) static inline struct fanotify_fh *fanotify_info_file_fh(struct fanotify_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) return (struct fanotify_fh *)(info->buf + info->dir_fh_totlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) static inline const char *fanotify_info_name(struct fanotify_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) return info->buf + info->dir_fh_totlen + info->file_fh_totlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) static inline void fanotify_info_init(struct fanotify_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) info->dir_fh_totlen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) info->file_fh_totlen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) info->name_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) static inline void fanotify_info_copy_name(struct fanotify_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) const struct qstr *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) info->name_len = name->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) strcpy(info->buf + info->dir_fh_totlen + info->file_fh_totlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) name->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * Common structure for fanotify events. Concrete structs are allocated in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * fanotify_handle_event() and freed when the information is retrieved by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * userspace. The type of event determines how it was allocated, how it will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * be freed and which concrete struct it may be cast to.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) enum fanotify_event_type {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) FANOTIFY_EVENT_TYPE_FID, /* fixed length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) FANOTIFY_EVENT_TYPE_FID_NAME, /* variable length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) FANOTIFY_EVENT_TYPE_PATH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) FANOTIFY_EVENT_TYPE_PATH_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) FANOTIFY_EVENT_TYPE_OVERFLOW, /* struct fanotify_event */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) struct fanotify_event {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) struct fsnotify_event fse;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) u32 mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) enum fanotify_event_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) struct pid *pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) static inline void fanotify_init_event(struct fanotify_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) unsigned long id, u32 mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) fsnotify_init_event(&event->fse, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) event->mask = mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) event->pid = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) struct fanotify_fid_event {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) struct fanotify_event fae;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) __kernel_fsid_t fsid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) struct fanotify_fh object_fh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) /* Reserve space in object_fh.buf[] - access with fanotify_fh_buf() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) unsigned char _inline_fh_buf[FANOTIFY_INLINE_FH_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) static inline struct fanotify_fid_event *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) FANOTIFY_FE(struct fanotify_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) return container_of(event, struct fanotify_fid_event, fae);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) struct fanotify_name_event {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) struct fanotify_event fae;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) __kernel_fsid_t fsid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) struct fanotify_info info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) static inline struct fanotify_name_event *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) FANOTIFY_NE(struct fanotify_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) return container_of(event, struct fanotify_name_event, fae);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) static inline __kernel_fsid_t *fanotify_event_fsid(struct fanotify_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) if (event->type == FANOTIFY_EVENT_TYPE_FID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) return &FANOTIFY_FE(event)->fsid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) else if (event->type == FANOTIFY_EVENT_TYPE_FID_NAME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) return &FANOTIFY_NE(event)->fsid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) static inline struct fanotify_fh *fanotify_event_object_fh(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) struct fanotify_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) if (event->type == FANOTIFY_EVENT_TYPE_FID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) return &FANOTIFY_FE(event)->object_fh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) else if (event->type == FANOTIFY_EVENT_TYPE_FID_NAME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) return fanotify_info_file_fh(&FANOTIFY_NE(event)->info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) static inline struct fanotify_info *fanotify_event_info(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) struct fanotify_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) if (event->type == FANOTIFY_EVENT_TYPE_FID_NAME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) return &FANOTIFY_NE(event)->info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) static inline int fanotify_event_object_fh_len(struct fanotify_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) struct fanotify_info *info = fanotify_event_info(event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) struct fanotify_fh *fh = fanotify_event_object_fh(event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) if (info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) return info->file_fh_totlen ? fh->len : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) return fh ? fh->len : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) static inline int fanotify_event_dir_fh_len(struct fanotify_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) struct fanotify_info *info = fanotify_event_info(event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) return info ? fanotify_info_dir_fh_len(info) : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) struct fanotify_path_event {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) struct fanotify_event fae;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) struct path path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) static inline struct fanotify_path_event *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) FANOTIFY_PE(struct fanotify_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) return container_of(event, struct fanotify_path_event, fae);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) * Structure for permission fanotify events. It gets allocated and freed in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) * fanotify_handle_event() since we wait there for user response. When the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) * information is retrieved by userspace the structure is moved from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) * group->notification_list to group->fanotify_data.access_list to wait for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) * user response.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) struct fanotify_perm_event {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) struct fanotify_event fae;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) struct path path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) unsigned short response; /* userspace answer to the event */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) unsigned short state; /* state of the event */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) int fd; /* fd we passed to userspace for this event */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) static inline struct fanotify_perm_event *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) FANOTIFY_PERM(struct fanotify_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) return container_of(event, struct fanotify_perm_event, fae);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) static inline bool fanotify_is_perm_event(u32 mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) return IS_ENABLED(CONFIG_FANOTIFY_ACCESS_PERMISSIONS) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) mask & FANOTIFY_PERM_EVENTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) static inline struct fanotify_event *FANOTIFY_E(struct fsnotify_event *fse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) return container_of(fse, struct fanotify_event, fse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) static inline bool fanotify_event_has_path(struct fanotify_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) return event->type == FANOTIFY_EVENT_TYPE_PATH ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) event->type == FANOTIFY_EVENT_TYPE_PATH_PERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) static inline struct path *fanotify_event_path(struct fanotify_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) if (event->type == FANOTIFY_EVENT_TYPE_PATH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) return &FANOTIFY_PE(event)->path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) else if (event->type == FANOTIFY_EVENT_TYPE_PATH_PERM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) return &FANOTIFY_PERM(event)->path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) }