{"id":41002,"date":"2026-10-19T00:31:47","date_gmt":"2026-10-18T16:31:47","guid":{"rendered":"https:\/\/www.54iter.cn\/?vuln=cve-2026-98530"},"modified":"2026-10-19T00:31:47","modified_gmt":"2026-10-18T16:31:47","slug":"cve-2026-98530","status":"publish","type":"vuln","link":"https:\/\/www.54iter.cn\/?vuln=cve-2026-98530","title":{"rendered":"CVE-2026-98530 &#8211; In the Linux kernel, the following vulnerability has been resolved:\n\nkprobes: Fix permanen"},"content":{"rendered":"<p>In the Linux kernel, the following vulnerability has been resolved:<\/p>\n<p>kprobes: Fix permanent hang when flushing the kprobe optimizer<\/p>\n<p>Writing 0 to \/proc\/sys\/debug\/kprobes-optimization while a kprobe is<br \/>\njump-optimized never returns. The writer sleeps in D state forever with<br \/>\nkprobe_sysctl_mutex held, so any later read or write of that sysctl<br \/>\nhangs as well. For example, with vfs_read+9 as an optimizable address<br \/>\nin this build:<\/p>\n<p>  # cd \/sys\/kernel\/tracing<br \/>\n  # echo &#8216;p:myprobe vfs_read+9&#8217; &gt;&gt; kprobe_events<br \/>\n  # echo 1 &gt; events\/kprobes\/myprobe\/enable<br \/>\n  # # wait until \/sys\/kernel\/debug\/kprobes\/list shows [OPTIMIZED]<br \/>\n  # echo 0 &gt; \/proc\/sys\/debug\/kprobes-optimization<\/p>\n<p>  INFO: task sh:246 blocked for more than 10 seconds.<br \/>\n  Call Trace:<\/p>\n<p>   __schedule+0x1176\/0x4f70<br \/>\n   schedule+0xdc\/0x2c0<br \/>\n   schedule_timeout+0x17b\/0x260<br \/>\n   wait_for_completion+0x173\/0x3c0<br \/>\n   wait_for_kprobe_optimizer_locked+0xbc\/0x130<br \/>\n   proc_kprobes_optimization_handler+0x156\/0x1b0<br \/>\n   proc_sys_call_handler+0x324\/0x490<br \/>\n   vfs_write+0x52d\/0xfe0<br \/>\n   ksys_write+0xff\/0x200<br \/>\n   do_syscall_64+0x106\/0x630<br \/>\n   entry_SYSCALL_64_after_hwframe+0x77\/0x7f<\/p>\n<p>  &#8230;<br \/>\n  INFO: task cat:265 is blocked on a mutex likely owned by task sh:246.<\/p>\n<p>wait_for_kprobe_optimizer_locked() reinitializes optimizer_completion,<br \/>\nasks the optimizer thread to flush and sleeps in wait_for_completion().<br \/>\nThe thread drains the (un)optimizing lists, but calls complete() only<br \/>\nif completion_done() is true, i.e. if the completion is already done,<br \/>\nwhich never happens while someone waits. disarm_all_kprobes() and<br \/>\nkprobe_trace_self_tests_init() wait the same way.<\/p>\n<p>Calling complete() unconditionally would not be enough: the waiter<br \/>\ndrops kprobe_mutex while it sleeps, and nothing else serializes the<br \/>\nsysctl handler against the debugfs &#8220;enabled&#8221; file. A second flusher<br \/>\nthat still finds the lists non-empty, e.g. because a disabled probe is<br \/>\nqueued for unoptimizing, reinitializes the completion under the first:<\/p>\n<p>  sysctl write                      debugfs &#8220;enabled&#8221; write<br \/>\n  unoptimize_all_kprobes()<br \/>\n    wait_for_kprobe_optimizer_locked()<br \/>\n      init_completion(c)<br \/>\n      mutex_unlock(&amp;kprobe_mutex)<br \/>\n      wait_for_completion(c)<br \/>\n                                    disarm_all_kprobes()<br \/>\n                                      wait_for_kprobe_optimizer_locked()<br \/>\n                                        init_completion(c)<br \/>\n                                          \/\/ c-&gt;wait is reset, the first<br \/>\n                                          \/\/ waiter is off the queue<br \/>\n                                        mutex_unlock(&amp;kprobe_mutex)<br \/>\n                                        wait_for_completion(c)<br \/>\n  kprobe_optimizer()<br \/>\n    complete(c)<br \/>\n      \/\/ wakes the debugfs writer only<\/p>\n<p>where c is &amp;optimizer_completion. Lining up the two writes during an<br \/>\noptimizer pass loses the sysctl writer this way.<\/p>\n<p>Replace the completion with a counter of optimizer passes, bumped at the<br \/>\nend of each pass and signalled with wake_up_var_locked(), both under<br \/>\nkprobe_mutex. A flusher samples the count and waits with<br \/>\nwait_var_event_mutex(), which drops kprobe_mutex only while sleeping, so<br \/>\na new count means a whole pass ran in the meantime. Nothing is<br \/>\nreinitialized, so several flushers can sleep in the wait at once.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the Linux kernel, the following vulnerability has been resolved:<\/p>\n<p>kprobes: Fix permanent hang when flushing the kprobe optimizer<\/p>\n<p>Writing 0 to \/proc\/sys\/debug\/kprobes-optimization while a kprobe is<\/p>\n","protected":false},"template":"","meta":[],"categories":[],"tags":[],"class_list":["post-41002","vuln","type-vuln","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.54iter.cn\/index.php?rest_route=\/wp\/v2\/vuln\/41002","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=41002"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.54iter.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=41002"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.54iter.cn\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=41002"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}