summaryrefslogtreecommitdiffstats
path: root/fs/notify
diff options
context:
space:
mode:
authorMatthew Bobrowski <mbobrowski@mbobrowski.org>2018-11-07 22:05:49 -0500
committerJan Kara <jack@suse.cz>2018-11-13 12:38:18 -0500
commit2d10b23082a7eb8be508b3789f2e7250a88a5ddb (patch)
tree254bf00ccfa504aa6faa19c5e64372534fee8de7 /fs/notify
parentb469e7e47c8a075cc08bcd1e85d4365134bdcdd5 (diff)
fanotify: return only user requested event types in event mask
Modify fanotify_should_send_event() so that it now returns a mask for an event that contains ONLY flags for the event types that have been specifically requested by the user. Flags that may have been included within the event mask, but have not been explicitly requested by the user will not be present in the returned value. As an example, given the situation where a user requests events of type FAN_OPEN. Traditionally, the event mask returned within an event that occurred on a filesystem object that has been marked for monitoring and is opened, will only ever have the FAN_OPEN bit set. With the introduction of the new flags like FAN_OPEN_EXEC, and perhaps any other future event flags, there is a possibility of the returned event mask containing more than a single bit set, despite having only requested the single event type. Prior to these modifications performed to fanotify_should_send_event(), a user would have received a bundled event mask containing flags FAN_OPEN and FAN_OPEN_EXEC in the instance that a file was opened for execution via execve(), for example. This means that a user would receive event types in the returned event mask that have not been requested. This runs the possibility of breaking existing systems and causing other unforeseen issues. To mitigate this possibility, fanotify_should_send_event() has been modified to return the event mask containing ONLY event types explicitly requested by the user. This means that we will NOT report events that the user did no set a mask for, and we will NOT report events that the user has set an ignore mask for. The function name fanotify_should_send_event() has also been updated so that it's more relevant to what it has been designed to do. Signed-off-by: Matthew Bobrowski <mbobrowski@mbobrowski.org> Reviewed-by: Amir Goldstein <amir73il@gmail.com> Signed-off-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/notify')
-rw-r--r--fs/notify/fanotify/fanotify.c28
1 files changed, 16 insertions, 12 deletions
diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c
index e08a6647267b..f4f8359bc597 100644
--- a/fs/notify/fanotify/fanotify.c
+++ b/fs/notify/fanotify/fanotify.c
@@ -89,7 +89,13 @@ static int fanotify_get_response(struct fsnotify_group *group,
89 return ret; 89 return ret;
90} 90}
91 91
92static bool fanotify_should_send_event(struct fsnotify_iter_info *iter_info, 92/*
93 * This function returns a mask for an event that only contains the flags
94 * that have been specifically requested by the user. Flags that may have
95 * been included within the event mask, but have not been explicitly
96 * requested by the user, will not be present in the returned mask.
97 */
98static u32 fanotify_group_event_mask(struct fsnotify_iter_info *iter_info,
93 u32 event_mask, const void *data, 99 u32 event_mask, const void *data,
94 int data_type) 100 int data_type)
95{ 101{
@@ -101,14 +107,14 @@ static bool fanotify_should_send_event(struct fsnotify_iter_info *iter_info,
101 pr_debug("%s: report_mask=%x mask=%x data=%p data_type=%d\n", 107 pr_debug("%s: report_mask=%x mask=%x data=%p data_type=%d\n",
102 __func__, iter_info->report_mask, event_mask, data, data_type); 108 __func__, iter_info->report_mask, event_mask, data, data_type);
103 109
104 /* if we don't have enough info to send an event to userspace say no */ 110 /* If we don't have enough info to send an event to userspace say no */
105 if (data_type != FSNOTIFY_EVENT_PATH) 111 if (data_type != FSNOTIFY_EVENT_PATH)
106 return false; 112 return 0;
107 113
108 /* sorry, fanotify only gives a damn about files and dirs */ 114 /* Sorry, fanotify only gives a damn about files and dirs */
109 if (!d_is_reg(path->dentry) && 115 if (!d_is_reg(path->dentry) &&
110 !d_can_lookup(path->dentry)) 116 !d_can_lookup(path->dentry))
111 return false; 117 return 0;
112 118
113 fsnotify_foreach_obj_type(type) { 119 fsnotify_foreach_obj_type(type) {
114 if (!fsnotify_iter_should_report_type(iter_info, type)) 120 if (!fsnotify_iter_should_report_type(iter_info, type))
@@ -129,13 +135,10 @@ static bool fanotify_should_send_event(struct fsnotify_iter_info *iter_info,
129 135
130 if (d_is_dir(path->dentry) && 136 if (d_is_dir(path->dentry) &&
131 !(marks_mask & FS_ISDIR & ~marks_ignored_mask)) 137 !(marks_mask & FS_ISDIR & ~marks_ignored_mask))
132 return false; 138 return 0;
133
134 if (event_mask & FANOTIFY_OUTGOING_EVENTS &
135 marks_mask & ~marks_ignored_mask)
136 return true;
137 139
138 return false; 140 return event_mask & FANOTIFY_OUTGOING_EVENTS & marks_mask &
141 ~marks_ignored_mask;
139} 142}
140 143
141struct fanotify_event_info *fanotify_alloc_event(struct fsnotify_group *group, 144struct fanotify_event_info *fanotify_alloc_event(struct fsnotify_group *group,
@@ -210,7 +213,8 @@ static int fanotify_handle_event(struct fsnotify_group *group,
210 213
211 BUILD_BUG_ON(HWEIGHT32(ALL_FANOTIFY_EVENT_BITS) != 10); 214 BUILD_BUG_ON(HWEIGHT32(ALL_FANOTIFY_EVENT_BITS) != 10);
212 215
213 if (!fanotify_should_send_event(iter_info, mask, data, data_type)) 216 mask = fanotify_group_event_mask(iter_info, mask, data, data_type);
217 if (!mask)
214 return 0; 218 return 0;
215 219
216 pr_debug("%s: group=%p inode=%p mask=%x\n", __func__, group, inode, 220 pr_debug("%s: group=%p inode=%p mask=%x\n", __func__, group, inode,