diff --git a/fsnotify.c b/fsnotify.c index 7966606ed..36125abed 100644 --- a/fsnotify.c +++ b/fsnotify.c @@ -259,7 +259,8 @@ const struct fdtype_ops inotify_dump_ops = { static int dump_fanotify_entry(union fdinfo_entries *e, void *arg) { struct fsnotify_params *fsn_params = arg; - FanotifyMarkEntry *fme = &e->ffy; + FanotifyMarkEntry *fme = &e->ffy.e; + int ret = -1; fme->id = fsn_params->id; @@ -275,7 +276,7 @@ static int dump_fanotify_entry(union fdinfo_entries *e, void *arg) fme->ie->f_handle->handle[0], fme->ie->f_handle->handle[1]); if (check_open_handle(fme->s_dev, fme->ie->i_ino, fme->ie->f_handle)) - return -1; + goto out; } if (fme->type == MARK_TYPE__MOUNT) { @@ -286,7 +287,7 @@ static int dump_fanotify_entry(union fdinfo_entries *e, void *arg) m = lookup_mnt_id(fme->me->mnt_id); if (!m) { pr_err("Can't find mnt_id %x\n", fme->me->mnt_id); - return -1; + goto out; } fme->s_dev = m->s_dev; @@ -295,13 +296,18 @@ static int dump_fanotify_entry(union fdinfo_entries *e, void *arg) } - return pb_write_one(fdset_fd(glob_fdset, CR_FD_FANOTIFY_MARK), fme, PB_FANOTIFY_MARK); + ret = pb_write_one(fdset_fd(glob_fdset, CR_FD_FANOTIFY_MARK), fme, PB_FANOTIFY_MARK); + +out: + free_fanotify_mark_entry(e); + return ret; } static int dump_one_fanotify(int lfd, u32 id, const struct fd_parms *p) { FanotifyFileEntry fe = FANOTIFY_FILE_ENTRY__INIT; struct fsnotify_params fsn_params = { .id = id, }; + int ret; fe.id = id; fe.flags = p->flags; @@ -316,18 +322,22 @@ static int dump_one_fanotify(int lfd, u32 id, const struct fd_parms *p) fe.faflags = fsn_params.faflags; fe.evflags = fsn_params.evflags; - return pb_write_one(fdset_fd(glob_fdset, CR_FD_FANOTIFY_FILE), &fe, PB_FANOTIFY_FILE); + ret = pb_write_one(fdset_fd(glob_fdset, CR_FD_FANOTIFY_FILE), &fe, PB_FANOTIFY_FILE); + + return ret; } static int pre_dump_fanotify_entry(union fdinfo_entries *e, void *arg) { - FanotifyMarkEntry *fme = &e->ffy; + FanotifyMarkEntry *fme = &e->ffy.e; + int ret = 0; if (fme->type == MARK_TYPE__INODE) - return irmap_queue_cache(fme->s_dev, fme->ie->i_ino, + ret = irmap_queue_cache(fme->s_dev, fme->ie->i_ino, fme->ie->f_handle); - else - return 0; + + free_fanotify_mark_entry(e); + return ret; } static int pre_dump_one_fanotify(int pid, int lfd) diff --git a/include/proc_parse.h b/include/proc_parse.h index 2bef49488..e583f2999 100644 --- a/include/proc_parse.h +++ b/include/proc_parse.h @@ -172,16 +172,27 @@ struct inotify_wd_entry { struct list_head node; }; +struct fanotify_mark_entry { + FanotifyMarkEntry e; + FhEntry f_handle; + struct list_head node; + union { + FanotifyInodeMarkEntry ie; + FanotifyMountMarkEntry me; + }; +}; + union fdinfo_entries { EventfdFileEntry efd; EventpollTfdEntry epl; SignalfdEntry sfd; struct inotify_wd_entry ify; - FanotifyMarkEntry ffy; + struct fanotify_mark_entry ffy; TimerfdEntry tfy; }; extern void free_inotify_wd_entry(union fdinfo_entries *e); +extern void free_fanotify_mark_entry(union fdinfo_entries *e); struct fdinfo_common { off64_t pos; diff --git a/proc_parse.c b/proc_parse.c index c6390fa76..0a3e3c059 100644 --- a/proc_parse.c +++ b/proc_parse.c @@ -1044,6 +1044,13 @@ void free_inotify_wd_entry(union fdinfo_entries *e) xfree(e); } +void free_fanotify_mark_entry(union fdinfo_entries *e) +{ + if (e->ffy.e.ie) + free_fhandle(e->ffy.ie.f_handle); + xfree(e); +} + static void parse_fhandle_encoded(char *tok, FhEntry *fh) { char *d = (char *)fh->handle; @@ -1233,37 +1240,44 @@ static int parse_fdinfo_pid_s(char *pid, int fd, int type, continue; } if (fdinfo_field(str, "fanotify ino")) { - FanotifyInodeMarkEntry ie = FANOTIFY_INODE_MARK_ENTRY__INIT; - FhEntry f_handle = FH_ENTRY__INIT; + union fdinfo_entries *e; int hoff = 0; if (type != FD_TYPES__FANOTIFY) goto parse_err; - fanotify_mark_entry__init(&entry.ffy); - ie.f_handle = &f_handle; - entry.ffy.ie = &ie; + e = xmalloc(sizeof(*e)); + if (!e) + goto parse_err; + + fanotify_mark_entry__init(&e->ffy.e); + fanotify_inode_mark_entry__init(&e->ffy.ie); + fh_entry__init(&e->ffy.f_handle); + e->ffy.e.ie = &e->ffy.ie; + e->ffy.ie.f_handle = &e->ffy.f_handle; ret = sscanf(str, "fanotify ino:%"PRIx64" sdev:%x mflags:%x mask:%x ignored_mask:%x " "fhandle-bytes:%x fhandle-type:%x f_handle: %n", - &ie.i_ino, &entry.ffy.s_dev, - &entry.ffy.mflags, &entry.ffy.mask, &entry.ffy.ignored_mask, - &f_handle.bytes, &f_handle.type, + &e->ffy.ie.i_ino, &e->ffy.e.s_dev, + &e->ffy.e.mflags, &e->ffy.e.mask, &e->ffy.e.ignored_mask, + &e->ffy.f_handle.bytes, &e->ffy.f_handle.type, &hoff); - if (ret != 7 || hoff == 0) + if (ret != 7 || hoff == 0) { + free_fanotify_mark_entry(e); goto parse_err; + } - if (alloc_fhandle(&f_handle)) { + if (alloc_fhandle(&e->ffy.f_handle)) { + free_fanotify_mark_entry(e); ret = -1; goto out; } - parse_fhandle_encoded(str + hoff, &f_handle); + parse_fhandle_encoded(str + hoff, &e->ffy.f_handle); - entry.ffy.type = MARK_TYPE__INODE; - ret = cb(&entry, arg); + e->ffy.e.type = MARK_TYPE__INODE; + ret = cb(e, arg); - free_fhandle(&f_handle); if (ret) goto out; @@ -1272,23 +1286,28 @@ static int parse_fdinfo_pid_s(char *pid, int fd, int type, continue; } if (fdinfo_field(str, "fanotify mnt_id")) { - FanotifyMountMarkEntry me = FANOTIFY_MOUNT_MARK_ENTRY__INIT; + union fdinfo_entries *e; if (type != FD_TYPES__FANOTIFY) goto parse_err; - fanotify_mark_entry__init(&entry.ffy); - entry.ffy.me = &me; + e = xmalloc(sizeof(*e)); + if (!e) + goto parse_err; + + fanotify_mark_entry__init(&e->ffy.e); + fanotify_mount_mark_entry__init(&e->ffy.me); + e->ffy.e.me = &e->ffy.me; ret = sscanf(str, "fanotify mnt_id:%x mflags:%x mask:%x ignored_mask:%x", - &me.mnt_id, &entry.ffy.mflags, - &entry.ffy.mask, &entry.ffy.ignored_mask); + &e->ffy.e.me->mnt_id, &e->ffy.e.mflags, + &e->ffy.e.mask, &e->ffy.e.ignored_mask); if (ret != 4) goto parse_err; - entry.ffy.type = MARK_TYPE__MOUNT; - ret = cb(&entry, arg); + e->ffy.e.type = MARK_TYPE__MOUNT; + ret = cb(e, arg); if (ret) goto out;