summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYichong Chen <chenyichong@uniontech.com>2026-07-31 10:18:27 +0800
committerJan Kara <jack@suse.cz>2026-07-31 14:18:17 +0200
commit68615158c12de36220446dfea5cfdf9ba6c19690 (patch)
treea703e68b0078485206e6a9cc55d82a70d3c70ea4
parentd7f1cf5be33ef0175a4e8ed8687aeb98fb00a851 (diff)
downloadlinux-stable-68615158c12de36220446dfea5cfdf9ba6c19690.tar.gz
linux-stable-68615158c12de36220446dfea5cfdf9ba6c19690.zip
fanotify: report full event length for FIONREAD
fanotify_ioctl(FIONREAD) reports the number of bytes available to read from the event queue. It currently accounts only FAN_EVENT_METADATA_LEN for each queued event. That underestimates events that carry additional information records, such as FAN_REPORT_DFID_NAME events. A userspace program that uses FIONREAD to size its read buffer can receive a length that is smaller than the next event. Reading with that buffer then fails with -EINVAL, while a larger buffer succeeds and reports a larger metadata.event_len. Use fanotify_event_len() when summing queued events so FIONREAD includes all info records. Fixes: 5e469c830fdb ("fanotify: copy event fid info to user") Signed-off-by: Yichong Chen <chenyichong@uniontech.com> Link: https://patch.msgid.link/20260731021827.602479-1-chenyichong@uniontech.com Signed-off-by: Jan Kara <jack@suse.cz>
-rw-r--r--fs/notify/fanotify/fanotify_user.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c
index faffe8f0cb12..463495a78693 100644
--- a/fs/notify/fanotify/fanotify_user.c
+++ b/fs/notify/fanotify/fanotify_user.c
@@ -1147,11 +1147,13 @@ static long fanotify_ioctl(struct file *file, unsigned int cmd, unsigned long ar
{
struct fsnotify_group *group;
struct fsnotify_event *fsn_event;
+ unsigned int info_mode;
void __user *p;
int ret = -ENOTTY;
size_t send_len = 0;
group = file->private_data;
+ info_mode = FAN_GROUP_FLAG(group, FANOTIFY_INFO_MODES);
p = (void __user *) arg;
@@ -1159,7 +1161,8 @@ static long fanotify_ioctl(struct file *file, unsigned int cmd, unsigned long ar
case FIONREAD:
spin_lock(&group->notification_lock);
list_for_each_entry(fsn_event, &group->notification_list, list)
- send_len += FAN_EVENT_METADATA_LEN;
+ send_len += fanotify_event_len(info_mode,
+ FANOTIFY_E(fsn_event));
spin_unlock(&group->notification_lock);
ret = put_user(send_len, (int __user *) p);
break;