CVE-2024-58098

Severity CVSS v4.0:
Pending analysis
Type:
Unavailable / Other
Publication date:
05/05/2025
Last modified:
10/11/2025

Description

In the Linux kernel, the following vulnerability has been resolved:<br /> <br /> bpf: track changes_pkt_data property for global functions<br /> <br /> When processing calls to certain helpers, verifier invalidates all<br /> packet pointers in a current state. For example, consider the<br /> following program:<br /> <br /> __attribute__((__noinline__))<br /> long skb_pull_data(struct __sk_buff *sk, __u32 len)<br /> {<br /> return bpf_skb_pull_data(sk, len);<br /> }<br /> <br /> SEC("tc")<br /> int test_invalidate_checks(struct __sk_buff *sk)<br /> {<br /> int *p = (void *)(long)sk-&gt;data;<br /> if ((void *)(p + 1) &gt; (void *)(long)sk-&gt;data_end) return TCX_DROP;<br /> skb_pull_data(sk, 0);<br /> *p = 42;<br /> return TCX_PASS;<br /> }<br /> <br /> After a call to bpf_skb_pull_data() the pointer &amp;#39;p&amp;#39; can&amp;#39;t be used<br /> safely. See function filter.c:bpf_helper_changes_pkt_data() for a list<br /> of such helpers.<br /> <br /> At the moment verifier invalidates packet pointers when processing<br /> helper function calls, and does not traverse global sub-programs when<br /> processing calls to global sub-programs. This means that calls to<br /> helpers done from global sub-programs do not invalidate pointers in<br /> the caller state. E.g. the program above is unsafe, but is not<br /> rejected by verifier.<br /> <br /> This commit fixes the omission by computing field<br /> bpf_subprog_info-&gt;changes_pkt_data for each sub-program before main<br /> verification pass.<br /> changes_pkt_data should be set if:<br /> - subprogram calls helper for which bpf_helper_changes_pkt_data<br /> returns true;<br /> - subprogram calls a global function,<br /> for which bpf_subprog_info-&gt;changes_pkt_data should be set.<br /> <br /> The verifier.c:check_cfg() pass is modified to compute this<br /> information. The commit relies on depth first instruction traversal<br /> done by check_cfg() and absence of recursive function calls:<br /> - check_cfg() would eventually visit every call to subprogram S in a<br /> state when S is fully explored;<br /> - when S is fully explored:<br /> - every direct helper call within S is explored<br /> (and thus changes_pkt_data is set if needed);<br /> - every call to subprogram S1 called by S was visited with S1 fully<br /> explored (and thus S inherits changes_pkt_data from S1).<br /> <br /> The downside of such approach is that dead code elimination is not<br /> taken into account: if a helper call inside global function is dead<br /> because of current configuration, verifier would conservatively assume<br /> that the call occurs for the purpose of the changes_pkt_data<br /> computation.

Vulnerable products and versions

CPE From Up to
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 5.6 (including) 6.6.90 (excluding)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 6.7 (including) 6.12.25 (excluding)
cpe:2.3:o:linux:linux_kernel:6.13:rc1:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:6.13:rc2:*:*:*:*:*:*