diff --git a/cr-check.c b/cr-check.c index df51484f6..fe7d03c99 100644 --- a/cr-check.c +++ b/cr-check.c @@ -353,7 +353,8 @@ pipe_err: static int check_one_inotify(union fdinfo_entries *e, void *arg) { - *(int *)arg = e->ify.wd; + *(int *)arg = e->ify.e.wd; + free_inotify_wd_entry(e); return 0; } diff --git a/fsnotify.c b/fsnotify.c index f9e0d0a01..7966606ed 100644 --- a/fsnotify.c +++ b/fsnotify.c @@ -199,7 +199,8 @@ err: static int dump_inotify_entry(union fdinfo_entries *e, void *arg) { - InotifyWdEntry *we = &e->ify; + InotifyWdEntry *we = &e->ify.e; + int ret = -1; we->id = *(u32 *)arg; pr_info("wd: wd 0x%08x s_dev 0x%08x i_ino 0x%16"PRIx64" mask 0x%08x\n", @@ -209,9 +210,13 @@ static int dump_inotify_entry(union fdinfo_entries *e, void *arg) we->f_handle->handle[0], we->f_handle->handle[1]); if (check_open_handle(we->s_dev, we->i_ino, we->f_handle)) - return -1; + goto out; - return pb_write_one(fdset_fd(glob_fdset, CR_FD_INOTIFY_WD), we, PB_INOTIFY_WD); + if (pb_write_one(fdset_fd(glob_fdset, CR_FD_INOTIFY_WD), we, PB_INOTIFY_WD)) + goto out; +out: + free_inotify_wd_entry(e); + return ret; } static int dump_one_inotify(int lfd, u32 id, const struct fd_parms *p) @@ -231,8 +236,13 @@ static int dump_one_inotify(int lfd, u32 id, const struct fd_parms *p) static int pre_dump_inotify_entry(union fdinfo_entries *e, void *arg) { - InotifyWdEntry *we = &e->ify; - return irmap_queue_cache(we->s_dev, we->i_ino, we->f_handle); + InotifyWdEntry *we = &e->ify.e; + int ret; + + ret = irmap_queue_cache(we->s_dev, we->i_ino, we->f_handle); + free_inotify_wd_entry(e); + + return ret; } static int pre_dump_one_inotify(int pid, int lfd) diff --git a/include/fsnotify.h b/include/fsnotify.h index cabf525ce..f631b0917 100644 --- a/include/fsnotify.h +++ b/include/fsnotify.h @@ -4,6 +4,9 @@ #include "asm/types.h" #include "files.h" +#include "protobuf.h" +#include "protobuf/fsnotify.pb-c.h" + struct fsnotify_params { u32 id; u32 faflags; diff --git a/include/proc_parse.h b/include/proc_parse.h index 3ac25b260..2bef49488 100644 --- a/include/proc_parse.h +++ b/include/proc_parse.h @@ -166,15 +166,23 @@ extern int parse_smaps(pid_t pid, struct vm_area_list *vma_area_list, bool use_m extern int parse_self_maps_lite(struct vm_area_list *vms); extern int parse_pid_status(pid_t pid, struct proc_status_creds *); +struct inotify_wd_entry { + InotifyWdEntry e; + FhEntry f_handle; + struct list_head node; +}; + union fdinfo_entries { EventfdFileEntry efd; EventpollTfdEntry epl; SignalfdEntry sfd; - InotifyWdEntry ify; + struct inotify_wd_entry ify; FanotifyMarkEntry ffy; TimerfdEntry tfy; }; +extern void free_inotify_wd_entry(union fdinfo_entries *e); + struct fdinfo_common { off64_t pos; int flags; diff --git a/proc_parse.c b/proc_parse.c index def91b2a3..c6390fa76 100644 --- a/proc_parse.c +++ b/proc_parse.c @@ -1038,6 +1038,12 @@ static void free_fhandle(FhEntry *fh) xfree(fh->handle); } +void free_inotify_wd_entry(union fdinfo_entries *e) +{ + free_fhandle(e->ify.e.f_handle); + xfree(e); +} + static void parse_fhandle_encoded(char *tok, FhEntry *fh) { char *d = (char *)fh->handle; @@ -1290,36 +1296,45 @@ static int parse_fdinfo_pid_s(char *pid, int fd, int type, continue; } if (fdinfo_field(str, "inotify wd")) { - FhEntry f_handle = FH_ENTRY__INIT; + InotifyWdEntry *ify; + union fdinfo_entries *e; int hoff; - inotify_wd_entry__init(&entry.ify); - entry.ify.f_handle = &f_handle; - if (type != FD_TYPES__INOTIFY) goto parse_err; + + e = xmalloc(sizeof(*e)); + if (!e) + goto parse_err; + ify = &e->ify.e; + + inotify_wd_entry__init(ify); + ify->f_handle = &e->ify.f_handle; + fh_entry__init(ify->f_handle); + ret = sscanf(str, "inotify wd:%x ino:%"PRIx64" sdev:%x " "mask:%x ignored_mask:%x " "fhandle-bytes:%x fhandle-type:%x " "f_handle: %n", - &entry.ify.wd, &entry.ify.i_ino, &entry.ify.s_dev, - &entry.ify.mask, &entry.ify.ignored_mask, - &entry.ify.f_handle->bytes, &entry.ify.f_handle->type, + &ify->wd, &ify->i_ino, &ify->s_dev, + &ify->mask, &ify->ignored_mask, + &ify->f_handle->bytes, &ify->f_handle->type, &hoff); - if (ret != 7) + if (ret != 7) { + free_inotify_wd_entry(e); goto parse_err; + } - if (alloc_fhandle(&f_handle)) { + if (alloc_fhandle(ify->f_handle)) { + free_inotify_wd_entry(e); ret = -1; goto out; } - parse_fhandle_encoded(str + hoff, entry.ify.f_handle); + parse_fhandle_encoded(str + hoff, ify->f_handle); - ret = cb(&entry, arg); - - free_fhandle(&f_handle); + ret = cb(e, arg); if (ret) goto out;