Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

libsolv “resolve_weak” function a heap-overflow bug and an UaF bug #426

Closed
yangjiageng opened this issue Dec 13, 2020 · 4 comments
Closed

Comments

@yangjiageng
Copy link

yangjiageng commented Dec 13, 2020

Description:
There are two memory vulnerabilities in function:
static int resolve_weak (Solver *solv, int level, int disablerules, Queue *dq, Queue *dqs, int *rerunp)
at src/solver.c: line 2222 & 2249
if (solv->decisionmap[i] < 0) // line 2222
continue;

  FOR_PROVIDES(p, pp, rec)
    {
      if (solv->decisionmap[p] > 0)		// line 2249
  {
    dq->count = qcount;
    break;
  }

The first bug is caused by the dangerous variable “decisionmap[]”.
If the value of index variable “i” is bigger than the size of decisionmap[], there will be a heap overflow bug.
Our PoC file will trigger this bug.
Please reproduce this issue through the following PoC: /libsolvBuildDir/tools/testsolv resolve_weak-2222
If you configure CC with flag -fsanitize=address, you will get the following outputs:

testcase_read: cannot parse command 'sys#>=Req:'
test 1:
test 2:
test 3:
test 4:
AddressSanitizer: heap-buffer-overflow on address 0x6020000008c0 at pc 0x7ff8dafd9495 bp 0x7ffc1b98e350 sp 0x7ffc1b98e348
READ of size 4 at 0x6020000008c0 thread T0
#0 0x7ff8dafd9494 in resolve_weak /root/Experiments/real-world/libsolv/src/solver.c:2222:11
#1 0x7ff8dafd9494 in solver_run_sat /root/Experiments/real-world/libsolv/src/solver.c:2740:12
#2 0x7ff8daffe65a in solver_solve /root/Experiments/real-world/libsolv/src/solver.c:4137:3
#3 0x4f1eea in main /root/Experiments/real-world/libsolv/tools/testsolv.c:241:8
#4 0x7ff8d9fdabf6 in __libc_start_main /build/glibc-S7xCS9/glibc-2.27/csu/../csu/libc-start.c:310
#5 0x41e6f9 in _start (/root/Experiments/real-world/libsolv/build/tools/testsolv+0x41e6f9)

0x6020000008c0 is located 0 bytes to the right of 16-byte region [0x6020000008b0,0x6020000008c0)
allocated by thread T0 here:
#0 0x4abe48 in calloc /root/Downloads/llvm-build/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cpp:154
#1 0x7ff8db137f10 in solv_calloc /root/Experiments/real-world/libsolv/src/util.c:79:9
#2 0x7ff8dafbfb9a in solver_create /root/Experiments/real-world/libsolv/src/solver.c:1327:29
#3 0x7ff8e45772d4 in testcase_read /root/Experiments/real-world/libsolv/ext/testcase.c:2268:15
#4 0x4f144b in main /root/Experiments/real-world/libsolv/tools/testsolv.c:159:11
#5 0x7ff8d9fdabf6 in __libc_start_main /build/glibc-S7xCS9/glibc-2.27/csu/../csu/libc-start.c:310

SUMMARY: AddressSanitizer: heap-buffer-overflow /root/Experiments/real-world/libsolv/src/solver.c:2222:11 in resolve_weak
Shadow bytes around the buggy address:
0x0c047fff80c0: fa fa fd fa fa fa fd fa fa fa fd fd fa fa fd fd
0x0c047fff80d0: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
0x0c047fff80e0: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
0x0c047fff80f0: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
0x0c047fff8100: fa fa fd fa fa fa fd fa fa fa 01 fa fa fa 01 fa
=>0x0c047fff8110: fa fa 01 fa fa fa 00 00[fa]fa fd fd fa fa 05 fa
0x0c047fff8120: fa fa 00 00 fa fa 04 fa fa fa 04 fa fa fa 00 04
0x0c047fff8130: fa fa 04 fa fa fa 04 fa fa fa 01 fa fa fa fd fa
0x0c047fff8140: fa fa fd fa fa fa fd fa fa fa 01 fa fa fa 01 fa
0x0c047fff8150: fa fa 04 fa fa fa 00 fa fa fa fd fa fa fa fd fa
0x0c047fff8160: fa fa fd fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
==90772==ABORTING

The second bug is a use-after-free bug.

Please reproduce this issue through the following PoC: /libsolvBuildDir/tools/testsolv resolve_weak-2249
If you configure CC with flag -fsanitize=address, you will get the following outputs:

testcase_read: cannot parse command '¤repo'
testcase_read: system: unknown repo 'system'
setsolverflags: unknown flag 'strongrongrecommends'
str2job: bad line 'in'
testcase_read: cannot parse command 'to'
setsolverflags: unknown flag 'strecommends'
===========================================================
==69476==ERROR: AddressSanitizer: heap-use-after-free on address 0x603000000070 at pc 0x7fdd5adaa5fe bp 0x7ffe681b5090 sp 0x7ffe681b5088
READ of size 4 at 0x603000000070 thread T0
#0 0x7fdd5adaa5fd in resolve_weak /root/Experiments/real-world/libsolv/src/solver.c:2249:13
#1 0x7fdd5adaa5fd in solver_run_sat /root/Experiments/real-world/libsolv/src/solver.c:2740:12
#2 0x7fdd5add065a in solver_solve /root/Experiments/real-world/libsolv/src/solver.c:4137:3
#3 0x4f1eea in main /root/Experiments/real-world/libsolv/tools/testsolv.c:241:8
#4 0x7fdd59dacbf6 in __libc_start_main /build/glibc-S7xCS9/glibc-2.27/csu/../csu/libc-start.c:310
#5 0x41e6f9 in _start (/root/Experiments/real-world/libsolv/build/tools/testsolv+0x41e6f9)

0x603000000070 is located 0 bytes inside of 28-byte region [0x603000000070,0x60300000008c)
freed by thread T0 here:
#0 0x4ab960 in free /root/Downloads/llvm-build/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cpp:123
#1 0x7fdd5af0a17d in solv_free /root/Experiments/real-world/libsolv/src/util.c:113:5
#2 0x7fdd5ad83e2d in map_free /root/Experiments/real-world/libsolv/src/bitmap.c:31:12
#3 0x7fdd5b052564 in pool_addfileprovides_queue /root/Experiments/real-world/libsolv/src/fileprovides.c:596:3
#4 0x7fdd5b052564 in pool_addfileprovides /root/Experiments/real-world/libsolv/src/fileprovides.c:635:3
#5 0x7fdd6434757f in testcase_read /root/Experiments/real-world/libsolv/ext/testcase.c:2180:8
#6 0x4f144b in main /root/Experiments/real-world/libsolv/tools/testsolv.c:159:11
#7 0x7fdd59dacbf6 in __libc_start_main /build/glibc-S7xCS9/glibc-2.27/csu/../csu/libc-start.c:310

previously allocated by thread T0 here:
#0 0x4abe48 in calloc /root/Downloads/llvm-build/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cpp:154
#1 0x7fdd5af09f10 in solv_calloc /root/Experiments/real-world/libsolv/src/util.c:79:9
#2 0x7fdd5ad83dba in map_init /root/Experiments/real-world/libsolv/src/bitmap.c:24:22
#3 0x7fdd5b051ee6 in pool_addfileprovides_queue /root/Experiments/real-world/libsolv/src/fileprovides.c:565:3
#4 0x7fdd5b051ee6 in pool_addfileprovides /root/Experiments/real-world/libsolv/src/fileprovides.c:635:3
#5 0x7fdd6434757f in testcase_read /root/Experiments/real-world/libsolv/ext/testcase.c:2180:8
#6 0x4f144b in main /root/Experiments/real-world/libsolv/tools/testsolv.c:159:11
#7 0x7fdd59dacbf6 in __libc_start_main /build/glibc-S7xCS9/glibc-2.27/csu/../csu/libc-start.c:310

SUMMARY: AddressSanitizer: heap-use-after-free /root/Experiments/real-world/libsolv/src/solver.c:2249:13 in resolve_weak
Shadow bytes around the buggy address:
0x0c067fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c067fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c067fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c067fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c067fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c067fff8000: fa fa 00 00 00 00 fa fa 00 00 00 00 fa fa[fd]fd
0x0c067fff8010: fd fd fa fa fd fd fd fd fa fa 00 00 00 00 fa fa
0x0c067fff8020: fd fd fd fa fa fa 00 00 00 00 fa fa fd fd fd fd
0x0c067fff8030: fa fa fd fd fd fd fa fa 00 00 00 00 fa fa fd fd
0x0c067fff8040: fd fd fa fa 00 00 00 00 fa fa 00 00 00 00 fa fa
0x0c067fff8050: 00 00 00 00 fa fa 00 00 00 00 fa fa 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
==69476==ABORTING

The ASAN outputs information about these overflow bug.
And attacker can use this bug to achieve a DoS attack.
Please reproduce and fix these two bugs.

@mlschroe
Copy link
Member

Made testcase reader more robust. I think the use after free is also fixed with this.

@00xc
Copy link

00xc commented Feb 22, 2022

This was assigned CVE-2021-44576.

@xingxing118
Copy link

CVE-2021-44575CVE-2021-44569CVE-2021-44576CVE-2021-44574 CVE-2021-44573CVE-2021-44577CVE-2021-44571CVE-2021-44568
Hello, I want to confirm, are these CVEs fixed by this PR 0077ef2? @yangjiageng @mlschroe

@mlschroe
Copy link
Member

mlschroe commented Mar 3, 2022

Yes, that's correct.

halstead pushed a commit to openembedded/openembedded-core that referenced this issue Mar 31, 2022
The existing patch for CVE-2021-3200 also fixes CVE-2021-44568 through
CVE-2021-44671 and CVE-2021-44573 through CVE-2021-44677, so update
CVE tags in patch to reflect this.

Reference:

openSUSE/libsolv#426

Signed-off-by: Steve Sakoman <steve@sakoman.com>
splitice pushed a commit to HalleyAssist/poky that referenced this issue Mar 31, 2022
The existing patch for CVE-2021-3200 also fixes CVE-2021-44568 through
CVE-2021-44671 and CVE-2021-44573 through CVE-2021-44677, so update
CVE tags in patch to reflect this.

Reference:

openSUSE/libsolv#426

(From OE-Core rev: 3096134d25fc4cf9bd18839838a62a6c89344e31)

Signed-off-by: Steve Sakoman <steve@sakoman.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
jpuhlman pushed a commit to MontaVista-OpenSourceTechnology/poky that referenced this issue Jun 3, 2022
Source: poky
MR: 118243
Type: Integration
Disposition: Merged from poky
ChangeID: e779ccdf4e75f3fe6f0d68b6973bff311003b8a7
Description:

The existing patch for CVE-2021-3200 also fixes CVE-2021-44568 through
CVE-2021-44671 and CVE-2021-44573 through CVE-2021-44677, so update
CVE tags in patch to reflect this.

Reference:

openSUSE/libsolv#426

(From OE-Core rev: 3096134d25fc4cf9bd18839838a62a6c89344e31)

Signed-off-by: Steve Sakoman <steve@sakoman.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Jeremy A. Puhlman <jpuhlman@mvista.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants