|
|
Message-ID: <agPq_e6A1cNnHgUz@mail.gmail.com>
Date: Wed, 13 May 2026 05:07:41 +0200
From: Luca Kellermann <mailto.luca.kellermann@...il.com>
To: Rich Felker <dalias@...c.org>
Cc: musl@...ts.openwall.com
Subject: Re: musl multi-level table format for binary locale images
On Tue, May 12, 2026 at 07:09:32PM -0400, Rich Felker wrote:
> [...]
>
> The code to perform lookups is not yet merged much less hooked up to
> any test framework, but I'm attaching a draft to this email. It needs
> to be pointed at the start of the actual table (after the 16-byte file
> header).
>
> [...]
>
> static unsigned get32(const char *b0)
> {
> const unsigned char *b = (const void *)b0;
> return (b[0]<<24) | (b[1]<<16) | (b[2]<<8) | b[3];
> }
b[0] is promoted to int before shifting so a bit is shifted into the
sign position (UB) if b[0] > 0x7f.
> const char *lookup(const char *ld, int key)
> {
> unsigned shift, scale, len, val, x, k = key;
>
> do {
> k -= get32(ld);
> shift = ld[4];
> scale = ld[5];
> //if (shift > 31 || scale > 2) return 0;
> //len = (get16(ld+6)+1) << scale;
> len = get16(ld+6);
Here you could also check that len & ((1 << scale) - 1) == 0 to ensure
that len is a multiple of 1 << scale.
> x = (k>>shift) << scale;
> k &= (1U<<shift) - 1;
> if (x >= len) return 0;
If scale > shift and k > (0xffffffff >> (scale - shift)), the invalid
index would not be detected. For strerror() this would mean, for
example, that INT_MIN + 1 results in "Operation not permitted" instead
of NULL (which would presumably be replaced by "Unknown error")
because: (0x80000002>>0) << 1 == 4.
Invalid indexes should instead be detected before applying scale:
x = k>>shift;
k &= (1U<<shift) - 1;
if (x >= (len>>scale)) return 0;
x <<= scale;
> ld += 8;
> for (int i=val=0; i<(1U<<scale); i++)
> val = 256*val + get8(ld+x+i);
> if (!val) return 0;
> ld += len + val-1;
Because len + val-1 is evaluated as type unsigned, this will wrap
around and give an incorrect result when the sum is greater than
0xffffffff (locale file has to be unreasonably large though). A
possible fix:
ld += len;
ld += val-1;
> } while (shift);
>
> return ld;
> }
>
> [...]
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.