mirror of
https://github.com/torvalds/linux.git
synced 2026-07-29 02:31:27 +02:00
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:8e1de70425("thunderbolt: Add support for XDomain lane bonding") Fixes:cdae7c07e3("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>
This commit is contained in:
parent
322e93448d
commit
a504b9f279
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
@ -733,6 +734,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;
|
||||
|
|
@ -764,7 +766,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);
|
||||
}
|
||||
|
|
@ -818,7 +820,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;
|
||||
|
||||
|
|
@ -870,6 +873,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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user