Commit f68eafeb authored by Vincent Mailhol's avatar Vincent Mailhol Committed by Marc Kleine-Budde

can: do not copy the payload of RTR frames

The actual payload length of the CAN Remote Transmission Request (RTR)
frames is always 0, i.e. no payload is transmitted on the wire.
However, those RTR frames still use the DLC to indicate the length of
the requested frame.

For this reason, it is incorrect to copy the payload of RTR frames
(the payload buffer would only contain garbage data). This patch
encapsulates the payload copy in a check toward the RTR flag.

Link: https://lore.kernel.org/all/20211207121531.42941-4-mailhol.vincent@wanadoo.fr
Cc: Yasushi SHOJI <yashi@spacecubics.com>
Tested-by: default avatarYasushi SHOJI <yashi@spacecubics.com>
Signed-off-by: default avatarVincent Mailhol <mailhol.vincent@wanadoo.fr>
Signed-off-by: default avatarMarc Kleine-Budde <mkl@pengutronix.de>
parent 0b0ce2c6
...@@ -677,16 +677,17 @@ static int pch_can_rx_normal(struct net_device *ndev, u32 obj_num, int quota) ...@@ -677,16 +677,17 @@ static int pch_can_rx_normal(struct net_device *ndev, u32 obj_num, int quota)
cf->can_id = id; cf->can_id = id;
} }
if (id2 & PCH_ID2_DIR)
cf->can_id |= CAN_RTR_FLAG;
cf->len = can_cc_dlc2len((ioread32(&priv->regs-> cf->len = can_cc_dlc2len((ioread32(&priv->regs->
ifregs[0].mcont)) & 0xF); ifregs[0].mcont)) & 0xF);
for (i = 0; i < cf->len; i += 2) { if (id2 & PCH_ID2_DIR) {
data_reg = ioread16(&priv->regs->ifregs[0].data[i / 2]); cf->can_id |= CAN_RTR_FLAG;
cf->data[i] = data_reg; } else {
cf->data[i + 1] = data_reg >> 8; for (i = 0; i < cf->len; i += 2) {
data_reg = ioread16(&priv->regs->ifregs[0].data[i / 2]);
cf->data[i] = data_reg;
cf->data[i + 1] = data_reg >> 8;
}
} }
rcv_pkts++; rcv_pkts++;
......
...@@ -730,7 +730,8 @@ static void mcp251x_hw_rx(struct spi_device *spi, int buf_idx) ...@@ -730,7 +730,8 @@ static void mcp251x_hw_rx(struct spi_device *spi, int buf_idx)
} }
/* Data length */ /* Data length */
frame->len = can_cc_dlc2len(buf[RXBDLC_OFF] & RXBDLC_LEN_MASK); frame->len = can_cc_dlc2len(buf[RXBDLC_OFF] & RXBDLC_LEN_MASK);
memcpy(frame->data, buf + RXBDAT_OFF, frame->len); if (!(frame->can_id & CAN_RTR_FLAG))
memcpy(frame->data, buf + RXBDAT_OFF, frame->len);
priv->net->stats.rx_packets++; priv->net->stats.rx_packets++;
priv->net->stats.rx_bytes += frame->len; priv->net->stats.rx_bytes += frame->len;
......
...@@ -450,12 +450,12 @@ static void mcba_usb_process_can(struct mcba_priv *priv, ...@@ -450,12 +450,12 @@ static void mcba_usb_process_can(struct mcba_priv *priv,
cf->can_id = (sid & 0xffe0) >> 5; cf->can_id = (sid & 0xffe0) >> 5;
} }
if (msg->dlc & MCBA_DLC_RTR_MASK)
cf->can_id |= CAN_RTR_FLAG;
cf->len = can_cc_dlc2len(msg->dlc & MCBA_DLC_MASK); cf->len = can_cc_dlc2len(msg->dlc & MCBA_DLC_MASK);
memcpy(cf->data, msg->data, cf->len); if (msg->dlc & MCBA_DLC_RTR_MASK)
cf->can_id |= CAN_RTR_FLAG;
else
memcpy(cf->data, msg->data, cf->len);
stats->rx_packets++; stats->rx_packets++;
stats->rx_bytes += cf->len; stats->rx_bytes += cf->len;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment