{"id":26021,"date":"2026-09-18T04:32:14","date_gmt":"2026-09-17T20:32:14","guid":{"rendered":"https:\/\/www.54iter.cn\/?vuln=cve-2026-93164"},"modified":"2026-09-18T04:32:14","modified_gmt":"2026-09-17T20:32:14","slug":"cve-2026-93164","status":"publish","type":"vuln","link":"https:\/\/www.54iter.cn\/?vuln=cve-2026-93164","title":{"rendered":"CVE-2026-93164 &#8211; In the Linux kernel, the following vulnerability has been resolved:\n\nuprobes\/x86: Move opt"},"content":{"rendered":"<p>In the Linux kernel, the following vulnerability has been resolved:<\/p>\n<p>uprobes\/x86: Move optimized uprobe from nop5 to nop10<\/p>\n<p>Andrii reported an issue with optimized uprobes [1] that can clobber<br \/>\nredzone area with call instruction storing return address on stack<br \/>\nwhere user code may keep temporary data without adjusting rsp.<\/p>\n<p>Fixing this by moving the optimized uprobes on top of 10-bytes nop<br \/>\ninstruction, so we can squeeze another instruction to escape the<br \/>\nredzone area before doing the call, like:<\/p>\n<p>  lea -0x80(%rsp), %rsp<br \/>\n  call tramp<\/p>\n<p>Note the lea instruction is used to adjust the rsp register without<br \/>\nchanging the flags.<\/p>\n<p>We use nop10 and following transformation to optimized instructions<br \/>\nabove and back as suggested by Peterz [2].<\/p>\n<p>Optimize path (int3_update_optimize):<\/p>\n<p>  1) Initial state after set_swbp() installed the uprobe:<br \/>\n      cc 2e 0f 1f 84 00 00 00 00 00<\/p>\n<p>     From offset 0 this is INT3 followed by the tail of the original<br \/>\n     10-byte NOP.<\/p>\n<p>     After a previous unoptimization bytes 5..9 may still contain the<br \/>\n     old call instruction, which remains valid for threads already there.<\/p>\n<p>  2) Rewrite the LEA tail and call displacement:<br \/>\n      cc [8d 64 24 80 e8 d0 d1 d2 d3]<\/p>\n<p>     From offset 0 this traps on the uprobe INT3.  Bytes 1..9 are not<br \/>\n     executable entry points while byte 0 is trapped.<\/p>\n<p>  3) Publish the first LEA byte:<br \/>\n      [48] 8d 64 24 80 e8 d0 d1 d2 d3<\/p>\n<p>     From offset 0 this is:<br \/>\n        lea -0x80(%rsp), %rsp<br \/>\n        call <\/p>\n<p>Unoptimize path (int3_update_unoptimize):<\/p>\n<p>  1) Initial optimized state:<br \/>\n      48 8d 64 24 80 e8 d0 d1 d2 d3<br \/>\n     Same as 3) above.<\/p>\n<p>  2) Trap new entries before restoring the NOP bytes:<br \/>\n      [cc] 8d 64 24 80 e8 d0 d1 d2 d3<\/p>\n<p>     From offset 0 this traps. A thread that had already executed the<br \/>\n     LEA can still reach the intact CALL at offset 5.<\/p>\n<p>  3) Restore bytes 1..4 of the original NOP while keeping byte 0 trapped<br \/>\n     and byte 5 as CALL.<br \/>\n      cc [2e 0f 1f 84] e8 d0 d1 d2 d3<\/p>\n<p>     From offset 0 this still traps. Offset 5 is still the CALL for any<br \/>\n     thread that was already past the first LEA byte.<\/p>\n<p>  4) Publish the first byte of the original NOP:<br \/>\n      [66] 2e 0f 1f 84 e8 d0 d1 d2 d3<\/p>\n<p>     From offset 0 this is the restored 10-byte NOP; the CALL opcode and<br \/>\n     displacement are now only NOP operands.  Offset 5 still decodes as<br \/>\n     CALL for a thread that was already there.<\/p>\n<p>     Tthere is only a single target uprobe-trampoline for the given nop10<br \/>\n     instruction address, so the CALL instruction will not be changed across<br \/>\n     unoptimization\/optimization cycles.<br \/>\n     Therefore, any task that is preempted at the CALL instruction is guaranteed<br \/>\n     to observe that CALL and not anything else.<\/p>\n<p>Note as explained in [2] we need to use following nop10:<br \/>\n       PF1   PF2   ESC   NOPL  MOD   SIB   DISP32<br \/>\nNOP10: 0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00 &#8212; cs nopw 0x00000000(%rax,%rax,1)<\/p>\n<p>which means we need to allow 0x2e prefix which maps to INAT_PFX_CS<br \/>\nattribute in is_prefix_bad function.<\/p>\n<p>Also changing the uprobe syscall error when called out of uprobe<br \/>\ntrampoline to -EPROTO, so we are able to detect the fixed kernel.<\/p>\n<p>The optimized uprobe performance stays the same:<\/p>\n<p>        uprobe-nop     :    3.129 \u00b1 0.013M\/s<br \/>\n        uprobe-push    :    3.045 \u00b1 0.006M\/s<br \/>\n        uprobe-ret     :    1.095 \u00b1 0.004M\/s<br \/>\n  &#8211;&gt;   uprobe-nop10   :    7.170 \u00b1 0.020M\/s<br \/>\n        uretprobe-nop  :    2.143 \u00b1 0.021M\/s<br \/>\n        uretprobe-push :    2.090 \u00b1 0.000M\/s<br \/>\n        uretprobe-ret  :    0.942 \u00b1 0.000M\/s<br \/>\n  &#8211;&gt;   uretprobe-nop10:    3.381 \u00b1 0.003M\/s<br \/>\n        usdt-nop       :    3.245 \u00b1 0.004M\/s<br \/>\n  &#8211;&gt;   usdt-nop10     :    7.256 \u00b1 0.023M\/s<\/p>\n<p>[1] https:\/\/lore.kernel.org\/bpf\/20260509003146.976844-1-andrii@kernel.org\/<br \/>\n[2] https:\/\/lore.kernel.org\/bpf\/20260518104306.GU3102624@noisy.programming.kicks-ass.net\/#t<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the Linux kernel, the following vulnerability has been resolved:<\/p>\n<p>uprobes\/x86: Move optimized uprobe from nop5 to nop10<\/p>\n<p>Andrii reported an issue with optimized uprobes [1] that can clobber<br \/>\nredzone<\/p>\n","protected":false},"template":"","meta":[],"categories":[],"tags":[],"class_list":["post-26021","vuln","type-vuln","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.54iter.cn\/index.php?rest_route=\/wp\/v2\/vuln\/26021","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=26021"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.54iter.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=26021"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.54iter.cn\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=26021"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}