# Buffer overflow in req_parsebody method in lua_request.c

Unsigned underflow in mod_lua req_parsebody multipart parser lets a crafted boundary make vlen wrap to SIZE_MAX, causing zero-size allocation and heap overflow crash.

- Payout: hidden
- Severity: high
- Program: Internet Bug Bounty
- Found by (vendor credit): Chamal, Anonymous working with Trend Micro Zero Day Initiative
- Found by: chamal
- Disclosed: 2022-01-04
- CVE: CVE-2021-44790
- Write-up quality: 7/10
- Original: https://hackerone.com/reports/1434056
- Library page: https://bugbountylibrary.com/r/h1%3A1434056
- Tags: area:web domain:web impact:dos kind:bounty platform:hackerone sev:high technique:source-review vuln:dos vuln:memory-corruption

**Target:** mod_lua r:parsebody() multipart/form-data parser (lua_request.c)
**Root cause:** vlen = end - crlf - 8 is computed without checking end - crlf >= 8; a short boundary makes the signed difference negative, which wraps to SIZE_MAX when stored in size_t, so apr_pcalloc(vlen+1) allocates 0 bytes before memcpy writes vlen bytes.
**Steps:**
1. Build httpd with `./configure --enable-lua=shared` and enable mod_lua with SetHandler lua-script for *.lua
2. Place a Lua script calling r:parsebody() in htdocs
3. Start `./httpd -X`
4. Send `curl -v -X POST -H 'content-type: multipart/form-data; boundary=-' --data-binary $'-\r\n\r\naaa-' http://127.0.0.1/test.lua`
5. Observe SIGSEGV in memcpy at lua_request.c:415 under valgrind
**How found:** Code review of req_parsebody in lua_request.c spotted that the subtraction end - crlf - 8 lacked a bounds check, allowing a negative result to be stored in size_t.
**Exploitation:** Attacker sends a multipart POST with a one-character boundary and a body shorter than 8 bytes past the boundary marker; the parser computes a negative length, wraps to SIZE_MAX, allocates a zero-length buffer, and memcpy overflows, crashing the worker process.
**Insight:** In multipart parsers, boundary-length arithmetic (end - crlf - 8) is a classic unsigned-underflow sink: try minimal/empty boundaries and truncated bodies to force negative offsets that wrap in size_t before allocation.
