CVE-2022-49006
Severity CVSS v4.0:
Pending analysis
Type:
CWE-416
Use After Free
Publication date:
21/10/2024
Last modified:
04/11/2024
Description
In the Linux kernel, the following vulnerability has been resolved:<br />
<br />
tracing: Free buffers when a used dynamic event is removed<br />
<br />
After 65536 dynamic events have been added and removed, the "type" field<br />
of the event then uses the first type number that is available (not<br />
currently used by other events). A type number is the identifier of the<br />
binary blobs in the tracing ring buffer (known as events) to map them to<br />
logic that can parse the binary blob.<br />
<br />
The issue is that if a dynamic event (like a kprobe event) is traced and<br />
is in the ring buffer, and then that event is removed (because it is<br />
dynamic, which means it can be created and destroyed), if another dynamic<br />
event is created that has the same number that new event&#39;s logic on<br />
parsing the binary blob will be used.<br />
<br />
To show how this can be an issue, the following can crash the kernel:<br />
<br />
# cd /sys/kernel/tracing<br />
# for i in `seq 65536`; do<br />
echo &#39;p:kprobes/foo do_sys_openat2 $arg1:u32&#39; > kprobe_events<br />
# done<br />
<br />
For every iteration of the above, the writing to the kprobe_events will<br />
remove the old event and create a new one (with the same format) and<br />
increase the type number to the next available on until the type number<br />
reaches over 65535 which is the max number for the 16 bit type. After it<br />
reaches that number, the logic to allocate a new number simply looks for<br />
the next available number. When an dynamic event is removed, that number<br />
is then available to be reused by the next dynamic event created. That is,<br />
once the above reaches the max number, the number assigned to the event in<br />
that loop will remain the same.<br />
<br />
Now that means deleting one dynamic event and created another will reuse<br />
the previous events type number. This is where bad things can happen.<br />
After the above loop finishes, the kprobes/foo event which reads the<br />
do_sys_openat2 function call&#39;s first parameter as an integer.<br />
<br />
# echo 1 > kprobes/foo/enable<br />
# cat /etc/passwd > /dev/null<br />
# cat trace<br />
cat-2211 [005] .... 2007.849603: foo: (do_sys_openat2+0x0/0x130) arg1=4294967196<br />
cat-2211 [005] .... 2007.849620: foo: (do_sys_openat2+0x0/0x130) arg1=4294967196<br />
cat-2211 [005] .... 2007.849838: foo: (do_sys_openat2+0x0/0x130) arg1=4294967196<br />
cat-2211 [005] .... 2007.849880: foo: (do_sys_openat2+0x0/0x130) arg1=4294967196<br />
# echo 0 > kprobes/foo/enable<br />
<br />
Now if we delete the kprobe and create a new one that reads a string:<br />
<br />
# echo &#39;p:kprobes/foo do_sys_openat2 +0($arg2):string&#39; > kprobe_events<br />
<br />
And now we can the trace:<br />
<br />
# cat trace<br />
sendmail-1942 [002] ..... 530.136320: foo: (do_sys_openat2+0x0/0x240) arg1= cat-2046 [004] ..... 530.930817: foo: (do_sys_openat2+0x0/0x240) arg1="������������������������������������������������������������������������������������������������"<br />
cat-2046 [004] ..... 530.930961: foo: (do_sys_openat2+0x0/0x240) arg1="������������������������������������������������������������������������������������������������"<br />
cat-2046 [004] ..... 530.934278: foo: (do_sys_openat2+0x0/0x240) arg1="������������������������������������������������������������������������������������������������"<br />
cat-2046 [004] ..... 530.934563: foo: (do_sys_openat2+0x0/0x240) arg1="���������������������������������������<br />
---truncated---
Impact
Base Score 3.x
7.80
Severity 3.x
HIGH
Vulnerable products and versions
CPE | From | Up to |
---|---|---|
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 2.6.33 (including) | 5.4.226 (excluding) |
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 5.5 (including) | 5.10.158 (excluding) |
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 5.11 (including) | 5.15.82 (excluding) |
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 5.16 (including) | 6.0.12 (excluding) |
cpe:2.3:o:linux:linux_kernel:6.1:rc1:*:*:*:*:*:* | ||
cpe:2.3:o:linux:linux_kernel:6.1:rc2:*:*:*:*:*:* | ||
cpe:2.3:o:linux:linux_kernel:6.1:rc3:*:*:*:*:*:* | ||
cpe:2.3:o:linux:linux_kernel:6.1:rc4:*:*:*:*:*:* | ||
cpe:2.3:o:linux:linux_kernel:6.1:rc5:*:*:*:*:*:* | ||
cpe:2.3:o:linux:linux_kernel:6.1:rc6:*:*:*:*:*:* | ||
cpe:2.3:o:linux:linux_kernel:6.1:rc7:*:*:*:*:*:* |
To consult the complete list of CPE names with products and versions, see this page
References to Advisories, Solutions, and Tools
- https://git.kernel.org/stable/c/1603feac154ff38514e8354e3079a455eb4801e2
- https://git.kernel.org/stable/c/417d5ea6e735e5d88ffb6c436cf2938f3f476dd1
- https://git.kernel.org/stable/c/4313e5a613049dfc1819a6dfb5f94cf2caff9452
- https://git.kernel.org/stable/c/be111ebd8868d4b7c041cb3c6102e1ae27d6dc1d
- https://git.kernel.org/stable/c/c52d0c8c4f38f7580cff61c4dfe1034c580cedfd