summaryrefslogtreecommitdiff
path: root/fs/notify/fanotify/fanotify_user.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/notify/fanotify/fanotify_user.c')
-rw-r--r--fs/notify/fanotify/fanotify_user.c39
1 files changed, 20 insertions, 19 deletions
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c
index e48fc07d80ef..0b3b74fa3a27 100644
--- a/fs/notify/fanotify/fanotify_user.c
+++ b/fs/notify/fanotify/fanotify_user.c
@@ -53,11 +53,13 @@ struct kmem_cache *fanotify_perm_event_cachep __read_mostly;
static int fanotify_event_info_len(struct fanotify_event *event)
{
- if (!fanotify_event_has_fid(event))
+ int fh_len = fanotify_event_object_fh_len(event);
+
+ if (!fh_len)
return 0;
return roundup(sizeof(struct fanotify_event_info_fid) +
- sizeof(struct file_handle) + event->fh_len,
+ sizeof(struct file_handle) + fh_len,
FANOTIFY_EVENT_ALIGN);
}
@@ -200,8 +202,9 @@ static int copy_fid_to_user(struct fanotify_event *event, char __user *buf)
{
struct fanotify_event_info_fid info = { };
struct file_handle handle = { };
- unsigned char bounce[FANOTIFY_INLINE_FH_LEN], *fh;
- size_t fh_len = event->fh_len;
+ unsigned char bounce[FANOTIFY_INLINE_FH_LEN], *fh_buf;
+ struct fanotify_fh *fh = fanotify_event_object_fh(event);
+ size_t fh_len = fh->len;
size_t len = fanotify_event_info_len(event);
if (!len)
@@ -213,13 +216,13 @@ static int copy_fid_to_user(struct fanotify_event *event, char __user *buf)
/* Copy event info fid header followed by vaiable sized file handle */
info.hdr.info_type = FAN_EVENT_INFO_TYPE_FID;
info.hdr.len = len;
- info.fsid = event->fid.fsid;
+ info.fsid = *fanotify_event_fsid(event);
if (copy_to_user(buf, &info, sizeof(info)))
return -EFAULT;
buf += sizeof(info);
len -= sizeof(info);
- handle.handle_type = event->fh_type;
+ handle.handle_type = fh->type;
handle.handle_bytes = fh_len;
if (copy_to_user(buf, &handle, sizeof(handle)))
return -EFAULT;
@@ -230,12 +233,12 @@ static int copy_fid_to_user(struct fanotify_event *event, char __user *buf)
* For an inline fh, copy through stack to exclude the copy from
* usercopy hardening protections.
*/
- fh = fanotify_event_fh(event);
+ fh_buf = fanotify_fh_buf(fh);
if (fh_len <= FANOTIFY_INLINE_FH_LEN) {
- memcpy(bounce, fh, fh_len);
- fh = bounce;
+ memcpy(bounce, fh_buf, fh_len);
+ fh_buf = bounce;
}
- if (copy_to_user(buf, fh, fh_len))
+ if (copy_to_user(buf, fh_buf, fh_len))
return -EFAULT;
/* Pad with 0's */
@@ -254,12 +257,14 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group,
{
struct fanotify_event_metadata metadata;
struct fanotify_event *event;
+ struct path *path;
struct file *f = NULL;
int ret, fd = FAN_NOFD;
pr_debug("%s: group=%p event=%p\n", __func__, group, fsn_event);
event = container_of(fsn_event, struct fanotify_event, fse);
+ path = fanotify_event_path(event);
metadata.event_len = FAN_EVENT_METADATA_LEN;
metadata.metadata_len = FAN_EVENT_METADATA_LEN;
metadata.vers = FANOTIFY_METADATA_VERSION;
@@ -267,16 +272,12 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group,
metadata.mask = event->mask & FANOTIFY_OUTGOING_EVENTS;
metadata.pid = pid_vnr(event->pid);
- if (fanotify_event_has_path(event)) {
- struct path *path = &event->path;
-
- if (path->mnt && path->dentry) {
- fd = create_fd(group, path, &f);
- if (fd < 0)
- return fd;
- }
- } else if (fanotify_event_has_fid(event)) {
+ if (fanotify_event_has_fid(event)) {
metadata.event_len += fanotify_event_info_len(event);
+ } else if (path && path->mnt && path->dentry) {
+ fd = create_fd(group, path, &f);
+ if (fd < 0)
+ return fd;
}
metadata.fd = fd;