From b525a898d4ab602d7e5ca26ed32a750e387fd9e2 Mon Sep 17 00:00:00 2001 From: Patrick Menschel Date: Tue, 31 Oct 2023 10:29:09 +0100 Subject: [PATCH 01/28] can: isotp: change error format from decimal to symbolic error names stable inclusion from stable-5.10.200 commit 186ab5645199cac4008645aff711c5d77f7fae5f category: bugfix issue: #IA8M8T CVE: NA Signed-off-by: wanxiaoqing --------------------------------------- commit 46d8657a6b284e32b6b3bf1a6c93ee507fdd3cdb upstream This patch changes the format string for errors from decimal %d to symbolic error names %pe to achieve more comprehensive log messages. Link: https://lore.kernel.org/r/20210427052150.2308-2-menschel.p@posteo.de Signed-off-by: Patrick Menschel Signed-off-by: Marc Kleine-Budde Signed-off-by: Oliver Hartkopp Signed-off-by: Greg Kroah-Hartman Signed-off-by: wanxiaoqing --- net/can/isotp.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/net/can/isotp.c b/net/can/isotp.c index 16ebc187af1c..d34f9ab2eb62 100644 --- a/net/can/isotp.c +++ b/net/can/isotp.c @@ -228,8 +228,8 @@ static int isotp_send_fc(struct sock *sk, int ae, u8 flowstatus) can_send_ret = can_send(nskb, 1); if (can_send_ret) - pr_notice_once("can-isotp: %s: can_send_ret %d\n", - __func__, can_send_ret); + pr_notice_once("can-isotp: %s: can_send_ret %pe\n", + __func__, ERR_PTR(can_send_ret)); dev_put(dev); @@ -814,8 +814,8 @@ static enum hrtimer_restart isotp_tx_timer_handler(struct hrtimer *hrtimer) can_send_ret = can_send(skb, 1); if (can_send_ret) - pr_notice_once("can-isotp: %s: can_send_ret %d\n", - __func__, can_send_ret); + pr_notice_once("can-isotp: %s: can_send_ret %pe\n", + __func__, ERR_PTR(can_send_ret)); if (so->tx.idx >= so->tx.len) { /* we are done */ @@ -976,8 +976,8 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) err = can_send(skb, 1); dev_put(dev); if (err) { - pr_notice_once("can-isotp: %s: can_send_ret %d\n", - __func__, err); + pr_notice_once("can-isotp: %s: can_send_ret %pe\n", + __func__, ERR_PTR(err)); /* no transmission -> no timeout monitoring */ if (hrtimer_sec) -- Gitee From 028450785536cc24a72319b119d47d86e04cb5fa Mon Sep 17 00:00:00 2001 From: Patrick Menschel Date: Tue, 31 Oct 2023 10:29:10 +0100 Subject: [PATCH 02/28] can: isotp: add symbolic error message to isotp_module_init() stable inclusion from stable-5.10.200 commit 57798a2cfe1594e7fa0f920811fe69cb093d8954 category: bugfix issue: #IA8M8T CVE: NA Signed-off-by: wanxiaoqing --------------------------------------- commit 6a5ddae578842652719fb926b22f1d510fe50bee upstream This patch adds the value of err with format %pe to the already existing error message. Link: https://lore.kernel.org/r/20210427052150.2308-3-menschel.p@posteo.de Signed-off-by: Patrick Menschel Signed-off-by: Marc Kleine-Budde Signed-off-by: Oliver Hartkopp Signed-off-by: Greg Kroah-Hartman Signed-off-by: wanxiaoqing --- net/can/isotp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/can/isotp.c b/net/can/isotp.c index d34f9ab2eb62..009d5216f3ea 100644 --- a/net/can/isotp.c +++ b/net/can/isotp.c @@ -1550,7 +1550,7 @@ static __init int isotp_module_init(void) err = can_proto_register(&isotp_can_proto); if (err < 0) - pr_err("can: registration of isotp protocol failed\n"); + pr_err("can: registration of isotp protocol failed %pe\n", ERR_PTR(err)); else register_netdevice_notifier(&canisotp_notifier); -- Gitee From f2e96f0ca32294f0208dfcc7eadbc279b3962e6f Mon Sep 17 00:00:00 2001 From: Patrick Menschel Date: Tue, 31 Oct 2023 10:29:11 +0100 Subject: [PATCH 03/28] can: isotp: Add error message if txqueuelen is too small stable inclusion from stable-5.10.200 commit 7adbc048d84b54aaa2faf466d888e436fb83f70b category: bugfix issue: #IA8M8T CVE: NA Signed-off-by: wanxiaoqing --------------------------------------- commit c69d190f7bb9a03cf5237d45a457993730d01605 upstream This patch adds an additional error message in case that txqueuelen is set too small and advices the user to increase txqueuelen. This is likely to happen even with small transfers if txqueuelen is at default value 10 frames. Link: https://lore.kernel.org/r/20210427052150.2308-4-menschel.p@posteo.de Signed-off-by: Patrick Menschel Signed-off-by: Marc Kleine-Budde Signed-off-by: Oliver Hartkopp Signed-off-by: Greg Kroah-Hartman Signed-off-by: wanxiaoqing --- net/can/isotp.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/can/isotp.c b/net/can/isotp.c index 009d5216f3ea..ef72e5344789 100644 --- a/net/can/isotp.c +++ b/net/can/isotp.c @@ -813,10 +813,12 @@ static enum hrtimer_restart isotp_tx_timer_handler(struct hrtimer *hrtimer) can_skb_set_owner(skb, sk); can_send_ret = can_send(skb, 1); - if (can_send_ret) + if (can_send_ret) { pr_notice_once("can-isotp: %s: can_send_ret %pe\n", __func__, ERR_PTR(can_send_ret)); - + if (can_send_ret == -ENOBUFS) + pr_notice_once("can-isotp: tx queue is full, increasing txqueuelen may prevent this error\n"); + } if (so->tx.idx >= so->tx.len) { /* we are done */ so->tx.state = ISOTP_IDLE; -- Gitee From 44944cff7214729a832628a5d48a752d262415ef Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Tue, 31 Oct 2023 10:29:12 +0100 Subject: [PATCH 04/28] can: isotp: set max PDU size to 64 kByte stable inclusion from stable-5.10.200 commit 93b1e3f3a263e9986e8f46d23f1a932d4e34adf4 category: bugfix issue: #IA8M8T CVE: NA Signed-off-by: wanxiaoqing --------------------------------------- commit 9c0c191d82a1de964ac953a1df8b5744ec670b07 upstream The reason to extend the max PDU size from 4095 Byte (12 bit length value) to a 32 bit value (up to 4 GByte) was to be able to flash 64 kByte bootloaders with a single ISO-TP PDU. The max PDU size in the Linux kernel implementation was set to 8200 Bytes to be able to test the length information escape sequence. It turns out that the demand for 64 kByte PDUs is real so the value for MAX_MSG_LENGTH is set to 66000 to be able to potentially add some checksums to the 65.536 Byte block. Link: https://github.com/linux-can/can-utils/issues/347#issuecomment-1056142301 Link: https://lore.kernel.org/all/20220309120416.83514-3-socketcan@hartkopp.net Signed-off-by: Oliver Hartkopp Signed-off-by: Marc Kleine-Budde Signed-off-by: Greg Kroah-Hartman Signed-off-by: wanxiaoqing --- net/can/isotp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/can/isotp.c b/net/can/isotp.c index ef72e5344789..fb179a333784 100644 --- a/net/can/isotp.c +++ b/net/can/isotp.c @@ -87,9 +87,9 @@ MODULE_ALIAS("can-proto-6"); /* ISO 15765-2:2016 supports more than 4095 byte per ISO PDU as the FF_DL can * take full 32 bit values (4 Gbyte). We would need some good concept to handle * this between user space and kernel space. For now increase the static buffer - * to something about 8 kbyte to be able to test this new functionality. + * to something about 64 kbyte to be able to test this new functionality. */ -#define MAX_MSG_LENGTH 8200 +#define MAX_MSG_LENGTH 66000 /* N_PCI type values in bits 7-4 of N_PCI bytes */ #define N_PCI_SF 0x00 /* single frame */ -- Gitee From d93a79240d87a3a26aa4bfc6d743466befe63373 Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Tue, 31 Oct 2023 10:29:13 +0100 Subject: [PATCH 05/28] can: isotp: isotp_bind(): return -EINVAL on incorrect CAN ID formatting stable inclusion from stable-5.10.200 commit 0386f37047899b3af95b00090b1f4ff4f5990f8d category: bugfix issue: #IA8M8T CVE: NA Signed-off-by: wanxiaoqing --------------------------------------- commit 2aa39889c463195a0dfe2aff9fad413139c32a4f upstream Commit 3ea566422cbd ("can: isotp: sanitize CAN ID checks in isotp_bind()") checks the given CAN ID address information by sanitizing the input values. This check (silently) removes obsolete bits by masking the given CAN IDs. Derek Will suggested to give a feedback to the application programmer when the 'sanitizing' was actually needed which means the programmer provided CAN ID content in a wrong format (e.g. SFF CAN IDs with a CAN ID > 0x7FF). Link: https://lore.kernel.org/all/20220515181633.76671-1-socketcan@hartkopp.net Suggested-by: Derek Will Signed-off-by: Oliver Hartkopp Signed-off-by: Marc Kleine-Budde Signed-off-by: Greg Kroah-Hartman Signed-off-by: wanxiaoqing --- net/can/isotp.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/net/can/isotp.c b/net/can/isotp.c index fb179a333784..902cb61b6495 100644 --- a/net/can/isotp.c +++ b/net/can/isotp.c @@ -1142,6 +1142,11 @@ static int isotp_bind(struct socket *sock, struct sockaddr *uaddr, int len) else rx_id &= CAN_SFF_MASK; + /* give feedback on wrong CAN-ID values */ + if (tx_id != addr->can_addr.tp.tx_id || + rx_id != addr->can_addr.tp.rx_id) + return -EINVAL; + if (!addr->can_ifindex) return -ENODEV; -- Gitee From cefe3302b4e372922175f1c83ea5b55369bb2c7b Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Tue, 31 Oct 2023 10:29:14 +0100 Subject: [PATCH 06/28] can: isotp: check CAN address family in isotp_bind() stable inclusion from stable-5.10.200 commit de3c02383aa678f6799402ac47fdd89cf4bfcaa9 category: bugfix issue: #IA8M8T CVE: NA Signed-off-by: wanxiaoqing --------------------------------------- commit c6adf659a8ba85913e16a571d5a9bcd17d3d1234 upstream Add missing check to block non-AF_CAN binds. Syzbot created some code which matched the right sockaddr struct size but used AF_XDP (0x2C) instead of AF_CAN (0x1D) in the address family field: bind$xdp(r2, &(0x7f0000000540)={0x2c, 0x0, r4, 0x0, r2}, 0x10) ^^^^ This has no funtional impact but the userspace should be notified about the wrong address family field content. Link: https://syzkaller.appspot.com/text?tag=CrashLog&x=11ff9d8c480000 Reported-by: syzbot+5aed6c3aaba661f5b917@syzkaller.appspotmail.com Signed-off-by: Oliver Hartkopp Link: https://lore.kernel.org/all/20230104201844.13168-1-socketcan@hartkopp.net Signed-off-by: Marc Kleine-Budde Signed-off-by: Greg Kroah-Hartman Signed-off-by: wanxiaoqing --- net/can/isotp.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/can/isotp.c b/net/can/isotp.c index 902cb61b6495..87de9a08cc85 100644 --- a/net/can/isotp.c +++ b/net/can/isotp.c @@ -1129,6 +1129,9 @@ static int isotp_bind(struct socket *sock, struct sockaddr *uaddr, int len) if (len < ISOTP_MIN_NAMELEN) return -EINVAL; + if (addr->can_family != AF_CAN) + return -EINVAL; + /* sanitize tx/rx CAN identifiers */ tx_id = addr->can_addr.tp.tx_id; if (tx_id & CAN_EFF_FLAG) -- Gitee From c07525277bf6bf0678e02371cee6553899b6747d Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Tue, 31 Oct 2023 10:29:15 +0100 Subject: [PATCH 07/28] can: isotp: handle wait_event_interruptible() return values stable inclusion from stable-5.10.200 commit 569c95b7ece0644dbe5d49d058d25bfa2a50d872 category: bugfix issue: #IA8M8T CVE: NA Signed-off-by: wanxiaoqing --------------------------------------- commit 823b2e42720f96f277940c37ea438b7c5ead51a4 upstream When wait_event_interruptible() has been interrupted by a signal the tx.state value might not be ISOTP_IDLE. Force the state machines into idle state to inhibit the timer handlers to continue working. Fixes: 866337865f37 ("can: isotp: fix tx state handling for echo tx processing") Cc: stable@vger.kernel.org Signed-off-by: Oliver Hartkopp Link: https://lore.kernel.org/all/20230112192347.1944-1-socketcan@hartkopp.net Signed-off-by: Marc Kleine-Budde Signed-off-by: Greg Kroah-Hartman Signed-off-by: wanxiaoqing --- net/can/isotp.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/can/isotp.c b/net/can/isotp.c index 87de9a08cc85..42194b0d176c 100644 --- a/net/can/isotp.c +++ b/net/can/isotp.c @@ -1071,6 +1071,10 @@ static int isotp_release(struct socket *sock) /* wait for complete transmission of current pdu */ wait_event_interruptible(so->wait, so->tx.state == ISOTP_IDLE); + /* force state machines to be idle also when a signal occurred */ + so->tx.state = ISOTP_IDLE; + so->rx.state = ISOTP_IDLE; + spin_lock(&isotp_notifier_lock); while (isotp_busy_notifier == so) { spin_unlock(&isotp_notifier_lock); -- Gitee From 8d329e75fd944babdfe590401430a208554abf53 Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Tue, 31 Oct 2023 10:29:16 +0100 Subject: [PATCH 08/28] can: isotp: add local echo tx processing and tx without FC stable inclusion from stable-5.10.200 commit e4c4e0e1b29ca5ca539ae3cea8145e0a8154420e category: bugfix issue: #IA8M8T CVE: NA Signed-off-by: wanxiaoqing --------------------------------------- commit 4b7fe92c06901f4563af0e36d25223a5ab343782 upstream commit 9f39d36530e5678d092d53c5c2c60d82b4dcc169 upstream commit 051737439eaee5bdd03d3c2ef5510d54a478fd05 upstream Due to the existing patch order applied to isotp.c in the stable kernel the original order of depending patches the three original patches 4b7fe92c0690 ("can: isotp: add local echo tx processing for consecutive frames") 9f39d36530e5 ("can: isotp: add support for transmission without flow control") 051737439eae ("can: isotp: fix race between isotp_sendsmg() and isotp_release()") can not be split into different patches that can be applied in working steps to the stable tree. Signed-off-by: Oliver Hartkopp Signed-off-by: Greg Kroah-Hartman Signed-off-by: wanxiaoqing --- include/uapi/linux/can/isotp.h | 25 ++- net/can/isotp.c | 398 +++++++++++++++++++++------------ 2 files changed, 267 insertions(+), 156 deletions(-) diff --git a/include/uapi/linux/can/isotp.h b/include/uapi/linux/can/isotp.h index 590f8aea2b6d..439c982f7e81 100644 --- a/include/uapi/linux/can/isotp.h +++ b/include/uapi/linux/can/isotp.h @@ -124,18 +124,19 @@ struct can_isotp_ll_options { /* flags for isotp behaviour */ -#define CAN_ISOTP_LISTEN_MODE 0x001 /* listen only (do not send FC) */ -#define CAN_ISOTP_EXTEND_ADDR 0x002 /* enable extended addressing */ -#define CAN_ISOTP_TX_PADDING 0x004 /* enable CAN frame padding tx path */ -#define CAN_ISOTP_RX_PADDING 0x008 /* enable CAN frame padding rx path */ -#define CAN_ISOTP_CHK_PAD_LEN 0x010 /* check received CAN frame padding */ -#define CAN_ISOTP_CHK_PAD_DATA 0x020 /* check received CAN frame padding */ -#define CAN_ISOTP_HALF_DUPLEX 0x040 /* half duplex error state handling */ -#define CAN_ISOTP_FORCE_TXSTMIN 0x080 /* ignore stmin from received FC */ -#define CAN_ISOTP_FORCE_RXSTMIN 0x100 /* ignore CFs depending on rx stmin */ -#define CAN_ISOTP_RX_EXT_ADDR 0x200 /* different rx extended addressing */ -#define CAN_ISOTP_WAIT_TX_DONE 0x400 /* wait for tx completion */ -#define CAN_ISOTP_SF_BROADCAST 0x800 /* 1-to-N functional addressing */ +#define CAN_ISOTP_LISTEN_MODE 0x0001 /* listen only (do not send FC) */ +#define CAN_ISOTP_EXTEND_ADDR 0x0002 /* enable extended addressing */ +#define CAN_ISOTP_TX_PADDING 0x0004 /* enable CAN frame padding tx path */ +#define CAN_ISOTP_RX_PADDING 0x0008 /* enable CAN frame padding rx path */ +#define CAN_ISOTP_CHK_PAD_LEN 0x0010 /* check received CAN frame padding */ +#define CAN_ISOTP_CHK_PAD_DATA 0x0020 /* check received CAN frame padding */ +#define CAN_ISOTP_HALF_DUPLEX 0x0040 /* half duplex error state handling */ +#define CAN_ISOTP_FORCE_TXSTMIN 0x0080 /* ignore stmin from received FC */ +#define CAN_ISOTP_FORCE_RXSTMIN 0x0100 /* ignore CFs depending on rx stmin */ +#define CAN_ISOTP_RX_EXT_ADDR 0x0200 /* different rx extended addressing */ +#define CAN_ISOTP_WAIT_TX_DONE 0x0400 /* wait for tx completion */ +#define CAN_ISOTP_SF_BROADCAST 0x0800 /* 1-to-N functional addressing */ +#define CAN_ISOTP_CF_BROADCAST 0x1000 /* 1-to-N transmission w/o FC */ /* protocol machine default values */ diff --git a/net/can/isotp.c b/net/can/isotp.c index 42194b0d176c..f362b50484fc 100644 --- a/net/can/isotp.c +++ b/net/can/isotp.c @@ -14,7 +14,6 @@ * - use CAN_ISOTP_WAIT_TX_DONE flag to block the caller until the PDU is sent * - as we have static buffers the check whether the PDU fits into the buffer * is done at FF reception time (no support for sending 'wait frames') - * - take care of the tx-queue-len as traffic shaping is still on the TODO list * * Copyright (c) 2020 Volkswagen Group Electronic Research * All rights reserved. @@ -105,18 +104,23 @@ MODULE_ALIAS("can-proto-6"); #define FC_CONTENT_SZ 3 /* flow control content size in byte (FS/BS/STmin) */ #define ISOTP_CHECK_PADDING (CAN_ISOTP_CHK_PAD_LEN | CAN_ISOTP_CHK_PAD_DATA) +#define ISOTP_ALL_BC_FLAGS (CAN_ISOTP_SF_BROADCAST | CAN_ISOTP_CF_BROADCAST) /* Flow Status given in FC frame */ #define ISOTP_FC_CTS 0 /* clear to send */ #define ISOTP_FC_WT 1 /* wait */ #define ISOTP_FC_OVFLW 2 /* overflow */ +#define ISOTP_FC_TIMEOUT 1 /* 1 sec */ +#define ISOTP_ECHO_TIMEOUT 2 /* 2 secs */ + enum { ISOTP_IDLE = 0, ISOTP_WAIT_FIRST_FC, ISOTP_WAIT_FC, ISOTP_WAIT_DATA, - ISOTP_SENDING + ISOTP_SENDING, + ISOTP_SHUTDOWN, }; struct tpcon { @@ -137,13 +141,14 @@ struct isotp_sock { canid_t rxid; ktime_t tx_gap; ktime_t lastrxcf_tstamp; - struct hrtimer rxtimer, txtimer; + struct hrtimer rxtimer, txtimer, txfrtimer; struct can_isotp_options opt; struct can_isotp_fc_options rxfc, txfc; struct can_isotp_ll_options ll; u32 frame_txtime; u32 force_tx_stmin; u32 force_rx_stmin; + u32 cfecho; /* consecutive frame echo tag */ struct tpcon rx, tx; struct list_head notifier; wait_queue_head_t wait; @@ -159,6 +164,17 @@ static inline struct isotp_sock *isotp_sk(const struct sock *sk) return (struct isotp_sock *)sk; } +static u32 isotp_bc_flags(struct isotp_sock *so) +{ + return so->opt.flags & ISOTP_ALL_BC_FLAGS; +} + +static bool isotp_register_rxid(struct isotp_sock *so) +{ + /* no broadcast modes => register rx_id for FC frame reception */ + return (isotp_bc_flags(so) == 0); +} + static enum hrtimer_restart isotp_rx_timer_handler(struct hrtimer *hrtimer) { struct isotp_sock *so = container_of(hrtimer, struct isotp_sock, @@ -240,7 +256,8 @@ static int isotp_send_fc(struct sock *sk, int ae, u8 flowstatus) so->lastrxcf_tstamp = ktime_set(0, 0); /* start rx timeout watchdog */ - hrtimer_start(&so->rxtimer, ktime_set(1, 0), HRTIMER_MODE_REL_SOFT); + hrtimer_start(&so->rxtimer, ktime_set(ISOTP_FC_TIMEOUT, 0), + HRTIMER_MODE_REL_SOFT); return 0; } @@ -326,6 +343,8 @@ static int check_pad(struct isotp_sock *so, struct canfd_frame *cf, return 0; } +static void isotp_send_cframe(struct isotp_sock *so); + static int isotp_rcv_fc(struct isotp_sock *so, struct canfd_frame *cf, int ae) { struct sock *sk = &so->sk; @@ -380,14 +399,15 @@ static int isotp_rcv_fc(struct isotp_sock *so, struct canfd_frame *cf, int ae) case ISOTP_FC_CTS: so->tx.bs = 0; so->tx.state = ISOTP_SENDING; - /* start cyclic timer for sending CF frame */ - hrtimer_start(&so->txtimer, so->tx_gap, + /* send CF frame and enable echo timeout handling */ + hrtimer_start(&so->txtimer, ktime_set(ISOTP_ECHO_TIMEOUT, 0), HRTIMER_MODE_REL_SOFT); + isotp_send_cframe(so); break; case ISOTP_FC_WT: /* start timer to wait for next FC frame */ - hrtimer_start(&so->txtimer, ktime_set(1, 0), + hrtimer_start(&so->txtimer, ktime_set(ISOTP_FC_TIMEOUT, 0), HRTIMER_MODE_REL_SOFT); break; @@ -582,7 +602,7 @@ static int isotp_rcv_cf(struct sock *sk, struct canfd_frame *cf, int ae, /* perform blocksize handling, if enabled */ if (!so->rxfc.bs || ++so->rx.bs < so->rxfc.bs) { /* start rx timeout watchdog */ - hrtimer_start(&so->rxtimer, ktime_set(1, 0), + hrtimer_start(&so->rxtimer, ktime_set(ISOTP_FC_TIMEOUT, 0), HRTIMER_MODE_REL_SOFT); return 0; } @@ -713,6 +733,63 @@ static void isotp_fill_dataframe(struct canfd_frame *cf, struct isotp_sock *so, cf->data[0] = so->opt.ext_address; } +static void isotp_send_cframe(struct isotp_sock *so) +{ + struct sock *sk = &so->sk; + struct sk_buff *skb; + struct net_device *dev; + struct canfd_frame *cf; + int can_send_ret; + int ae = (so->opt.flags & CAN_ISOTP_EXTEND_ADDR) ? 1 : 0; + + dev = dev_get_by_index(sock_net(sk), so->ifindex); + if (!dev) + return; + + skb = alloc_skb(so->ll.mtu + sizeof(struct can_skb_priv), GFP_ATOMIC); + if (!skb) { + dev_put(dev); + return; + } + + can_skb_reserve(skb); + can_skb_prv(skb)->ifindex = dev->ifindex; + can_skb_prv(skb)->skbcnt = 0; + + cf = (struct canfd_frame *)skb->data; + skb_put_zero(skb, so->ll.mtu); + + /* create consecutive frame */ + isotp_fill_dataframe(cf, so, ae, 0); + + /* place consecutive frame N_PCI in appropriate index */ + cf->data[ae] = N_PCI_CF | so->tx.sn++; + so->tx.sn %= 16; + so->tx.bs++; + + cf->flags = so->ll.tx_flags; + + skb->dev = dev; + can_skb_set_owner(skb, sk); + + /* cfecho should have been zero'ed by init/isotp_rcv_echo() */ + if (so->cfecho) + pr_notice_once("can-isotp: cfecho is %08X != 0\n", so->cfecho); + + /* set consecutive frame echo tag */ + so->cfecho = *(u32 *)cf->data; + + /* send frame with local echo enabled */ + can_send_ret = can_send(skb, 1); + if (can_send_ret) { + pr_notice_once("can-isotp: %s: can_send_ret %pe\n", + __func__, ERR_PTR(can_send_ret)); + if (can_send_ret == -ENOBUFS) + pr_notice_once("can-isotp: tx queue is full\n"); + } + dev_put(dev); +} + static void isotp_create_fframe(struct canfd_frame *cf, struct isotp_sock *so, int ae) { @@ -746,145 +823,123 @@ static void isotp_create_fframe(struct canfd_frame *cf, struct isotp_sock *so, cf->data[i] = so->tx.buf[so->tx.idx++]; so->tx.sn = 1; - so->tx.state = ISOTP_WAIT_FIRST_FC; } -static enum hrtimer_restart isotp_tx_timer_handler(struct hrtimer *hrtimer) +static void isotp_rcv_echo(struct sk_buff *skb, void *data) { - struct isotp_sock *so = container_of(hrtimer, struct isotp_sock, - txtimer); - struct sock *sk = &so->sk; - struct sk_buff *skb; - struct net_device *dev; - struct canfd_frame *cf; - enum hrtimer_restart restart = HRTIMER_NORESTART; - int can_send_ret; - int ae = (so->opt.flags & CAN_ISOTP_EXTEND_ADDR) ? 1 : 0; + struct sock *sk = (struct sock *)data; + struct isotp_sock *so = isotp_sk(sk); + struct canfd_frame *cf = (struct canfd_frame *)skb->data; - switch (so->tx.state) { - case ISOTP_WAIT_FC: - case ISOTP_WAIT_FIRST_FC: + /* only handle my own local echo CF/SF skb's (no FF!) */ + if (skb->sk != sk || so->cfecho != *(u32 *)cf->data) + return; - /* we did not get any flow control frame in time */ + /* cancel local echo timeout */ + hrtimer_cancel(&so->txtimer); - /* report 'communication error on send' */ - sk->sk_err = ECOMM; - if (!sock_flag(sk, SOCK_DEAD)) - sk->sk_error_report(sk); + /* local echo skb with consecutive frame has been consumed */ + so->cfecho = 0; - /* reset tx state */ + if (so->tx.idx >= so->tx.len) { + /* we are done */ so->tx.state = ISOTP_IDLE; wake_up_interruptible(&so->wait); - break; - - case ISOTP_SENDING: - - /* push out the next segmented pdu */ - dev = dev_get_by_index(sock_net(sk), so->ifindex); - if (!dev) - break; + return; + } -isotp_tx_burst: - skb = alloc_skb(so->ll.mtu + sizeof(struct can_skb_priv), - GFP_ATOMIC); - if (!skb) { - dev_put(dev); - break; - } + if (so->txfc.bs && so->tx.bs >= so->txfc.bs) { + /* stop and wait for FC with timeout */ + so->tx.state = ISOTP_WAIT_FC; + hrtimer_start(&so->txtimer, ktime_set(ISOTP_FC_TIMEOUT, 0), + HRTIMER_MODE_REL_SOFT); + return; + } - can_skb_reserve(skb); - can_skb_prv(skb)->ifindex = dev->ifindex; - can_skb_prv(skb)->skbcnt = 0; + /* no gap between data frames needed => use burst mode */ + if (!so->tx_gap) { + /* enable echo timeout handling */ + hrtimer_start(&so->txtimer, ktime_set(ISOTP_ECHO_TIMEOUT, 0), + HRTIMER_MODE_REL_SOFT); + isotp_send_cframe(so); + return; + } - cf = (struct canfd_frame *)skb->data; - skb_put_zero(skb, so->ll.mtu); + /* start timer to send next consecutive frame with correct delay */ + hrtimer_start(&so->txfrtimer, so->tx_gap, HRTIMER_MODE_REL_SOFT); +} - /* create consecutive frame */ - isotp_fill_dataframe(cf, so, ae, 0); +static enum hrtimer_restart isotp_tx_timer_handler(struct hrtimer *hrtimer) +{ + struct isotp_sock *so = container_of(hrtimer, struct isotp_sock, + txtimer); + struct sock *sk = &so->sk; - /* place consecutive frame N_PCI in appropriate index */ - cf->data[ae] = N_PCI_CF | so->tx.sn++; - so->tx.sn %= 16; - so->tx.bs++; + /* don't handle timeouts in IDLE or SHUTDOWN state */ + if (so->tx.state == ISOTP_IDLE || so->tx.state == ISOTP_SHUTDOWN) + return HRTIMER_NORESTART; - cf->flags = so->ll.tx_flags; + /* we did not get any flow control or echo frame in time */ - skb->dev = dev; - can_skb_set_owner(skb, sk); + /* report 'communication error on send' */ + sk->sk_err = ECOMM; + if (!sock_flag(sk, SOCK_DEAD)) + sk->sk_error_report(sk); - can_send_ret = can_send(skb, 1); - if (can_send_ret) { - pr_notice_once("can-isotp: %s: can_send_ret %pe\n", - __func__, ERR_PTR(can_send_ret)); - if (can_send_ret == -ENOBUFS) - pr_notice_once("can-isotp: tx queue is full, increasing txqueuelen may prevent this error\n"); - } - if (so->tx.idx >= so->tx.len) { - /* we are done */ - so->tx.state = ISOTP_IDLE; - dev_put(dev); - wake_up_interruptible(&so->wait); - break; - } + /* reset tx state */ + so->tx.state = ISOTP_IDLE; + wake_up_interruptible(&so->wait); - if (so->txfc.bs && so->tx.bs >= so->txfc.bs) { - /* stop and wait for FC */ - so->tx.state = ISOTP_WAIT_FC; - dev_put(dev); - hrtimer_set_expires(&so->txtimer, - ktime_add(ktime_get(), - ktime_set(1, 0))); - restart = HRTIMER_RESTART; - break; - } + return HRTIMER_NORESTART; +} - /* no gap between data frames needed => use burst mode */ - if (!so->tx_gap) - goto isotp_tx_burst; +static enum hrtimer_restart isotp_txfr_timer_handler(struct hrtimer *hrtimer) +{ + struct isotp_sock *so = container_of(hrtimer, struct isotp_sock, + txfrtimer); - /* start timer to send next data frame with correct delay */ - dev_put(dev); - hrtimer_set_expires(&so->txtimer, - ktime_add(ktime_get(), so->tx_gap)); - restart = HRTIMER_RESTART; - break; + /* start echo timeout handling and cover below protocol error */ + hrtimer_start(&so->txtimer, ktime_set(ISOTP_ECHO_TIMEOUT, 0), + HRTIMER_MODE_REL_SOFT); - default: - WARN_ON_ONCE(1); - } + /* cfecho should be consumed by isotp_rcv_echo() here */ + if (so->tx.state == ISOTP_SENDING && !so->cfecho) + isotp_send_cframe(so); - return restart; + return HRTIMER_NORESTART; } static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) { struct sock *sk = sock->sk; struct isotp_sock *so = isotp_sk(sk); - u32 old_state = so->tx.state; struct sk_buff *skb; struct net_device *dev; struct canfd_frame *cf; int ae = (so->opt.flags & CAN_ISOTP_EXTEND_ADDR) ? 1 : 0; int wait_tx_done = (so->opt.flags & CAN_ISOTP_WAIT_TX_DONE) ? 1 : 0; - s64 hrtimer_sec = 0; + s64 hrtimer_sec = ISOTP_ECHO_TIMEOUT; int off; int err; - if (!so->bound) + if (!so->bound || so->tx.state == ISOTP_SHUTDOWN) return -EADDRNOTAVAIL; +wait_free_buffer: /* we do not support multiple buffers - for now */ - if (cmpxchg(&so->tx.state, ISOTP_IDLE, ISOTP_SENDING) != ISOTP_IDLE || - wq_has_sleeper(&so->wait)) { - if (msg->msg_flags & MSG_DONTWAIT) { - err = -EAGAIN; - goto err_out; - } + if (wq_has_sleeper(&so->wait) && (msg->msg_flags & MSG_DONTWAIT)) + return -EAGAIN; - /* wait for complete transmission of current pdu */ - err = wait_event_interruptible(so->wait, so->tx.state == ISOTP_IDLE); - if (err) - goto err_out; + /* wait for complete transmission of current pdu */ + err = wait_event_interruptible(so->wait, so->tx.state == ISOTP_IDLE); + if (err) + goto err_event_drop; + + if (cmpxchg(&so->tx.state, ISOTP_IDLE, ISOTP_SENDING) != ISOTP_IDLE) { + if (so->tx.state == ISOTP_SHUTDOWN) + return -EADDRNOTAVAIL; + + goto wait_free_buffer; } if (!size || size > MAX_MSG_LENGTH) { @@ -896,7 +951,7 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) off = (so->tx.ll_dl > CAN_MAX_DLEN) ? 1 : 0; /* does the given data fit into a single frame for SF_BROADCAST? */ - if ((so->opt.flags & CAN_ISOTP_SF_BROADCAST) && + if ((isotp_bc_flags(so) == CAN_ISOTP_SF_BROADCAST) && (size > so->tx.ll_dl - SF_PCI_SZ4 - ae - off)) { err = -EINVAL; goto err_out_drop; @@ -929,6 +984,10 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) cf = (struct canfd_frame *)skb->data; skb_put_zero(skb, so->ll.mtu); + /* cfecho should have been zero'ed by init / former isotp_rcv_echo() */ + if (so->cfecho) + pr_notice_once("can-isotp: uninit cfecho %08X\n", so->cfecho); + /* check for single frame transmission depending on TX_DL */ if (size <= so->tx.ll_dl - SF_PCI_SZ4 - ae - off) { /* The message size generally fits into a SingleFrame - good. @@ -954,22 +1013,40 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) else cf->data[ae] |= size; - so->tx.state = ISOTP_IDLE; - wake_up_interruptible(&so->wait); - - /* don't enable wait queue for a single frame transmission */ - wait_tx_done = 0; + /* set CF echo tag for isotp_rcv_echo() (SF-mode) */ + so->cfecho = *(u32 *)cf->data; } else { - /* send first frame and wait for FC */ + /* send first frame */ isotp_create_fframe(cf, so, ae); - /* start timeout for FC */ - hrtimer_sec = 1; - hrtimer_start(&so->txtimer, ktime_set(hrtimer_sec, 0), - HRTIMER_MODE_REL_SOFT); + if (isotp_bc_flags(so) == CAN_ISOTP_CF_BROADCAST) { + /* set timer for FC-less operation (STmin = 0) */ + if (so->opt.flags & CAN_ISOTP_FORCE_TXSTMIN) + so->tx_gap = ktime_set(0, so->force_tx_stmin); + else + so->tx_gap = ktime_set(0, so->frame_txtime); + + /* disable wait for FCs due to activated block size */ + so->txfc.bs = 0; + + /* set CF echo tag for isotp_rcv_echo() (CF-mode) */ + so->cfecho = *(u32 *)cf->data; + } else { + /* standard flow control check */ + so->tx.state = ISOTP_WAIT_FIRST_FC; + + /* start timeout for FC */ + hrtimer_sec = ISOTP_FC_TIMEOUT; + + /* no CF echo tag for isotp_rcv_echo() (FF-mode) */ + so->cfecho = 0; + } } + hrtimer_start(&so->txtimer, ktime_set(hrtimer_sec, 0), + HRTIMER_MODE_REL_SOFT); + /* send the first or only CAN frame */ cf->flags = so->ll.tx_flags; @@ -982,15 +1059,19 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) __func__, ERR_PTR(err)); /* no transmission -> no timeout monitoring */ - if (hrtimer_sec) - hrtimer_cancel(&so->txtimer); + hrtimer_cancel(&so->txtimer); + + /* reset consecutive frame echo tag */ + so->cfecho = 0; goto err_out_drop; } if (wait_tx_done) { /* wait for complete transmission of current pdu */ - wait_event_interruptible(so->wait, so->tx.state == ISOTP_IDLE); + err = wait_event_interruptible(so->wait, so->tx.state == ISOTP_IDLE); + if (err) + goto err_event_drop; err = sock_error(sk); if (err) @@ -999,13 +1080,15 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) return size; +err_event_drop: + /* got signal: force tx state machine to be idle */ + so->tx.state = ISOTP_IDLE; + hrtimer_cancel(&so->txfrtimer); + hrtimer_cancel(&so->txtimer); err_out_drop: /* drop this PDU and unlock a potential wait queue */ - old_state = ISOTP_IDLE; -err_out: - so->tx.state = old_state; - if (so->tx.state == ISOTP_IDLE) - wake_up_interruptible(&so->wait); + so->tx.state = ISOTP_IDLE; + wake_up_interruptible(&so->wait); return err; } @@ -1069,10 +1152,12 @@ static int isotp_release(struct socket *sock) net = sock_net(sk); /* wait for complete transmission of current pdu */ - wait_event_interruptible(so->wait, so->tx.state == ISOTP_IDLE); + while (wait_event_interruptible(so->wait, so->tx.state == ISOTP_IDLE) == 0 && + cmpxchg(&so->tx.state, ISOTP_IDLE, ISOTP_SHUTDOWN) != ISOTP_IDLE) + ; /* force state machines to be idle also when a signal occurred */ - so->tx.state = ISOTP_IDLE; + so->tx.state = ISOTP_SHUTDOWN; so->rx.state = ISOTP_IDLE; spin_lock(&isotp_notifier_lock); @@ -1087,21 +1172,27 @@ static int isotp_release(struct socket *sock) lock_sock(sk); /* remove current filters & unregister */ - if (so->bound && (!(so->opt.flags & CAN_ISOTP_SF_BROADCAST))) { + if (so->bound) { if (so->ifindex) { struct net_device *dev; dev = dev_get_by_index(net, so->ifindex); if (dev) { - can_rx_unregister(net, dev, so->rxid, - SINGLE_MASK(so->rxid), - isotp_rcv, sk); + if (isotp_register_rxid(so)) + can_rx_unregister(net, dev, so->rxid, + SINGLE_MASK(so->rxid), + isotp_rcv, sk); + + can_rx_unregister(net, dev, so->txid, + SINGLE_MASK(so->txid), + isotp_rcv_echo, sk); dev_put(dev); synchronize_rcu(); } } } + hrtimer_cancel(&so->txfrtimer); hrtimer_cancel(&so->txtimer); hrtimer_cancel(&so->rxtimer); @@ -1128,7 +1219,6 @@ static int isotp_bind(struct socket *sock, struct sockaddr *uaddr, int len) canid_t tx_id, rx_id; int err = 0; int notify_enetdown = 0; - int do_rx_reg = 1; if (len < ISOTP_MIN_NAMELEN) return -EINVAL; @@ -1164,12 +1254,8 @@ static int isotp_bind(struct socket *sock, struct sockaddr *uaddr, int len) goto out; } - /* do not register frame reception for functional addressing */ - if (so->opt.flags & CAN_ISOTP_SF_BROADCAST) - do_rx_reg = 0; - - /* do not validate rx address for functional addressing */ - if (do_rx_reg && rx_id == tx_id) { + /* ensure different CAN IDs when the rx_id is to be registered */ + if (isotp_register_rxid(so) && rx_id == tx_id) { err = -EADDRNOTAVAIL; goto out; } @@ -1194,10 +1280,17 @@ static int isotp_bind(struct socket *sock, struct sockaddr *uaddr, int len) ifindex = dev->ifindex; - if (do_rx_reg) + if (isotp_register_rxid(so)) can_rx_register(net, dev, rx_id, SINGLE_MASK(rx_id), isotp_rcv, sk, "isotp", sk); + /* no consecutive frame echo skb in flight */ + so->cfecho = 0; + + /* register for echo skb's */ + can_rx_register(net, dev, tx_id, SINGLE_MASK(tx_id), + isotp_rcv_echo, sk, "isotpe", sk); + dev_put(dev); /* switch to new settings */ @@ -1258,6 +1351,15 @@ static int isotp_setsockopt_locked(struct socket *sock, int level, int optname, if (!(so->opt.flags & CAN_ISOTP_RX_EXT_ADDR)) so->opt.rx_ext_address = so->opt.ext_address; + /* these broadcast flags are not allowed together */ + if (isotp_bc_flags(so) == ISOTP_ALL_BC_FLAGS) { + /* CAN_ISOTP_SF_BROADCAST is prioritized */ + so->opt.flags &= ~CAN_ISOTP_CF_BROADCAST; + + /* give user feedback on wrong config attempt */ + ret = -EINVAL; + } + /* check for frame_txtime changes (0 => no changes) */ if (so->opt.frame_txtime) { if (so->opt.frame_txtime == CAN_ISOTP_FRAME_TXTIME_ZERO) @@ -1408,10 +1510,16 @@ static void isotp_notify(struct isotp_sock *so, unsigned long msg, case NETDEV_UNREGISTER: lock_sock(sk); /* remove current filters & unregister */ - if (so->bound && (!(so->opt.flags & CAN_ISOTP_SF_BROADCAST))) - can_rx_unregister(dev_net(dev), dev, so->rxid, - SINGLE_MASK(so->rxid), - isotp_rcv, sk); + if (so->bound) { + if (isotp_register_rxid(so)) + can_rx_unregister(dev_net(dev), dev, so->rxid, + SINGLE_MASK(so->rxid), + isotp_rcv, sk); + + can_rx_unregister(dev_net(dev), dev, so->txid, + SINGLE_MASK(so->txid), + isotp_rcv_echo, sk); + } so->ifindex = 0; so->bound = 0; @@ -1484,6 +1592,8 @@ static int isotp_init(struct sock *sk) so->rxtimer.function = isotp_rx_timer_handler; hrtimer_init(&so->txtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL_SOFT); so->txtimer.function = isotp_tx_timer_handler; + hrtimer_init(&so->txfrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL_SOFT); + so->txfrtimer.function = isotp_txfr_timer_handler; init_waitqueue_head(&so->wait); spin_lock_init(&so->rx_lock); -- Gitee From 19553764883114174856cf2b8539d165ea931c87 Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Tue, 31 Oct 2023 10:29:17 +0100 Subject: [PATCH 09/28] can: isotp: isotp_bind(): do not validate unused address information stable inclusion from stable-5.10.200 commit 8716c28f695cc5fe507235d37827fe6ad2816f4c category: bugfix issue: #IA8M8T CVE: NA Signed-off-by: wanxiaoqing --------------------------------------- commit b76b163f46b661499921a0049982764a6659bfe7 upstream With commit 2aa39889c463 ("can: isotp: isotp_bind(): return -EINVAL on incorrect CAN ID formatting") the bind() syscall returns -EINVAL when the given CAN ID needed to be sanitized. But in the case of an unconfirmed broadcast mode the rx CAN ID is not needed and may be uninitialized from the caller - which is ok. This patch makes sure the result of an inproper CAN ID format is only provided when the address information is needed. Link: https://lore.kernel.org/all/20220517145653.2556-1-socketcan@hartkopp.net Signed-off-by: Oliver Hartkopp Signed-off-by: Marc Kleine-Budde Signed-off-by: Greg Kroah-Hartman Signed-off-by: wanxiaoqing --- net/can/isotp.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/net/can/isotp.c b/net/can/isotp.c index f362b50484fc..08dfa34d68d5 100644 --- a/net/can/isotp.c +++ b/net/can/isotp.c @@ -1216,7 +1216,8 @@ static int isotp_bind(struct socket *sock, struct sockaddr *uaddr, int len) struct net *net = sock_net(sk); int ifindex; struct net_device *dev; - canid_t tx_id, rx_id; + canid_t tx_id = addr->can_addr.tp.tx_id; + canid_t rx_id = addr->can_addr.tp.rx_id; int err = 0; int notify_enetdown = 0; @@ -1226,24 +1227,28 @@ static int isotp_bind(struct socket *sock, struct sockaddr *uaddr, int len) if (addr->can_family != AF_CAN) return -EINVAL; - /* sanitize tx/rx CAN identifiers */ - tx_id = addr->can_addr.tp.tx_id; + /* sanitize tx CAN identifier */ if (tx_id & CAN_EFF_FLAG) tx_id &= (CAN_EFF_FLAG | CAN_EFF_MASK); else tx_id &= CAN_SFF_MASK; - rx_id = addr->can_addr.tp.rx_id; - if (rx_id & CAN_EFF_FLAG) - rx_id &= (CAN_EFF_FLAG | CAN_EFF_MASK); - else - rx_id &= CAN_SFF_MASK; - - /* give feedback on wrong CAN-ID values */ - if (tx_id != addr->can_addr.tp.tx_id || - rx_id != addr->can_addr.tp.rx_id) + /* give feedback on wrong CAN-ID value */ + if (tx_id != addr->can_addr.tp.tx_id) return -EINVAL; + /* sanitize rx CAN identifier (if needed) */ + if (isotp_register_rxid(so)) { + if (rx_id & CAN_EFF_FLAG) + rx_id &= (CAN_EFF_FLAG | CAN_EFF_MASK); + else + rx_id &= CAN_SFF_MASK; + + /* give feedback on wrong CAN-ID value */ + if (rx_id != addr->can_addr.tp.rx_id) + return -EINVAL; + } + if (!addr->can_ifindex) return -ENODEV; -- Gitee From cbdb9b1313d0c6adcbe78df3b152ad2390782d89 Mon Sep 17 00:00:00 2001 From: Lukas Magel Date: Tue, 31 Oct 2023 10:29:18 +0100 Subject: [PATCH 10/28] can: isotp: isotp_sendmsg(): fix TX state detection and wait behavior stable inclusion from stable-5.10.200 commit deddf60c271f1fc1edba25c4bf66d02854df5c5d category: bugfix issue: #IA8M8T CVE: NA Signed-off-by: wanxiaoqing --------------------------------------- [ Upstream commit d9c2ba65e651467de739324d978b04ed8729f483 ] With patch [1], isotp_poll was updated to also queue the poller in the so->wait queue, which is used for send state changes. Since the queue now also contains polling tasks that are not interested in sending, the queue fill state can no longer be used as an indication of send readiness. As a consequence, nonblocking writes can lead to a race and lock-up of the socket if there is a second task polling the socket in parallel. With this patch, isotp_sendmsg does not consult wq_has_sleepers but instead tries to atomically set so->tx.state and waits on so->wait if it is unable to do so. This behavior is in alignment with isotp_poll, which also checks so->tx.state to determine send readiness. V2: - Revert direct exit to goto err_event_drop [1] https://lore.kernel.org/all/20230331125511.372783-1-michal.sojka@cvut.cz Reported-by: Maxime Jayat Closes: https://lore.kernel.org/linux-can/11328958-453f-447f-9af8-3b5824dfb041@munic.io/ Signed-off-by: Lukas Magel Reviewed-by: Oliver Hartkopp Fixes: 79e19fa79cb5 ("can: isotp: isotp_ops: fix poll() to not report false EPOLLOUT events") Link: https://github.com/pylessard/python-udsoncan/issues/178#issuecomment-1743786590 Link: https://lore.kernel.org/all/20230827092205.7908-1-lukas.magel@posteo.net Signed-off-by: Marc Kleine-Budde Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Signed-off-by: wanxiaoqing --- net/can/isotp.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/net/can/isotp.c b/net/can/isotp.c index 08dfa34d68d5..c646fef8f3ba 100644 --- a/net/can/isotp.c +++ b/net/can/isotp.c @@ -925,21 +925,18 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) if (!so->bound || so->tx.state == ISOTP_SHUTDOWN) return -EADDRNOTAVAIL; -wait_free_buffer: - /* we do not support multiple buffers - for now */ - if (wq_has_sleeper(&so->wait) && (msg->msg_flags & MSG_DONTWAIT)) - return -EAGAIN; + while (cmpxchg(&so->tx.state, ISOTP_IDLE, ISOTP_SENDING) != ISOTP_IDLE) { + /* we do not support multiple buffers - for now */ + if (msg->msg_flags & MSG_DONTWAIT) + return -EAGAIN; - /* wait for complete transmission of current pdu */ - err = wait_event_interruptible(so->wait, so->tx.state == ISOTP_IDLE); - if (err) - goto err_event_drop; - - if (cmpxchg(&so->tx.state, ISOTP_IDLE, ISOTP_SENDING) != ISOTP_IDLE) { if (so->tx.state == ISOTP_SHUTDOWN) return -EADDRNOTAVAIL; - goto wait_free_buffer; + /* wait for complete transmission of current pdu */ + err = wait_event_interruptible(so->wait, so->tx.state == ISOTP_IDLE); + if (err) + goto err_event_drop; } if (!size || size > MAX_MSG_LENGTH) { -- Gitee From c3b352b7bf1c4cdd2eae425212854ec8b4a5a45d Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 27 Sep 2023 13:22:12 -0700 Subject: [PATCH 11/28] PCI: Prevent xHCI driver from claiming AMD VanGogh USB3 DRD device stable inclusion from stable-5.10.200 commit 747b8f877998f6ee1b21c975b2e3c9de22827c26 category: bugfix issue: #IA8M8T CVE: NA Signed-off-by: wanxiaoqing --------------------------------------- commit 7e6f3b6d2c352b5fde37ce3fed83bdf6172eebd4 upstream. The AMD VanGogh SoC contains a DesignWare USB3 Dual-Role Device that can be operated as either a USB Host or a USB Device, similar to on the AMD Nolan platform. be6646bfbaec ("PCI: Prevent xHCI driver from claiming AMD Nolan USB3 DRD device") added a quirk to let the dwc3 driver claim the Nolan device since it provides more specific support. Extend that quirk to include the VanGogh SoC USB3 device. Link: https://lore.kernel.org/r/20230927202212.2388216-1-vi@endrift.com Signed-off-by: Vicki Pfau [bhelgaas: include be6646bfbaec reference, add stable tag] Signed-off-by: Bjorn Helgaas Cc: stable@vger.kernel.org # v3.19+ Signed-off-by: Greg Kroah-Hartman Signed-off-by: wanxiaoqing --- drivers/pci/quirks.c | 8 +++++--- include/linux/pci_ids.h | 1 + 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index c0d113481191..158ff4331a14 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -597,7 +597,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS100, quirk_ati_ /* * In the AMD NL platform, this device ([1022:7912]) has a class code of * PCI_CLASS_SERIAL_USB_XHCI (0x0c0330), which means the xhci driver will - * claim it. + * claim it. The same applies on the VanGogh platform device ([1022:163a]). * * But the dwc3 driver is a more specific driver for this device, and we'd * prefer to use it instead of xhci. To prevent xhci from claiming the @@ -605,7 +605,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS100, quirk_ati_ * defines as "USB device (not host controller)". The dwc3 driver can then * claim it based on its Vendor and Device ID. */ -static void quirk_amd_nl_class(struct pci_dev *pdev) +static void quirk_amd_dwc_class(struct pci_dev *pdev) { u32 class = pdev->class; @@ -615,7 +615,9 @@ static void quirk_amd_nl_class(struct pci_dev *pdev) class, pdev->class); } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_NL_USB, - quirk_amd_nl_class); + quirk_amd_dwc_class); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VANGOGH_USB, + quirk_amd_dwc_class); /* * Synopsys USB 3.x host HAPS platform has a class code of diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 4b34a5c12599..1a41147b22e8 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -555,6 +555,7 @@ #define PCI_DEVICE_ID_AMD_17H_M30H_DF_F3 0x1493 #define PCI_DEVICE_ID_AMD_17H_M60H_DF_F3 0x144b #define PCI_DEVICE_ID_AMD_17H_M70H_DF_F3 0x1443 +#define PCI_DEVICE_ID_AMD_VANGOGH_USB 0x163a #define PCI_DEVICE_ID_AMD_19H_DF_F3 0x1653 #define PCI_DEVICE_ID_AMD_CNB17H_F3 0x1703 #define PCI_DEVICE_ID_AMD_LANCE 0x2000 -- Gitee From c4aad2e7d21904e4cd0b20476ae84a506214d161 Mon Sep 17 00:00:00 2001 From: LihaSika Date: Fri, 27 Oct 2023 20:28:04 +0300 Subject: [PATCH 12/28] usb: storage: set 1.50 as the lower bcdDevice for older "Super Top" compatibility stable inclusion from stable-5.10.200 commit 8e0324f2cbb72b4519bf68ae4738ed3ff7c35030 category: bugfix issue: #IA8M8T CVE: NA Signed-off-by: wanxiaoqing --------------------------------------- commit 0e3139e6543b241b3e65956a55c712333bef48ac upstream. Change lower bcdDevice value for "Super Top USB 2.0 SATA BRIDGE" to match 1.50. I have such an older device with bcdDevice=1.50 and it will not work otherwise. Cc: stable@vger.kernel.org Signed-off-by: Liha Sikanen Link: https://lore.kernel.org/r/ccf7d12a-8362-4916-b3e0-f4150f54affd@gmail.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: wanxiaoqing --- drivers/usb/storage/unusual_cypress.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/storage/unusual_cypress.h b/drivers/usb/storage/unusual_cypress.h index 0547daf116a2..5df40759d77a 100644 --- a/drivers/usb/storage/unusual_cypress.h +++ b/drivers/usb/storage/unusual_cypress.h @@ -19,7 +19,7 @@ UNUSUAL_DEV( 0x04b4, 0x6831, 0x0000, 0x9999, "Cypress ISD-300LP", USB_SC_CYP_ATACB, USB_PR_DEVICE, NULL, 0), -UNUSUAL_DEV( 0x14cd, 0x6116, 0x0160, 0x0160, +UNUSUAL_DEV( 0x14cd, 0x6116, 0x0150, 0x0160, "Super Top", "USB 2.0 SATA BRIDGE", USB_SC_CYP_ATACB, USB_PR_DEVICE, NULL, 0), -- Gitee From 4fb497f27e298e24c8aa66c0cf73f157b28135e0 Mon Sep 17 00:00:00 2001 From: Andrey Konovalov Date: Thu, 26 Oct 2023 22:01:12 +0200 Subject: [PATCH 13/28] usb: raw-gadget: properly handle interrupted requests stable inclusion from stable-5.10.200 commit e705aee2a65701c462ed2be619ed83be3eb95901 category: bugfix issue: #IA8M8T CVE: NA Signed-off-by: wanxiaoqing --------------------------------------- commit e8033bde451eddfb9b1bbd6e2d848c1b5c277222 upstream. Currently, if a USB request that was queued by Raw Gadget is interrupted (via a signal), wait_for_completion_interruptible returns -ERESTARTSYS. Raw Gadget then attempts to propagate this value to userspace as a return value from its ioctls. However, when -ERESTARTSYS is returned by a syscall handler, the kernel internally restarts the syscall. This doesn't allow userspace applications to interrupt requests queued by Raw Gadget (which is required when the emulated device is asked to switch altsettings). It also violates the implied interface of Raw Gadget that a single ioctl must only queue a single USB request. Instead, make Raw Gadget do what GadgetFS does: check whether the request was interrupted (dequeued with status == -ECONNRESET) and report -EINTR to userspace. Fixes: f2c2e717642c ("usb: gadget: add raw-gadget interface") Cc: stable Signed-off-by: Andrey Konovalov Link: https://lore.kernel.org/r/0db45b1d7cc466e3d4d1ab353f61d63c977fbbc5.1698350424.git.andreyknvl@gmail.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: wanxiaoqing --- drivers/usb/gadget/legacy/raw_gadget.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/drivers/usb/gadget/legacy/raw_gadget.c b/drivers/usb/gadget/legacy/raw_gadget.c index ddb39e672801..72ecce73ab53 100644 --- a/drivers/usb/gadget/legacy/raw_gadget.c +++ b/drivers/usb/gadget/legacy/raw_gadget.c @@ -662,12 +662,12 @@ static int raw_process_ep0_io(struct raw_dev *dev, struct usb_raw_ep_io *io, if (WARN_ON(in && dev->ep0_out_pending)) { ret = -ENODEV; dev->state = STATE_DEV_FAILED; - goto out_done; + goto out_unlock; } if (WARN_ON(!in && dev->ep0_in_pending)) { ret = -ENODEV; dev->state = STATE_DEV_FAILED; - goto out_done; + goto out_unlock; } dev->req->buf = data; @@ -682,7 +682,7 @@ static int raw_process_ep0_io(struct raw_dev *dev, struct usb_raw_ep_io *io, "fail, usb_ep_queue returned %d\n", ret); spin_lock_irqsave(&dev->lock, flags); dev->state = STATE_DEV_FAILED; - goto out_done; + goto out_queue_failed; } ret = wait_for_completion_interruptible(&dev->ep0_done); @@ -691,13 +691,16 @@ static int raw_process_ep0_io(struct raw_dev *dev, struct usb_raw_ep_io *io, usb_ep_dequeue(dev->gadget->ep0, dev->req); wait_for_completion(&dev->ep0_done); spin_lock_irqsave(&dev->lock, flags); - goto out_done; + if (dev->ep0_status == -ECONNRESET) + dev->ep0_status = -EINTR; + goto out_interrupted; } spin_lock_irqsave(&dev->lock, flags); - ret = dev->ep0_status; -out_done: +out_interrupted: + ret = dev->ep0_status; +out_queue_failed: dev->ep0_urb_queued = false; out_unlock: spin_unlock_irqrestore(&dev->lock, flags); @@ -1059,7 +1062,7 @@ static int raw_process_ep_io(struct raw_dev *dev, struct usb_raw_ep_io *io, "fail, usb_ep_queue returned %d\n", ret); spin_lock_irqsave(&dev->lock, flags); dev->state = STATE_DEV_FAILED; - goto out_done; + goto out_queue_failed; } ret = wait_for_completion_interruptible(&done); @@ -1068,13 +1071,16 @@ static int raw_process_ep_io(struct raw_dev *dev, struct usb_raw_ep_io *io, usb_ep_dequeue(ep->ep, ep->req); wait_for_completion(&done); spin_lock_irqsave(&dev->lock, flags); - goto out_done; + if (ep->status == -ECONNRESET) + ep->status = -EINTR; + goto out_interrupted; } spin_lock_irqsave(&dev->lock, flags); - ret = ep->status; -out_done: +out_interrupted: + ret = ep->status; +out_queue_failed: ep->urb_queued = false; out_unlock: spin_unlock_irqrestore(&dev->lock, flags); -- Gitee From 4e035a59de55ddd5b456af43e07bf24a2120e533 Mon Sep 17 00:00:00 2001 From: Cameron Williams Date: Fri, 20 Oct 2023 17:03:08 +0100 Subject: [PATCH 14/28] tty: 8250: Remove UC-257 and UC-431 stable inclusion from stable-5.10.200 commit a8bf6f62187f02337cf04348e0dc599d38fff001 category: bugfix issue: #IA8M8T CVE: NA Signed-off-by: wanxiaoqing --------------------------------------- commit 33092fb3af51deb80849e90a17bada44bbcde6b3 upstream. The UC-257 is a serial + LPT card, so remove it from this driver. A patch has been submitted to add it to parport_serial instead. Additionaly, the UC-431 does not use this card ID, only the UC-420 does. The 431 is a 3-port card and there is no generic 3-port configuration available, so remove reference to it from this driver. Fixes: 152d1afa834c ("tty: Add support for Brainboxes UC cards.") Cc: stable@vger.kernel.org Signed-off-by: Cameron Williams Link: https://lore.kernel.org/r/DU0PR02MB78995ADF7394C74AD4CF3357C4DBA@DU0PR02MB7899.eurprd02.prod.outlook.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: wanxiaoqing --- drivers/tty/serial/8250/8250_pci.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index fd857d434326..8b099d19335c 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -5159,13 +5159,6 @@ static const struct pci_device_id serial_pci_tbl[] = { PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_b2_1_115200 }, - /* - * Brainboxes UC-257 - */ - { PCI_VENDOR_ID_INTASHIELD, 0x0861, - PCI_ANY_ID, PCI_ANY_ID, - 0, 0, - pbn_b2_2_115200 }, /* * Brainboxes UC-260/271/701/756 */ @@ -5245,7 +5238,7 @@ static const struct pci_device_id serial_pci_tbl[] = { 0, 0, pbn_b2_4_115200 }, /* - * Brainboxes UC-420/431 + * Brainboxes UC-420 */ { PCI_VENDOR_ID_INTASHIELD, 0x0921, PCI_ANY_ID, PCI_ANY_ID, -- Gitee From f5e5921b327b0b6ecc95feef656e8c7a350bc717 Mon Sep 17 00:00:00 2001 From: Cameron Williams Date: Fri, 20 Oct 2023 17:03:09 +0100 Subject: [PATCH 15/28] tty: 8250: Add support for additional Brainboxes UC cards stable inclusion from stable-5.10.200 commit 119f38e8ca163914144642cce94f072d633113cf category: bugfix issue: #IA8M8T CVE: NA Signed-off-by: wanxiaoqing --------------------------------------- commit c563db486db7d245c0e2f319443417ae8e692f7f upstream. Add device IDs for some more Brainboxes UC cards, namely UC-235/UC-246, UC-253/UC-734, UC-302, UC-313, UC-346, UC-357, UC-607 and UC-836. Cc: stable@vger.kernel.org Signed-off-by: Cameron Williams Link: https://lore.kernel.org/r/DU0PR02MB789969998A6C3FAFCD95C85DC4DBA@DU0PR02MB7899.eurprd02.prod.outlook.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: wanxiaoqing --- drivers/tty/serial/8250/8250_pci.c | 57 ++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 8b099d19335c..2d2e4fc65667 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -5159,6 +5159,17 @@ static const struct pci_device_id serial_pci_tbl[] = { PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_b2_1_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x0AA2, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_1_115200 }, + /* + * Brainboxes UC-253/UC-734 + */ + { PCI_VENDOR_ID_INTASHIELD, 0x0CA1, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, /* * Brainboxes UC-260/271/701/756 */ @@ -5191,6 +5202,14 @@ static const struct pci_device_id serial_pci_tbl[] = { PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_b2_2_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x08E2, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x08E3, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, /* * Brainboxes UC-310 */ @@ -5201,6 +5220,14 @@ static const struct pci_device_id serial_pci_tbl[] = { /* * Brainboxes UC-313 */ + { PCI_VENDOR_ID_INTASHIELD, 0x08A1, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x08A2, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, { PCI_VENDOR_ID_INTASHIELD, 0x08A3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, @@ -5215,6 +5242,10 @@ static const struct pci_device_id serial_pci_tbl[] = { /* * Brainboxes UC-346 */ + { PCI_VENDOR_ID_INTASHIELD, 0x0B01, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_4_115200 }, { PCI_VENDOR_ID_INTASHIELD, 0x0B02, PCI_ANY_ID, PCI_ANY_ID, 0, 0, @@ -5226,6 +5257,10 @@ static const struct pci_device_id serial_pci_tbl[] = { PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_b2_2_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x0A82, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, { PCI_VENDOR_ID_INTASHIELD, 0x0A83, PCI_ANY_ID, PCI_ANY_ID, 0, 0, @@ -5244,6 +5279,28 @@ static const struct pci_device_id serial_pci_tbl[] = { PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_b2_4_115200 }, + /* + * Brainboxes UC-607 + */ + { PCI_VENDOR_ID_INTASHIELD, 0x09A1, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x09A2, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x09A3, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, + /* + * Brainboxes UC-836 + */ + { PCI_VENDOR_ID_INTASHIELD, 0x0D41, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_4_115200 }, /* * Perle PCI-RAS cards */ -- Gitee From e11b33b4cdca1bb7bda5532c3e0f9db30ae6f84e Mon Sep 17 00:00:00 2001 From: Cameron Williams Date: Fri, 20 Oct 2023 17:03:10 +0100 Subject: [PATCH 16/28] tty: 8250: Add support for Brainboxes UP cards stable inclusion from stable-5.10.200 commit 73bcb4d44988393255ab033dfd2f0bdfdb8f8e78 category: bugfix issue: #IA8M8T CVE: NA Signed-off-by: wanxiaoqing --------------------------------------- commit 2c6fec1e1532f15350be7e14ba6b88a39d289fe4 upstream. Add support for the Brainboxes UP (powered PCI) range of cards, namely UP-189, UP-200, UP-869 and UP-880. Cc: stable@vger.kernel.org Signed-off-by: Cameron Williams Link: https://lore.kernel.org/r/DU0PR02MB7899B5B59FF3D8587E88C117C4DBA@DU0PR02MB7899.eurprd02.prod.outlook.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: wanxiaoqing --- drivers/tty/serial/8250/8250_pci.c | 60 ++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 2d2e4fc65667..0511ebc5b179 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -5181,6 +5181,66 @@ static const struct pci_device_id serial_pci_tbl[] = { PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_COMMUNICATION_MULTISERIAL << 8, 0xffff00, pbn_b2_4_115200 }, + /* + * Brainboxes UP-189 + */ + { PCI_VENDOR_ID_INTASHIELD, 0x0AC1, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x0AC2, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x0AC3, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, + /* + * Brainboxes UP-200 + */ + { PCI_VENDOR_ID_INTASHIELD, 0x0B21, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x0B22, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x0B23, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, + /* + * Brainboxes UP-869 + */ + { PCI_VENDOR_ID_INTASHIELD, 0x0C01, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x0C02, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x0C03, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, + /* + * Brainboxes UP-880 + */ + { PCI_VENDOR_ID_INTASHIELD, 0x0C21, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x0C22, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x0C23, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, /* * Brainboxes UC-268 */ -- Gitee From 1240fbf20a007bebad336dbfeb4a6e8ab7e02cfd Mon Sep 17 00:00:00 2001 From: Cameron Williams Date: Fri, 20 Oct 2023 17:03:11 +0100 Subject: [PATCH 17/28] tty: 8250: Add support for Intashield IS-100 stable inclusion from stable-5.10.200 commit 9109649559f9815ecff167af38d7d621fa631bb7 category: bugfix issue: #IA8M8T CVE: NA Signed-off-by: wanxiaoqing --------------------------------------- commit 4d994e3cf1b541ff32dfb03fbbc60eea68f9645b upstream. Add support for the Intashield IS-100 1 port serial card. Cc: stable@vger.kernel.org Signed-off-by: Cameron Williams Link: https://lore.kernel.org/r/DU0PR02MB7899A0E0CDAA505AF5A874CDC4DBA@DU0PR02MB7899.eurprd02.prod.outlook.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: wanxiaoqing --- drivers/tty/serial/8250/8250_pci.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 0511ebc5b179..89b14f5541fa 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -5132,6 +5132,12 @@ static const struct pci_device_id serial_pci_tbl[] = { 0, 0, pbn_b1_bt_1_115200 }, + /* + * IntaShield IS-100 + */ + { PCI_VENDOR_ID_INTASHIELD, 0x0D60, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, + pbn_b2_1_115200 }, /* * IntaShield IS-200 */ -- Gitee From c0ee827eadb27680a33f17b600191192cfb07723 Mon Sep 17 00:00:00 2001 From: Mark Hasemeyer Date: Wed, 18 Oct 2023 17:59:31 -0600 Subject: [PATCH 18/28] ALSA: hda: intel-dsp-config: Fix JSL Chromebook quirk detection stable inclusion from stable-5.10.200 commit a5feaf765935cfd43a089738c20a8486cd192f51 category: bugfix issue: #IA8M8T CVE: NA Signed-off-by: wanxiaoqing --------------------------------------- commit 7c05b44e1a50d9cbfc4f731dddc436a24ddc129a upstream. Some Jasperlake Chromebooks overwrite the system vendor DMI value to the name of the OEM that manufactured the device. This breaks Chromebook quirk detection as it expects the system vendor to be "Google". Add another quirk detection entry that looks for "Google" in the BIOS version. Cc: stable@vger.kernel.org Signed-off-by: Mark Hasemeyer Reviewed-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20231018235944.1860717-1-markhas@chromium.org Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman Signed-off-by: wanxiaoqing --- sound/hda/intel-dsp-config.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sound/hda/intel-dsp-config.c b/sound/hda/intel-dsp-config.c index 801c89a3a1b6..48c78388c1d2 100644 --- a/sound/hda/intel-dsp-config.c +++ b/sound/hda/intel-dsp-config.c @@ -329,6 +329,12 @@ static const struct config_entry config_table[] = { DMI_MATCH(DMI_SYS_VENDOR, "Google"), } }, + { + .ident = "Google firmware", + .matches = { + DMI_MATCH(DMI_BIOS_VERSION, "Google"), + } + }, {} } }, -- Gitee From ef268ba3ae4de1d8fe0b497badfbaa5c04d38e41 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 8 Nov 2023 17:30:52 +0100 Subject: [PATCH 19/28] Linux 5.10.200 stable inclusion from stable-5.10.200^0 commit 3e55583405ac3f8651966dcd23590adb3db1d8c2 category: bugfix issue: #IA8M8T CVE: NA Signed-off-by: wanxiaoqing --------------------------------------- Link: https://lore.kernel.org/r/20231106130304.678610325@linuxfoundation.org Tested-by: Dominique Martinet Tested-by: Salvatore Bonaccorso Tested-by: Jon Hunter Tested-by: Shuah Khan Link: https://lore.kernel.org/r/20231107202447.670990820@linuxfoundation.org Tested-by: Florian Fainelli Tested-by: Jon Hunter Tested-by: Linux Kernel Functional Testing Tested-by: Pavel Machek (CIP) Tested-by: Guenter Roeck Signed-off-by: Greg Kroah-Hartman Signed-off-by: wanxiaoqing --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 7448e85c3602..8102901289f0 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 VERSION = 5 PATCHLEVEL = 10 -SUBLEVEL = 199 +SUBLEVEL = 200 EXTRAVERSION = NAME = Dare mighty things -- Gitee From beb423b0530a85875454fb030e4811670ecd5404 Mon Sep 17 00:00:00 2001 From: David Howells Date: Mon, 25 Sep 2023 13:02:59 +0100 Subject: [PATCH 20/28] iov_iter, x86: Be consistent about the __user tag on copy_mc_to_user() stable inclusion from stable-5.10.201 commit bdb7de7ed5baffabf11987f4d95273b8fc0958d7 category: bugfix issue: #IA8M8T CVE: NA Signed-off-by: wanxiaoqing --------------------------------------- [ Upstream commit 066baf92bed934c9fb4bcee97a193f47aa63431c ] copy_mc_to_user() has the destination marked __user on powerpc, but not on x86; the latter results in a sparse warning in lib/iov_iter.c. Fix this by applying the tag on x86 too. Fixes: ec6347bb4339 ("x86, powerpc: Rename memcpy_mcsafe() to copy_mc_to_{user, kernel}()") Signed-off-by: David Howells Link: https://lore.kernel.org/r/20230925120309.1731676-3-dhowells@redhat.com cc: Dan Williams cc: Thomas Gleixner cc: Ingo Molnar cc: Borislav Petkov cc: Dave Hansen cc: "H. Peter Anvin" cc: Alexander Viro cc: Jens Axboe cc: Christoph Hellwig cc: Christian Brauner cc: Matthew Wilcox cc: Linus Torvalds cc: David Laight cc: x86@kernel.org cc: linux-block@vger.kernel.org cc: linux-fsdevel@vger.kernel.org cc: linux-mm@kvack.org Signed-off-by: Christian Brauner Signed-off-by: Sasha Levin Signed-off-by: wanxiaoqing --- arch/x86/include/asm/uaccess.h | 2 +- arch/x86/lib/copy_mc.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h index bb1430283c72..bf2561a5eb58 100644 --- a/arch/x86/include/asm/uaccess.h +++ b/arch/x86/include/asm/uaccess.h @@ -446,7 +446,7 @@ copy_mc_to_kernel(void *to, const void *from, unsigned len); #define copy_mc_to_kernel copy_mc_to_kernel unsigned long __must_check -copy_mc_to_user(void *to, const void *from, unsigned len); +copy_mc_to_user(void __user *to, const void *from, unsigned len); #endif /* diff --git a/arch/x86/lib/copy_mc.c b/arch/x86/lib/copy_mc.c index c13e8c9ee926..e058ef2d454d 100644 --- a/arch/x86/lib/copy_mc.c +++ b/arch/x86/lib/copy_mc.c @@ -74,23 +74,23 @@ unsigned long __must_check copy_mc_to_kernel(void *dst, const void *src, unsigne } EXPORT_SYMBOL_GPL(copy_mc_to_kernel); -unsigned long __must_check copy_mc_to_user(void *dst, const void *src, unsigned len) +unsigned long __must_check copy_mc_to_user(void __user *dst, const void *src, unsigned len) { unsigned long ret; if (copy_mc_fragile_enabled) { __uaccess_begin(); - ret = copy_mc_fragile(dst, src, len); + ret = copy_mc_fragile((__force void *)dst, src, len); __uaccess_end(); return ret; } if (static_cpu_has(X86_FEATURE_ERMS)) { __uaccess_begin(); - ret = copy_mc_enhanced_fast_string(dst, src, len); + ret = copy_mc_enhanced_fast_string((__force void *)dst, src, len); __uaccess_end(); return ret; } - return copy_user_generic(dst, src, len); + return copy_user_generic((__force void *)dst, src, len); } -- Gitee From 723488e2137fada31e242b2bc23901b55068f531 Mon Sep 17 00:00:00 2001 From: Qais Yousef Date: Sun, 17 Sep 2023 00:29:54 +0100 Subject: [PATCH 21/28] sched/uclamp: Ignore (util == 0) optimization in feec() when p_util_max = 0 stable inclusion from stable-5.10.201 commit 9fe0f6b5720e2b2ed4fdd44c98ec721e27282016 category: bugfix issue: #IA8M8T CVE: NA Signed-off-by: wanxiaoqing --------------------------------------- [ Upstream commit 23c9519def98ee0fa97ea5871535e9b136f522fc ] find_energy_efficient_cpu() bails out early if effective util of the task is 0 as the delta at this point will be zero and there's nothing for EAS to do. When uclamp is being used, this could lead to wrong decisions when uclamp_max is set to 0. In this case the task is capped to performance point 0, but it is actually running and consuming energy and we can benefit from EAS energy calculations. Rework the condition so that it bails out when both util and uclamp_min are 0. We can do that without needing to use uclamp_task_util(); remove it. Fixes: d81304bc6193 ("sched/uclamp: Cater for uclamp in find_energy_efficient_cpu()'s early exit condition") Signed-off-by: Qais Yousef (Google) Signed-off-by: Ingo Molnar Reviewed-by: Vincent Guittot Reviewed-by: Dietmar Eggemann Acked-by: Peter Zijlstra (Intel) Link: https://lore.kernel.org/r/20230916232955.2099394-3-qyousef@layalina.io Signed-off-by: Sasha Levin Signed-off-by: wanxiaoqing --- kernel/sched/fair.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 4e5f903958c6..9a701e968c0b 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -7017,7 +7017,7 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu) goto fail; sync_entity_load_avg(&p->se); - if (!uclamp_task_util(p, p_util_min, p_util_max)) + if (!task_util_est(p) && p_util_min == 0) goto unlock; for (; pd; pd = pd->next) { -- Gitee From 9ecaee9dcef41be7b5ca62b8216b795e693265cc Mon Sep 17 00:00:00 2001 From: Reuben Hawkins Date: Mon, 2 Oct 2023 20:57:04 -0500 Subject: [PATCH 22/28] vfs: fix readahead(2) on block devices stable inclusion from stable-5.10.201 commit f49926b8d2a530975c9abb1f44f8893350dc54d6 category: bugfix issue: #IA8M8T CVE: NA Signed-off-by: wanxiaoqing --------------------------------------- [ Upstream commit 7116c0af4b8414b2f19fdb366eea213cbd9d91c2 ] Readahead was factored to call generic_fadvise. That refactor added an S_ISREG restriction which broke readahead on block devices. In addition to S_ISREG, this change checks S_ISBLK to fix block device readahead. There is no change in behavior with any file type besides block devices in this change. Fixes: 3d8f7615319b ("vfs: implement readahead(2) using POSIX_FADV_WILLNEED") Signed-off-by: Reuben Hawkins Link: https://lore.kernel.org/r/20231003015704.2415-1-reubenhwk@gmail.com Reviewed-by: Amir Goldstein Signed-off-by: Christian Brauner Signed-off-by: Sasha Levin Signed-off-by: wanxiaoqing --- mm/readahead.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mm/readahead.c b/mm/readahead.c index c5b0457415be..d30bcf4bc63b 100644 --- a/mm/readahead.c +++ b/mm/readahead.c @@ -625,7 +625,8 @@ ssize_t ksys_readahead(int fd, loff_t offset, size_t count) */ ret = -EINVAL; if (!f.file->f_mapping || !f.file->f_mapping->a_ops || - !S_ISREG(file_inode(f.file)->i_mode)) + (!S_ISREG(file_inode(f.file)->i_mode) && + !S_ISBLK(file_inode(f.file)->i_mode))) goto out; ret = vfs_fadvise(f.file, offset, count, POSIX_FADV_WILLNEED); -- Gitee From 544ec2ecef21b6779a2fc744d1f6535bb145a1aa Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Mon, 4 Sep 2023 22:04:49 -0700 Subject: [PATCH 23/28] x86/srso: Fix SBPB enablement for (possible) future fixed HW stable inclusion from stable-5.10.201 commit f52587051637af5799323413307f57988bdfedbb category: bugfix issue: #IA8M8T CVE: NA Signed-off-by: wanxiaoqing --------------------------------------- [ Upstream commit 1d1142ac51307145dbb256ac3535a1d43a1c9800 ] Make the SBPB check more robust against the (possible) case where future HW has SRSO fixed but doesn't have the SRSO_NO bit set. Fixes: 1b5277c0ea0b ("x86/srso: Add SRSO_NO support") Signed-off-by: Josh Poimboeuf Signed-off-by: Ingo Molnar Signed-off-by: Borislav Petkov (AMD) Acked-by: Borislav Petkov (AMD) Link: https://lore.kernel.org/r/cee5050db750b391c9f35f5334f8ff40e66c01b9.1693889988.git.jpoimboe@kernel.org Signed-off-by: Sasha Levin Signed-off-by: wanxiaoqing --- arch/x86/kernel/cpu/bugs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index 008d000a862c..579367c28f4b 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c @@ -2473,7 +2473,7 @@ static void __init srso_select_mitigation(void) pr_info("%s%s\n", srso_strings[srso_mitigation], (has_microcode ? "" : ", no microcode")); pred_cmd: - if ((boot_cpu_has(X86_FEATURE_SRSO_NO) || srso_cmd == SRSO_CMD_OFF) && + if ((!boot_cpu_has_bug(X86_BUG_SRSO) || srso_cmd == SRSO_CMD_OFF) && boot_cpu_has(X86_FEATURE_SBPB)) x86_pred_cmd = PRED_CMD_SBPB; } -- Gitee From ee2197b4eddf3cfc6f0c957008d3396a402e758a Mon Sep 17 00:00:00 2001 From: Ben Wolsieffer Date: Thu, 19 Oct 2023 16:45:49 -0400 Subject: [PATCH 24/28] futex: Don't include process MM in futex key on no-MMU MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit stable inclusion from stable-5.10.201 commit ffa4cc86e959f52600f6f77a56b632af4a582594 category: bugfix issue: #IA8M8T CVE: NA Signed-off-by: wanxiaoqing --------------------------------------- [ Upstream commit c73801ae4f22b390228ebf471d55668e824198b6 ] On no-MMU, all futexes are treated as private because there is no need to map a virtual address to physical to match the futex across processes. This doesn't quite work though, because private futexes include the current process's mm_struct as part of their key. This makes it impossible for one process to wake up a shared futex being waited on in another process. Fix this bug by excluding the mm_struct from the key. With a single address space, the futex address is already a unique key. Fixes: 784bdf3bb694 ("futex: Assume all mappings are private on !MMU systems") Signed-off-by: Ben Wolsieffer Signed-off-by: Ingo Molnar Acked-by: Peter Zijlstra Cc: Thomas Gleixner Cc: Darren Hart Cc: Davidlohr Bueso Cc: André Almeida Link: https://lore.kernel.org/r/20231019204548.1236437-2-ben.wolsieffer@hefring.com Signed-off-by: Sasha Levin Signed-off-by: wanxiaoqing --- kernel/futex/core.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/kernel/futex/core.c b/kernel/futex/core.c index 8dd0bc50ac36..cde0ca876b93 100644 --- a/kernel/futex/core.c +++ b/kernel/futex/core.c @@ -514,7 +514,17 @@ static int get_futex_key(u32 __user *uaddr, bool fshared, union futex_key *key, * but access_ok() should be faster than find_vma() */ if (!fshared) { - key->private.mm = mm; + /* + * On no-MMU, shared futexes are treated as private, therefore + * we must not include the current process in the key. Since + * there is only one address space, the address is a unique key + * on its own. + */ + if (IS_ENABLED(CONFIG_MMU)) + key->private.mm = mm; + else + key->private.mm = NULL; + key->private.address = address; return 0; } -- Gitee From 9694572505c64e3d3a996d84b68f0c6d1807b3ea Mon Sep 17 00:00:00 2001 From: Yuntao Wang Date: Mon, 7 Aug 2023 16:45:47 +0800 Subject: [PATCH 25/28] x86/boot: Fix incorrect startup_gdt_descr.size stable inclusion from stable-5.10.201 commit 66f9969141c0c5961e657fded8379699417106a5 category: bugfix issue: #IA8M8T CVE: NA Signed-off-by: wanxiaoqing --------------------------------------- [ Upstream commit 001470fed5959d01faecbd57fcf2f60294da0de1 ] Since the size value is added to the base address to yield the last valid byte address of the GDT, the current size value of startup_gdt_descr is incorrect (too large by one), fix it. [ mingo: This probably never mattered, because startup_gdt[] is only used in a very controlled fashion - but make it consistent nevertheless. ] Fixes: 866b556efa12 ("x86/head/64: Install startup GDT") Signed-off-by: Yuntao Wang Signed-off-by: Ingo Molnar Cc: "H. Peter Anvin" Link: https://lore.kernel.org/r/20230807084547.217390-1-ytcoode@gmail.com Signed-off-by: Sasha Levin Signed-off-by: wanxiaoqing --- arch/x86/kernel/head64.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index efe13ab366f4..8596b4dca945 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c @@ -80,7 +80,7 @@ static struct desc_struct startup_gdt[GDT_ENTRIES] = { * while the kernel still uses a direct mapping. */ static struct desc_ptr startup_gdt_descr = { - .size = sizeof(startup_gdt), + .size = sizeof(startup_gdt)-1, .address = 0, }; -- Gitee From 5a80dfe930534eea680b1b4570553831315926e7 Mon Sep 17 00:00:00 2001 From: Chen Yu Date: Fri, 20 Oct 2023 15:25:22 +0800 Subject: [PATCH 26/28] genirq/matrix: Exclude managed interrupts in irq_matrix_allocated() stable inclusion from stable-5.10.201 commit 47479ed7fcf750b08f3143f64804fae908e14078 category: bugfix issue: #IA8M8T CVE: NA Signed-off-by: wanxiaoqing --------------------------------------- [ Upstream commit a0b0bad10587ae2948a7c36ca4ffc206007fbcf3 ] When a CPU is about to be offlined, x86 validates that all active interrupts which are targeted to this CPU can be migrated to the remaining online CPUs. If not, the offline operation is aborted. The validation uses irq_matrix_allocated() to retrieve the number of vectors which are allocated on the outgoing CPU. The returned number of allocated vectors includes also vectors which are associated to managed interrupts. That's overaccounting because managed interrupts are: - not migrated when the affinity mask of the interrupt targets only the outgoing CPU - migrated to another CPU, but in that case the vector is already pre-allocated on the potential target CPUs and must not be taken into account. As a consequence the check whether the remaining online CPUs have enough capacity for migrating the allocated vectors from the outgoing CPU might fail incorrectly. Let irq_matrix_allocated() return only the number of allocated non-managed interrupts to make this validation check correct. [ tglx: Amend changelog and fixup kernel-doc comment ] Fixes: 2f75d9e1c905 ("genirq: Implement bitmap matrix allocator") Reported-by: Wendy Wang Signed-off-by: Chen Yu Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/r/20231020072522.557846-1-yu.c.chen@intel.com Signed-off-by: Sasha Levin Signed-off-by: wanxiaoqing --- kernel/irq/matrix.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/kernel/irq/matrix.c b/kernel/irq/matrix.c index 8e586858bcf4..d25edbb87119 100644 --- a/kernel/irq/matrix.c +++ b/kernel/irq/matrix.c @@ -466,16 +466,16 @@ unsigned int irq_matrix_reserved(struct irq_matrix *m) } /** - * irq_matrix_allocated - Get the number of allocated irqs on the local cpu + * irq_matrix_allocated - Get the number of allocated non-managed irqs on the local CPU * @m: Pointer to the matrix to search * - * This returns number of allocated irqs + * This returns number of allocated non-managed interrupts. */ unsigned int irq_matrix_allocated(struct irq_matrix *m) { struct cpumap *cm = this_cpu_ptr(m->maps); - return cm->allocated; + return cm->allocated - cm->managed_allocated; } #ifdef CONFIG_GENERIC_IRQ_DEBUGFS -- Gitee From d108ffadfec51abcb57965e4ac802f2a36998ddb Mon Sep 17 00:00:00 2001 From: Andrii Staikov Date: Fri, 8 Sep 2023 14:42:01 +0200 Subject: [PATCH 27/28] i40e: fix potential memory leaks in i40e_remove() stable inclusion from stable-5.10.201 commit 61e7961ff33d18a27e539e713397e9069d4b332d category: bugfix issue: #IA8M8T CVE: NA Signed-off-by: wanxiaoqing --------------------------------------- [ Upstream commit 5ca636d927a106780451d957734f02589b972e2b ] Instead of freeing memory of a single VSI, make sure the memory for all VSIs is cleared before releasing VSIs. Add releasing of their resources in a loop with the iteration number equal to the number of allocated VSIs. Fixes: 41c445ff0f48 ("i40e: main driver core") Signed-off-by: Andrii Staikov Signed-off-by: Aleksandr Loktionov Reviewed-by: Simon Horman Signed-off-by: Tony Nguyen Signed-off-by: Sasha Levin Signed-off-by: wanxiaoqing --- drivers/net/ethernet/intel/i40e/i40e_main.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index d23a467d0d20..64e1f6f407b4 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -15601,11 +15601,15 @@ static void i40e_remove(struct pci_dev *pdev) i40e_switch_branch_release(pf->veb[i]); } - /* Now we can shutdown the PF's VSI, just before we kill + /* Now we can shutdown the PF's VSIs, just before we kill * adminq and hmc. */ - if (pf->vsi[pf->lan_vsi]) - i40e_vsi_release(pf->vsi[pf->lan_vsi]); + for (i = pf->num_alloc_vsi; i--;) + if (pf->vsi[i]) { + i40e_vsi_close(pf->vsi[i]); + i40e_vsi_release(pf->vsi[i]); + pf->vsi[i] = NULL; + } i40e_cloud_filter_exit(pf); -- Gitee From d3eca73357180dbfd8d19111dbc778aa7040bccb Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 12 Sep 2023 09:17:25 +0000 Subject: [PATCH 28/28] udp: add missing WRITE_ONCE() around up->encap_rcv stable inclusion from stable-5.10.201 commit 0ca9fc8200d41fde03e6664261bb526846a1d0ca category: bugfix issue: #IA8M8T CVE: NA Signed-off-by: wanxiaoqing --------------------------------------- [ Upstream commit 6d5a12eb91224d707f8691dccb40a5719fe5466d ] UDP_ENCAP_ESPINUDP_NON_IKE setsockopt() writes over up->encap_rcv while other cpus read it. Fixes: 067b207b281d ("[UDP]: Cleanup UDP encapsulation code") Signed-off-by: Eric Dumazet Reviewed-by: Willem de Bruijn Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin Signed-off-by: wanxiaoqing --- net/ipv4/udp.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 913966e7703f..476f79f1563a 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -2645,10 +2645,12 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname, case UDP_ENCAP_ESPINUDP_NON_IKE: #if IS_ENABLED(CONFIG_IPV6) if (sk->sk_family == AF_INET6) - up->encap_rcv = ipv6_stub->xfrm6_udp_encap_rcv; + WRITE_ONCE(up->encap_rcv, + ipv6_stub->xfrm6_udp_encap_rcv); else #endif - up->encap_rcv = xfrm4_udp_encap_rcv; + WRITE_ONCE(up->encap_rcv, + xfrm4_udp_encap_rcv); #endif fallthrough; case UDP_ENCAP_L2TPINUDP: -- Gitee