mirror of
git://git.yoctoproject.org/linux-yocto.git
synced 2025-12-22 18:47:06 +01:00
Bluetooth: MGMT: fix crash in set_mesh_sync and set_mesh_complete
There is a BUG: KASAN: stack-out-of-bounds in set_mesh_sync due to
memcpy from badly declared on-stack flexible array.
Another crash is in set_mesh_complete() due to double list_del via
mgmt_pending_valid + mgmt_pending_remove.
Use DEFINE_FLEX to declare the flexible array right, and don't memcpy
outside bounds.
As mgmt_pending_valid removes the cmd from list, use mgmt_pending_free,
and also report status on error.
Fixes: 302a1f674c ("Bluetooth: MGMT: Fix possible UAFs")
Signed-off-by: Pauli Virtanen <pav@iki.fi>
Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
parent
0d92808024
commit
e8785404de
|
|
@ -853,7 +853,7 @@ struct mgmt_cp_set_mesh {
|
|||
__le16 window;
|
||||
__le16 period;
|
||||
__u8 num_ad_types;
|
||||
__u8 ad_types[];
|
||||
__u8 ad_types[] __counted_by(num_ad_types);
|
||||
} __packed;
|
||||
#define MGMT_SET_MESH_RECEIVER_SIZE 6
|
||||
|
||||
|
|
|
|||
|
|
@ -2175,19 +2175,24 @@ static void set_mesh_complete(struct hci_dev *hdev, void *data, int err)
|
|||
sk = cmd->sk;
|
||||
|
||||
if (status) {
|
||||
mgmt_cmd_status(cmd->sk, hdev->id, MGMT_OP_SET_MESH_RECEIVER,
|
||||
status);
|
||||
mgmt_pending_foreach(MGMT_OP_SET_MESH_RECEIVER, hdev, true,
|
||||
cmd_status_rsp, &status);
|
||||
return;
|
||||
goto done;
|
||||
}
|
||||
|
||||
mgmt_pending_remove(cmd);
|
||||
mgmt_cmd_complete(sk, hdev->id, MGMT_OP_SET_MESH_RECEIVER, 0, NULL, 0);
|
||||
|
||||
done:
|
||||
mgmt_pending_free(cmd);
|
||||
}
|
||||
|
||||
static int set_mesh_sync(struct hci_dev *hdev, void *data)
|
||||
{
|
||||
struct mgmt_pending_cmd *cmd = data;
|
||||
struct mgmt_cp_set_mesh cp;
|
||||
DEFINE_FLEX(struct mgmt_cp_set_mesh, cp, ad_types, num_ad_types,
|
||||
sizeof(hdev->mesh_ad_types));
|
||||
size_t len;
|
||||
|
||||
mutex_lock(&hdev->mgmt_pending_lock);
|
||||
|
|
@ -2197,27 +2202,26 @@ static int set_mesh_sync(struct hci_dev *hdev, void *data)
|
|||
return -ECANCELED;
|
||||
}
|
||||
|
||||
memcpy(&cp, cmd->param, sizeof(cp));
|
||||
len = cmd->param_len;
|
||||
memcpy(cp, cmd->param, min(__struct_size(cp), len));
|
||||
|
||||
mutex_unlock(&hdev->mgmt_pending_lock);
|
||||
|
||||
len = cmd->param_len;
|
||||
|
||||
memset(hdev->mesh_ad_types, 0, sizeof(hdev->mesh_ad_types));
|
||||
|
||||
if (cp.enable)
|
||||
if (cp->enable)
|
||||
hci_dev_set_flag(hdev, HCI_MESH);
|
||||
else
|
||||
hci_dev_clear_flag(hdev, HCI_MESH);
|
||||
|
||||
hdev->le_scan_interval = __le16_to_cpu(cp.period);
|
||||
hdev->le_scan_window = __le16_to_cpu(cp.window);
|
||||
hdev->le_scan_interval = __le16_to_cpu(cp->period);
|
||||
hdev->le_scan_window = __le16_to_cpu(cp->window);
|
||||
|
||||
len -= sizeof(cp);
|
||||
len -= sizeof(struct mgmt_cp_set_mesh);
|
||||
|
||||
/* If filters don't fit, forward all adv pkts */
|
||||
if (len <= sizeof(hdev->mesh_ad_types))
|
||||
memcpy(hdev->mesh_ad_types, cp.ad_types, len);
|
||||
memcpy(hdev->mesh_ad_types, cp->ad_types, len);
|
||||
|
||||
hci_update_passive_scan_sync(hdev);
|
||||
return 0;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user