Skip to content

Commit 8ec205e

Browse files
committed
Merge tag 'linux-can-fixes-for-6.18-20251126' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can
Marc Kleine-Budde says: ==================== pull-request: can 2025-11-26 this is a pull request of 8 patches for net/main. Seungjin Bae provides a patch for the kvaser_usb driver to fix a potential infinite loop in the USB data stream command parser. Thomas Mühlbacher's patch for the sja1000 driver IRQ handler's max loop handling, that might lead to unhandled interrupts. 3 patches by me for the gs_usb driver fix handling of failed transmit URBs and add checking of the actual length of received URBs before accessing the data. The next patch is by me and is a port of Thomas Mühlbacher's patch (fix IRQ handler's max loop handling, that might lead to unhandled interrupts.) to the sun4i_can driver. Biju Das provides a patch for the rcar_canfd driver to fix the CAN-FD mode setting. The last patch is by Shaurya Rane for the em_canid filter to ensure that the complete CAN frame is present in the linear data buffer before accessing it. * tag 'linux-can-fixes-for-6.18-20251126' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can: net/sched: em_canid: fix uninit-value in em_canid_match can: rcar_canfd: Fix CAN-FD mode as default can: sun4i_can: sun4i_can_interrupt(): fix max irq loop handling can: gs_usb: gs_usb_receive_bulk_callback(): check actual_length before accessing data can: gs_usb: gs_usb_receive_bulk_callback(): check actual_length before accessing header can: gs_usb: gs_usb_xmit_callback(): fix handling of failed transmitted URBs can: sja1000: fix max irq loop handling can: kvaser_usb: leaf: Fix potential infinite loop in command parsers ==================== Link: https://patch.msgid.link/20251126155713.217105-1-mkl@pengutronix.de Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2 parents 5ffcb7b + 0c92210 commit 8ec205e

6 files changed

Lines changed: 127 additions & 41 deletions

File tree

drivers/net/can/rcar/rcar_canfd.c

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -709,6 +709,11 @@ static void rcar_canfd_set_bit_reg(void __iomem *addr, u32 val)
709709
rcar_canfd_update(val, val, addr);
710710
}
711711

712+
static void rcar_canfd_clear_bit_reg(void __iomem *addr, u32 val)
713+
{
714+
rcar_canfd_update(val, 0, addr);
715+
}
716+
712717
static void rcar_canfd_update_bit_reg(void __iomem *addr, u32 mask, u32 val)
713718
{
714719
rcar_canfd_update(mask, val, addr);
@@ -755,25 +760,6 @@ static void rcar_canfd_set_rnc(struct rcar_canfd_global *gpriv, unsigned int ch,
755760
rcar_canfd_set_bit(gpriv->base, RCANFD_GAFLCFG(w), rnc);
756761
}
757762

758-
static void rcar_canfd_set_mode(struct rcar_canfd_global *gpriv)
759-
{
760-
if (gpriv->info->ch_interface_mode) {
761-
u32 ch, val = gpriv->fdmode ? RCANFD_GEN4_FDCFG_FDOE
762-
: RCANFD_GEN4_FDCFG_CLOE;
763-
764-
for_each_set_bit(ch, &gpriv->channels_mask,
765-
gpriv->info->max_channels)
766-
rcar_canfd_set_bit_reg(&gpriv->fcbase[ch].cfdcfg, val);
767-
} else {
768-
if (gpriv->fdmode)
769-
rcar_canfd_set_bit(gpriv->base, RCANFD_GRMCFG,
770-
RCANFD_GRMCFG_RCMC);
771-
else
772-
rcar_canfd_clear_bit(gpriv->base, RCANFD_GRMCFG,
773-
RCANFD_GRMCFG_RCMC);
774-
}
775-
}
776-
777763
static int rcar_canfd_reset_controller(struct rcar_canfd_global *gpriv)
778764
{
779765
struct device *dev = &gpriv->pdev->dev;
@@ -806,6 +792,16 @@ static int rcar_canfd_reset_controller(struct rcar_canfd_global *gpriv)
806792
/* Reset Global error flags */
807793
rcar_canfd_write(gpriv->base, RCANFD_GERFL, 0x0);
808794

795+
/* Set the controller into appropriate mode */
796+
if (!gpriv->info->ch_interface_mode) {
797+
if (gpriv->fdmode)
798+
rcar_canfd_set_bit(gpriv->base, RCANFD_GRMCFG,
799+
RCANFD_GRMCFG_RCMC);
800+
else
801+
rcar_canfd_clear_bit(gpriv->base, RCANFD_GRMCFG,
802+
RCANFD_GRMCFG_RCMC);
803+
}
804+
809805
/* Transition all Channels to reset mode */
810806
for_each_set_bit(ch, &gpriv->channels_mask, gpriv->info->max_channels) {
811807
rcar_canfd_clear_bit(gpriv->base,
@@ -823,10 +819,23 @@ static int rcar_canfd_reset_controller(struct rcar_canfd_global *gpriv)
823819
dev_dbg(dev, "channel %u reset failed\n", ch);
824820
return err;
825821
}
826-
}
827822

828-
/* Set the controller into appropriate mode */
829-
rcar_canfd_set_mode(gpriv);
823+
/* Set the controller into appropriate mode */
824+
if (gpriv->info->ch_interface_mode) {
825+
/* Do not set CLOE and FDOE simultaneously */
826+
if (!gpriv->fdmode) {
827+
rcar_canfd_clear_bit_reg(&gpriv->fcbase[ch].cfdcfg,
828+
RCANFD_GEN4_FDCFG_FDOE);
829+
rcar_canfd_set_bit_reg(&gpriv->fcbase[ch].cfdcfg,
830+
RCANFD_GEN4_FDCFG_CLOE);
831+
} else {
832+
rcar_canfd_clear_bit_reg(&gpriv->fcbase[ch].cfdcfg,
833+
RCANFD_GEN4_FDCFG_FDOE);
834+
rcar_canfd_clear_bit_reg(&gpriv->fcbase[ch].cfdcfg,
835+
RCANFD_GEN4_FDCFG_CLOE);
836+
}
837+
}
838+
}
830839

831840
return 0;
832841
}

drivers/net/can/sja1000/sja1000.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -548,8 +548,8 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id)
548548
if (priv->read_reg(priv, SJA1000_IER) == IRQ_OFF)
549549
goto out;
550550

551-
while ((isrc = priv->read_reg(priv, SJA1000_IR)) &&
552-
(n < SJA1000_MAX_IRQ)) {
551+
while ((n < SJA1000_MAX_IRQ) &&
552+
(isrc = priv->read_reg(priv, SJA1000_IR))) {
553553

554554
status = priv->read_reg(priv, SJA1000_SR);
555555
/* check for absent controller due to hw unplug */

drivers/net/can/sun4i_can.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -657,8 +657,8 @@ static irqreturn_t sun4i_can_interrupt(int irq, void *dev_id)
657657
u8 isrc, status;
658658
int n = 0;
659659

660-
while ((isrc = readl(priv->base + SUN4I_REG_INT_ADDR)) &&
661-
(n < SUN4I_CAN_MAX_IRQ)) {
660+
while ((n < SUN4I_CAN_MAX_IRQ) &&
661+
(isrc = readl(priv->base + SUN4I_REG_INT_ADDR))) {
662662
n++;
663663
status = readl(priv->base + SUN4I_REG_STA_ADDR);
664664

drivers/net/can/usb/gs_usb.c

Lines changed: 87 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -261,14 +261,21 @@ struct canfd_quirk {
261261
u8 quirk;
262262
} __packed;
263263

264+
/* struct gs_host_frame::echo_id == GS_HOST_FRAME_ECHO_ID_RX indicates
265+
* a regular RX'ed CAN frame
266+
*/
267+
#define GS_HOST_FRAME_ECHO_ID_RX 0xffffffff
268+
264269
struct gs_host_frame {
265-
u32 echo_id;
266-
__le32 can_id;
270+
struct_group(header,
271+
u32 echo_id;
272+
__le32 can_id;
267273

268-
u8 can_dlc;
269-
u8 channel;
270-
u8 flags;
271-
u8 reserved;
274+
u8 can_dlc;
275+
u8 channel;
276+
u8 flags;
277+
u8 reserved;
278+
);
272279

273280
union {
274281
DECLARE_FLEX_ARRAY(struct classic_can, classic_can);
@@ -568,6 +575,37 @@ gs_usb_get_echo_skb(struct gs_can *dev, struct sk_buff *skb,
568575
return len;
569576
}
570577

578+
static unsigned int
579+
gs_usb_get_minimum_rx_length(const struct gs_can *dev, const struct gs_host_frame *hf,
580+
unsigned int *data_length_p)
581+
{
582+
unsigned int minimum_length, data_length = 0;
583+
584+
if (hf->flags & GS_CAN_FLAG_FD) {
585+
if (hf->echo_id == GS_HOST_FRAME_ECHO_ID_RX)
586+
data_length = can_fd_dlc2len(hf->can_dlc);
587+
588+
if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP)
589+
/* timestamp follows data field of max size */
590+
minimum_length = struct_size(hf, canfd_ts, 1);
591+
else
592+
minimum_length = sizeof(hf->header) + data_length;
593+
} else {
594+
if (hf->echo_id == GS_HOST_FRAME_ECHO_ID_RX &&
595+
!(hf->can_id & cpu_to_le32(CAN_RTR_FLAG)))
596+
data_length = can_cc_dlc2len(hf->can_dlc);
597+
598+
if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP)
599+
/* timestamp follows data field of max size */
600+
minimum_length = struct_size(hf, classic_can_ts, 1);
601+
else
602+
minimum_length = sizeof(hf->header) + data_length;
603+
}
604+
605+
*data_length_p = data_length;
606+
return minimum_length;
607+
}
608+
571609
static void gs_usb_receive_bulk_callback(struct urb *urb)
572610
{
573611
struct gs_usb *parent = urb->context;
@@ -576,6 +614,7 @@ static void gs_usb_receive_bulk_callback(struct urb *urb)
576614
int rc;
577615
struct net_device_stats *stats;
578616
struct gs_host_frame *hf = urb->transfer_buffer;
617+
unsigned int minimum_length, data_length;
579618
struct gs_tx_context *txc;
580619
struct can_frame *cf;
581620
struct canfd_frame *cfd;
@@ -594,6 +633,15 @@ static void gs_usb_receive_bulk_callback(struct urb *urb)
594633
return;
595634
}
596635

636+
minimum_length = sizeof(hf->header);
637+
if (urb->actual_length < minimum_length) {
638+
dev_err_ratelimited(&parent->udev->dev,
639+
"short read (actual_length=%u, minimum_length=%u)\n",
640+
urb->actual_length, minimum_length);
641+
642+
goto resubmit_urb;
643+
}
644+
597645
/* device reports out of range channel id */
598646
if (hf->channel >= parent->channel_cnt)
599647
goto device_detach;
@@ -609,20 +657,33 @@ static void gs_usb_receive_bulk_callback(struct urb *urb)
609657
if (!netif_running(netdev))
610658
goto resubmit_urb;
611659

612-
if (hf->echo_id == -1) { /* normal rx */
660+
minimum_length = gs_usb_get_minimum_rx_length(dev, hf, &data_length);
661+
if (urb->actual_length < minimum_length) {
662+
stats->rx_errors++;
663+
stats->rx_length_errors++;
664+
665+
if (net_ratelimit())
666+
netdev_err(netdev,
667+
"short read (actual_length=%u, minimum_length=%u)\n",
668+
urb->actual_length, minimum_length);
669+
670+
goto resubmit_urb;
671+
}
672+
673+
if (hf->echo_id == GS_HOST_FRAME_ECHO_ID_RX) { /* normal rx */
613674
if (hf->flags & GS_CAN_FLAG_FD) {
614675
skb = alloc_canfd_skb(netdev, &cfd);
615676
if (!skb)
616677
return;
617678

618679
cfd->can_id = le32_to_cpu(hf->can_id);
619-
cfd->len = can_fd_dlc2len(hf->can_dlc);
680+
cfd->len = data_length;
620681
if (hf->flags & GS_CAN_FLAG_BRS)
621682
cfd->flags |= CANFD_BRS;
622683
if (hf->flags & GS_CAN_FLAG_ESI)
623684
cfd->flags |= CANFD_ESI;
624685

625-
memcpy(cfd->data, hf->canfd->data, cfd->len);
686+
memcpy(cfd->data, hf->canfd->data, data_length);
626687
} else {
627688
skb = alloc_can_skb(netdev, &cf);
628689
if (!skb)
@@ -631,7 +692,7 @@ static void gs_usb_receive_bulk_callback(struct urb *urb)
631692
cf->can_id = le32_to_cpu(hf->can_id);
632693
can_frame_set_cc_len(cf, hf->can_dlc, dev->can.ctrlmode);
633694

634-
memcpy(cf->data, hf->classic_can->data, 8);
695+
memcpy(cf->data, hf->classic_can->data, data_length);
635696

636697
/* ERROR frames tell us information about the controller */
637698
if (le32_to_cpu(hf->can_id) & CAN_ERR_FLAG)
@@ -687,7 +748,7 @@ static void gs_usb_receive_bulk_callback(struct urb *urb)
687748
resubmit_urb:
688749
usb_fill_bulk_urb(urb, parent->udev,
689750
parent->pipe_in,
690-
hf, dev->parent->hf_size_rx,
751+
hf, parent->hf_size_rx,
691752
gs_usb_receive_bulk_callback, parent);
692753

693754
rc = usb_submit_urb(urb, GFP_ATOMIC);
@@ -750,8 +811,21 @@ static void gs_usb_xmit_callback(struct urb *urb)
750811
struct gs_can *dev = txc->dev;
751812
struct net_device *netdev = dev->netdev;
752813

753-
if (urb->status)
754-
netdev_info(netdev, "usb xmit fail %u\n", txc->echo_id);
814+
if (!urb->status)
815+
return;
816+
817+
if (urb->status != -ESHUTDOWN && net_ratelimit())
818+
netdev_info(netdev, "failed to xmit URB %u: %pe\n",
819+
txc->echo_id, ERR_PTR(urb->status));
820+
821+
netdev->stats.tx_dropped++;
822+
netdev->stats.tx_errors++;
823+
824+
can_free_echo_skb(netdev, txc->echo_id, NULL);
825+
gs_free_tx_context(txc);
826+
atomic_dec(&dev->active_tx_urbs);
827+
828+
netif_wake_queue(netdev);
755829
}
756830

757831
static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb,

drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -685,7 +685,7 @@ static int kvaser_usb_leaf_wait_cmd(const struct kvaser_usb *dev, u8 id,
685685
* for further details.
686686
*/
687687
if (tmp->len == 0) {
688-
pos = round_up(pos,
688+
pos = round_up(pos + 1,
689689
le16_to_cpu
690690
(dev->bulk_in->wMaxPacketSize));
691691
continue;
@@ -1732,7 +1732,7 @@ static void kvaser_usb_leaf_read_bulk_callback(struct kvaser_usb *dev,
17321732
* number of events in case of a heavy rx load on the bus.
17331733
*/
17341734
if (cmd->len == 0) {
1735-
pos = round_up(pos, le16_to_cpu
1735+
pos = round_up(pos + 1, le16_to_cpu
17361736
(dev->bulk_in->wMaxPacketSize));
17371737
continue;
17381738
}

net/sched/em_canid.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,9 @@ static int em_canid_match(struct sk_buff *skb, struct tcf_ematch *m,
9999
int i;
100100
const struct can_filter *lp;
101101

102+
if (!pskb_may_pull(skb, CAN_MTU))
103+
return 0;
104+
102105
can_id = em_canid_get_id(skb);
103106

104107
if (can_id & CAN_EFF_FLAG) {

0 commit comments

Comments
 (0)