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&amp;#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 &amp;#39;p:kprobes/foo do_sys_openat2 $arg1:u32&amp;#39; &gt; 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&amp;#39;s first parameter as an integer.<br /> <br /> # echo 1 &gt; kprobes/foo/enable<br /> # cat /etc/passwd &gt; /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 &gt; kprobes/foo/enable<br /> <br /> Now if we delete the kprobe and create a new one that reads a string:<br /> <br /> # echo &amp;#39;p:kprobes/foo do_sys_openat2 +0($arg2):string&amp;#39; &gt; 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---

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:*:*:*:*:*:*