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); 146