diff options
author | Jan Kara <jack@suse.cz> | 2019-03-12 07:42:37 -0400 |
---|---|---|
committer | Jan Kara <jack@suse.cz> | 2019-03-19 04:29:07 -0400 |
commit | b2d22b6bb33aac10c415e4ba13c8eade201c6f09 (patch) | |
tree | 1610454690dd14fe250d0b6e8b6be1f580f1f360 /fs/notify | |
parent | 62c9d2674b31d4c8a674bee86b7edc6da2803aea (diff) |
fanotify: Allow copying of file handle to userspace
When file handle is embedded inside fanotify_event and usercopy checks
are enabled, we get a warning like:
Bad or missing usercopy whitelist? Kernel memory exposure attempt detected
from SLAB object 'fanotify_event' (offset 40, size 8)!
WARNING: CPU: 1 PID: 7649 at mm/usercopy.c:78 usercopy_warn+0xeb/0x110
mm/usercopy.c:78
Annotate handling in fanotify_event properly to mark copying it to
userspace is fine.
Reported-by: syzbot+2c49971e251e36216d1f@syzkaller.appspotmail.com
Fixes: a8b13aa20afb ("fanotify: enable FAN_REPORT_FID init flag")
Signed-off-by: Kees Cook <keescook@chromium.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_user.c | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index 56992b32c6bb..a90bb19dcfa2 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c | |||
@@ -208,6 +208,7 @@ static int copy_fid_to_user(struct fanotify_event *event, char __user *buf) | |||
208 | { | 208 | { |
209 | struct fanotify_event_info_fid info = { }; | 209 | struct fanotify_event_info_fid info = { }; |
210 | struct file_handle handle = { }; | 210 | struct file_handle handle = { }; |
211 | unsigned char bounce[FANOTIFY_INLINE_FH_LEN], *fh; | ||
211 | size_t fh_len = event->fh_len; | 212 | size_t fh_len = event->fh_len; |
212 | size_t len = fanotify_event_info_len(event); | 213 | size_t len = fanotify_event_info_len(event); |
213 | 214 | ||
@@ -233,7 +234,16 @@ static int copy_fid_to_user(struct fanotify_event *event, char __user *buf) | |||
233 | 234 | ||
234 | buf += sizeof(handle); | 235 | buf += sizeof(handle); |
235 | len -= sizeof(handle); | 236 | len -= sizeof(handle); |
236 | if (copy_to_user(buf, fanotify_event_fh(event), fh_len)) | 237 | /* |
238 | * For an inline fh, copy through stack to exclude the copy from | ||
239 | * usercopy hardening protections. | ||
240 | */ | ||
241 | fh = fanotify_event_fh(event); | ||
242 | if (fh_len <= FANOTIFY_INLINE_FH_LEN) { | ||
243 | memcpy(bounce, fh, fh_len); | ||
244 | fh = bounce; | ||
245 | } | ||
246 | if (copy_to_user(buf, fh, fh_len)) | ||
237 | return -EFAULT; | 247 | return -EFAULT; |
238 | 248 | ||
239 | /* Pad with 0's */ | 249 | /* Pad with 0's */ |