Skip to content

Commit a504b9f

Browse files
mjbommarwesteri
authored andcommitted
thunderbolt: Validate XDomain request packet size before type cast
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: 8e1de70 ("thunderbolt: Add support for XDomain lane bonding") Fixes: cdae7c0 ("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>
1 parent 322e934 commit a504b9f

1 file changed

Lines changed: 6 additions & 2 deletions

File tree

drivers/thunderbolt/xdomain.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ static const char * const state_names[] = {
5555
struct xdomain_request_work {
5656
struct work_struct work;
5757
struct tb_xdp_header *pkg;
58+
size_t pkg_len;
5859
struct tb *tb;
5960
};
6061

@@ -733,6 +734,7 @@ static void tb_xdp_handle_request(struct work_struct *work)
733734
struct xdomain_request_work *xw = container_of(work, typeof(*xw), work);
734735
const struct tb_xdp_header *pkg = xw->pkg;
735736
const struct tb_xdomain_header *xhdr = &pkg->xd_hdr;
737+
size_t pkg_len = xw->pkg_len;
736738
struct tb *tb = xw->tb;
737739
struct tb_ctl *ctl = tb->ctl;
738740
struct tb_xdomain *xd;
@@ -764,7 +766,7 @@ static void tb_xdp_handle_request(struct work_struct *work)
764766
switch (pkg->type) {
765767
case PROPERTIES_REQUEST:
766768
tb_dbg(tb, "%llx: received XDomain properties request\n", route);
767-
if (xd) {
769+
if (xd && pkg_len >= sizeof(struct tb_xdp_properties)) {
768770
ret = tb_xdp_properties_response(tb, ctl, xd, sequence,
769771
(const struct tb_xdp_properties *)pkg);
770772
}
@@ -818,7 +820,8 @@ static void tb_xdp_handle_request(struct work_struct *work)
818820
tb_dbg(tb, "%llx: received XDomain link state change request\n",
819821
route);
820822

821-
if (xd && xd->state == XDOMAIN_STATE_BONDING_UUID_HIGH) {
823+
if (xd && xd->state == XDOMAIN_STATE_BONDING_UUID_HIGH &&
824+
pkg_len >= sizeof(struct tb_xdp_link_state_change)) {
822825
const struct tb_xdp_link_state_change *lsc =
823826
(const struct tb_xdp_link_state_change *)pkg;
824827

@@ -870,6 +873,7 @@ tb_xdp_schedule_request(struct tb *tb, const struct tb_xdp_header *hdr,
870873
kfree(xw);
871874
return false;
872875
}
876+
xw->pkg_len = size;
873877
xw->tb = tb_domain_get(tb);
874878

875879
schedule_work(&xw->work);

0 commit comments

Comments
 (0)