LUA_ENV might have embedded '\0' ('strcmp' in symbolic execution)

36 views
Skip to first unread message

Jure Bagić

unread,
Dec 11, 2025, 11:03:34 AM (5 days ago) Dec 11
to lua-l
potential bug
Message-ID: <daz4z63fabayrhruby4tkislbezypbmxvrtr4r2iivbwtlfh6g@qtitqh3b7dma>
Reply-To:

In ldebug.c:562:
> return (name && strcmp(name, LUA_ENV) == 0) ? "global" : "field";

LUA_ENV might have multiple '\0'. When constructing literal strings Lua takes
the size of the literal which would include the embedded '\0', as it should.
However 'strcmp' might prematurely stop comparing bytes in 'name' and
'LUA_ENV'.

This is the definition of 'strcmp' in libmusl:
> int strcmp(const char *l, const char *r)
> {
> for (; *l==*r && *l; l++, r++);
> return *(unsigned char *)l - *(unsigned char *)r;
> }

Same for the unreadable glibc when comparing unaligned bytes of 'p1':
> int
> strcmp (const char *p1, const char *p2)
> {
> /* Handle the unaligned bytes of p1 first. */
> uintptr_t n = -(uintptr_t)p1 % sizeof(op_t);
> for (int i = 0; i < n; ++i)
> {
> unsigned char c1 = *p1++;
> unsigned char c2 = *p2++;
> int diff = c1 - c2;
> if (c1 == '\0' || diff != 0)
> return diff;
> }
>
> /* P1 is now aligned to op_t. P2 may or may not be. */
> const op_t *x1 = (const op_t *) p1;
> op_t w1 = *x1++;
> uintptr_t ofs = (uintptr_t) p2 % sizeof(op_t);
> return ofs == 0
> ? strcmp_aligned_loop (x1, (const op_t *)p2, w1)
> : strcmp_unaligned_loop (x1, (const op_t *)(p2 - ofs), w1, ofs);
> }

Let's say 'name' is "bo\0" and LUA_ENV is "bo\0gus".
The 'strcmp(name, LUA_ENV)' would return 0 because it would stop comparing at
'\0' but the strings are obviously not the same. Additionally, inverse could
occur if the upvalue name somehow had embedded '\0' in it (although this is not
exposed in the C API nor is it a valid syntax).

-- Jure
signature.asc

Jure Bagić

unread,
Dec 11, 2025, 11:11:05 AM (5 days ago) Dec 11
to lua-l
Apologies in advance for the malformed 'Subject' header in the email.

-- Jure
signature.asc

Luiz Henrique de Figueiredo

unread,
Dec 11, 2025, 11:17:01 AM (5 days ago) Dec 11
to lu...@googlegroups.com
> LUA_ENV might have multiple '\0'.

This is unreasonable. LUA_ENV is supposed to be an upvalue name and so
must be a valid identifier.

Jure Bagić

unread,
Dec 11, 2025, 12:15:42 PM (5 days ago) Dec 11
to lua-l
Additionally maybe a small update to the comment of that function, instead of
'_ENV' use LUA_ENV.

And the suggestion for the fix (slow but minimal changes):
> if (name && strlen(name) == LL(LUA_ENV) &&
> strncmp(name, LUA_ENV, LL(LUA_ENV)) == 0)
> return "global";
> return "field";

-- Jure
signature.asc

Jure Bagić

unread,
Dec 11, 2025, 12:17:18 PM (5 days ago) Dec 11
to lu...@googlegroups.com
> --
> You received this message because you are subscribed to the Google Groups "lua-l" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to lua-l+un...@googlegroups.com.
> To view this discussion visit https://groups.google.com/d/msgid/lua-l/CAD55k3ojxN8htn6ArNRD%2Bd11c1dbyrznUschHdXROKjNDOmDUg%40mail.gmail.com.

Sure, I agree (ignore my last email).

-- Jure
signature.asc
Reply all
Reply to author
Forward
0 new messages