REDHAT-BUG-2460380: Buffer Overflow
MANUALLYVERIFIEDREPORT package: libsolv-0.7.33-2.el10 ------
[Security] Heap Buffer Overflow in repoaddsolv via Negative maxsize
Summary: Heap buffer overflow in repoaddsolv when parsing attacker-controlled .solv files; large encoded maxsize/allsize header values can decode to negative signed Id values, leading to undersized heap allocation while a subsequent fread uses DATAREADCHUNK (8192) bytes.
Requirements to exploit: Ability to supply a crafted .solv file that a victim processes with libsolv (directly or via a consumer such as dumpsolv or an application that calls repoaddsolv on untrusted input).
Component affected: libsolv
Version affected: <= 0.7.36
Version fixed (if any already): >= TBD
CVSS: 6.5 (Medium) — CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H
Impact: Moderate (proposed). Per https://access.redhat.com/security/updates/classification this is memory corruption reachable via untrusted .solv ingestion and can at least cause a denial of service; it is not clearly "High" because an attacker typically needs the victim to process attacker-controlled input (configuration/user action) and reliable system compromise is not demonstrated here. This may be "Low" instead in product contexts where the vulnerable path is not used by default, is only reachable via uncommon workflows, or is effectively mitigated (e.g., only trusted solvdb is processed).
Embargo: no
Acknowledgement: Aisle Research
Steps to reproduce if available: See "Reproduction steps" below.
Mitigation if available: Prefer only consuming trusted .solv / solvdb inputs; avoid parsing untrusted .solv files until patched.
Original report:
Hello libsolv maintainers,
We believe that we have discovered a potential security vulnerability in repoaddsolv when parsing attacker-controlled .solv files.
Vulnerability details
readid decodes into an unsigned value and returns Id (signed int), so large encoded values can become negative after conversion:
c / src/reposolv.c / static Id readid(Repodata data, Id max) { unsigned int x = 0; ... return x; }
In repoaddsolv, maxsize and allsize are read with max=0 (no bounds check), then used for allocation and read length:
c / src/reposolv.c / maxsize = readid(&data, 0); allsize = readid(&data, 0); maxsize += 5; if (maxsize > allsize) maxsize = allsize;
buf = solvcalloc(maxsize + DATAREADCHUNK + 4, 1);
l = maxsize; if (l < DATAREADCHUNK) l = DATAREADCHUNK; if (l > allsize) l = allsize; if (!l || fread(buf, l, 1, data.fp) != 1)
If maxsize is negative, solvcalloc(maxsize + 8192 + 4, 1) can allocate a much smaller buffer, but l is then raised to 8192, and fread writes 8192 bytes into that undersized heap buffer.
Most relevant CWEs: - CWE-122 (Heap-based Buffer Overflow): direct overflow sink. - CWE-20 (Improper Input Validation): negative header fields are accepted. - CWE-195 (Signed to Unsigned Conversion Error): signed int values flow into allocation sizing.
Reproduction steps
1. Build libsolv with ASAN (or run a consumer binary that calls repoaddsolv on .solv input, e.g. dumpsolv). 2. Run the parser on this file (dumpsolv crafted.solv or equivalent).
Crash: [root@c28a4ffb0823 workspace]# ./build-asan/tools/dumpsolv ./vuln11011negativemaxsize.solv ================================================================= ==542==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x5020000000b1 at pc 0x00000041fb3c bp 0x7ffffffc5fd0 sp 0x7ffffffc5798 WRITE of size 8192 at 0x5020000000b1 thread T0 #0 0x00000041fb3b (/workspace/build-asan/tools/dumpsolv+0x41fb3b) (BuildId: 3a1e71d74bd4d38c896ffc899393aedf86bf1cfc) #1 0x7fffff662147 (/workspace/build-asan/src/libsolv.so.1+0x57147) (BuildId: ebfff12c035b97f95b2d532a1d6d237ac31e770a) #2 0x0000004e45fe (/workspace/build-asan/tools/dumpsolv+0x4e45fe) (BuildId: 3a1e71d74bd4d38c896ffc899393aedf86bf1cfc) #3 0x7fffff2f0447 (/lib64/libc.so.6+0x3447) (BuildId: dae6ae6929d69dca842288f5300af5a33d1bdcd7) #4 0x7fffff2f050a (/lib64/libc.so.6+0x350a) (BuildId: dae6ae6929d69dca842288f5300af5a33d1bdcd7) #5 0x000000401514 (/workspace/build-asan/tools/dumpsolv+0x401514) (BuildId: 3a1e71d74bd4d38c896ffc899393aedf86bf1cfc)
0x5020000000b1 is located 0 bytes after 1-byte region [0x5020000000b0,0x5020000000b1) allocated by thread T0 here: #0 0x0000004a1343 (/workspace/build-asan/tools/dumpsolv+0x4a1343) (BuildId: 3a1e71d74bd4d38c896ffc899393aedf86bf1cfc) #1 0x7fffff6b6be6 (/workspace/build-asan/src/libsolv.so.1+0xabbe6) (BuildId: ebfff12c035b97f95b2d532a1d6d237ac31e770a) #2 0x7fffff662100 (/workspace/build-asan/src/libsolv.so.1+0x57100) (BuildId: ebfff12c035b97f95b2d532a1d6d237ac31e770a) #3 0x0000004e45fe (/workspace/build-asan/tools/dumpsolv+0x4e45fe) (BuildId: 3a1e71d74bd4d38c896ffc899393aedf86bf1cfc) #4 0x7fffff2f0447 (/lib64/libc.so.6+0x3447) (BuildId: dae6ae6929d69dca842288f5300af5a33d1bdcd7) #5 0x7fffff2f050a (/lib64/libc.so.6+0x350a) (BuildId: dae6ae6929d69dca842288f5300af5a33d1bdcd7) #6 0x000000401514 (/workspace/build-asan/tools/dumpsolv+0x401514) (BuildId: 3a1e71d74bd4d38c896ffc899393aedf86bf1cfc)
SUMMARY: AddressSanitizer: heap-buffer-overflow (/workspace/build-asan/tools/dumpsolv+0x41fb3b) (BuildId: 3a1e71d74bd4d38c896ffc899393aedf86bf1cfc) Shadow bytes around the buggy address: 0x501ffffffe00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x501ffffffe80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x501fffffff00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x501fffffff80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x502000000000: fa fa 00 00 fa fa 04 fa fa fa 00 00 fa fa 04 fa =>0x502000000080: fa fa 04 fa fa fa[01]fa fa fa fa fa fa fa fa fa 0x502000000100: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x502000000180: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x502000000200: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x502000000280: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x502000000300: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa Proposed fix
diff diff --git a/src/reposolv.c b/src/reposolv.c @@ maxsize = readid(&data, 0); allsize = readid(&data, 0); + if (maxsize < 0 || allsize < 0) + { + data.error = poolerror(pool, SOLVERRORCORRUPT, "negative data size in solv header"); + id = 0; + goto dataerror; + } + if (maxsize > INTMAX - 5) + { + data.error = poolerror(pool, SOLVERROROVERFLOW, "data size overflow in solv header"); + id = 0; + goto dataerror; + } maxsize += 5; / so we can read the next schema of an array / if (maxsize > allsize) maxsize = allsize; @@ if (keydepth) data.error = poolerror(pool, SOLVERROREOF, "unexpected EOF, depth = %d", keydepth); @@ +dataerror:
Best wishes, Aisle Research
------ This report was generated using AI technology. Always review AI-generated content prior to use
Affected Software
Event History
Frequently Asked Questions
What is the severity of REDHAT-BUG-2460380?
The severity of REDHAT-BUG-2460380 is classified as medium with a score of 4.
What type of vulnerability is REDHAT-BUG-2460380?
REDHAT-BUG-2460380 is a heap buffer overflow vulnerability.
How do I fix REDHAT-BUG-2460380?
To fix REDHAT-BUG-2460380, update the libsolv package to the patched version provided by Red Hat.
What can be exploited with REDHAT-BUG-2460380?
REDHAT-BUG-2460380 can be exploited by an attacker through specially crafted .solv files that contain negative encoded maxsize/allsize header values.
What is the impact of REDHAT-BUG-2460380?
The impact of REDHAT-BUG-2460380 includes potential arbitrary code execution due to the buffer overflow.