Open
[webhook] fix: CVE-2026-9149 - openEuler-24.03-LTS-SP2 #103
[webhook] fix: CVE-2026-9149 - openEuler-24.03-LTS-SP2 #103
Open
xiaoo_robotAdd on 8 days ago
Total: 2 files changed+155-1
@@ -0,0 +1,147 @@
1+From 210386037c892a720972ad35a3d8f7073b4d763b Mon Sep 17 00:00:00 2001
2+From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar@redhat.com>
3+Date: Thu, 23 Apr 2026 18:04:24 +0200
4+Subject: [PATCH] Cope with integer overflow in data size arithmetics in
5+ repo_add_solv()
6+ 
7+When parsing solv files with maliciously large "maxsize" or "allsize"
8+data size, e.g. this maxsize value at offset 0x29--0x2E:
9+ 
10+ 00000000 53 4f 4c 56 00 00 00 08 00 00 00 01 00 00 00 00 |SOLV............|
11+ 00000010 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 01 |................|
12+ 00000020 00 00 00 00 00 00 00 00 00 8f ff ff bf 77 86 8d |.............w..|
13+ 00000030 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ...............|
14+ 00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
15+ *
16+ 00002030 00 |.|
17+ 00002031
18+ 
19+read_id() function will decode and return 4294959095 value, and a subsequent
20+assignment:
21+ 
22+ int maxsize;
23+ [...]
24+ maxsize = read_id(&data, 0);
25+ 
26+will experience an integer overflow on plaforms where signed int has 4-byte
27+size (e.g. x86_64).
28+ 
29+The same flaw is possible at the next line:
30+ 
31+ allsize = read_id(&data, 0);
32+ 
33+Subsequent arithmetics will interpreter the value as a very large negative
34+number, possibly doing wrong decisions:
35+ 
36+ maxsize += 5; /* so we can read the next schema of an array */
37+ if (maxsize > allsize)
38+ maxsize = allsize;
39+ 
40+and finally, the negative value passed to solv_calloc():
41+ 
42+ buf = solv_calloc(maxsize + DATA_READ_CHUNK + 4, 1); /* 4 extra bytes to detect overflows */
43+ 
44+will be coerced to an unsigned type (size_t) leading to allocating a smaller
45+buffer then intended. Then writing to the small buffer will experience a heap
46+buffer overflow:
47+ 
48+ l = maxsize;
49+ if (l < DATA_READ_CHUNK)
50+ l = DATA_READ_CHUNK;
51+ if (l > allsize)
52+ l = allsize;
53+ if (!l || fread(buf, l, 1, data.fp) != 1)
54+ 
55+This flaw can be demostrated by passing that solv file to the dumpsolv tool which
56+will crash if compiled with ASAN:
57+ 
58+ $ /tmp/b/tools/dumpsolv /tmp/vuln_1_101_1_negative_maxsize.solv
59+ =================================================================
60+ ==17608==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7c0a2ede00b1 at pc 0x7fea30451468 b
61+ p 0x7ffe07220a50 sp 0x7ffe07220220
62+ WRITE of size 8192 at 0x7c0a2ede00b1 thread T0
63+ #0 0x7fea30451467 in fread.part.0 (/lib64/libasan.so.8+0x51467) (BuildId: 80bfc4ae44fdec6ef5fecfb01
64+ e2b57d28660991c)
65+ #1 0x7fea3028eef1 in repo_add_solv /home/test/libsolv/src/repo_solv.c:1034
66+ #2 0x0000004041cc in main /home/test/libsolv/tools/dumpsolv.c:471
67+ #3 0x7fea3003c680 in __libc_start_call_main (/lib64/libc.so.6+0x3680) (BuildId: c04494d63bca865bedf571a4075ef8867ccf9fa9)
68+ #4 0x7fea3003c797 in __libc_start_main@GLIBC_2.2.5 (/lib64/libc.so.6+0x3797) (BuildId: c04494d63bca865bedf571a4075ef8867ccf9fa9)
69+ #5 0x000000400694 in _start (/tmp/b/tools/dumpsolv+0x400694) (BuildId: 0a70b5b14e5cd81f90a309bb2ff3219dfbf30bb8)
70+ 
71+ 0x7c0a2ede00b1 is located 0 bytes after 1-byte region [0x7c0a2ede00b0,0x7c0a2ede00b1)
72+ allocated by thread T0 here:
73+ #0 0x7fea304ef41f in malloc (/lib64/libasan.so.8+0xef41f) (BuildId: 80bfc4ae44fdec6ef5fecfb01e2b57d28660991c)
74+ #1 0x7fea302e4b4c in solv_calloc /home/test/libsolv/src/util.c:77
75+ #2 0x7fea3028ee38 in repo_add_solv /home/test/libsolv/src/repo_solv.c:1025
76+ #3 0x0000004041cc in main /home/test/libsolv/tools/dumpsolv.c:471
77+ #4 0x7fea3003c680 in __libc_start_call_main (/lib64/libc.so.6+0x3680) (BuildId: c04494d63bca865bedf571a4075ef8867ccf9fa9)
78+ #5 0x7fea3003c797 in __libc_start_main@GLIBC_2.2.5 (/lib64/libc.so.6+0x3797) (BuildId: c04494d63bca865bedf571a4075ef8867ccf9fa9)
79+ #6 0x000000400694 in _start (/tmp/b/tools/dumpsolv+0x400694) (BuildId: 0a70b5b14e5cd81f90a309bb2ff3219dfbf30bb8)
80+ 
81+ SUMMARY: AddressSanitizer: heap-buffer-overflow /home/test/libsolv/src/repo_solv.c:1034 in repo_add_solv
82+ 
83+This patch catches the integer overflow, sets an error and jumps to the end of
84+the function just after deallocation of the buffer (which would contain an
85+undefined pointer). This patch also handles a possible integer overflow at
86+"maxsize += 5" line.
87+ 
88+I originally wanted to replace read_id() with read_u32(), but
89+complemtary repowriter_write() function also stored the value as
90+a signed integer, so I guess the the Id type is inteded there.
91+ 
92+There are probably other ways how to fix it, like passing INT_MAX-5
93+limit to read_id(), though the error message would be less
94+understandable.
95+ 
96+It's also possible to reject this patch with an explanation that loading
97+untrusted solv files is not supported. Though some kind of
98+fortification would be welcomed by people who debug solver problems
99+from reported solv files.
100+ 
101+Reported by Aisle Research.
102+Reference: https://github.com/openSUSE/libsolv/commit/210386037c892a720972ad35a3d8f7073b4d763b.patch
103+Conflict: NA
104+ 
105+---
106+ src/repo_solv.c | 14 ++++++++++++++
107+ 1 file changed, 14 insertions(+)
108+ 
109+diff --git a/src/repo_solv.c b/src/repo_solv.c
110+index d98c973ff..b8c981fa9 100644
111+--- a/src/repo_solv.c
112++++ b/src/repo_solv.c
113+@@ -18,6 +18,7 @@
114+ #include <stdlib.h>
115+ #include <unistd.h>
116+ #include <string.h>
117++#include <limits.h>
118+
119+ #include "repo_solv.h"
120+ #include "util.h"
121+@@ -1018,6 +1019,18 @@ repo_add_solv(Repo *repo, FILE *fp, int flags)
122+
123+ maxsize = read_id(&data, 0);
124+ allsize = read_id(&data, 0);
125++ if (maxsize < 0 || allsize < 0)
126++ {
127++ data.error = pool_error(pool, SOLV_ERROR_CORRUPT, "negative data size in solv header");
128++ id = 0;
129++ goto data_error;
130++ }
131++ if (maxsize > INT_MAX - 5)
132++ {
133++ data.error = pool_error(pool, SOLV_ERROR_OVERFLOW, "data size overflow in solv header");
134++ id = 0;
135++ goto data_error;
136++ }
137+ maxsize += 5; /* so we can read the next schema of an array */
138+ if (maxsize > allsize)
139+ maxsize = allsize;
140+@@ -1343,6 +1356,7 @@ printf("=> %s %s %p\n", pool_id2str(pool, keys[key].name), pool_id2str(pool, key
141+ }
142+ solv_free(buf);
143+
144++data_error:
145+ if (data.error)
146+ {
147+ /* free solvables */
@@ -15,7 +15,7 @@
15 15 
16Name: libsolv16Name: libsolv
17Version: 0.7.2417Version: 0.7.24
18-Release: 318+Release: 4
19Summary: Package dependency solver 19Summary: Package dependency solver
20License: BSD20License: BSD
21URL: https://github.com/openSUSE/libsolv21URL: https://github.com/openSUSE/libsolv
@@ -28,6 +28,7 @@ Patch6004: backport-Fix-a-couple-small-static-analysis-findings-for-uninitializ
28Patch6005: backport-resolve_installed-remove-dead-code.patch28Patch6005: backport-resolve_installed-remove-dead-code.patch
29Patch6006: backport-Move-special-updaters-handling-into-its-own-function.patch29Patch6006: backport-Move-special-updaters-handling-into-its-own-function.patch
30Patch6007: backport-Handle-installed-packages-in-three-passes.patch30Patch6007: backport-Handle-installed-packages-in-three-passes.patch
31+Patch6008: backport-CVE-2026-9149.patch
31 32 
32BuildRequires: cmake gcc-c++ ninja-build pkgconfig(rpm) zlib-devel33BuildRequires: cmake gcc-c++ ninja-build pkgconfig(rpm) zlib-devel
33BuildRequires: libxml2-devel xz-devel bzip2-devel 34BuildRequires: libxml2-devel xz-devel bzip2-devel
@@ -221,6 +222,12 @@ Python 3 version.
221%{_mandir}/man3/%{name}*.3*222%{_mandir}/man3/%{name}*.3*
222 223 
223%changelog224%changelog
225+* Fri Oct 30 2026 xiaoo_robot <xiaoo_robot@petalmail.com> - 0.7.24-4
226+- Type:CVE
227+- CVE:CVE-2026-9149
228+- SUG:NA
229+- DESC:fix CVE-2026-9149
230+ 
224* Tue Jul 23 2024 LuWu <2398491106@qq.com> - 0.7.24-3231* Tue Jul 23 2024 LuWu <2398491106@qq.com> - 0.7.24-3
225- Handle installed packages in three passes 232- Handle installed packages in three passes
226 233