From: 10144149 <tang.wenjun3@xxxxxxxxxx> Problem: multipathd dead when we run "show map mpathx json" command with system messages as follows: Oct 13 11:37:30 rhel7-1 multipathd: *** Error in `/sbin/multipathd': realloc(): invalid next size: 0x00007f8cf8004210 *** Oct 13 11:37:30 rhel7-1 multipathd: ======= Backtrace: ========= Oct 13 11:37:30 rhel7-1 multipathd: /lib64/libc.so.6(+0x7bc67)[0x7f8d06171c67] Oct 13 11:37:30 rhel7-1 multipathd: /lib64/libc.so.6(+0x7fb17)[0x7f8d06175b17] Oct 13 11:37:30 rhel7-1 multipathd: /lib64/libc.so.6(realloc+0xd2)[0x7f8d06176702] Reasons: in function snprint_multipath_fields_json vector_foreach_slot (pgp->paths, pp, j) { fwd += snprint_path(buff + fwd, len - fwd, PRINT_JSON_PATH, pp, 0); if (fwd > len) return fwd; fwd += snprint_json_elem_footer(buff + fwd, len - fwd, 3, j + 1 == VECTOR_SIZE(pgp->paths)); if (fwd > len) return fwd; } snprint_path (char * line, int len, char * format, struct path * pp, int pad) when len - fwd = 0 , The len is not restricted in snprint_path,and the Memory of line is rewritten in snprint_path, it cause realloc() failed , so fwd > len modify fwd >= len. consider of ben’s advice, It would probably also be smart to change all the if (!TAIL) lines to if (TAIL <= 0) just as an extra precaution. Other commands also have this type of risk. Signed-off-by: 10144149 <tang.wenjun3@xxxxxxxxxx> --- libmultipath/print.c | 141 ++++++++++++++++++++++++++------------------------- 1 file changed, 71 insertions(+), 70 deletions(-) diff --git a/libmultipath/print.c b/libmultipath/print.c index 9aa41ad..2eadb81 100644 --- a/libmultipath/print.c +++ b/libmultipath/print.c @@ -778,7 +778,7 @@ snprint_multipath_header (char * line, int len, char * format) struct multipath_data * data; do { - if (!TAIL) + if (TAIL <= 0) break; if (*f != '%') { @@ -811,7 +811,7 @@ snprint_multipath (char * line, int len, char * format, char buff[MAX_FIELD_LEN] = {}; do { - if (!TAIL) + if (TAIL <= 0) break; if (*f != '%') { @@ -845,7 +845,7 @@ snprint_path_header (char * line, int len, char * format) struct path_data * data; do { - if (!TAIL) + if (TAIL <= 0) break; if (*f != '%') { @@ -878,7 +878,7 @@ snprint_path (char * line, int len, char * format, char buff[MAX_FIELD_LEN]; do { - if (!TAIL) + if (TAIL <= 0) break; if (*f != '%') { @@ -913,7 +913,7 @@ snprint_pathgroup (char * line, int len, char * format, char buff[MAX_FIELD_LEN]; do { - if (!TAIL) + if (TAIL <= 0) break; if (*f != '%') { @@ -1004,11 +1004,11 @@ snprint_multipath_topology (char * buff, int len, struct multipath * mpp, c += sprintf(c, "%c[%dm", 0x1B, 0); /* bold off */ fwd += snprint_multipath(buff + fwd, len - fwd, style, mpp, 1); - if (fwd > len) + if (fwd >= len) return len; fwd += snprint_multipath(buff + fwd, len - fwd, PRINT_MAP_PROPS, mpp, 1); - if (fwd > len) + if (fwd >= len) return len; if (!mpp->pg) @@ -1022,7 +1022,7 @@ snprint_multipath_topology (char * buff, int len, struct multipath * mpp, } else strcpy(f, "`-+- " PRINT_PG_INDENT); fwd += snprint_pathgroup(buff + fwd, len - fwd, fmt, pgp); - if (fwd > len) + if (fwd >= len) return len; vector_foreach_slot (pgp->paths, pp, i) { @@ -1035,13 +1035,14 @@ snprint_multipath_topology (char * buff, int len, struct multipath * mpp, else strcpy(f, " `- " PRINT_PATH_INDENT); fwd += snprint_path(buff + fwd, len - fwd, fmt, pp, 1); - if (fwd > len) + if (fwd >= len) return len; } } return fwd; } + static int snprint_json (char * buff, int len, int indent, char *json_str) { @@ -1049,7 +1050,7 @@ snprint_json (char * buff, int len, int indent, char *json_str) for (i = 0; i < indent; i++) { fwd += snprintf(buff + fwd, len - fwd, PRINT_JSON_INDENT); - if (fwd > len) + if (fwd >= len) return fwd; } @@ -1063,7 +1064,7 @@ snprint_json_header (char * buff, int len) int fwd = 0; fwd += snprint_json(buff, len, 0, PRINT_JSON_START_ELEM); - if (fwd > len) + if (fwd >= len) return fwd; fwd += snprintf(buff + fwd, len - fwd, PRINT_JSON_START_VERSION, @@ -1078,7 +1079,7 @@ snprint_json_elem_footer (char * buff, int len, int indent, int last) for (i = 0; i < indent; i++) { fwd += snprintf(buff + fwd, len - fwd, PRINT_JSON_INDENT); - if (fwd > len) + if (fwd >= len) return fwd; } @@ -1098,50 +1099,50 @@ snprint_multipath_fields_json (char * buff, int len, struct pathgroup *pgp; fwd += snprint_multipath(buff, len, PRINT_JSON_MAP, mpp, 0); - if (fwd > len) + if (fwd >= len) return fwd; fwd += snprint_json(buff + fwd, len - fwd, 2, PRINT_JSON_START_GROUPS); - if (fwd > len) + if (fwd >= len) return fwd; vector_foreach_slot (mpp->pg, pgp, i) { pgp->selector = mpp->selector; fwd += snprint_pathgroup(buff + fwd, len - fwd, PRINT_JSON_GROUP, pgp); - if (fwd > len) + if (fwd >= len) return fwd; fwd += snprintf(buff + fwd, len - fwd, PRINT_JSON_GROUP_NUM, i + 1); - if (fwd > len) + if (fwd >= len) return fwd; fwd += snprint_json(buff + fwd, len - fwd, 3, PRINT_JSON_START_PATHS); - if (fwd > len) + if (fwd >= len) return fwd; vector_foreach_slot (pgp->paths, pp, j) { fwd += snprint_path(buff + fwd, len - fwd, PRINT_JSON_PATH, pp, 0); - if (fwd > len) + if (fwd >= len) return fwd; fwd += snprint_json_elem_footer(buff + fwd, len - fwd, 3, j + 1 == VECTOR_SIZE(pgp->paths)); - if (fwd > len) + if (fwd >= len) return fwd; } fwd += snprint_json(buff + fwd, len - fwd, 0, PRINT_JSON_END_ARRAY); - if (fwd > len) + if (fwd >= len) return fwd; fwd += snprint_json_elem_footer(buff + fwd, len - fwd, 2, i + 1 == VECTOR_SIZE(mpp->pg)); - if (fwd > len) + if (fwd >= len) return fwd; } fwd += snprint_json(buff + fwd, len - fwd, 0, PRINT_JSON_END_ARRAY); - if (fwd > len) + if (fwd >= len) return fwd; fwd += snprint_json_elem_footer(buff + fwd, len - fwd, 1, last); @@ -1154,23 +1155,23 @@ snprint_multipath_map_json (char * buff, int len, int fwd = 0; fwd += snprint_json_header(buff, len); - if (fwd > len) + if (fwd >= len) return len; fwd += snprint_json(buff + fwd, len - fwd, 0, PRINT_JSON_START_MAP); - if (fwd > len) + if (fwd >= len) return len; fwd += snprint_multipath_fields_json(buff + fwd, len - fwd, mpp, 1); - if (fwd > len) + if (fwd >= len) return len; fwd += snprint_json(buff + fwd, len - fwd, 0, "\n"); - if (fwd > len) + if (fwd >= len) return len; fwd += snprint_json(buff + fwd, len - fwd, 0, PRINT_JSON_END_LAST); - if (fwd > len) + if (fwd >= len) return len; return fwd; } @@ -1182,26 +1183,26 @@ snprint_multipath_topology_json (char * buff, int len, struct vectors * vecs) struct multipath * mpp; fwd += snprint_json_header(buff, len); - if (fwd > len) + if (fwd >= len) return len; fwd += snprint_json(buff + fwd, len - fwd, 1, PRINT_JSON_START_MAPS); - if (fwd > len) + if (fwd >= len) return len; vector_foreach_slot(vecs->mpvec, mpp, i) { fwd += snprint_multipath_fields_json(buff + fwd, len - fwd, mpp, i + 1 == VECTOR_SIZE(vecs->mpvec)); - if (fwd > len) + if (fwd >= len) return len; } fwd += snprint_json(buff + fwd, len - fwd, 0, PRINT_JSON_END_ARRAY); - if (fwd > len) + if (fwd >= len) return len; fwd += snprint_json(buff + fwd, len - fwd, 0, PRINT_JSON_END_LAST); - if (fwd > len) + if (fwd >= len) return len; return fwd; } @@ -1225,16 +1226,16 @@ snprint_hwentry (struct config *conf, char * buff, int len, struct hwentry * hwe return 0; fwd += snprintf(buff + fwd, len - fwd, "\tdevice {\n"); - if (fwd > len) + if (fwd >= len) return len; iterate_sub_keywords(rootkw, kw, i) { fwd += snprint_keyword(buff + fwd, len - fwd, "\t\t%k %v\n", kw, hwe); - if (fwd > len) + if (fwd >= len) return len; } fwd += snprintf(buff + fwd, len - fwd, "\t}\n"); - if (fwd > len) + if (fwd >= len) return len; return fwd; } @@ -1252,15 +1253,15 @@ snprint_hwtable (struct config *conf, char * buff, int len, vector hwtable) return 0; fwd += snprintf(buff + fwd, len - fwd, "devices {\n"); - if (fwd > len) + if (fwd >= len) return len; vector_foreach_slot (hwtable, hwe, i) { fwd += snprint_hwentry(conf, buff + fwd, len - fwd, hwe); - if (fwd > len) + if (fwd >= len) return len; } fwd += snprintf(buff + fwd, len - fwd, "}\n"); - if (fwd > len) + if (fwd >= len) return len; return fwd; } @@ -1278,16 +1279,16 @@ snprint_mpentry (struct config *conf, char * buff, int len, struct mpentry * mpe return 0; fwd += snprintf(buff + fwd, len - fwd, "\tmultipath {\n"); - if (fwd > len) + if (fwd >= len) return len; iterate_sub_keywords(rootkw, kw, i) { fwd += snprint_keyword(buff + fwd, len - fwd, "\t\t%k %v\n", kw, mpe); - if (fwd > len) + if (fwd >= len) return len; } fwd += snprintf(buff + fwd, len - fwd, "\t}\n"); - if (fwd > len) + if (fwd >= len) return len; return fwd; } @@ -1305,15 +1306,15 @@ snprint_mptable (struct config *conf, char * buff, int len, vector mptable) return 0; fwd += snprintf(buff + fwd, len - fwd, "multipaths {\n"); - if (fwd > len) + if (fwd >= len) return len; vector_foreach_slot (mptable, mpe, i) { fwd += snprint_mpentry(conf, buff + fwd, len - fwd, mpe); - if (fwd > len) + if (fwd >= len) return len; } fwd += snprintf(buff + fwd, len - fwd, "}\n"); - if (fwd > len) + if (fwd >= len) return len; return fwd; } @@ -1331,19 +1332,19 @@ snprint_overrides (struct config *conf, char * buff, int len, struct hwentry *ov return 0; fwd += snprintf(buff + fwd, len - fwd, "overrides {\n"); - if (fwd > len) + if (fwd >= len) return len; if (!overrides) goto out; iterate_sub_keywords(rootkw, kw, i) { fwd += snprint_keyword(buff + fwd, len - fwd, "\t%k %v\n", kw, NULL); - if (fwd > len) + if (fwd >= len) return len; } out: fwd += snprintf(buff + fwd, len - fwd, "}\n"); - if (fwd > len) + if (fwd >= len) return len; return fwd; } @@ -1361,17 +1362,17 @@ snprint_defaults (struct config *conf, char * buff, int len) return 0; fwd += snprintf(buff + fwd, len - fwd, "defaults {\n"); - if (fwd > len) + if (fwd >= len) return len; iterate_sub_keywords(rootkw, kw, i) { fwd += snprint_keyword(buff + fwd, len - fwd, "\t%k %v\n", kw, NULL); - if (fwd > len) + if (fwd >= len) return len; } fwd += snprintf(buff + fwd, len - fwd, "}\n"); - if (fwd > len) + if (fwd >= len) return len; return fwd; } @@ -1508,7 +1509,7 @@ snprint_blacklist (struct config *conf, char * buff, int len) return 0; fwd += snprintf(buff + fwd, len - fwd, "blacklist {\n"); - if (fwd > len) + if (fwd >= len) return len; vector_foreach_slot (conf->blist_devnode, ble, i) { @@ -1517,7 +1518,7 @@ snprint_blacklist (struct config *conf, char * buff, int len) return 0; fwd += snprint_keyword(buff + fwd, len - fwd, "\t%k %v\n", kw, ble); - if (fwd > len) + if (fwd >= len) return len; } vector_foreach_slot (conf->blist_wwid, ble, i) { @@ -1526,7 +1527,7 @@ snprint_blacklist (struct config *conf, char * buff, int len) return 0; fwd += snprint_keyword(buff + fwd, len - fwd, "\t%k %v\n", kw, ble); - if (fwd > len) + if (fwd >= len) return len; } vector_foreach_slot (conf->blist_property, ble, i) { @@ -1535,7 +1536,7 @@ snprint_blacklist (struct config *conf, char * buff, int len) return 0; fwd += snprint_keyword(buff + fwd, len - fwd, "\t%k %v\n", kw, ble); - if (fwd > len) + if (fwd >= len) return len; } rootkw = find_keyword(conf->keywords, rootkw->sub, "device"); @@ -1544,28 +1545,28 @@ snprint_blacklist (struct config *conf, char * buff, int len) vector_foreach_slot (conf->blist_device, bled, i) { fwd += snprintf(buff + fwd, len - fwd, "\tdevice {\n"); - if (fwd > len) + if (fwd >= len) return len; kw = find_keyword(conf->keywords, rootkw->sub, "vendor"); if (!kw) return 0; fwd += snprint_keyword(buff + fwd, len - fwd, "\t\t%k %v\n", kw, bled); - if (fwd > len) + if (fwd >= len) return len; kw = find_keyword(conf->keywords, rootkw->sub, "product"); if (!kw) return 0; fwd += snprint_keyword(buff + fwd, len - fwd, "\t\t%k %v\n", kw, bled); - if (fwd > len) + if (fwd >= len) return len; fwd += snprintf(buff + fwd, len - fwd, "\t}\n"); - if (fwd > len) + if (fwd >= len) return len; } fwd += snprintf(buff + fwd, len - fwd, "}\n"); - if (fwd > len) + if (fwd >= len) return len; return fwd; } @@ -1585,7 +1586,7 @@ snprint_blacklist_except (struct config *conf, char * buff, int len) return 0; fwd += snprintf(buff + fwd, len - fwd, "blacklist_exceptions {\n"); - if (fwd > len) + if (fwd >= len) return len; vector_foreach_slot (conf->elist_devnode, ele, i) { @@ -1594,7 +1595,7 @@ snprint_blacklist_except (struct config *conf, char * buff, int len) return 0; fwd += snprint_keyword(buff + fwd, len - fwd, "\t%k %v\n", kw, ele); - if (fwd > len) + if (fwd >= len) return len; } vector_foreach_slot (conf->elist_wwid, ele, i) { @@ -1603,7 +1604,7 @@ snprint_blacklist_except (struct config *conf, char * buff, int len) return 0; fwd += snprint_keyword(buff + fwd, len - fwd, "\t%k %v\n", kw, ele); - if (fwd > len) + if (fwd >= len) return len; } vector_foreach_slot (conf->elist_property, ele, i) { @@ -1612,7 +1613,7 @@ snprint_blacklist_except (struct config *conf, char * buff, int len) return 0; fwd += snprint_keyword(buff + fwd, len - fwd, "\t%k %v\n", kw, ele); - if (fwd > len) + if (fwd >= len) return len; } rootkw = find_keyword(conf->keywords, rootkw->sub, "device"); @@ -1621,28 +1622,28 @@ snprint_blacklist_except (struct config *conf, char * buff, int len) vector_foreach_slot (conf->elist_device, eled, i) { fwd += snprintf(buff + fwd, len - fwd, "\tdevice {\n"); - if (fwd > len) + if (fwd >= len) return len; kw = find_keyword(conf->keywords, rootkw->sub, "vendor"); if (!kw) return 0; fwd += snprint_keyword(buff + fwd, len - fwd, "\t\t%k %v\n", kw, eled); - if (fwd > len) + if (fwd >= len) return len; kw = find_keyword(conf->keywords, rootkw->sub, "product"); if (!kw) return 0; fwd += snprint_keyword(buff + fwd, len - fwd, "\t\t%k %v\n", kw, eled); - if (fwd > len) + if (fwd >= len) return len; fwd += snprintf(buff + fwd, len - fwd, "\t}\n"); - if (fwd > len) + if (fwd >= len) return len; } fwd += snprintf(buff + fwd, len - fwd, "}\n"); - if (fwd > len) + if (fwd >= len) return len; return fwd; } @@ -1674,7 +1675,7 @@ snprint_status (char * buff, int len, struct vectors *vecs) fwd += snprintf(buff + fwd, len - fwd, "\npaths: %d\nbusy: %s\n", monitored_count, is_uevent_busy()? "True" : "False"); - if (fwd > len) + if (fwd >= len) return len; return fwd; } @@ -1740,7 +1741,7 @@ snprint_devices (struct config *conf, char * buff, int len, struct vectors *vecs } closedir(blkdir); - if (fwd > len) + if (fwd >= len) return len; return fwd; } -- 2.8.1.windows.1 -- dm-devel mailing list dm-devel@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/dm-devel