{"id":41115,"date":"2026-10-19T00:32:13","date_gmt":"2026-10-18T16:32:13","guid":{"rendered":"https:\/\/www.54iter.cn\/?vuln=cve-2026-98643"},"modified":"2026-10-19T00:32:13","modified_gmt":"2026-10-18T16:32:13","slug":"cve-2026-98643","status":"publish","type":"vuln","link":"https:\/\/www.54iter.cn\/?vuln=cve-2026-98643","title":{"rendered":"CVE-2026-98643 &#8211; In the Linux kernel, the following vulnerability has been resolved:\n\nbpf: Fix out-of-bound"},"content":{"rendered":"<p>In the Linux kernel, the following vulnerability has been resolved:<\/p>\n<p>bpf: Fix out-of-bounds read of rtt_min in sock_ops<\/p>\n<p>A sockops prog reading skops-&gt;rtt_min never checks the sk type: on the<br \/>\ntcp_conn_request() path sock_ops-&gt;sk is a request_sock (non-full), and the<br \/>\nctx rewrite casts it to a tcp_sock (full) and reads rtt_min past the end of<br \/>\nthe request_sock, returning dirty adjacent memory.<\/p>\n<p>\tSEC(&#8220;sockops&#8221;)<br \/>\n\tint prog(struct bpf_sock_ops *skops)<br \/>\n\t{<br \/>\n\t\tswitch (skops-&gt;op) {<br \/>\n\t\tcase BPF_SOCK_OPS_RWND_INIT:<br \/>\n\t\t\tleak = skops-&gt;rtt_min;   \/* reads the request_sock OOB *\/<br \/>\n\t\t&#8230;<br \/>\n\t\t}<br \/>\n\t}<\/p>\n<p>For instance one such read returned rtt_min=0xffff8881, the high half of a<br \/>\nleaked kernel pointer.<\/p>\n<p>Guarding that cast is exactly what SOCK_OPS_GET_FIELD() does &#8212; it checks<br \/>\nis_locked_tcp_sock and returns 0 when sock_ops-&gt;sk is not a locked full<br \/>\nsocket. Every other tcp_sock field in sock_ops goes through it; rtt_min is<br \/>\nthe only one open-coded, so it skips the check.<\/p>\n<p>Read rtt_min through SOCK_OPS_GET_FIELD() too. rtt_min is a bit special:<br \/>\nit is a struct minmax and we only want the current min, so pass<br \/>\nrtt_min.s[0].v. That is equivalent to the old hand-computed offset<\/p>\n<p>\toffsetof(struct tcp_sock, rtt_min) + sizeof_field(struct minmax_sample, t)<\/p>\n<p>(s[0] sits at rtt_min + 0 and .v at + sizeof(.t), i.e. what minmax_get()<br \/>\nreturns), so the loaded field is unchanged and only the full-sock guard is<br \/>\nadded. The two BUILD_BUG_ON()s that protected the hand-computed offset<br \/>\nare no longer needed.<\/p>\n<p>Before patch:<\/p>\n<p>\t0: r1 = *(u64 *)(r1 +0)      ; r1 = skops-&gt;sk<br \/>\n\t1: r1 = *(u32 *)(r1 +2324)   ; ((tcp_sock *)sk)-&gt;rtt_min.s[0].v<\/p>\n<p>After patch:<\/p>\n<p>\t0: *(u64 *)(r1 +56) = r9<br \/>\n\t1: r9 = *(u8 *)(r1 +50)      ; is_locked_tcp_sock<br \/>\n\t2: if r9 == 0 goto pc+4      ; not a locked full sock -&gt; 0<br \/>\n\t3: r9 = *(u64 *)(r1 +56)<br \/>\n\t4: r1 = *(u64 *)(r1 +0)      ; r1 = skops-&gt;sk<br \/>\n\t5: r1 = *(u32 *)(r1 +2324)   ; rtt_min.s[0].v<br \/>\n\t6: goto pc+2<br \/>\n\t7: r9 = *(u64 *)(r1 +56)<br \/>\n\t8: r1 = 0<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the Linux kernel, the following vulnerability has been resolved:<\/p>\n<p>bpf: Fix out-of-bounds read of rtt_min in sock_ops<\/p>\n<p>A sockops prog reading skops-&gt;rtt_min never checks the sk type: on the<br \/>\ntcp_conn<\/p>\n","protected":false},"template":"","meta":[],"categories":[],"tags":[],"class_list":["post-41115","vuln","type-vuln","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.54iter.cn\/index.php?rest_route=\/wp\/v2\/vuln\/41115","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.54iter.cn\/index.php?rest_route=\/wp\/v2\/vuln"}],"about":[{"href":"https:\/\/www.54iter.cn\/index.php?rest_route=\/wp\/v2\/types\/vuln"}],"wp:attachment":[{"href":"https:\/\/www.54iter.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=41115"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.54iter.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=41115"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.54iter.cn\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=41115"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}