|
|
0e1b67 |
From 780f79420073e0c09cd41afea28ac217a6d4ef29 Mon Sep 17 00:00:00 2001
|
|
|
0e1b67 |
From: Karel Zak <kzak@redhat.com>
|
|
|
0e1b67 |
Date: Fri, 26 Jun 2020 12:59:32 +0200
|
|
|
0e1b67 |
Subject: [PATCH 49/55] libmount: (parser) fix memory leak on error before
|
|
|
0e1b67 |
end-of-file
|
|
|
0e1b67 |
|
|
|
0e1b67 |
Let's simplify the loop where we add FS to the table. The optimization
|
|
|
0e1b67 |
for recoverable errors is a fragile overkill. The new code always
|
|
|
0e1b67 |
allocates and unrefs FS for each loop.
|
|
|
0e1b67 |
|
|
|
0e1b67 |
Addresses: https://github.com/karelzak/util-linux/pull/1068
|
|
|
0e1b67 |
Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=1900498
|
|
|
0e1b67 |
Upstream: http://github.com/karelzak/util-linux/commit/fe0d12d4f82269096f8d0cffc51ca9590814c284
|
|
|
0e1b67 |
Signed-off-by: Karel Zak <kzak@redhat.com>
|
|
|
0e1b67 |
---
|
|
|
0e1b67 |
libmount/src/fs.c | 2 +-
|
|
|
0e1b67 |
libmount/src/tab_parse.c | 49 ++++++++++++++++++++++------------------
|
|
|
0e1b67 |
2 files changed, 28 insertions(+), 23 deletions(-)
|
|
|
0e1b67 |
|
|
|
0e1b67 |
diff --git a/libmount/src/fs.c b/libmount/src/fs.c
|
|
|
0e1b67 |
index def32253c..aae4961c3 100644
|
|
|
0e1b67 |
--- a/libmount/src/fs.c
|
|
|
0e1b67 |
+++ b/libmount/src/fs.c
|
|
|
0e1b67 |
@@ -34,7 +34,7 @@ struct libmnt_fs *mnt_new_fs(void)
|
|
|
0e1b67 |
|
|
|
0e1b67 |
fs->refcount = 1;
|
|
|
0e1b67 |
INIT_LIST_HEAD(&fs->ents);
|
|
|
0e1b67 |
- /*DBG(FS, ul_debugobj(fs, "alloc"));*/
|
|
|
0e1b67 |
+ DBG(FS, ul_debugobj(fs, "alloc"));
|
|
|
0e1b67 |
return fs;
|
|
|
0e1b67 |
}
|
|
|
0e1b67 |
|
|
|
0e1b67 |
diff --git a/libmount/src/tab_parse.c b/libmount/src/tab_parse.c
|
|
|
0e1b67 |
index 10fc68279..719c1abca 100644
|
|
|
0e1b67 |
--- a/libmount/src/tab_parse.c
|
|
|
0e1b67 |
+++ b/libmount/src/tab_parse.c
|
|
|
0e1b67 |
@@ -608,7 +608,6 @@ static int __table_parse_stream(struct libmnt_table *tb, FILE *f, const char *fi
|
|
|
0e1b67 |
int rc = -1;
|
|
|
0e1b67 |
int flags = 0;
|
|
|
0e1b67 |
pid_t tid = -1;
|
|
|
0e1b67 |
- struct libmnt_fs *fs = NULL;
|
|
|
0e1b67 |
struct libmnt_parser pa = { .line = 0 };
|
|
|
0e1b67 |
|
|
|
0e1b67 |
assert(tb);
|
|
|
0e1b67 |
@@ -628,19 +627,25 @@ static int __table_parse_stream(struct libmnt_table *tb, FILE *f, const char *fi
|
|
|
0e1b67 |
if (filename && strcmp(filename, _PATH_PROC_MOUNTS) == 0)
|
|
|
0e1b67 |
flags = MNT_FS_KERNEL;
|
|
|
0e1b67 |
|
|
|
0e1b67 |
- while (!feof(f)) {
|
|
|
0e1b67 |
- if (!fs) {
|
|
|
0e1b67 |
- fs = mnt_new_fs();
|
|
|
0e1b67 |
- if (!fs)
|
|
|
0e1b67 |
- goto err;
|
|
|
0e1b67 |
+ do {
|
|
|
0e1b67 |
+ struct libmnt_fs *fs;
|
|
|
0e1b67 |
+
|
|
|
0e1b67 |
+ if (feof(f)) {
|
|
|
0e1b67 |
+ DBG(TAB, ul_debugobj(tb, "end-of-file"));
|
|
|
0e1b67 |
+ break;
|
|
|
0e1b67 |
}
|
|
|
0e1b67 |
+ fs = mnt_new_fs();
|
|
|
0e1b67 |
+ if (!fs)
|
|
|
0e1b67 |
+ goto err;
|
|
|
0e1b67 |
|
|
|
0e1b67 |
+ /* parse */
|
|
|
0e1b67 |
rc = mnt_table_parse_next(&pa, tb, fs);
|
|
|
0e1b67 |
|
|
|
0e1b67 |
- if (!rc && tb->fltrcb && tb->fltrcb(fs, tb->fltrcb_data))
|
|
|
0e1b67 |
- rc = 1; /* filtered out by callback... */
|
|
|
0e1b67 |
+ if (rc != 0 && tb->fltrcb && tb->fltrcb(fs, tb->fltrcb_data))
|
|
|
0e1b67 |
+ rc = 1; /* error filtered out by callback... */
|
|
|
0e1b67 |
|
|
|
0e1b67 |
- if (!rc) {
|
|
|
0e1b67 |
+ /* add to the table */
|
|
|
0e1b67 |
+ if (rc == 0) {
|
|
|
0e1b67 |
rc = mnt_table_add_fs(tb, fs);
|
|
|
0e1b67 |
fs->flags |= flags;
|
|
|
0e1b67 |
|
|
|
0e1b67 |
@@ -651,21 +656,21 @@ static int __table_parse_stream(struct libmnt_table *tb, FILE *f, const char *fi
|
|
|
0e1b67 |
}
|
|
|
0e1b67 |
}
|
|
|
0e1b67 |
|
|
|
0e1b67 |
- if (rc) {
|
|
|
0e1b67 |
- if (rc > 0) {
|
|
|
0e1b67 |
- mnt_reset_fs(fs);
|
|
|
0e1b67 |
- assert(fs->refcount == 1);
|
|
|
0e1b67 |
- continue; /* recoverable error, reuse fs*/
|
|
|
0e1b67 |
- }
|
|
|
0e1b67 |
+ /* remove refernece (or deallocate on error) */
|
|
|
0e1b67 |
+ mnt_unref_fs(fs);
|
|
|
0e1b67 |
|
|
|
0e1b67 |
- mnt_unref_fs(fs);
|
|
|
0e1b67 |
- if (feof(f))
|
|
|
0e1b67 |
- break;
|
|
|
0e1b67 |
- goto err; /* fatal error */
|
|
|
0e1b67 |
+ /* recoverable error */
|
|
|
0e1b67 |
+ if (rc > 0) {
|
|
|
0e1b67 |
+ DBG(TAB, ul_debugobj(tb, "recoverable error (continue)"));
|
|
|
0e1b67 |
+ continue;
|
|
|
0e1b67 |
}
|
|
|
0e1b67 |
- mnt_unref_fs(fs);
|
|
|
0e1b67 |
- fs = NULL;
|
|
|
0e1b67 |
- }
|
|
|
0e1b67 |
+
|
|
|
0e1b67 |
+ /* fatal errors */
|
|
|
0e1b67 |
+ if (rc < 0 && !feof(f)) {
|
|
|
0e1b67 |
+ DBG(TAB, ul_debugobj(tb, "fatal error"));
|
|
|
0e1b67 |
+ goto err;
|
|
|
0e1b67 |
+ }
|
|
|
0e1b67 |
+ } while (1);
|
|
|
0e1b67 |
|
|
|
0e1b67 |
DBG(TAB, ul_debugobj(tb, "%s: stop parsing (%d entries)",
|
|
|
0e1b67 |
filename, mnt_table_get_nents(tb)));
|
|
|
0e1b67 |
--
|
|
|
0e1b67 |
2.29.2
|
|
|
0e1b67 |
|