From 9925f594b9ae553a58d2c760918adf5b13f49c96 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Jan 28 2023 06:11:31 +0000 Subject: import device-mapper-multipath-0.8.4-35.el8 --- diff --git a/SOURCES/0127-libmultipath-don-t-leak-memory-on-invalid-strings.patch b/SOURCES/0127-libmultipath-don-t-leak-memory-on-invalid-strings.patch new file mode 100644 index 0000000..ded6361 --- /dev/null +++ b/SOURCES/0127-libmultipath-don-t-leak-memory-on-invalid-strings.patch @@ -0,0 +1,35 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 14 Dec 2022 15:38:19 -0600 +Subject: [PATCH] libmultipath: don't leak memory on invalid strings + +If set_path() or set_str_noslash() are called with a bad value, they +ignore it and continue to use the old value. But they weren't freeing +the bad value, causing a memory leak. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmultipath/dict.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/libmultipath/dict.c b/libmultipath/dict.c +index d7cd94a5..a8c9e989 100644 +--- a/libmultipath/dict.c ++++ b/libmultipath/dict.c +@@ -169,6 +169,7 @@ set_path(vector strvec, void *ptr, const char *file, int line_nr) + if ((*str_ptr)[0] != '/'){ + condlog(1, "%s line %d, %s is not an absolute path. Ignoring", + file, line_nr, *str_ptr); ++ free(*str_ptr); + *str_ptr = old_str; + } else + free(old_str); +@@ -189,6 +190,7 @@ set_str_noslash(vector strvec, void *ptr, const char *file, int line_nr) + if (strchr(*str_ptr, '/')) { + condlog(1, "%s line %d, %s cannot contain a slash. Ignoring", + file, line_nr, *str_ptr); ++ free(*str_ptr); + *str_ptr = old_str; + } else + free(old_str); diff --git a/SOURCES/0128-libmutipath-validate-the-argument-count-of-config-st.patch b/SOURCES/0128-libmutipath-validate-the-argument-count-of-config-st.patch new file mode 100644 index 0000000..ced384f --- /dev/null +++ b/SOURCES/0128-libmutipath-validate-the-argument-count-of-config-st.patch @@ -0,0 +1,195 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 14 Dec 2022 15:38:20 -0600 +Subject: [PATCH] libmutipath: validate the argument count of config strings + +The features, path_selector, and hardware_handler config options pass +their strings directly into the kernel. If users omit the argument +counts from these strings, or use the wrong value, the kernel's table +parsing gets completely messed up, and the error messages it prints +don't reflect what actully went wrong. To avoid messing up the +kernel table parsing, verify that these strings correctly set the +argument count to the number of arguments they have. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmultipath/dict.c | 110 ++++++++++++++++++++++++++++++++++++++++---- + 1 file changed, 101 insertions(+), 9 deletions(-) + +diff --git a/libmultipath/dict.c b/libmultipath/dict.c +index a8c9e989..952b33d0 100644 +--- a/libmultipath/dict.c ++++ b/libmultipath/dict.c +@@ -155,6 +155,58 @@ set_dir(vector strvec, void *ptr, const char *file, int line_nr) + return 0; + } + ++static int ++set_arg_str(vector strvec, void *ptr, int count_idx, const char *file, ++ int line_nr) ++{ ++ char **str_ptr = (char **)ptr; ++ char *old_str = *str_ptr; ++ const char * const spaces = " \f\r\t\v"; ++ char *p, *end; ++ int idx = -1; ++ long int count = -1; ++ ++ *str_ptr = set_value(strvec); ++ if (!*str_ptr) { ++ free(old_str); ++ return 1; ++ } ++ p = *str_ptr; ++ while (*p != '\0') { ++ p += strspn(p, spaces); ++ if (*p == '\0') ++ break; ++ idx += 1; ++ if (idx == count_idx) { ++ errno = 0; ++ count = strtol(p, &end, 10); ++ if (errno == ERANGE || end == p || ++ !(isspace(*end) || *end == '\0')) { ++ count = -1; ++ break; ++ } ++ } ++ p += strcspn(p, spaces); ++ } ++ if (count < 0) { ++ condlog(1, "%s line %d, missing argument count for %s", ++ file, line_nr, (char*)VECTOR_SLOT(strvec, 0)); ++ goto fail; ++ } ++ if (count != idx - count_idx) { ++ condlog(1, "%s line %d, invalid argument count for %s:, got '%ld' expected '%d'", ++ file, line_nr, (char*)VECTOR_SLOT(strvec, 0), count, ++ idx - count_idx); ++ goto fail; ++ } ++ free(old_str); ++ return 0; ++fail: ++ free(*str_ptr); ++ *str_ptr = old_str; ++ return 0; ++} ++ + static int + set_path(vector strvec, void *ptr, const char *file, int line_nr) + { +@@ -337,6 +389,14 @@ def_ ## option ## _handler (struct config *conf, vector strvec, \ + return set_int(strvec, &conf->option, minval, maxval, file, line_nr); \ + } + ++#define declare_def_arg_str_handler(option, count_idx) \ ++static int \ ++def_ ## option ## _handler (struct config *conf, vector strvec, \ ++ const char *file, int line_nr) \ ++{ \ ++ return set_arg_str(strvec, &conf->option, count_idx, file, line_nr); \ ++} ++ + #define declare_def_snprint(option, function) \ + static int \ + snprint_def_ ## option (struct config *conf, char * buff, int len, \ +@@ -389,6 +449,17 @@ hw_ ## option ## _handler (struct config *conf, vector strvec, \ + return set_int(strvec, &hwe->option, minval, maxval, file, line_nr); \ + } + ++#define declare_hw_arg_str_handler(option, count_idx) \ ++static int \ ++hw_ ## option ## _handler (struct config *conf, vector strvec, \ ++ const char *file, int line_nr) \ ++{ \ ++ struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable); \ ++ if (!hwe) \ ++ return 1; \ ++ return set_arg_str(strvec, &hwe->option, count_idx, file, line_nr); \ ++} ++ + + #define declare_hw_snprint(option, function) \ + static int \ +@@ -420,6 +491,16 @@ ovr_ ## option ## _handler (struct config *conf, vector strvec, \ + file, line_nr); \ + } + ++#define declare_ovr_arg_str_handler(option, count_idx) \ ++static int \ ++ovr_ ## option ## _handler (struct config *conf, vector strvec, \ ++ const char *file, int line_nr) \ ++{ \ ++ if (!conf->overrides) \ ++ return 1; \ ++ return set_arg_str(strvec, &conf->overrides->option, count_idx, file, line_nr); \ ++} ++ + #define declare_ovr_snprint(option, function) \ + static int \ + snprint_ovr_ ## option (struct config *conf, char * buff, int len, \ +@@ -450,6 +531,17 @@ mp_ ## option ## _handler (struct config *conf, vector strvec, \ + return set_int(strvec, &mpe->option, minval, maxval, file, line_nr); \ + } + ++#define declare_mp_arg_str_handler(option, count_idx) \ ++static int \ ++mp_ ## option ## _handler (struct config *conf, vector strvec, \ ++ const char *file, int line_nr) \ ++{ \ ++ struct mpentry * mpe = VECTOR_LAST_SLOT(conf->mptable); \ ++ if (!mpe) \ ++ return 1; \ ++ return set_arg_str(strvec, &mpe->option, count_idx, file, line_nr); \ ++} ++ + #define declare_mp_snprint(option, function) \ + static int \ + snprint_mp_ ## option (struct config *conf, char * buff, int len, \ +@@ -634,13 +726,13 @@ snprint_def_marginal_pathgroups(struct config *conf, char *buff, int len, + } + + +-declare_def_handler(selector, set_str) ++declare_def_arg_str_handler(selector, 1) + declare_def_snprint_defstr(selector, print_str, DEFAULT_SELECTOR) +-declare_hw_handler(selector, set_str) ++declare_hw_arg_str_handler(selector, 1) + declare_hw_snprint(selector, print_str) +-declare_ovr_handler(selector, set_str) ++declare_ovr_arg_str_handler(selector, 1) + declare_ovr_snprint(selector, print_str) +-declare_mp_handler(selector, set_str) ++declare_mp_arg_str_handler(selector, 1) + declare_mp_snprint(selector, print_str) + + static int snprint_uid_attrs(struct config *conf, char *buff, int len, +@@ -717,13 +809,13 @@ declare_hw_snprint(prio_args, print_str) + declare_mp_handler(prio_args, set_str) + declare_mp_snprint(prio_args, print_str) + +-declare_def_handler(features, set_str) ++declare_def_arg_str_handler(features, 0) + declare_def_snprint_defstr(features, print_str, DEFAULT_FEATURES) +-declare_ovr_handler(features, set_str) ++declare_ovr_arg_str_handler(features, 0) + declare_ovr_snprint(features, print_str) +-declare_hw_handler(features, set_str) ++declare_hw_arg_str_handler(features, 0) + declare_hw_snprint(features, print_str) +-declare_mp_handler(features, set_str) ++declare_mp_arg_str_handler(features, 0) + declare_mp_snprint(features, print_str) + + declare_def_handler(checker_name, set_str) +@@ -1894,7 +1986,7 @@ declare_hw_snprint(revision, print_str) + declare_hw_handler(bl_product, set_regex) + declare_hw_snprint(bl_product, print_str) + +-declare_hw_handler(hwhandler, set_str) ++declare_hw_arg_str_handler(hwhandler, 0) + declare_hw_snprint(hwhandler, print_str) + + /* diff --git a/SPECS/device-mapper-multipath.spec b/SPECS/device-mapper-multipath.spec index 638ae6b..af16a9c 100644 --- a/SPECS/device-mapper-multipath.spec +++ b/SPECS/device-mapper-multipath.spec @@ -1,7 +1,7 @@ Summary: Tools to manage multipath devices using device-mapper Name: device-mapper-multipath Version: 0.8.4 -Release: 34%{?dist} +Release: 35%{?dist} License: GPLv2 Group: System Environment/Base URL: http://christophe.varoqui.free.fr/ @@ -137,6 +137,8 @@ Patch00123: 0123-libmultipath-get-nvme-path-transport-protocol.patch Patch00124: 0124-libmultipath-enforce-queue_mode-bio-for-nmve-tcp-pat.patch Patch00125: 0125-multipath-add-historical-service-time-to-the-man-pag.patch Patch00126: 0126-libmultipath-copy-mpp-hwe-from-pp-hwe.patch +Patch00127: 0127-libmultipath-don-t-leak-memory-on-invalid-strings.patch +Patch00128: 0128-libmutipath-validate-the-argument-count-of-config-st.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -341,6 +343,11 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Mon Jan 16 2023 Benjamin Marzinski 0.8.4-35 +- Add 0127-libmultipath-don-t-leak-memory-on-invalid-strings.patch +- Add 0128-libmutipath-validate-the-argument-count-of-config-st.patch +- Resolves: bz #2155560 + * Tue Nov 29 2022 Benjamin Marzinski 0.8.4-34 - Add 0126-libmultipath-copy-mpp-hwe-from-pp-hwe.patch * Fixes bz #2126714