From 966e5868aa01fa416d354f000a549005bc2e462b Mon Sep 17 00:00:00 2001 From: liuzhiqiang Date: Thu, 8 Dec 2022 02:48:34 +0000 Subject: [PATCH] backport two bugfix patches fix issue:https://gitee.com/src-openeuler/mdadm/issues/I62L1B?from=project-issue Signed-off-by: liuzhiqiang --- ...LL-ptr-dereferences-and-memory-leaks.patch | 76 ++++++++ ...en-md-device-for-CREATE-and-ASSEMBLE.patch | 165 ++++++++++++++++++ mdadm.spec | 7 +- 3 files changed, 247 insertions(+), 1 deletion(-) create mode 100644 0005-Fix-possible-NULL-ptr-dereferences-and-memory-leaks.patch create mode 100644 0006-mdadm-Don-t-open-md-device-for-CREATE-and-ASSEMBLE.patch diff --git a/0005-Fix-possible-NULL-ptr-dereferences-and-memory-leaks.patch b/0005-Fix-possible-NULL-ptr-dereferences-and-memory-leaks.patch new file mode 100644 index 0000000..b6acb7e --- /dev/null +++ b/0005-Fix-possible-NULL-ptr-dereferences-and-memory-leaks.patch @@ -0,0 +1,76 @@ +From ac934fb9123ac13e1de5883df1e5d136ebbb544e Mon Sep 17 00:00:00 2001 +From: Mateusz Grzonka +Date: Mon, 13 Jun 2022 11:59:34 +0200 +Subject: [PATCH 2/5] Fix possible NULL ptr dereferences and memory leaks + +In Assemble there was a NULL check for sra variable, +which effectively didn't stop the execution in every case. +That might have resulted in a NULL pointer dereference. + +Also in super-ddf, mu variable was set to NULL for some condition, +and then immidiately dereferenced. +Additionally some memory wasn't freed as well. + +Conflict:NA +Reference:https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git//commit?id=626bc45396c4959f2c4685c2faa7c4f553f4efdf + +Signed-off-by: Mateusz Grzonka +Signed-off-by: Jes Sorensen +--- + Assemble.c | 7 ++++++- + super-ddf.c | 9 +++++++-- + 2 files changed, 13 insertions(+), 3 deletions(-) + +diff --git a/Assemble.c b/Assemble.c +index 914c193..3ef4b29 100644 +--- a/Assemble.c ++++ b/Assemble.c +@@ -1909,7 +1909,12 @@ int assemble_container_content(struct supertype *st, int mdfd, + } + + sra = sysfs_read(mdfd, NULL, GET_VERSION|GET_DEVS); +- if (sra == NULL || strcmp(sra->text_version, content->text_version) != 0) { ++ if (sra == NULL) { ++ pr_err("Failed to read sysfs parameters\n"); ++ return 1; ++ } ++ ++ if (strcmp(sra->text_version, content->text_version) != 0) { + if (content->array.major_version == -1 && + content->array.minor_version == -2 && + c->readonly && +diff --git a/super-ddf.c b/super-ddf.c +index c095e8a..b61aa2f 100644 +--- a/super-ddf.c ++++ b/super-ddf.c +@@ -5121,13 +5121,16 @@ static struct mdinfo *ddf_activate_spare(struct active_array *a, + */ + vc = find_vdcr(ddf, a->info.container_member, rv->disk.raid_disk, + &n_bvd, &vcl); +- if (vc == NULL) ++ if (vc == NULL) { ++ free(rv); + return NULL; ++ } + + mu = xmalloc(sizeof(*mu)); + if (posix_memalign(&mu->space, 512, sizeof(struct vcl)) != 0) { + free(mu); +- mu = NULL; ++ free(rv); ++ return NULL; + } + + mu->len = ddf->conf_rec_len * 512 * vcl->conf.sec_elmnt_count; +@@ -5157,6 +5160,8 @@ static struct mdinfo *ddf_activate_spare(struct active_array *a, + pr_err("BUG: can't find disk %d (%d/%d)\n", + di->disk.raid_disk, + di->disk.major, di->disk.minor); ++ free(mu); ++ free(rv); + return NULL; + } + vc->phys_refnum[i_prim] = ddf->phys->entries[dl->pdnum].refnum; +-- +1.8.3.1 + diff --git a/0006-mdadm-Don-t-open-md-device-for-CREATE-and-ASSEMBLE.patch b/0006-mdadm-Don-t-open-md-device-for-CREATE-and-ASSEMBLE.patch new file mode 100644 index 0000000..7da8255 --- /dev/null +++ b/0006-mdadm-Don-t-open-md-device-for-CREATE-and-ASSEMBLE.patch @@ -0,0 +1,165 @@ +From 3ad381a0de084f63c4a1ac570f91d5fc585c6e3c Mon Sep 17 00:00:00 2001 +From: Logan Gunthorpe +Date: Wed, 27 Jul 2022 15:52:46 -0600 +Subject: [PATCH] mdadm: Don't open md device for CREATE and ASSEMBLE + +The mdadm command tries to open the md device for most modes, first +thing, no matter what. When running to create or assemble an array, +in most cases, the md device will not exist, the open call will fail +and everything will proceed correctly. + +However, when running tests, a create or assembly command may be run +shortly after stopping an array and the old md device file may still +be around. Then, if create_on_open is set in the kernel, a new md +device will be created when mdadm does its initial open. + +When mdadm gets around to creating the new device with the new_array +parameter it issues this error: + + mdadm: Fail to create md0 when using + /sys/module/md_mod/parameters/new_array, fallback to creation via node + +This is because an mddev was already created by the kernel with the +earlier open() call and thus the new one being created will fail with +EEXIST. The mdadm command will still successfully be created due to +falling back to the node creation method. However, the error message +itself will fail any test that's running it. + +This issue is a race condition that is very rare, but a recent change +in the kernel caused this to happen more frequently: about 1 in 50 +times. + +To fix this, don't bother trying to open the md device for CREATE, +ASSEMBLE and BUILD commands, as the file descriptor will never be used +anyway even if it is successfully openned. The mdfd has not been used +for these commands since: + + 7f91af49ad09 ("Delay creation of array devices for assemble/build/create") + +The checks that were done on the open device can be changed to being +done with stat. + +Side note: it would be nice to disable create_on_open as well to help +solve this, but it seems the work for this was never finished. By default, +mdadm will create using the old node interface when a name is specified +unless the user specifically puts names=yes in a config file, which +doesn't seem to be common or desirable to require this.. + +Conflict:NA +Reference:https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git//commit?id=27ad4900501c615b7c6b266bf23948e5606dba53 + +Signed-off-by: Logan Gunthorpe +Signed-off-by: Jes Sorensen +--- + lib.c | 12 ++++++++++++ + mdadm.c | 40 ++++++++++++++++++++-------------------- + mdadm.h | 1 + + 3 files changed, 33 insertions(+), 20 deletions(-) + +diff --git a/lib.c b/lib.c +index 7e3e3d4..e395b28 100644 +--- a/lib.c ++++ b/lib.c +@@ -164,6 +164,18 @@ char *stat2devnm(struct stat *st) + return devid2devnm(st->st_rdev); + } + ++bool stat_is_md_dev(struct stat *st) ++{ ++ if ((S_IFMT & st->st_mode) != S_IFBLK) ++ return false; ++ if (major(st->st_rdev) == MD_MAJOR) ++ return true; ++ if (major(st->st_rdev) == (unsigned)get_mdp_major()) ++ return true; ++ ++ return false; ++} ++ + char *fd2devnm(int fd) + { + struct stat stb; +diff --git a/mdadm.c b/mdadm.c +index 26299b2..0537f4a 100644 +--- a/mdadm.c ++++ b/mdadm.c +@@ -1347,6 +1347,9 @@ int main(int argc, char *argv[]) + + if (mode == MANAGE || mode == BUILD || mode == CREATE || + mode == GROW || (mode == ASSEMBLE && ! c.scan)) { ++ struct stat stb; ++ int ret; ++ + if (devs_found < 1) { + pr_err("an md device must be given in this mode\n"); + exit(2); +@@ -1359,6 +1362,12 @@ int main(int argc, char *argv[]) + mdfd = open_mddev(devlist->devname, 1); + if (mdfd < 0) + exit(1); ++ ++ ret = fstat(mdfd, &stb); ++ if (ret) { ++ pr_err("fstat failed on %s.\n", devlist->devname); ++ exit(1); ++ } + } else { + char *bname = basename(devlist->devname); + +@@ -1366,30 +1375,21 @@ int main(int argc, char *argv[]) + pr_err("Name %s is too long.\n", devlist->devname); + exit(1); + } +- /* non-existent device is OK */ +- mdfd = open_mddev(devlist->devname, 0); +- } +- if (mdfd == -2) { +- pr_err("device %s exists but is not an md array.\n", devlist->devname); +- exit(1); +- } +- if ((int)ident.super_minor == -2) { +- struct stat stb; +- if (mdfd < 0) { ++ ++ ret = stat(devlist->devname, &stb); ++ if (ident.super_minor == -2 && ret != 0) { + pr_err("--super-minor=dev given, and listed device %s doesn't exist.\n", +- devlist->devname); ++ devlist->devname); ++ exit(1); ++ } ++ ++ if (!ret && !stat_is_md_dev(&stb)) { ++ pr_err("device %s exists but is not an md array.\n", devlist->devname); + exit(1); + } +- fstat(mdfd, &stb); +- ident.super_minor = minor(stb.st_rdev); +- } +- if (mdfd >= 0 && mode != MANAGE && mode != GROW) { +- /* We don't really want this open yet, we just might +- * have wanted to check some things +- */ +- close(mdfd); +- mdfd = -1; + } ++ if (ident.super_minor == -2) ++ ident.super_minor = minor(stb.st_rdev); + } + + if (s.raiddisks) { +diff --git a/mdadm.h b/mdadm.h +index c7268a7..08875b0 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1660,6 +1660,7 @@ void *super1_make_v0(struct supertype *st, struct mdinfo *info, mdp_super_t *sb0 + extern char *stat2kname(struct stat *st); + extern char *fd2kname(int fd); + extern char *stat2devnm(struct stat *st); ++bool stat_is_md_dev(struct stat *st); + extern char *fd2devnm(int fd); + extern void udev_block(char *devnm); + extern void udev_unblock(void); +-- +2.33.0 + diff --git a/mdadm.spec b/mdadm.spec index c40ab8e..d30526b 100644 --- a/mdadm.spec +++ b/mdadm.spec @@ -1,6 +1,6 @@ Name: mdadm Version: 4.2 -Release: 3 +Release: 4 Summary: The software RAID arrays user manage tools License: GPLv2+ URL: http://www.kernel.org/pub/linux/utils/raid/mdadm/ @@ -14,6 +14,8 @@ Patch1: 0001-mdadm-remove-Werror-to-fix-Werror-address-of-packed-.patch Patch2: 0002-mdadm-Fix-mdadm-r-remove-option-regresision.patch Patch3: 0003-monitor-Avoid-segfault-when-calling-NULL-get_bad_blo.patch Patch4: 0004-mdadm-mdcheck_start.service-mdcheck_continue.service.patch +Patch5: 0005-Fix-possible-NULL-ptr-dereferences-and-memory-leaks.patch +Patch6: 0006-mdadm-Don-t-open-md-device-for-CREATE-and-ASSEMBLE.patch BuildRequires: systemd gcc binutils libudev-devel Requires(post): systemd coreutils @@ -79,6 +81,9 @@ install -d -m 710 %{buildroot}/var/run/mdadm/ %{_mandir}/man*/* %changelog +* Thu Dec 8 2022 Zhiqiang Liu - 4.2-4 +- backport two bugfix patches + * Fri Dec 2 2022 miaoguanqin - 4.2-3 - mdadmcheck_start.service mdadm_continue.service error -- Gitee