{"id":29223,"date":"2026-09-25T20:32:11","date_gmt":"2026-09-25T12:32:11","guid":{"rendered":"https:\/\/www.54iter.cn\/?vuln=cve-2026-98068"},"modified":"2026-09-25T20:32:11","modified_gmt":"2026-09-25T12:32:11","slug":"cve-2026-98068","status":"publish","type":"vuln","link":"https:\/\/www.54iter.cn\/?vuln=cve-2026-98068","title":{"rendered":"CVE-2026-98068 &#8211; In the Linux kernel, the following vulnerability has been resolved:\n\nnet\/rds: don&#8217;t let rd"},"content":{"rendered":"<p>In the Linux kernel, the following vulnerability has been resolved:<\/p>\n<p>net\/rds: don&#8217;t let rds_conn_shutdown() consume a concurrent drop<\/p>\n<p>rds_conn_shutdown() finishes by moving the path from<br \/>\nRDS_CONN_DISCONNECTING to RDS_CONN_DOWN, and also accepts<br \/>\nRDS_CONN_ERROR as the starting state of that final transition, so that<br \/>\na FIN processed in softirq context during the teardown does not derail<br \/>\nthe shutdown into a noisy error path.<\/p>\n<p>But consuming that RDS_CONN_ERROR also consumes the shutdown pass that<br \/>\ncame with it: rds_conn_path_drop() sets RDS_CONN_ERROR and then queues<br \/>\ncp_down_w, and a pass that starts on a path already in RDS_CONN_DOWN<br \/>\nis a no-op.  For the FIN case that is harmless &#8211; the socket the FIN<br \/>\narrived on is the very socket the teardown just released.  It is not<br \/>\nharmless for a dropper that attached something to the path first.<\/p>\n<p>rds_tcp_accept_one() is such a dropper.  Its path claim in<br \/>\nrds_tcp_accept_one_path() transitions RDS_CONN_DOWN -&gt;<br \/>\nRDS_CONN_CONNECTING, and a concurrent drop &#8211; a FIN on a previous<br \/>\nsocket in softirq context, an administrative reset &#8211; can put the path<br \/>\ninto RDS_CONN_ERROR between that claim and the state check that<br \/>\nfollows, which accepts RDS_CONN_ERROR.  The accept then installs the<br \/>\nfreshly accepted socket with rds_tcp_set_callbacks() while the queued<br \/>\nteardown &#8211; which sampled tc-&gt;t_sock before this socket existed &#8211; is<br \/>\nstill running.  rds_connect_path_complete() fails its transition to<br \/>\nRDS_CONN_UP and drops the path again, queueing the pass that should<br \/>\nreap the socket it just installed.  If the in-flight shutdown&#8217;s final<br \/>\ntransition consumes that drop&#8217;s RDS_CONN_ERROR, the queued pass finds<br \/>\nthe path in RDS_CONN_DOWN and does nothing.  The installed socket is<br \/>\nnever torn down: it sits established with its callbacks armed and its<br \/>\nrds_tcp_connection on rds_tcp_tc_list, the peer sees a connection that<br \/>\nnothing ever reads, and the path is wedged in RDS_CONN_DOWN until some<br \/>\nlater event drops it again.  Reproduced with widened race windows as<br \/>\nan ever-growing receive queue on a socket owned by a path stuck in<br \/>\nRDS_CONN_DOWN, with the peer&#8217;s send path wedged behind it.<\/p>\n<p>Make the final transition only DISCONNECTING -&gt; DOWN.  If it fails<br \/>\nbecause the path is in RDS_CONN_ERROR, a drop raced the teardown:<br \/>\ncancel the reconnect timer and clear RDS_RECONNECT_PENDING &#8211; the one<br \/>\npiece of the skipped tail that must not be left behind &#8211; and return,<br \/>\nletting the pass the drop queued finish the job: it tears down<br \/>\nwhatever attached to the path in the meantime, completes the<br \/>\ntransition to RDS_CONN_DOWN, and re-arms the reconnect from its own<br \/>\ntail.<\/p>\n<p>The timer quiesce in that branch matters because the racing drop does<br \/>\nnot always queue that pass: rds_conn_path_drop() returns without<br \/>\nqueueing when a destroy is pending &#8211; exactly the situation during a<br \/>\nnetns teardown or module unload, when a FIN on the dying socket is<br \/>\nprocessed while rds_conn_path_destroy() flushes cp_down_w.  If the<br \/>\nflushed pass is the one that takes this return, no later pass exists,<br \/>\nand rds_conn_path_destroy() would find cp_conn_w still armed<br \/>\n(WARN_ON) and then free a path whose reconnect timer can still fire.<br \/>\nWith the cancel in the branch, every exit of a shutdown pass leaves<br \/>\nthe timer quiesced no matter which pass completes the transition.<\/p>\n<p>The FIN case keeps making progress, one pass later and still without<br \/>\nnoisy logging.  Any other state keeps today&#8217;s rds_conn_path_error()<br \/>\nhandling; no current cp_state writer can leave a DISCONNECTING path<br \/>\nin anything but RDS_CONN_ERROR (every other writer is a cmpxchg from<br \/>\na non-DISCONNECTING state), so that branch is defensive.<\/p>\n<p>On kernels without the preceding patches the same hazard exists with<br \/>\nthe sample-based quiesce; the fix applies there equally.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the Linux kernel, the following vulnerability has been resolved:<\/p>\n<p>net\/rds: don&#8217;t let rds_conn_shutdown() consume a concurrent drop<\/p>\n<p>rds_conn_shutdown() finishes by moving the path from<br \/>\nRDS_CONN_DIS<\/p>\n","protected":false},"template":"","meta":[],"categories":[],"tags":[],"class_list":["post-29223","vuln","type-vuln","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.54iter.cn\/index.php?rest_route=\/wp\/v2\/vuln\/29223","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=29223"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.54iter.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=29223"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.54iter.cn\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=29223"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}