From: Michael Bommarito <michael.bommarito@gmail.com> stable inclusion from stable-v6.6.143 commit 0dd61ba03d05187726ecdf9c0e2175a81b9b24f6 category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/16034 CVE: CVE-2026-53147 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=... -------------------------------- commit a504b9f2797b739e0304d537e8aa4ce883ecce39 upstream. tb_xdp_handle_request() casts the received packet buffer to protocol-specific structs without verifying that the allocation is large enough for the target type. A peer can send a minimal XDomain packet that passes the generic header length check but is shorter than the struct accessed after the cast, causing out-of- bounds reads from the kmemdup allocation. Plumb the packet length through xdomain_request_work and validate it against the expected struct size before each cast. Fixes: 8e1de7042596 ("thunderbolt: Add support for XDomain lane bonding") Fixes: cdae7c07e3e3 ("thunderbolt: Add support for XDomain properties") Cc: stable@vger.kernel.org Assisted-by: Claude:claude-opus-4-7 Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Ze Zuo <zuoze1@huawei.com> --- drivers/thunderbolt/xdomain.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/thunderbolt/xdomain.c b/drivers/thunderbolt/xdomain.c index 31fec78a197b..868ef56827af 100644 --- a/drivers/thunderbolt/xdomain.c +++ b/drivers/thunderbolt/xdomain.c @@ -55,6 +55,7 @@ static const char * const state_names[] = { struct xdomain_request_work { struct work_struct work; struct tb_xdp_header *pkg; + size_t pkg_len; struct tb *tb; }; @@ -731,6 +732,7 @@ static void tb_xdp_handle_request(struct work_struct *work) struct xdomain_request_work *xw = container_of(work, typeof(*xw), work); const struct tb_xdp_header *pkg = xw->pkg; const struct tb_xdomain_header *xhdr = &pkg->xd_hdr; + size_t pkg_len = xw->pkg_len; struct tb *tb = xw->tb; struct tb_ctl *ctl = tb->ctl; struct tb_xdomain *xd; @@ -762,7 +764,7 @@ static void tb_xdp_handle_request(struct work_struct *work) switch (pkg->type) { case PROPERTIES_REQUEST: tb_dbg(tb, "%llx: received XDomain properties request\n", route); - if (xd) { + if (xd && pkg_len >= sizeof(struct tb_xdp_properties)) { ret = tb_xdp_properties_response(tb, ctl, xd, sequence, (const struct tb_xdp_properties *)pkg); } @@ -816,7 +818,8 @@ static void tb_xdp_handle_request(struct work_struct *work) tb_dbg(tb, "%llx: received XDomain link state change request\n", route); - if (xd && xd->state == XDOMAIN_STATE_BONDING_UUID_HIGH) { + if (xd && xd->state == XDOMAIN_STATE_BONDING_UUID_HIGH && + pkg_len >= sizeof(struct tb_xdp_link_state_change)) { const struct tb_xdp_link_state_change *lsc = (const struct tb_xdp_link_state_change *)pkg; @@ -868,6 +871,7 @@ tb_xdp_schedule_request(struct tb *tb, const struct tb_xdp_header *hdr, kfree(xw); return false; } + xw->pkg_len = size; xw->tb = tb_domain_get(tb); schedule_work(&xw->work); -- 2.25.1