thunderbolt: Fixes for v7.1-rc7

This includes more fixes to harden XDomain message handling against
 possible malicious hosts.
 
 All these have been in linux-next with no reported issues.
 -----BEGIN PGP SIGNATURE-----
 
 iQJTBAABCgA+FiEEVTdhRGBbNzLrSUBaAP2fSd+ZWKAFAmodYrsgHG1pa2Eud2Vz
 dGVyYmVyZ0BsaW51eC5pbnRlbC5jb20ACgkQAP2fSd+ZWKDgMA/44DwH9FgMW7JF
 sM0Gux3sQMcg/DFcOXua/9WM7WTdYhryTF0t6/IsuI3WtlFyb+fwNC4CTw6wXRyb
 2oOa2gmUTk1Lbwl2kJ2iLXNFGWKFu8v8+M/HYZedlV6kL2g6RiztJU64xk0vHWtv
 BnijYHaX4GDDDyKrI0xQ6UVLS2qrKsrsMPjjUztz4WA4l9LRcYZ1VUA0weoopObj
 f9vgDqmJO/sgHXV31TYR89bP6zXzQ/AgMoBe/kHXcw79xqMbCEIWNUiGeI5hvyAg
 DSjJAW9m9tpu8EjGisgrV8dPIsD+Y6iocieftjuox1eaR5wDSmcPYJIduKGirLWV
 nVk/6UJZJB5C30zgrhzHuowdFKtINoz7Se88zRYMJaqt16uVBAWfUivkqWBzg1+A
 LnWxLlnYJLx2SvsIBMH3TMx0FY6dmP0M5Y9PVA8QjbPa724wvrCHHCCgB4u7X/R/
 +K7T6jAPsBvKoAVcNr1ELBlaoZ2GPWIetosmf9VNZ7r9sXskadIo1UMTkQnW2ss5
 73b4QVZljwlVcAo+blFStyKM993dkTdsp1rld3G17YRGXbFnfMwpOCkHUuB0Sxgj
 uNHWWdSfe7cInDBPuC662imbeUDkGSAse0xi8qsetywbc5a5RQyw2948EUGwT7Ke
 BNoOvEYylx4Pd5r00u0RiFvSCHSQzA==
 =c9UC
 -----END PGP SIGNATURE-----

Merge tag 'thunderbolt-for-v7.1-rc7' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/westeri/thunderbolt into usb-linus

Mika writes:

thunderbolt: Fixes for v7.1-rc7

This includes more fixes to harden XDomain message handling against
possible malicious hosts.

All these have been in linux-next with no reported issues.

* tag 'thunderbolt-for-v7.1-rc7' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/westeri/thunderbolt:
  thunderbolt: Limit XDomain response copy to actual frame size
  thunderbolt: Validate XDomain request packet size before type cast
  thunderbolt: Clamp XDomain response data copy to allocation size
  thunderbolt: Bound root directory content to block size
  thunderbolt: Reject zero-length property entries in validator
This commit is contained in:
Greg Kroah-Hartman 2026-06-01 17:50:38 +02:00
commit 108c8b6c06
2 changed files with 17 additions and 3 deletions

View File

@ -60,6 +60,8 @@ static bool tb_property_entry_valid(const struct tb_property_entry *entry,
case TB_PROPERTY_TYPE_DIRECTORY:
case TB_PROPERTY_TYPE_DATA:
case TB_PROPERTY_TYPE_TEXT:
if (!entry->length)
return false;
if (entry->length > block_len)
return false;
if (check_add_overflow(entry->value, entry->length, &end) ||
@ -185,6 +187,10 @@ static struct tb_property_dir *__tb_property_parse_dir(const u32 *block,
if (is_root) {
content_offset = dir_offset + 2;
content_len = dir_len;
if (content_offset + content_len > block_len) {
tb_property_free_dir(dir);
return NULL;
}
} else {
if (dir_len < 4) {
tb_property_free_dir(dir);

View File

@ -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;
};
@ -122,7 +123,9 @@ static bool tb_xdomain_match(const struct tb_cfg_request *req,
static bool tb_xdomain_copy(struct tb_cfg_request *req,
const struct ctl_pkg *pkg)
{
memcpy(req->response, pkg->buffer, req->response_size);
size_t len = min_t(size_t, pkg->frame.size, req->response_size);
memcpy(req->response, pkg->buffer, len);
req->result.err = 0;
return true;
}
@ -393,6 +396,8 @@ static int tb_xdp_properties_request(struct tb_ctl *ctl, u64 route,
}
}
if (req.offset + len > data_len)
len = data_len - req.offset;
memcpy(data + req.offset, res->data, len * 4);
req.offset += len;
} while (!data_len || req.offset < data_len);
@ -731,6 +736,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 +768,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 +822,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 +875,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);