|
@@ -139,23 +139,32 @@ static bool fanotify_should_send_event(struct fsnotify_mark *inode_mark,
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
-struct fanotify_event_info *fanotify_alloc_event(struct inode *inode, u32 mask,
|
|
|
+struct fanotify_event_info *fanotify_alloc_event(struct fsnotify_group *group,
|
|
|
+ struct inode *inode, u32 mask,
|
|
|
const struct path *path)
|
|
|
{
|
|
|
struct fanotify_event_info *event;
|
|
|
+ gfp_t gfp = GFP_KERNEL;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * For queues with unlimited length lost events are not expected and
|
|
|
+ * can possibly have security implications. Avoid losing events when
|
|
|
+ * memory is short.
|
|
|
+ */
|
|
|
+ if (group->max_events == UINT_MAX)
|
|
|
+ gfp |= __GFP_NOFAIL;
|
|
|
|
|
|
if (fanotify_is_perm_event(mask)) {
|
|
|
struct fanotify_perm_event_info *pevent;
|
|
|
|
|
|
- pevent = kmem_cache_alloc(fanotify_perm_event_cachep,
|
|
|
- GFP_KERNEL);
|
|
|
+ pevent = kmem_cache_alloc(fanotify_perm_event_cachep, gfp);
|
|
|
if (!pevent)
|
|
|
return NULL;
|
|
|
event = &pevent->fae;
|
|
|
pevent->response = 0;
|
|
|
goto init;
|
|
|
}
|
|
|
- event = kmem_cache_alloc(fanotify_event_cachep, GFP_KERNEL);
|
|
|
+ event = kmem_cache_alloc(fanotify_event_cachep, gfp);
|
|
|
if (!event)
|
|
|
return NULL;
|
|
|
init: __maybe_unused
|
|
@@ -210,7 +219,7 @@ static int fanotify_handle_event(struct fsnotify_group *group,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
- event = fanotify_alloc_event(inode, mask, data);
|
|
|
+ event = fanotify_alloc_event(group, inode, mask, data);
|
|
|
ret = -ENOMEM;
|
|
|
if (unlikely(!event))
|
|
|
goto finish;
|