import UBI libsolv-0.7.33-5.el10_2
This commit is contained in:
parent
7cacaca997
commit
af59d2bca9
@ -0,0 +1,66 @@
|
||||
From c5b5db52aebde00bdeacecf4d0569c217ab3187d 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.
|
||||
---
|
||||
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 d400f959..25eaf8cb 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.53.0
|
||||
|
||||
147
0004-Cope-with-integer-overflow-in-data-size-arithmetics-.patch
Normal file
147
0004-Cope-with-integer-overflow-in-data-size-arithmetics-.patch
Normal file
@ -0,0 +1,147 @@
|
||||
From 210386037c892a720972ad35a3d8f7073b4d763b 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.
|
||||
---
|
||||
src/repo_solv.c | 14 ++++++++++++++
|
||||
1 file changed, 14 insertions(+)
|
||||
|
||||
diff --git a/src/repo_solv.c b/src/repo_solv.c
|
||||
index d98c973f..b8c981fa 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"
|
||||
@@ -1018,6 +1019,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;
|
||||
@@ -1343,6 +1356,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.54.0
|
||||
|
||||
@ -0,0 +1,62 @@
|
||||
From 6ba8fbf6603a7fcfdb1744df52d6f0c291f7b29f Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar@redhat.com>
|
||||
Date: Tue, 5 May 2026 10:52:20 +0200
|
||||
Subject: [PATCH] Fix a buffer overflow when decompressing solv pages
|
||||
|
||||
repopagestore_load_page_range() and
|
||||
repopagestore_read_or_setup_pages() functions called
|
||||
unchecked_decompress_buf() on compressed data which were just loaded
|
||||
from a solv file without validating them with check_decompress_buf().
|
||||
|
||||
If the solv file was maliously crafted to decompress beyond
|
||||
REPOPAGE_BLOBSIZE-byte-sized stack-allocated buffer (e.g. 100lllll
|
||||
byte with high lllll counter at the end of the buffer), or
|
||||
a backreference was pointing out of the output buffer (e.g.
|
||||
a reference at the beginning of the buffer with high offset pointing
|
||||
before a start of the buffer), unchecked_decompress_buf() would read
|
||||
or write out of the output buffer, causing a buffer overflow.
|
||||
|
||||
Trival fix would be calling check_decompress_buf() before
|
||||
unchecked_decompress_buf() as repopagestore_decompress_page() already
|
||||
does.
|
||||
|
||||
Instead, this patch uses repopagestore_decompress_page() to do the
|
||||
check and decompression in a single step.
|
||||
|
||||
Acknowledgement: Aisle Research
|
||||
|
||||
CVE-2026-48864
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=2460425
|
||||
---
|
||||
src/repopage.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/repopage.c b/src/repopage.c
|
||||
index a9a1c074..0967979b 100644
|
||||
--- a/src/repopage.c
|
||||
+++ b/src/repopage.c
|
||||
@@ -779,8 +779,8 @@ repopagestore_load_page_range(Repopagestore *store, unsigned int pstart, unsigne
|
||||
if (compressed)
|
||||
{
|
||||
unsigned int out_len;
|
||||
- out_len = unchecked_decompress_buf(buf, in_len, dest, REPOPAGE_BLOBSIZE);
|
||||
- if (out_len != REPOPAGE_BLOBSIZE && pnum < store->num_pages - 1)
|
||||
+ out_len = repopagestore_decompress_page(buf, in_len, dest, REPOPAGE_BLOBSIZE);
|
||||
+ if (out_len == 0 || (out_len != REPOPAGE_BLOBSIZE && pnum < store->num_pages - 1))
|
||||
{
|
||||
#ifdef DEBUG_PAGING
|
||||
fprintf(stderr, "can't decompress\n");
|
||||
@@ -947,8 +947,8 @@ repopagestore_read_or_setup_pages(Repopagestore *store, FILE *fp, unsigned int p
|
||||
}
|
||||
if (compressed)
|
||||
{
|
||||
- out_len = unchecked_decompress_buf(buf, in_len, dest, REPOPAGE_BLOBSIZE);
|
||||
- if (out_len != REPOPAGE_BLOBSIZE && i < npages - 1)
|
||||
+ out_len = repopagestore_decompress_page(buf, in_len, dest, REPOPAGE_BLOBSIZE);
|
||||
+ if (out_len == 0 || (out_len != REPOPAGE_BLOBSIZE && i < npages - 1))
|
||||
{
|
||||
return SOLV_ERROR_CORRUPT;
|
||||
}
|
||||
--
|
||||
2.54.0
|
||||
|
||||
31
libsolv.spec
31
libsolv.spec
@ -1,8 +1,8 @@
|
||||
## START: Set by rpmautospec
|
||||
## (rpmautospec version 0.8.3)
|
||||
## (rpmautospec version 0.8.4)
|
||||
## RPMAUTOSPEC: autorelease, autochangelog
|
||||
%define autorelease(e:s:pb:n) %{?-p:0.}%{lua:
|
||||
release_number = 2;
|
||||
release_number = 5;
|
||||
base_release_number = tonumber(rpm.expand("%{?-b*}%{!?-b:1}"));
|
||||
print(release_number + base_release_number - 1);
|
||||
}%{?-e:.%{-e*}}%{?-s:.%{-s*}}%{!?-n:%{?dist}}
|
||||
@ -71,6 +71,21 @@ Patch0: 0001-Add-support-for-computing-hashes-using-OpenSSL.patch
|
||||
# Submitted upstream https://github.com/openSUSE/libsolv/pull/604
|
||||
Patch1: 0002-Add-testcase-for-color-filtering-when-adding-update-.patch
|
||||
|
||||
# Fix a buffer overflow when copying SHA-384/512 checksum from a Debian
|
||||
# repository (CVE-2026-9150), RHEL-178263, in upstream after 0.7.36,
|
||||
# <https://github.com/openSUSE/libsolv/pull/616>
|
||||
Patch2: 0003-Fix-a-buffer-overflow-when-copying-SHA-384-512-check.patch
|
||||
|
||||
# Cope with integer overflow in data size arithmetics in repo_add_solv()
|
||||
# (CVE-2026-9149), RHEL-178267, in upstream after 0.7.37,
|
||||
# <https://github.com/openSUSE/libsolv/pull/617>
|
||||
Patch3: 0004-Cope-with-integer-overflow-in-data-size-arithmetics-.patch
|
||||
|
||||
# Fix a buffer overflow when decompressing solv pages (CVE-2026-48864),
|
||||
# RHEL-178270, rejected by upstream,
|
||||
# <https://github.com/openSUSE/libsolv/pull/622>.
|
||||
Patch4: 0005-Fix-a-buffer-overflow-when-decompressing-solv-pages.patch
|
||||
|
||||
BuildRequires: cmake >= 3.5
|
||||
BuildRequires: gcc-c++
|
||||
BuildRequires: ninja-build
|
||||
@ -316,6 +331,18 @@ export LD_LIBRARY_PATH=%{buildroot}%{_libdir}
|
||||
|
||||
%changelog
|
||||
## START: Generated by rpmautospec
|
||||
* Thu May 28 2026 Petr Písař <ppisar@redhat.com> - 0.7.33-5
|
||||
- Fix a buffer overflow when decompressing solv pages (CVE-2026-48864)
|
||||
(RHEL-178270)
|
||||
|
||||
* Thu May 28 2026 Petr Písař <ppisar@redhat.com> - 0.7.33-4
|
||||
- Cope with integer overflow in data size arithmetics in repo_add_solv()
|
||||
(CVE-2026-9149) (RHEL-178267)
|
||||
|
||||
* Thu May 28 2026 Petr Písař <ppisar@redhat.com> - 0.7.33-3
|
||||
- Fix a buffer overflow when copying SHA-384/512 checksum from a Debian
|
||||
repository (CVE-2026-9150) (RHEL-178263)
|
||||
|
||||
* Tue Jan 20 2026 Evan Goode <mail@evangoo.de> - 0.7.33-2
|
||||
- Add testcase for color filtering when adding update targets
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user