diff options
| author | Yichong Chen <chenyichong@uniontech.com> | 2026-07-31 10:18:27 +0800 |
|---|---|---|
| committer | Jan Kara <jack@suse.cz> | 2026-07-31 14:18:17 +0200 |
| commit | 68615158c12de36220446dfea5cfdf9ba6c19690 (patch) | |
| tree | a703e68b0078485206e6a9cc55d82a70d3c70ea4 | |
| parent | d7f1cf5be33ef0175a4e8ed8687aeb98fb00a851 (diff) | |
| download | linux-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.c | 5 |
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; |
