mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-31 01:11:51 -04:00
can: ems_usb: validate CPC message lengths
ems_usb_read_bulk_callback() walks CPC messages packed in one USB
receive buffer.
Check that each declared message fits in the URB payload. Also require the
type-specific payload to cover the fields used by the CAN, state, error and
overrun handlers.
Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Link: https://patch.msgid.link/20260706092752.79600-1-pengpeng@iscas.ac.cn
Fixes: 702171adee ("ems_usb: Added support for EMS CPC-USB/ARM7 CAN/USB interface")
Cc: stable@vger.kernel.org
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
This commit is contained in:
committed by
Marc Kleine-Budde
parent
7a0cf2b249
commit
02925f5137
@@ -409,6 +409,40 @@ static void ems_usb_rx_err(struct ems_usb *dev, struct ems_cpc_msg *msg)
|
||||
netif_rx(skb);
|
||||
}
|
||||
|
||||
static bool ems_usb_rx_msg_len_valid(struct ems_cpc_msg *msg)
|
||||
{
|
||||
size_t len = msg->length;
|
||||
size_t can_len;
|
||||
|
||||
switch (msg->type) {
|
||||
case CPC_MSG_TYPE_CAN_STATE:
|
||||
return len >= sizeof(msg->msg.can_state);
|
||||
|
||||
case CPC_MSG_TYPE_CAN_FRAME:
|
||||
case CPC_MSG_TYPE_EXT_CAN_FRAME:
|
||||
case CPC_MSG_TYPE_RTR_FRAME:
|
||||
case CPC_MSG_TYPE_EXT_RTR_FRAME:
|
||||
if (len < CPC_CAN_MSG_MIN_SIZE)
|
||||
return false;
|
||||
|
||||
if (msg->type == CPC_MSG_TYPE_RTR_FRAME ||
|
||||
msg->type == CPC_MSG_TYPE_EXT_RTR_FRAME)
|
||||
return true;
|
||||
|
||||
can_len = can_cc_dlc2len(msg->msg.can_msg.length & 0xf);
|
||||
return len >= CPC_CAN_MSG_MIN_SIZE + can_len;
|
||||
|
||||
case CPC_MSG_TYPE_CAN_FRAME_ERROR:
|
||||
return len >= sizeof(msg->msg.error);
|
||||
|
||||
case CPC_MSG_TYPE_OVERRUN:
|
||||
return len >= sizeof(msg->msg.overrun);
|
||||
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* callback for bulk IN urb
|
||||
*/
|
||||
@@ -451,6 +485,15 @@ static void ems_usb_read_bulk_callback(struct urb *urb)
|
||||
}
|
||||
|
||||
msg = (struct ems_cpc_msg *)&ibuf[start];
|
||||
if (msg->length >
|
||||
urb->actual_length - start - CPC_MSG_HEADER_LEN) {
|
||||
netdev_err(netdev, "format error\n");
|
||||
break;
|
||||
}
|
||||
if (!ems_usb_rx_msg_len_valid(msg)) {
|
||||
netdev_err(netdev, "format error\n");
|
||||
break;
|
||||
}
|
||||
|
||||
switch (msg->type) {
|
||||
case CPC_MSG_TYPE_CAN_STATE:
|
||||
|
||||
Reference in New Issue
Block a user