CVE-2026-48864: Libsolv: heap buffer overflow in libsolv repopagestore via unchecked decompression of malicious .solv page data
A flaw was found in libsolv. This heap buffer overflow occurs during the decompression of attacker-controlled compressed data within .solv files due to insufficient input validation. An attacker can provide a specially crafted .solv file, which, when processed by a vulnerable application, can lead to out-of-bounds memory access. This could result in information disclosure, alteration of program execution, or a denial of service.
Other sources
AIONLYREPORT package: libsolv-0.7.36-2.hum1 ------ Summary: Heap Buffer Overflow in repopagestoreloadpagerange via Malicious Compressed Data: libsolv decompresses attacker-controlled compressed .solv page data with uncheckeddecompressbuf before validating the required output length or back-reference safety, allowing out-of-bounds reads and writes during page loading. Requirements to exploit: An attacker must be able to supply a crafted .solv file or attacker-controlled repository metadata with compressed page data and cause a victim application to parse it through the normal loading flow that reaches repopagestorereadorsetuppages or repopagestoreloadpagerange. No privileges on the target are required, but the victim must ingest the malicious content. Component affected: libsolv - src/repopage.c (repopagestoreloadpagerange, repopagestorereadorsetuppages) Version affected: at least libsolv-0.7.36 (confirmed in the source report); likely other releases that contain the same src/repopage.c call sites without checkdecompressbuf before page decompression Patch available: Proposed fix included in this report (see "Proposed Fix"); upstream release status unknown. Version fixed (if any already): unknown Upstream coordination: Initial disclosure draft prepared for libsolv maintainers. CVSS: CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H - 7.8 (HIGH) AV:L - The vulnerable component is a local parser reached when a victim application loads attacker-controlled .solv content. AC:L - No unusual preconditions are required once crafted compressed page data is processed. PR:N - The attacker does not need privileges on the target system. UI:R - A victim must cause a vulnerable libsolv consumer to parse the malicious .solv content. S:U - The impact remains within the vulnerable component's security scope. C:H - Successful memory corruption could expose sensitive process memory. I:H - Successful memory corruption could allow modification of process state or control flow. A:H - Malformed metadata can crash the process and may permit broader denial of service. Impact: Moderate. This is a memory-safety flaw in a parser for attacker-controlled .solv metadata. The report demonstrates out-of-bounds read and write conditions during normal parsing, but exploitation still requires the victim to ingest malicious .solv content and does not show reliable code execution in a default remote, no-interaction scenario. Embargo: yes Reason: The source report proposes a standard 90-day coordinated disclosure window while the issue is validated and a fix is prepared. Suggested public date: 16-Jul-2026 Acknowledgement: Aisle Research Steps to reproduce: 1. Build libsolv with AddressSanitizer (-fsanitize=address) and symbols. 2. Prepare a .solv file containing vertical page data marked as compressed. 3. Encode a compressed stream that either decompresses beyond REPOPAGEBLOBSIZE (32 KB) or uses a back-reference offset larger than the amount of data already produced. 4. Load the file via normal .solv parsing flow, for example through a path that reaches repoaddsolv, repopagestorereadorsetuppages, or repopagestoreloadpagerange. 5. Observe an ASan crash such as heap-buffer-overflow or invalid read during uncheckeddecompressbuf. ------
Vulnerability Details
The issue is in page-loading paths that decompress attacker-controlled data from .solv files using uncheckeddecompressbuf without pre-validation: c / src/repopage.c / if (compressed) { unsigned int outlen; outlen = uncheckeddecompressbuf(buf, inlen, dest, REPOPAGEBLOBSIZE); if (outlen != REPOPAGEBLOBSIZE && pnum < store->numpages - 1) return 0; } c / src/repopage.c / if (compressed) { outlen = uncheckeddecompressbuf(buf, inlen, dest, REPOPAGEBLOBSIZE); if (outlen != REPOPAGEBLOBSIZE && i < npages - 1) return SOLVERRORCORRUPT; } uncheckeddecompressbuf does not enforce output bounds and does not validate back-reference safety before dereference. A safer pattern already exists elsewhere: c / src/repopage.c / unsigned int l = checkdecompressbuf(cpage, len); if (l == 0 || l > max) return 0; return uncheckeddecompressbuf(cpage, len, page, max); This makes crafted compressed pages able to trigger: Out-of-bounds write to the destination page buffer (REPOPAGEBLOBSIZE), and/or
Out-of-bounds read via invalid back-reference offsets.
Relevant CWEs: CWE-787 (Out-of-bounds Write)
CWE-125 (Out-of-bounds Read)
CWE-20 (Improper Input Validation)
Proposed Fix
Suggested patch to validate compressed pages before decompression in both vulnerable paths: diff diff --git a/src/repopage.c b/src/repopage.c — a/src/repopage.c +++ b/src/repopage.c @@ -770,8 +770,13 @@ repopagestoreloadpagerange(Repopagestore store, unsigned int pstart, unsigned int pend) if (compressed) { unsigned int outlen;
outlen = uncheckeddecompressbuf(buf, inlen, dest, REPOPAGEBLOBSIZE); + unsigned int outlen; + unsigned int needlen = checkdecompressbuf(buf, inlen); + if (needlen == 0 || needlen > REPOPAGEBLOBSIZE || + (needlen != REPOPAGEBLOBSIZE && pnum < store->numpages - 1)) + return 0; + outlen = uncheckeddecompressbuf(buf, inlen, dest, REPOPAGEBLOBSIZE); + if (outlen != needlen) + return 0; if (outlen != REPOPAGEBLOBSIZE && pnum < store->numpages - 1) { #ifdef DEBUGPAGING @@ -910,8 +915,13 @@ repopagestorereadorsetuppages(Repopagestore store, FILE fp, unsigned int pagesz, unsigned int blobsz) if (compressed) {
outlen = uncheckeddecompressbuf(buf, inlen, dest, REPOPAGEBLOBSIZE); + unsigned int needlen = checkdecompressbuf(buf, inlen); + if (needlen == 0 || needlen > REPOPAGEBLOBSIZE || + (needlen != REPOPAGEBLOBSIZE && i < npages - 1)) + return SOLVERRORCORRUPT; + outlen = uncheckeddecompressbuf(buf, inlen, dest, REPOPAGEBLOBSIZE); + if (outlen != needlen) + return SOLVERRORCORRUPT; if (outlen != REPOPAGEBLOBSIZE && i < npages - 1) { return SOLVERRORCORRUPT;
------ This report was generated using AI technology. Always review AI-generated content prior to use
— Red Hat
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
libsolvto a version that resolves this vulnerability.Fixed in libsolv-0.7.36-2.hum1 - Configuration
Build libsolv with AddressSanitizer (-fsanitize=address) and symbols to catch the heap-buffer-overflow during unchecked_decompress_buf processing of crafted .solv page data.
libsolv build compile with AddressSanitizer = -fsanitize=address - Compensating control
Validate/inspect any repository metadata or crafted .solv content before ingestion so attacker-controlled compressed page data reaches repopagestore_load_page_range and repopagestore_read_or_setup_pages (the normal .solv parsing flow path).
Event History
Frequently Asked Questions
What is the severity of CVE-2026-48864?
CVE-2026-48864 has a high severity rating of 7.8.
How do I fix CVE-2026-48864?
To fix CVE-2026-48864, ensure that you update the vulnerable applications that utilize libsolv to their patched versions.
What systems are affected by CVE-2026-48864?
CVE-2026-48864 affects Red Hat Enterprise Linux, libsolv, openSUSE libsolv, and various Red Hat products including OpenShift and Satellite.
What type of vulnerability is CVE-2026-48864?
CVE-2026-48864 is classified as a heap buffer overflow due to insufficient input validation.
How can an attacker exploit CVE-2026-48864?
An attacker can exploit CVE-2026-48864 by providing a specially crafted `.solv` file, leading to potential code execution on the affected system.