Out-of-Bounds Read in luaO_pushvfstring Due to Unsanitized String Inputs

95 views
Skip to first unread message

Cullen Clay (你講話真的很機車)

unread,
Jan 21, 2026, 7:00:05 AMJan 21
to lua-l
### Summary
The function `luaO_pushvfstring` in `lobject.c` suffers from a CWE-125 (Out-of-Bounds Read) vulnerability due to the use of `strlen` on unsanitized, potentially non-null-terminated strings.

### Description
1. The target function is `luaO_pushvfstring` located in `lobject.c`, which constructs formatted strings using variable arguments and a format string. The function process includes:
   - **Line 386**: `strlen` is invoked on the string argument `s` obtained from `va_arg(argp, char*)`.
   - **Line 388**: The function passes the string `s` directly to `addstr2buff`, which uses `strlen` without any null-termination validation.

2. If the caller provides a non-null-terminated string, this will cause `strlen` to read past allocated memory until it finds a null byte, thereby leading to an out-of-bounds read.

3. The function does not perform validation or sanitization to ensure that the string `s` passed to `strlen` is null-terminated. This could happen when the function is called via the Lua API, where untrusted strings may be passed.

4. There are no checks or mitigations against non-null-terminated strings, and the data flow from the variable arguments (source) to `strlen` (sink) is direct and unverified, making the function vulnerable to exploitation if an attacker can control the input strings.

### Code Snippet
```c
// Method: luaO_pushvfstring#378#441#lobject.c
378: const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
382:   while ((e = strchr(fmt, '%')) != NULL) {
383:     addstr2buff(&buff, fmt, ct_diff2sz(e - fmt));  
386:         const char *s = va_arg(argp, char *);
388:         addstr2buff(&buff, s, strlen(s));
439:   }
}
```

### Conclusion
Due to the lack of validation for null-terminated strings, `luaO_pushvfstring` can lead to potential out-of-bounds memory reads, making it susceptible to vulnerabilities. It is recommended to add checks to ensure that strings are null-terminated before processing them with `strlen`.

**Version Affected: 0b73ed8f083c99b5ff88e0822532db7ad8785881**

Philippe Verdy

unread,
Jan 24, 2026, 4:18:41 AMJan 24
to lu...@googlegroups.com
How would you validate that strings of unspecified length is null terminated? There's no way other than actually reading from the string until you find a null byte; you'll do this even if you don't count the checked bytes (like what strlen does).
The only safety you can take is to require an expected maximum string length so that the loop will not run out of safe bounds. But what can be the safe maximum? 2^31-1 is still very huge, if you're supposed to check the length of a parameter in the process command line, the OS or shell usually has some limit, which is generally not more than 64KB. The OS itself will not allow a process to be lauched with a commandline not null-terminated.

In other words this is not a problem of Lua for that case if there's one, but a problem of the OS or shell, if it allows launching processes with unterminated arbitrary string length in the command line buffer (and this bug would occur in the underliong binary API  or C using such datatype).

Lua strings have an explicit length field so they are always bounded (Lua uitself should ensure that it can always store the final null byte at end of the buffer): that length filed should be used and then using C's strlen() should be avoided for a function using that bound parameter.


--
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/814a70e8-828c-4040-b84a-d1c96923484en%40googlegroups.com.

Eleanor Bartle

unread,
Jan 24, 2026, 5:15:50 AMJan 24
to lua-l
We really need to do something about these slop reports. We won't ever see anything worth our attention otherwise.

David Given

unread,
Jan 24, 2026, 5:47:26 AMJan 24
to lu...@googlegroups.com
On Sat, 24 Jan 2026, at 10:18, Philippe Verdy wrote:
How would you validate that strings of unspecified length is null terminated? There's no way other than actually reading from the string until you find a null byte; you'll do this even if you don't count the checked bytes (like what strlen does).

It's actually a surprisingly interesting question, and I might try to do it one day --- a string must be either nul-terminated or else ends in an area of unmapped memory. (Or, potentially, if your address space is completely full and contains no nul characters, the string will just wrap round and be of infinite length.) Actually figuring out which it is very much gets into the weeds of OS-specific code.

...what do you mean, that sounds like a complete waste of time?

Reply all
Reply to author
Forward
0 new messages