fsnotify: Fix memory leaks on error paths in pre_dump functions

The pre_dump_one_inotify() and pre_dump_one_fanotify() functions leak
memory when irmap_queue_cache() fails because they return early without
freeing the allocated entries.

Add free_inotify_wd_entries() and free_fanotify_mark_entries() helper
functions to properly free the entry arrays, and use them in all dump
functions to ensure cleanup on both success and error paths.

Also use the helpers in dump_one_inotify() and dump_one_fanotify() to
consolidate the cleanup code.

Signed-off-by: 3idey <3idey@users.noreply.github.com>
This commit is contained in:
3idey 2026-01-22 16:32:03 +02:00
parent 9e5fbcd668
commit 0cc60eba50

View file

@ -75,6 +75,26 @@ typedef struct {
u64 __handle[16];
} fh_t;
/* Helper to free inotify watch descriptor entries */
static void free_inotify_wd_entries(InotifyWdEntry **wd, int n_wd)
{
int i;
for (i = 0; i < n_wd; i++)
xfree(wd[i]);
xfree(wd);
}
/* Helper to free fanotify mark entries */
static void free_fanotify_mark_entries(FanotifyMarkEntry **mark, int n_mark)
{
int i;
for (i = 0; i < n_mark; i++)
xfree(mark[i]);
xfree(mark);
}
/* Checks if file descriptor @lfd is inotify */
int is_inotify_link(char *link)
{
@ -345,31 +365,28 @@ static int dump_one_inotify(int lfd, u32 id, const struct fd_parms *p)
exit_code = 0;
free:
for (i = 0; i < ie.n_wd; i++)
xfree(ie.wd[i]);
xfree(ie.wd);
free_inotify_wd_entries(ie.wd, ie.n_wd);
return exit_code;
}
static int pre_dump_one_inotify(int pid, int lfd)
{
InotifyFileEntry ie = INOTIFY_FILE_ENTRY__INIT;
int i;
int ret = -1, i;
if (parse_fdinfo_pid(pid, lfd, FD_TYPES__INOTIFY, &ie))
return -1;
goto out;
for (i = 0; i < ie.n_wd; i++) {
InotifyWdEntry *we = ie.wd[i];
if (irmap_queue_cache(we->s_dev, we->i_ino, we->f_handle))
return -1;
xfree(we);
goto out;
}
return 0;
ret = 0;
out:
free_inotify_wd_entries(ie.wd, ie.n_wd);
return ret;
}
const struct fdtype_ops inotify_dump_ops = {
@ -445,30 +462,28 @@ static int dump_one_fanotify(int lfd, u32 id, const struct fd_parms *p)
ret = pb_write_one(img_from_set(glob_imgset, CR_FD_FILES), &fle, PB_FILE);
free:
for (i = 0; i < fe.n_mark; i++)
xfree(fe.mark[i]);
xfree(fe.mark);
free_fanotify_mark_entries(fe.mark, fe.n_mark);
return ret;
}
static int pre_dump_one_fanotify(int pid, int lfd)
{
FanotifyFileEntry fe = FANOTIFY_FILE_ENTRY__INIT;
int i;
int ret = -1, i;
if (parse_fdinfo_pid(pid, lfd, FD_TYPES__FANOTIFY, &fe))
return -1;
goto out;
for (i = 0; i < fe.n_mark; i++) {
FanotifyMarkEntry *me = fe.mark[i];
if (me->type == MARK_TYPE__INODE && irmap_queue_cache(me->s_dev, me->ie->i_ino, me->ie->f_handle))
return -1;
xfree(me);
goto out;
}
xfree(fe.mark);
return 0;
ret = 0;
out:
free_fanotify_mark_entries(fe.mark, fe.n_mark);
return ret;
}
const struct fdtype_ops fanotify_dump_ops = {