FAILED: patch "[PATCH] can: bcm: validate frame length in bcm_rx_setup() for RTR" failed to apply to 5.10-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 5.10-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.10.y
git checkout FETCH_HEAD
git cherry-pick -x 62ec41f364648be79d54d94d0d240ee326948afd
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026072029-swimmable-robust-7e81@gregkh' --subject-prefix 'PATCH 5.10.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 62ec41f364648be79d54d94d0d240ee326948afd Mon Sep 17 00:00:00 2001
From: Oliver Hartkopp <[email protected]>
Date: Tue, 14 Jul 2026 18:55:29 +0200
Subject: [PATCH] can: bcm: validate frame length in bcm_rx_setup() for RTR
replies
bcm_tx_setup() validates cf->len against the CAN/CAN FD DLC limits before installing frames for TX_SETUP, but bcm_rx_setup() never did the same for the RTR-reply frame configured via RX_SETUP with RX_RTR_FRAME.
net/can/bcm.c +41 -18
@@ -1246,22 +1246,37 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,return err; } -static void bcm_rx_setup_rtr_check (struct bcm_msg_head *msg_head, -struct bcm_op *op,void *new_frames) +static int bcm_rx_setup_rtr_check (struct bcm_msg_head *msg_head, +struct bcm_op *op,void *new_frames) { +struct canfd_frame *frame0 = new_frames; + +if (!(msg_head->flags &RX_RTR_FRAME )) +return 0 ; + +/* this frame is sent out as-is by bcm_can_tx() whenever a matching +* remote request is received, so validate its length the same way +* bcm_tx_setup() validates TX_SETUP frames before installing it +*/ +if (msg_head->flags &CAN_FD_FRAME ) { +if (frame0->len >64 ) +return -EINVAL ; + }else { +if (frame0->len >8 ) +return -EINVAL ; + } +/* funny feature in RX(!)_SETUP only for RTR-mode: * copy can_id into frame BUT without RTR-flag to * prevent a full-load-loopback-test ... ;-] * normalize this on the staged buffer, before it is * ever installed into op->frames. */ -if (msg_head->flags &RX_RTR_FRAME ) { -struct canfd_frame *frame0 = new_frames; +if ((msg_head->flags &TX_CP_CAN_ID ) || + frame0->can_id == op->can_id) + frame0->can_id = op->can_id & ~CAN_RTR_FLAG ; -if ((msg_head->flags &TX_CP_CAN_ID ) || - frame0->can_id == op->can_id) - frame0->can_id = op->can_id & ~CAN_RTR_FLAG ; - } +return 0 ; }/*
@@ -1324,7 +1339,11 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,return err; } -bcm_rx_setup_rtr_check (msg_head, op, new_frames); + err =bcm_rx_setup_rtr_check (msg_head, op, new_frames); +if (err <0 ) { +kfree (new_frames); +return err; + } }spin_lock_bh (&op->bcm_rx_update_lock);
@@ -1397,16 +1416,12 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,if (msg_head->nframes) { err =memcpy_from_msg (op->frames, msg, msg_head->nframes * op->cfsiz); -if (err <0 ) { -if (op->frames != &op->sframe) -kfree (op->frames); -if (op->last_frames != &op->last_sframe) -kfree (op->last_frames); -kfree (op); -return err; - } +if (err <0 ) + goto free_op; -bcm_rx_setup_rtr_check (msg_head, op, op->frames); + err =bcm_rx_setup_rtr_check (msg_head, op, op->frames); +if (err <0 ) + goto free_op; }/* bcm_can_tx / bcm_tx_timeout_handler needs this */
@@ -1505,6 +1520,14 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg, }return msg_head->nframes * op->cfsiz +MHSIZ ; + +free_op: +if (op->frames != &op->sframe) +kfree (op->frames); +if (op->last_frames != &op->last_sframe) +kfree (op->last_frames); +kfree (op); +return err; }/*
Oliver Hartkopp
maintainerPATCH 5/9 can: bcm: validate frame length in bcm_rx_setup() for RTR replies
commit 62ec41f364648be79d54d94d0d240ee326948afd upstream.
bcm_tx_setup() validates cf->len against the CAN/CAN FD DLC limits before installing frames for TX_SETUP, but bcm_rx_setup() never did the same for the RTR-reply frame configured via RX_SETUP with RX_RTR_FRAME.
--- net/can/bcm.c | 59 +++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 18 deletions(-)
net/can/bcm.c +41 -18
@@ -1194,22 +1194,37 @@ free_op:return err; } -static void bcm_rx_setup_rtr_check (struct bcm_msg_head *msg_head, -struct bcm_op *op,void *new_frames) +static int bcm_rx_setup_rtr_check (struct bcm_msg_head *msg_head, +struct bcm_op *op,void *new_frames) { +struct canfd_frame *frame0 = new_frames; + +if (!(msg_head->flags &RX_RTR_FRAME )) +return 0 ; + +/* this frame is sent out as-is by bcm_can_tx() whenever a matching +* remote request is received, so validate its length the same way +* bcm_tx_setup() validates TX_SETUP frames before installing it +*/ +if (msg_head->flags &CAN_FD_FRAME ) { +if (frame0->len >64 ) +return -EINVAL ; + }else { +if (frame0->len >8 ) +return -EINVAL ; + } +/* funny feature in RX(!)_SETUP only for RTR-mode: * copy can_id into frame BUT without RTR-flag to * prevent a full-load-loopback-test ... ;-] * normalize this on the staged buffer, before it is * ever installed into op->frames. */ -if (msg_head->flags &RX_RTR_FRAME ) { -struct canfd_frame *frame0 = new_frames; +if ((msg_head->flags &TX_CP_CAN_ID ) || + frame0->can_id == op->can_id) + frame0->can_id = op->can_id & ~CAN_RTR_FLAG ; -if ((msg_head->flags &TX_CP_CAN_ID ) || - frame0->can_id == op->can_id) - frame0->can_id = op->can_id & ~CAN_RTR_FLAG ; - } +return 0 ; }/*
@@ -1272,7 +1287,11 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,return err; } -bcm_rx_setup_rtr_check (msg_head, op, new_frames); + err =bcm_rx_setup_rtr_check (msg_head, op, new_frames); +if (err <0 ) { +kfree (new_frames); +return err; + } }spin_lock_bh (&op->bcm_rx_update_lock);
@@ -1345,16 +1364,12 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,if (msg_head->nframes) { err =memcpy_from_msg (op->frames, msg, msg_head->nframes * op->cfsiz); -if (err <0 ) { -if (op->frames != &op->sframe) -kfree (op->frames); -if (op->last_frames != &op->last_sframe) -kfree (op->last_frames); -kfree (op); -return err; - } +if (err <0 ) + goto free_op; -bcm_rx_setup_rtr_check (msg_head, op, op->frames); + err =bcm_rx_setup_rtr_check (msg_head, op, op->frames); +if (err <0 ) + goto free_op; }/* bcm_can_tx / bcm_tx_timeout_handler needs this */
@@ -1456,6 +1471,14 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg, }return msg_head->nframes * op->cfsiz +MHSIZ ; + +free_op: +if (op->frames != &op->sframe) +kfree (op->frames); +if (op->last_frames != &op->last_sframe) +kfree (op->last_frames); +kfree (op); +return err; }/*
Signature · 1 line
2.43.0