]> git.baikalelectronics.ru Git - kernel.git/commitdiff
can: do not copy the payload of RTR frames
authorVincent Mailhol <mailhol.vincent@wanadoo.fr>
Tue, 7 Dec 2021 12:15:29 +0000 (21:15 +0900)
committerMarc Kleine-Budde <mkl@pengutronix.de>
Wed, 5 Jan 2022 11:09:05 +0000 (12:09 +0100)
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: Yasushi SHOJI <yashi@spacecubics.com>
Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
drivers/net/can/pch_can.c
drivers/net/can/spi/mcp251x.c
drivers/net/can/usb/mcba_usb.c

index 6b45840db1f9be239c4189a992d753f4345f76f5..4bf9bfc4de727a1a52e764b9898977efa86f8923 100644 (file)
@@ -677,16 +677,17 @@ static int pch_can_rx_normal(struct net_device *ndev, u32 obj_num, int quota)
                        cf->can_id = id;
                }
 
-               if (id2 & PCH_ID2_DIR)
-                       cf->can_id |= CAN_RTR_FLAG;
-
                cf->len = can_cc_dlc2len((ioread32(&priv->regs->
                                                    ifregs[0].mcont)) & 0xF);
 
-               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;
+               if (id2 & PCH_ID2_DIR) {
+                       cf->can_id |= CAN_RTR_FLAG;
+               } else {
+                       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++;
index 0cec808e87277c1716e7c02641a00c53adc8d7d8..2fa1e85fa5291c9e82110bade3d1d1c220434d8a 100644 (file)
@@ -730,7 +730,8 @@ static void mcp251x_hw_rx(struct spi_device *spi, int buf_idx)
        }
        /* Data length */
        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_bytes += frame->len;
index a1a154c08b7f7f77dd0df05aaf34418a1fc26055..162d2e11caddf3d1c6649f85afefe14bc13dbb7b 100644 (file)
@@ -450,12 +450,12 @@ static void mcba_usb_process_can(struct mcba_priv *priv,
                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);
 
-       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_bytes += cf->len;