Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
150 changes: 150 additions & 0 deletions SPECS/libsolv/CVE-2026-9149.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
From b3280ca0511f4c08feddb600f374410a63807500 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar@redhat.com>
Date: Thu, 23 Apr 2026 18:04:24 +0200
Subject: [PATCH] Cope with integer overflow in data size arithmetics in
repo_add_solv()

When parsing solv files with maliciously large "maxsize" or "allsize"
data size, e.g. this maxsize value at offset 0x29--0x2E:

00000000 53 4f 4c 56 00 00 00 08 00 00 00 01 00 00 00 00 |SOLV............|
00000010 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 01 |................|
00000020 00 00 00 00 00 00 00 00 00 8f ff ff bf 77 86 8d |.............w..|
00000030 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ...............|
00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00002030 00 |.|
00002031

read_id() function will decode and return 4294959095 value, and a subsequent
assignment:

int maxsize;
[...]
maxsize = read_id(&data, 0);

will experience an integer overflow on plaforms where signed int has 4-byte
size (e.g. x86_64).

The same flaw is possible at the next line:

allsize = read_id(&data, 0);

Subsequent arithmetics will interpreter the value as a very large negative
number, possibly doing wrong decisions:

maxsize += 5; /* so we can read the next schema of an array */
if (maxsize > allsize)
maxsize = allsize;

and finally, the negative value passed to solv_calloc():

buf = solv_calloc(maxsize + DATA_READ_CHUNK + 4, 1); /* 4 extra bytes to detect overflows */

will be coerced to an unsigned type (size_t) leading to allocating a smaller
buffer then intended. Then writing to the small buffer will experience a heap
buffer overflow:

l = maxsize;
if (l < DATA_READ_CHUNK)
l = DATA_READ_CHUNK;
if (l > allsize)
l = allsize;
if (!l || fread(buf, l, 1, data.fp) != 1)

This flaw can be demostrated by passing that solv file to the dumpsolv tool which
will crash if compiled with ASAN:

$ /tmp/b/tools/dumpsolv /tmp/vuln_1_101_1_negative_maxsize.solv
=================================================================
==17608==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7c0a2ede00b1 at pc 0x7fea30451468 b
p 0x7ffe07220a50 sp 0x7ffe07220220
WRITE of size 8192 at 0x7c0a2ede00b1 thread T0
#0 0x7fea30451467 in fread.part.0 (/lib64/libasan.so.8+0x51467) (BuildId: 80bfc4ae44fdec6ef5fecfb01
e2b57d28660991c)
#1 0x7fea3028eef1 in repo_add_solv /home/test/libsolv/src/repo_solv.c:1034
#2 0x0000004041cc in main /home/test/libsolv/tools/dumpsolv.c:471
#3 0x7fea3003c680 in __libc_start_call_main (/lib64/libc.so.6+0x3680) (BuildId: c04494d63bca865bedf571a4075ef8867ccf9fa9)
#4 0x7fea3003c797 in __libc_start_main@GLIBC_2.2.5 (/lib64/libc.so.6+0x3797) (BuildId: c04494d63bca865bedf571a4075ef8867ccf9fa9)
#5 0x000000400694 in _start (/tmp/b/tools/dumpsolv+0x400694) (BuildId: 0a70b5b14e5cd81f90a309bb2ff3219dfbf30bb8)

0x7c0a2ede00b1 is located 0 bytes after 1-byte region [0x7c0a2ede00b0,0x7c0a2ede00b1)
allocated by thread T0 here:
#0 0x7fea304ef41f in malloc (/lib64/libasan.so.8+0xef41f) (BuildId: 80bfc4ae44fdec6ef5fecfb01e2b57d28660991c)
#1 0x7fea302e4b4c in solv_calloc /home/test/libsolv/src/util.c:77
#2 0x7fea3028ee38 in repo_add_solv /home/test/libsolv/src/repo_solv.c:1025
#3 0x0000004041cc in main /home/test/libsolv/tools/dumpsolv.c:471
#4 0x7fea3003c680 in __libc_start_call_main (/lib64/libc.so.6+0x3680) (BuildId: c04494d63bca865bedf571a4075ef8867ccf9fa9)
#5 0x7fea3003c797 in __libc_start_main@GLIBC_2.2.5 (/lib64/libc.so.6+0x3797) (BuildId: c04494d63bca865bedf571a4075ef8867ccf9fa9)
#6 0x000000400694 in _start (/tmp/b/tools/dumpsolv+0x400694) (BuildId: 0a70b5b14e5cd81f90a309bb2ff3219dfbf30bb8)

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/test/libsolv/src/repo_solv.c:1034 in repo_add_solv

This patch catches the integer overflow, sets an error and jumps to the end of
the function just after deallocation of the buffer (which would contain an
undefined pointer). This patch also handles a possible integer overflow at
"maxsize += 5" line.

I originally wanted to replace read_id() with read_u32(), but
complemtary repowriter_write() function also stored the value as
a signed integer, so I guess the the Id type is inteded there.

There are probably other ways how to fix it, like passing INT_MAX-5
limit to read_id(), though the error message would be less
understandable.

It's also possible to reject this patch with an explanation that loading
untrusted solv files is not supported. Though some kind of
fortification would be welcomed by people who debug solver problems
from reported solv files.

Reported by Aisle Research.

Signed-off-by: Azure Linux Security Servicing Account <azurelinux-security@microsoft.com>
Upstream-reference: https://github.com/openSUSE/libsolv/pull/617.patch
---
src/repo_solv.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)

diff --git a/src/repo_solv.c b/src/repo_solv.c
index 629ac68..00639aa 100644
--- a/src/repo_solv.c
+++ b/src/repo_solv.c
@@ -18,6 +18,7 @@
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
+#include <limits.h>

#include "repo_solv.h"
#include "util.h"
@@ -1078,6 +1079,18 @@ repo_add_solv(Repo *repo, FILE *fp, int flags)

maxsize = read_id(&data, 0);
allsize = read_id(&data, 0);
+ if (maxsize < 0 || allsize < 0)
+ {
+ data.error = pool_error(pool, SOLV_ERROR_CORRUPT, "negative data size in solv header");
+ id = 0;
+ goto data_error;
+ }
+ if (maxsize > INT_MAX - 5)
+ {
+ data.error = pool_error(pool, SOLV_ERROR_OVERFLOW, "data size overflow in solv header");
+ id = 0;
+ goto data_error;
+ }
maxsize += 5; /* so we can read the next schema of an array */
if (maxsize > allsize)
maxsize = allsize;
@@ -1403,6 +1416,7 @@ printf("=> %s %s %p\n", pool_id2str(pool, keys[key].name), pool_id2str(pool, key
}
solv_free(buf);

+data_error:
if (data.error)
{
/* free solvables */
--
2.45.4

69 changes: 69 additions & 0 deletions SPECS/libsolv/CVE-2026-9150.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
From a271883f877aa907e969da2d1ef21f258f4df0c5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar@redhat.com>
Date: Wed, 22 Apr 2026 09:18:29 +0200
Subject: [PATCH] Fix a buffer overflow when copying SHA-384/512 checksum from
a Debian repository

When parsing Debian repository, control2solvable() copies a package
checksum string from the repository into a stack-allocated "char
checksum[32 * 2 + 1]" array.

If the repository defined a SHA384 or SHA512 tag, a buffer overflow
occured (as can be seen when compiling libsolv with CFLAGS='-O0 -g
-fsanitize=address') because those tag values are longer:

$ cat /tmp/Packages
Package: p
Version: 1
Architecture: all
SHA512: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

$ /tmp/b/tools/deb2solv -r /tmp/Packages
=================================================================
==3695==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7b685ecf0071 at pc 0x7f6861683722 b
p 0x7fff37e3e7a0 sp 0x7fff37e3df60
WRITE of size 129 at 0x7b685ecf0071 thread T0
#0 0x7f6861683721 in strcpy.part.0 (/lib64/libasan.so.8+0x83721) (BuildId: 80bfc4ae44fdec6ef5fecfb01e2b57d28660991c)
#1 0x7f6861d7f34d in control2solvable /home/test/libsolv/ext/repo_deb.c:491
#2 0x7f6861d804ea in repo_add_debpackages /home/test/libsolv/ext/repo_deb.c:622
#3 0x000000400fd5 in main /home/test/libsolv/tools/deb2solv.c:134
#4 0x7f686123c680 in __libc_start_call_main (/lib64/libc.so.6+0x3680) (BuildId: c04494d63bca865bedf571a4075ef8867ccf9fa9)
#5 0x7f686123c797 in __libc_start_main@GLIBC_2.2.5 (/lib64/libc.so.6+0x3797) (BuildId: c04494d63bca865bedf571a4075ef8867ccf9fa9)
#6 0x000000400694 in _start (/tmp/b/tools/deb2solv+0x400694) (BuildId: a3350337819a51edd0c75293970d3458b5033bc9)

Address 0x7b685ecf0071 is located in stack of thread T0 at offset 113 in frame
#0 0x7f6861d7de2a in control2solvable /home/test/libsolv/ext/repo_deb.c:365

This frame has 1 object(s):
[48, 113) 'checksum' (line 371) <== Memory access at offset 113 overflows this variable

This patch fixes it by enlarging the buffer to accomodate the longest
supported digest string.

This flaw was introduced with c8164bfecf2ba8bcf4c24329534d3104f19da73c
commit ("[ABI BREAKAGE] add support for SHA224/384/512").

Reported by Aisle Research.

Signed-off-by: Azure Linux Security Servicing Account <azurelinux-security@microsoft.com>
Upstream-reference: https://github.com/openSUSE/libsolv/pull/616.patch
---
ext/repo_deb.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/ext/repo_deb.c b/ext/repo_deb.c
index d400f95..25eaf8c 100644
--- a/ext/repo_deb.c
+++ b/ext/repo_deb.c
@@ -368,7 +368,7 @@ control2solvable(Solvable *s, Repodata *data, char *control)
char *p, *q, *end, *tag;
int x, l;
int havesource = 0;
- char checksum[32 * 2 + 1];
+ char checksum[64 * 2 + 1];
Id checksumtype = 0;
Id newtype;

--
2.45.4

7 changes: 6 additions & 1 deletion SPECS/libsolv/libsolv.spec
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
Summary: A free package dependency solver
Name: libsolv
Version: 0.7.28
Release: 3%{?dist}
Release: 4%{?dist}
License: BSD
URL: https://github.com/openSUSE/libsolv
Source0: https://github.com/openSUSE/libsolv/archive/refs/tags/%{version}.tar.gz#/%{name}-%{version}.tar.gz
Patch0: CVE-2026-9149.patch
Patch1: CVE-2026-9150.patch
Group: Development/Tools
Vendor: Microsoft Corporation
Distribution: Azure Linux
Expand Down Expand Up @@ -80,6 +82,9 @@ find %{buildroot} -type f -name "*.la" -delete -print
%{_mandir}/man1/*

%changelog
* Wed May 27 2026 Azure Linux Security Servicing Account <azurelinux-security@microsoft.com> - 0.7.28-4
- Patch for CVE-2026-9150, CVE-2026-9149

* Fri April 11 2025 Riken Maharjan <rmaharjan@microsoft.com> - 0.7.28-3
- Enable conda support.

Expand Down
4 changes: 2 additions & 2 deletions toolkit/resources/manifests/package/pkggen_core_aarch64.txt
Original file line number Diff line number Diff line change
Expand Up @@ -191,8 +191,8 @@ cpio-lang-2.14-1.azl3.aarch64.rpm
e2fsprogs-libs-1.47.0-2.azl3.aarch64.rpm
e2fsprogs-1.47.0-2.azl3.aarch64.rpm
e2fsprogs-devel-1.47.0-2.azl3.aarch64.rpm
libsolv-0.7.28-3.azl3.aarch64.rpm
libsolv-devel-0.7.28-3.azl3.aarch64.rpm
libsolv-0.7.28-4.azl3.aarch64.rpm
libsolv-devel-0.7.28-4.azl3.aarch64.rpm
libssh2-1.11.1-2.azl3.aarch64.rpm
libssh2-devel-1.11.1-2.azl3.aarch64.rpm
krb5-1.21.3-4.azl3.aarch64.rpm
Expand Down
4 changes: 2 additions & 2 deletions toolkit/resources/manifests/package/pkggen_core_x86_64.txt
Original file line number Diff line number Diff line change
Expand Up @@ -191,8 +191,8 @@ cpio-lang-2.14-1.azl3.x86_64.rpm
e2fsprogs-libs-1.47.0-2.azl3.x86_64.rpm
e2fsprogs-1.47.0-2.azl3.x86_64.rpm
e2fsprogs-devel-1.47.0-2.azl3.x86_64.rpm
libsolv-0.7.28-3.azl3.x86_64.rpm
libsolv-devel-0.7.28-3.azl3.x86_64.rpm
libsolv-0.7.28-4.azl3.x86_64.rpm
libsolv-devel-0.7.28-4.azl3.x86_64.rpm
libssh2-1.11.1-2.azl3.x86_64.rpm
libssh2-devel-1.11.1-2.azl3.x86_64.rpm
krb5-1.21.3-4.azl3.x86_64.rpm
Expand Down
8 changes: 4 additions & 4 deletions toolkit/resources/manifests/package/toolchain_aarch64.txt
Original file line number Diff line number Diff line change
Expand Up @@ -225,10 +225,10 @@ libselinux-utils-3.6-4.azl3.aarch64.rpm
libsepol-3.6-2.azl3.aarch64.rpm
libsepol-debuginfo-3.6-2.azl3.aarch64.rpm
libsepol-devel-3.6-2.azl3.aarch64.rpm
libsolv-0.7.28-3.azl3.aarch64.rpm
libsolv-debuginfo-0.7.28-3.azl3.aarch64.rpm
libsolv-devel-0.7.28-3.azl3.aarch64.rpm
libsolv-tools-0.7.28-3.azl3.aarch64.rpm
libsolv-0.7.28-4.azl3.aarch64.rpm
libsolv-debuginfo-0.7.28-4.azl3.aarch64.rpm
libsolv-devel-0.7.28-4.azl3.aarch64.rpm
libsolv-tools-0.7.28-4.azl3.aarch64.rpm
libssh2-1.11.1-2.azl3.aarch64.rpm
libssh2-debuginfo-1.11.1-2.azl3.aarch64.rpm
libssh2-devel-1.11.1-2.azl3.aarch64.rpm
Expand Down
8 changes: 4 additions & 4 deletions toolkit/resources/manifests/package/toolchain_x86_64.txt
Original file line number Diff line number Diff line change
Expand Up @@ -233,10 +233,10 @@ libselinux-utils-3.6-4.azl3.x86_64.rpm
libsepol-3.6-2.azl3.x86_64.rpm
libsepol-debuginfo-3.6-2.azl3.x86_64.rpm
libsepol-devel-3.6-2.azl3.x86_64.rpm
libsolv-0.7.28-3.azl3.x86_64.rpm
libsolv-debuginfo-0.7.28-3.azl3.x86_64.rpm
libsolv-devel-0.7.28-3.azl3.x86_64.rpm
libsolv-tools-0.7.28-3.azl3.x86_64.rpm
libsolv-0.7.28-4.azl3.x86_64.rpm
libsolv-debuginfo-0.7.28-4.azl3.x86_64.rpm
libsolv-devel-0.7.28-4.azl3.x86_64.rpm
libsolv-tools-0.7.28-4.azl3.x86_64.rpm
libssh2-1.11.1-2.azl3.x86_64.rpm
libssh2-debuginfo-1.11.1-2.azl3.x86_64.rpm
libssh2-devel-1.11.1-2.azl3.x86_64.rpm
Expand Down
Loading