diff --git a/0019-Fix-memory-leak-in-file-Manage.patch b/0019-Fix-memory-leak-in-file-Manage.patch new file mode 100644 index 0000000000000000000000000000000000000000..f3125f5fd4c56cec41aa2cd2755df9e34c61aaa6 --- /dev/null +++ b/0019-Fix-memory-leak-in-file-Manage.patch @@ -0,0 +1,74 @@ +From f6feb3fbb50f48c193e9e4d775a20aa20f7b47b3 Mon Sep 17 00:00:00 2001 +From: Guanqin Miao +Date: Mon, 24 Apr 2023 16:06:36 +0800 +Subject: [PATCH] Fix memory leak in file Manage + +When we test mdadm with asan, we found some memory leaks in Manage.c +We fix these memory leaks based on code logic. + +v2: Fix free() of uninitialized 'tst' in abort path. + +Signed-off-by: Guanqin Miao +Signed-off-by: Li Xiao Keng +Acked-by: Mariusz Tkaczyk +Signed-off-by: Jes Sorensen +--- + Manage.c | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +diff --git a/Manage.c b/Manage.c +index f54de7c6..f997b163 100644 +--- a/Manage.c ++++ b/Manage.c +@@ -222,6 +222,7 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry) + if (verbose >= 0) + pr_err("Cannot get exclusive access to %s:Perhaps a running process, mounted filesystem or active volume group?\n", + devname); ++ sysfs_free(mdi); + return 1; + } + /* If this is an mdmon managed array, just write 'inactive' +@@ -801,8 +802,14 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv, + rdev, update, devname, + verbose, array); + dev_st->ss->free_super(dev_st); +- if (rv) ++ if (rv) { ++ free(dev_st); + return rv; ++ } ++ } ++ if (dev_st) { ++ dev_st->ss->free_super(dev_st); ++ free(dev_st); + } + } + if (dv->disposition == 'M') { +@@ -1362,7 +1369,7 @@ int Manage_subdevs(char *devname, int fd, + unsigned long long array_size; + struct mddev_dev *dv; + int tfd = -1; +- struct supertype *tst; ++ struct supertype *tst = NULL; + char *subarray = NULL; + int sysfd = -1; + int count = 0; /* number of actions taken */ +@@ -1699,6 +1706,7 @@ int Manage_subdevs(char *devname, int fd, + break; + } + } ++ free(tst); + if (frozen > 0) + sysfs_set_str(&info, NULL, "sync_action","idle"); + if (test && count == 0) +@@ -1706,6 +1714,7 @@ int Manage_subdevs(char *devname, int fd, + return 0; + + abort: ++ free(tst); + if (frozen > 0) + sysfs_set_str(&info, NULL, "sync_action","idle"); + return !test && busy ? 2 : 1; +-- +2.39.2 + diff --git a/0020-Manage-fix-check-after-dereference-issue.patch b/0020-Manage-fix-check-after-dereference-issue.patch new file mode 100644 index 0000000000000000000000000000000000000000..a95677268905a512d774f47ca224d2f9af543dff --- /dev/null +++ b/0020-Manage-fix-check-after-dereference-issue.patch @@ -0,0 +1,64 @@ +From e97ca3583c96591af0e4863c12c394074a51c84d Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Thu, 29 Feb 2024 12:52:07 +0100 +Subject: [PATCH] Manage: fix check after dereference issue + +The code dereferences dev_st earlier without checking, it gives SAST +problem. + +dev_st is needed for attempt_re_add(), but it is executed only if +dv->disposition != 'S', so move disposition check up. + +tst is a must to reach this place, dup_super() have to return valid +pointer, all it needs to check is if load_super() returns superblock. + +Signed-off-by: Mariusz Tkaczyk +--- + Manage.c | 26 ++++++++++++-------------- + 1 file changed, 12 insertions(+), 14 deletions(-) + +diff --git a/Manage.c b/Manage.c +index 30302ac8..77b79cf5 100644 +--- a/Manage.c ++++ b/Manage.c +@@ -794,25 +794,23 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv, + * simply re-add it. + */ + +- if (array->not_persistent == 0) { ++ if (array->not_persistent == 0 && dv->disposition != 'S') { ++ int rv = 0; ++ + dev_st = dup_super(tst); + dev_st->ss->load_super(dev_st, tfd, NULL); +- if (dev_st->sb && dv->disposition != 'S') { +- int rv; + +- rv = attempt_re_add(fd, tfd, dv, dev_st, tst, +- rdev, update, devname, +- verbose, array); +- dev_st->ss->free_super(dev_st); +- if (rv) { +- free(dev_st); +- return rv; +- } +- } +- if (dev_st) { ++ if (dev_st->sb) { ++ rv = attempt_re_add(fd, tfd, dv, dev_st, tst, rdev, update, ++ devname, verbose, array); ++ + dev_st->ss->free_super(dev_st); +- free(dev_st); + } ++ ++ free(dev_st); ++ ++ if (rv) ++ return rv; + } + if (dv->disposition == 'M') { + if (verbose > 0) +-- +2.39.2 + diff --git a/mdadm.spec b/mdadm.spec index fd4647b15e120de87a4efe358ca2d91450fd4abe..a56d1f2818c4d231cf6893bf3abab4af15b6dd63 100644 --- a/mdadm.spec +++ b/mdadm.spec @@ -1,6 +1,6 @@ Name: mdadm Version: 4.2 -Release: 15 +Release: 16 Summary: The software RAID arrays user manage tools License: GPLv2+ URL: http://www.kernel.org/pub/linux/utils/raid/mdadm/ @@ -28,6 +28,8 @@ Patch15: 0015-mdadm-Fix-double-free.patch Patch16: 0016-Mdmonitor-Fix-segfault.patch Patch17: 0017-mdmon-fix-segfault.patch Patch18: 0018-fix-memory-leak-in-file-mdadm.patch +Patch19: 0019-Fix-memory-leak-in-file-Manage.patch +Patch20: 0020-Manage-fix-check-after-dereference-issue.patch BuildRequires: systemd gcc binutils libudev-devel @@ -94,6 +96,9 @@ install -d -m 710 %{buildroot}/var/run/mdadm/ %{_mandir}/man*/* %changelog +* Mon Jun 24 2024 wuguanghao - 4.2-16 +- Manage: fix check after dereference issue + * Thu Jun 6 2024 zhangyaqi - 4.2-15 - fix memory leak in file mdadm