|
|
Message-ID: <20250320164210.522b40cb@ncopa-desktop.lan>
Date: Thu, 20 Mar 2025 16:42:10 +0100
From: Natanael Copa <ncopa@...inelinux.org>
To: Rich Felker <dalias@...c.org>
Cc: musl@...ts.openwall.com, Anders Svensson <anders.otp@...il.com>
Subject: Re: strerror_l() segfault
On Thu, 20 Mar 2025 09:47:18 -0400
Rich Felker <dalias@...c.org> wrote:
> On Thu, Mar 20, 2025 at 11:39:17AM +0100, Anders Svensson wrote:
> > I recently noticed a case [1] in which zfs diff segfaults for me on
> > Alpine 3.21.3 (musl 1.2.5), and then noticed that it didn't seem to
> > have anything to do with zfs: this little test utility, reproducing
> > the call zfs-2.2.7 was making, segfaults on both Alpine and Void/musl:
> >
> > #include <errno.h>
> > #include <string.h>
> > #include <locale.h>
> > #include <assert.h>
> >
> > int main(int argc, char **argv) {
> > locale_t loc = uselocale(0);
> > assert(loc != 0);
> > char *err = strerror_l(ENOENT, loc); /* segfaults here */
> > return 0;
> > }
> >
> > I read [2] that "Locale support is very limited, and barely works", so
> > should I just file this failure under that heading or is strerror_l()
> > unexpectedly broken? There doesn't seem to be anything wrong with how
> > zfs is using it, but I'm no expert.
>
> If you have not set a thread-local locale with uselocale, loc is equal
> to LC_GLOBAL_LOCALE, which is not a valid argument to the *_l
> functions per POSIX. There's been some discussion of this and I think
> the current understanding is that most (all?) other implementations do
> accept LC_GLOBAL_LOCALE here, and that it's necessary to do so for the
> API to actually be usable, and that POSIX needs to adopt this
> requirement. So musl will probably be adding this.
Would something like this work:
diff --git a/src/errno/strerror.c b/src/errno/strerror.c
index 7f926432..cea7c2ae 100644
--- a/src/errno/strerror.c
+++ b/src/errno/strerror.c
@@ -36,7 +36,7 @@ char *__strerror_l(int e, locale_t loc)
#endif
if (e >= sizeof errmsgidx / sizeof *errmsgidx) e = 0;
s = (char *)&errmsgstr + errmsgidx[e];
- return (char *)LCTRANS(s, LC_MESSAGES, loc);
+ return (char *)LCTRANS(s, LC_MESSAGES, loc == LC_GLOBAL_LOCALE ? CURRENT_LOCALE : loc);
}
char *strerror(int e)
-nc
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.