From d56db0c55012c8a9ea2d3c72749022292c0f65b8 Mon Sep 17 00:00:00 2001 From: erentar Date: Tue, 23 Jun 2026 02:38:46 +0200 Subject: [PATCH] liblsd: fix const-correctness in _parse_single_range() This fix was authored by hector-cao originally for chaos/powerman#216. _parse_single_range() accepts a `const char *str` argument and creates a mutable copy via strdup() into `orig`. However, it was incorrectly calling strchr() and strtoul() on the original const pointer `str` rather than on the mutable copy. This is both a correctness bug and a build failure with modern glibc: - glibc now provides const-preserving overloads of strchr(), returning `const char *` when passed a `const char *`. Assigning this to `char *p` discards the const qualifier, triggering a compile error with -Werror=discarded-qualifiers. - The subsequent `*p++ = '\0'` write through `p` would modify memory via a pointer originally derived from a const string. Fix by using `orig` (the mutable strdup copy) for strchr() and strtoul() calls, which is the correct buffer to mutate. --- src/liblsd/hostlist.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/liblsd/hostlist.c b/src/liblsd/hostlist.c index dc440df7..102331a8 100644 --- a/src/liblsd/hostlist.c +++ b/src/liblsd/hostlist.c @@ -1409,16 +1409,16 @@ static int _parse_single_range(const char *str, struct _range *range) { char *p, *q; char *orig = strdup(str); - if (!orig) + if (!orig) seterrno_ret(ENOMEM, 0); - if ((p = strchr(str, '-'))) { + if ((p = strchr(orig, '-'))) { *p++ = '\0'; if (*p == '-') /* do NOT allow negative numbers */ goto error; } - range->lo = strtoul(str, &q, 10); - if (q == str) + range->lo = strtoul(orig, &q, 10); + if (q == orig) goto error; range->hi = (p && *p) ? strtoul(p, &q, 10) : range->lo; @@ -1435,8 +1435,8 @@ static int _parse_single_range(const char *str, struct _range *range) seterrno_ret(ERANGE, 0); } + range->width = strlen(orig); free(orig); - range->width = strlen(str); return 1; error: