libmount: (parser) fix memory leak on error before end-of-file
Let's simplify the loop where we add FS to the table. The optimization for recoverable errors is a fragile overkill. The new code always allocates and unrefs FS for each loop. Addresses: https://github.com/karelzak/util-linux/pull/1068 Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
parent
d454da17da
commit
fe0d12d4f8
|
@ -39,7 +39,7 @@ struct libmnt_fs *mnt_new_fs(void)
|
|||
|
||||
fs->refcount = 1;
|
||||
INIT_LIST_HEAD(&fs->ents);
|
||||
/*DBG(FS, ul_debugobj(fs, "alloc"));*/
|
||||
DBG(FS, ul_debugobj(fs, "alloc"));
|
||||
return fs;
|
||||
}
|
||||
|
||||
|
|
|
@ -703,7 +703,6 @@ static int __table_parse_stream(struct libmnt_table *tb, FILE *f, const char *fi
|
|||
int rc = -1;
|
||||
int flags = 0;
|
||||
pid_t tid = -1;
|
||||
struct libmnt_fs *fs = NULL;
|
||||
struct libmnt_parser pa = { .line = 0 };
|
||||
|
||||
assert(tb);
|
||||
|
@ -723,19 +722,25 @@ static int __table_parse_stream(struct libmnt_table *tb, FILE *f, const char *fi
|
|||
if (filename && strcmp(filename, _PATH_PROC_MOUNTS) == 0)
|
||||
flags = MNT_FS_KERNEL;
|
||||
|
||||
while (!feof(f)) {
|
||||
if (!fs) {
|
||||
fs = mnt_new_fs();
|
||||
if (!fs)
|
||||
goto err;
|
||||
}
|
||||
do {
|
||||
struct libmnt_fs *fs;
|
||||
|
||||
if (feof(f)) {
|
||||
DBG(TAB, ul_debugobj(tb, "end-of-file"));
|
||||
break;
|
||||
}
|
||||
fs = mnt_new_fs();
|
||||
if (!fs)
|
||||
goto err;
|
||||
|
||||
/* parse */
|
||||
rc = mnt_table_parse_next(&pa, tb, fs);
|
||||
|
||||
if (!rc && tb->fltrcb && tb->fltrcb(fs, tb->fltrcb_data))
|
||||
rc = 1; /* filtered out by callback... */
|
||||
if (rc != 0 && tb->fltrcb && tb->fltrcb(fs, tb->fltrcb_data))
|
||||
rc = 1; /* error filtered out by callback... */
|
||||
|
||||
if (!rc) {
|
||||
/* add to the table */
|
||||
if (rc == 0) {
|
||||
rc = mnt_table_add_fs(tb, fs);
|
||||
fs->flags |= flags;
|
||||
|
||||
|
@ -746,21 +751,21 @@ static int __table_parse_stream(struct libmnt_table *tb, FILE *f, const char *fi
|
|||
}
|
||||
}
|
||||
|
||||
if (rc) {
|
||||
if (rc > 0) {
|
||||
mnt_reset_fs(fs);
|
||||
assert(fs->refcount == 1);
|
||||
continue; /* recoverable error, reuse fs*/
|
||||
}
|
||||
|
||||
mnt_unref_fs(fs);
|
||||
if (feof(f))
|
||||
break;
|
||||
goto err; /* fatal error */
|
||||
}
|
||||
/* remove refernece (or deallocate on error) */
|
||||
mnt_unref_fs(fs);
|
||||
fs = NULL;
|
||||
}
|
||||
|
||||
/* recoverable error */
|
||||
if (rc > 0) {
|
||||
DBG(TAB, ul_debugobj(tb, "recoverable error (continue)"));
|
||||
continue;
|
||||
}
|
||||
|
||||
/* fatal errors */
|
||||
if (rc < 0 && !feof(f)) {
|
||||
DBG(TAB, ul_debugobj(tb, "fatal error"));
|
||||
goto err;
|
||||
}
|
||||
} while (1);
|
||||
|
||||
DBG(TAB, ul_debugobj(tb, "%s: stop parsing (%d entries)",
|
||||
filename, mnt_table_get_nents(tb)));
|
||||
|
|
Loading…
Reference in New Issue