CVE-2023-4911 'Looney Tunables' — heap buffer overflow in glibc parse_tunables()
dce4d5e9-1c7d-4cec-865c-b58b86ff8f99
In glibc's dynamic loader (elf/dl-tunables.c), the function parse_tunables() — invoked from __tunables_init() during _dl_main() startup — has a heap buffer overflow when processing the GLIBC_TUNABLES environment variable in AT_SECURE binaries (SUID/SGID). For tunables whose security_level is NOT SXID_ERASE (e.g. glibc.malloc.mxfast which is SXID_IGNORE), the code copies the matched 'name=value' substring back into the heap buffer 'tunestr' (originally a strdup of the env var) at a running offset 'off'. Two parsing bugs compound: (1) value-scanning stops only at ':' or '\0', so a value containing '=' (like 'glibc.malloc.mxfast=glibc.malloc.mxfast=A') is treated as one long value; (2) at end of loop, when p[len]=='\0', the cursor p is NOT advanced — but on the next iteration the SAME bytes (now at p+20) re-parse as a second 'glibc.malloc.mxfast=A', triggering a SECOND writeback that prepends ':' + name + '=' + value. The 'off' offset grows past the original allocation, corrupting __minimal_malloc heap right next to ld.so loader data structures. Reachable by any local user against any SUID binary (su, sudo, mount, etc.), giving local root.
ls glibc/elf/dl-tunables*. Read the file and traced parse_tunables() (lines 169-257) with the published Qualys PoC input glibc.malloc.mxfast=glibc.malloc.mxfast=A. Key code positions: tunables_strdup() at line 46 (under-allocates), value-length scan at line 210 (only ':' or '\0' terminates), secure-context writeback loop at lines 226-242 (advances off without bounds check), end-of-iter cursor advance at line 254 (skipped when p[len]=='\0', enabling re-parse). Confirmed mxfast exists in elf/dl-tunables.list line 91.