From 66453c951e5cd45f1f86d5f12376009e0a81d4fa Mon Sep 17 00:00:00 2001 From: Yangyang Shen Date: Tue, 28 Jul 2020 10:46:35 +0800 Subject: [PATCH] libmount parser fix memory leak on error before end --- ...fix-memory-leak-on-error-before-end-.patch | 114 ++++++++++++++++++ util-linux.spec | 6 +- 2 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 libmount-parser-fix-memory-leak-on-error-before-end-.patch diff --git a/libmount-parser-fix-memory-leak-on-error-before-end-.patch b/libmount-parser-fix-memory-leak-on-error-before-end-.patch new file mode 100644 index 0000000..e50e234 --- /dev/null +++ b/libmount-parser-fix-memory-leak-on-error-before-end-.patch @@ -0,0 +1,114 @@ +From fe0d12d4f82269096f8d0cffc51ca9590814c284 Mon Sep 17 00:00:00 2001 +From: Karel Zak +Date: Fri, 26 Jun 2020 12:59:32 +0200 +Subject: [PATCH 821/863] 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 +--- + libmount/src/fs.c | 2 +- + libmount/src/tab_parse.c | 49 ++++++++++++++++++++++++++---------------------- + 2 files changed, 28 insertions(+), 23 deletions(-) + +diff --git a/libmount/src/fs.c b/libmount/src/fs.c +index bcc8273..52f937a 100644 +--- a/libmount/src/fs.c ++++ b/libmount/src/fs.c +@@ -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; + } + +diff --git a/libmount/src/tab_parse.c b/libmount/src/tab_parse.c +index 3b52f6b..e3f30c2 100644 +--- a/libmount/src/tab_parse.c ++++ b/libmount/src/tab_parse.c +@@ -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*/ +- } ++ /* remove refernece (or deallocate on error) */ ++ mnt_unref_fs(fs); + +- mnt_unref_fs(fs); +- if (feof(f)) +- break; +- goto err; /* fatal error */ ++ /* recoverable error */ ++ if (rc > 0) { ++ DBG(TAB, ul_debugobj(tb, "recoverable error (continue)")); ++ continue; + } +- mnt_unref_fs(fs); +- fs = NULL; +- } ++ ++ /* 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))); +-- +1.8.3.1 + diff --git a/util-linux.spec b/util-linux.spec index 3d48e59..76cdae5 100644 --- a/util-linux.spec +++ b/util-linux.spec @@ -2,7 +2,7 @@ Name: util-linux Version: 2.35.1 -Release: 2 +Release: 3 Summary: A random collection of Linux utilities License: GPLv2 and GPLv2+ and LGPLv2+ and BSD with advertising and Public Domain URL: https://git.kernel.org/pub/scm/utils/util-linux/util-linux.git @@ -67,6 +67,7 @@ Patch29: sfdisk-only-report-I-O-errors-on-move-data.patch Patch30: umount-don-t-try-it-as-non-suid-if-not-found-mountin.patch Patch31: write-fix-potential-string-overflow.patch Patch32: do-not-excute-mountpoint-test.patch +Patch33: libmount-parser-fix-memory-leak-on-error-before-end-.patch %description The util-linux package contains a random collection of files that @@ -411,6 +412,9 @@ fi %{_mandir}/man8/{swapoff.8*,swapon.8*,switch_root.8*,umount.8*,wdctl.8.gz,wipefs.8*,zramctl.8*} %changelog +* Tue Jul 28 2020 shenyangyang - 2.35.1-3 +- libmount parser fix memory leak on error before end + * Wed Jul 1 2020 liuchengaung - 2.35.1-2 - quality enhancement synchronization github patch