From 081b2ac90102e11b471a9a4cbaf0f9e9dcfa4f66 Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Sat, 23 Jul 2022 23:30:04 -0400 Subject: [PATCH] Fixes for 4.9 Signed-off-by: Sasha Levin --- ...fer-overflow-in-be_get_module_eeprom.patch | 144 +++++++++++++++ ...ge-large-transfer-count-reset-logic-.patch | 111 ++++++++++++ ...race-around-sysctl_igmp_max_membersh.patch | 36 ++++ ...races-around-sysctl_igmp_llm_reports.patch | 110 ++++++++++++ ...ta-race-around-sysctl_fwmark_reflect.patch | 36 ++++ ...x-use-of-dma-mapped-buffer-for-usb-b.patch | 94 ++++++++++ ...t-return-value-in-rsp_buf-alloc-err-.patch | 56 ++++++ ...e-separate-command-and-response-buff.patch | 97 ++++++++++ ...ta-race-between-perf_event_set_outpu.patch | 167 ++++++++++++++++++ ...versatile-fix-refcount-leak-in-versa.patch | 38 ++++ queue-4.9/series | 14 ++ ...ata-race-around-sysctl_tcp_fwmark_ac.patch | 37 ++++ ...race-around-sysctl_tcp_notsent_lowat.patch | 36 ++++ ...ace-around-sysctl_tcp_probe_threshol.patch | 36 ++++ ...-fix-a-possible-double-xfrm_pols_put.patch | 58 ++++++ 15 files changed, 1070 insertions(+) create mode 100644 queue-4.9/be2net-fix-buffer-overflow-in-be_get_module_eeprom.patch create mode 100644 queue-4.9/i2c-cadence-change-large-transfer-count-reset-logic-.patch create mode 100644 queue-4.9/igmp-fix-a-data-race-around-sysctl_igmp_max_membersh.patch create mode 100644 queue-4.9/igmp-fix-data-races-around-sysctl_igmp_llm_reports.patch create mode 100644 queue-4.9/ip-fix-a-data-race-around-sysctl_fwmark_reflect.patch create mode 100644 queue-4.9/misc-rtsx_usb-fix-use-of-dma-mapped-buffer-for-usb-b.patch create mode 100644 queue-4.9/misc-rtsx_usb-set-return-value-in-rsp_buf-alloc-err-.patch create mode 100644 queue-4.9/misc-rtsx_usb-use-separate-command-and-response-buff.patch create mode 100644 queue-4.9/perf-core-fix-data-race-between-perf_event_set_outpu.patch create mode 100644 queue-4.9/power-reset-arm-versatile-fix-refcount-leak-in-versa.patch create mode 100644 queue-4.9/tcp-dccp-fix-a-data-race-around-sysctl_tcp_fwmark_ac.patch create mode 100644 queue-4.9/tcp-fix-a-data-race-around-sysctl_tcp_notsent_lowat.patch create mode 100644 queue-4.9/tcp-fix-a-data-race-around-sysctl_tcp_probe_threshol.patch create mode 100644 queue-4.9/xfrm-xfrm_policy-fix-a-possible-double-xfrm_pols_put.patch diff --git a/queue-4.9/be2net-fix-buffer-overflow-in-be_get_module_eeprom.patch b/queue-4.9/be2net-fix-buffer-overflow-in-be_get_module_eeprom.patch new file mode 100644 index 00000000000..693df2d4551 --- /dev/null +++ b/queue-4.9/be2net-fix-buffer-overflow-in-be_get_module_eeprom.patch @@ -0,0 +1,144 @@ +From a6a828c4e952e5560421247512e0299edcf0a086 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 16 Jul 2022 11:51:34 +0300 +Subject: be2net: Fix buffer overflow in be_get_module_eeprom + +From: Hristo Venev + +[ Upstream commit d7241f679a59cfe27f92cb5c6272cb429fb1f7ec ] + +be_cmd_read_port_transceiver_data assumes that it is given a buffer that +is at least PAGE_DATA_LEN long, or twice that if the module supports SFF +8472. However, this is not always the case. + +Fix this by passing the desired offset and length to +be_cmd_read_port_transceiver_data so that we only copy the bytes once. + +Fixes: e36edd9d26cf ("be2net: add ethtool "-m" option support") +Signed-off-by: Hristo Venev +Link: https://lore.kernel.org/r/20220716085134.6095-1-hristo@venev.name +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/emulex/benet/be_cmds.c | 10 +++--- + drivers/net/ethernet/emulex/benet/be_cmds.h | 2 +- + .../net/ethernet/emulex/benet/be_ethtool.c | 31 ++++++++++++------- + 3 files changed, 25 insertions(+), 18 deletions(-) + +diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c +index 8887dd3abed7..619cc13ffb55 100644 +--- a/drivers/net/ethernet/emulex/benet/be_cmds.c ++++ b/drivers/net/ethernet/emulex/benet/be_cmds.c +@@ -2291,7 +2291,7 @@ int be_cmd_get_beacon_state(struct be_adapter *adapter, u8 port_num, u32 *state) + + /* Uses sync mcc */ + int be_cmd_read_port_transceiver_data(struct be_adapter *adapter, +- u8 page_num, u8 *data) ++ u8 page_num, u32 off, u32 len, u8 *data) + { + struct be_dma_mem cmd; + struct be_mcc_wrb *wrb; +@@ -2325,10 +2325,10 @@ int be_cmd_read_port_transceiver_data(struct be_adapter *adapter, + req->port = cpu_to_le32(adapter->hba_port_num); + req->page_num = cpu_to_le32(page_num); + status = be_mcc_notify_wait(adapter); +- if (!status) { ++ if (!status && len > 0) { + struct be_cmd_resp_port_type *resp = cmd.va; + +- memcpy(data, resp->page_data, PAGE_DATA_LEN); ++ memcpy(data, resp->page_data + off, len); + } + err: + mutex_unlock(&adapter->mcc_lock); +@@ -2419,7 +2419,7 @@ int be_cmd_query_cable_type(struct be_adapter *adapter) + int status; + + status = be_cmd_read_port_transceiver_data(adapter, TR_PAGE_A0, +- page_data); ++ 0, PAGE_DATA_LEN, page_data); + if (!status) { + switch (adapter->phy.interface_type) { + case PHY_TYPE_QSFP: +@@ -2444,7 +2444,7 @@ int be_cmd_query_sfp_info(struct be_adapter *adapter) + int status; + + status = be_cmd_read_port_transceiver_data(adapter, TR_PAGE_A0, +- page_data); ++ 0, PAGE_DATA_LEN, page_data); + if (!status) { + strlcpy(adapter->phy.vendor_name, page_data + + SFP_VENDOR_NAME_OFFSET, SFP_VENDOR_NAME_LEN - 1); +diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h +index 09da2d82c2f0..8af11a5e49fe 100644 +--- a/drivers/net/ethernet/emulex/benet/be_cmds.h ++++ b/drivers/net/ethernet/emulex/benet/be_cmds.h +@@ -2431,7 +2431,7 @@ int be_cmd_set_beacon_state(struct be_adapter *adapter, u8 port_num, u8 beacon, + int be_cmd_get_beacon_state(struct be_adapter *adapter, u8 port_num, + u32 *state); + int be_cmd_read_port_transceiver_data(struct be_adapter *adapter, +- u8 page_num, u8 *data); ++ u8 page_num, u32 off, u32 len, u8 *data); + int be_cmd_query_cable_type(struct be_adapter *adapter); + int be_cmd_query_sfp_info(struct be_adapter *adapter); + int lancer_cmd_read_object(struct be_adapter *adapter, struct be_dma_mem *cmd, +diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c +index 56db37d92937..ca7750f483f9 100644 +--- a/drivers/net/ethernet/emulex/benet/be_ethtool.c ++++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c +@@ -1345,7 +1345,7 @@ static int be_get_module_info(struct net_device *netdev, + return -EOPNOTSUPP; + + status = be_cmd_read_port_transceiver_data(adapter, TR_PAGE_A0, +- page_data); ++ 0, PAGE_DATA_LEN, page_data); + if (!status) { + if (!page_data[SFP_PLUS_SFF_8472_COMP]) { + modinfo->type = ETH_MODULE_SFF_8079; +@@ -1363,25 +1363,32 @@ static int be_get_module_eeprom(struct net_device *netdev, + { + struct be_adapter *adapter = netdev_priv(netdev); + int status; ++ u32 begin, end; + + if (!check_privilege(adapter, MAX_PRIVILEGES)) + return -EOPNOTSUPP; + +- status = be_cmd_read_port_transceiver_data(adapter, TR_PAGE_A0, +- data); +- if (status) +- goto err; ++ begin = eeprom->offset; ++ end = eeprom->offset + eeprom->len; ++ ++ if (begin < PAGE_DATA_LEN) { ++ status = be_cmd_read_port_transceiver_data(adapter, TR_PAGE_A0, begin, ++ min_t(u32, end, PAGE_DATA_LEN) - begin, ++ data); ++ if (status) ++ goto err; ++ ++ data += PAGE_DATA_LEN - begin; ++ begin = PAGE_DATA_LEN; ++ } + +- if (eeprom->offset + eeprom->len > PAGE_DATA_LEN) { +- status = be_cmd_read_port_transceiver_data(adapter, +- TR_PAGE_A2, +- data + +- PAGE_DATA_LEN); ++ if (end > PAGE_DATA_LEN) { ++ status = be_cmd_read_port_transceiver_data(adapter, TR_PAGE_A2, ++ begin - PAGE_DATA_LEN, ++ end - begin, data); + if (status) + goto err; + } +- if (eeprom->offset) +- memcpy(data, data + eeprom->offset, eeprom->len); + err: + return be_cmd_status(status); + } +-- +2.35.1 + diff --git a/queue-4.9/i2c-cadence-change-large-transfer-count-reset-logic-.patch b/queue-4.9/i2c-cadence-change-large-transfer-count-reset-logic-.patch new file mode 100644 index 00000000000..144546d554f --- /dev/null +++ b/queue-4.9/i2c-cadence-change-large-transfer-count-reset-logic-.patch @@ -0,0 +1,111 @@ +From 07fa063bc43ce44fc92c4f1fc55f0ab37a49b1ab Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Jun 2022 17:29:19 -0600 +Subject: i2c: cadence: Change large transfer count reset logic to be + unconditional + +From: Robert Hancock + +[ Upstream commit 4ca8ca873d454635c20d508261bfc0081af75cf8 ] + +Problems were observed on the Xilinx ZynqMP platform with large I2C reads. +When a read of 277 bytes was performed, the controller NAKed the transfer +after only 252 bytes were transferred and returned an ENXIO error on the +transfer. + +There is some code in cdns_i2c_master_isr to handle this case by resetting +the transfer count in the controller before it reaches 0, to allow larger +transfers to work, but it was conditional on the CDNS_I2C_BROKEN_HOLD_BIT +quirk being set on the controller, and ZynqMP uses the r1p14 version of +the core where this quirk is not being set. The requirement to do this to +support larger reads seems like an inherently required workaround due to +the core only having an 8-bit transfer size register, so it does not +appear that this should be conditional on the broken HOLD bit quirk which +is used elsewhere in the driver. + +Remove the dependency on the CDNS_I2C_BROKEN_HOLD_BIT for this transfer +size reset logic to fix this problem. + +Fixes: 63cab195bf49 ("i2c: removed work arounds in i2c driver for Zynq Ultrascale+ MPSoC") +Signed-off-by: Robert Hancock +Reviewed-by: Shubhrajyoti Datta +Acked-by: Michal Simek +Signed-off-by: Wolfram Sang +Signed-off-by: Sasha Levin +--- + drivers/i2c/busses/i2c-cadence.c | 30 +++++------------------------- + 1 file changed, 5 insertions(+), 25 deletions(-) + +diff --git a/drivers/i2c/busses/i2c-cadence.c b/drivers/i2c/busses/i2c-cadence.c +index 9ab056bb834d..fce1906e7df1 100644 +--- a/drivers/i2c/busses/i2c-cadence.c ++++ b/drivers/i2c/busses/i2c-cadence.c +@@ -203,9 +203,9 @@ static inline bool cdns_is_holdquirk(struct cdns_i2c *id, bool hold_wrkaround) + */ + static irqreturn_t cdns_i2c_isr(int irq, void *ptr) + { +- unsigned int isr_status, avail_bytes, updatetx; ++ unsigned int isr_status, avail_bytes; + unsigned int bytes_to_send; +- bool hold_quirk; ++ bool updatetx; + struct cdns_i2c *id = ptr; + /* Signal completion only after everything is updated */ + int done_flag = 0; +@@ -224,11 +224,7 @@ static irqreturn_t cdns_i2c_isr(int irq, void *ptr) + * Check if transfer size register needs to be updated again for a + * large data receive operation. + */ +- updatetx = 0; +- if (id->recv_count > id->curr_recv_count) +- updatetx = 1; +- +- hold_quirk = (id->quirks & CDNS_I2C_BROKEN_HOLD_BIT) && updatetx; ++ updatetx = id->recv_count > id->curr_recv_count; + + /* When receiving, handle data interrupt and completion interrupt */ + if (id->p_recv_buf && +@@ -251,7 +247,7 @@ static irqreturn_t cdns_i2c_isr(int irq, void *ptr) + id->recv_count--; + id->curr_recv_count--; + +- if (cdns_is_holdquirk(id, hold_quirk)) ++ if (cdns_is_holdquirk(id, updatetx)) + break; + } + +@@ -262,7 +258,7 @@ static irqreturn_t cdns_i2c_isr(int irq, void *ptr) + * maintain transfer size non-zero while performing a large + * receive operation. + */ +- if (cdns_is_holdquirk(id, hold_quirk)) { ++ if (cdns_is_holdquirk(id, updatetx)) { + /* wait while fifo is full */ + while (cdns_i2c_readreg(CDNS_I2C_XFER_SIZE_OFFSET) != + (id->curr_recv_count - CDNS_I2C_FIFO_DEPTH)) +@@ -284,22 +280,6 @@ static irqreturn_t cdns_i2c_isr(int irq, void *ptr) + CDNS_I2C_XFER_SIZE_OFFSET); + id->curr_recv_count = id->recv_count; + } +- } else if (id->recv_count && !hold_quirk && +- !id->curr_recv_count) { +- +- /* Set the slave address in address register*/ +- cdns_i2c_writereg(id->p_msg->addr & CDNS_I2C_ADDR_MASK, +- CDNS_I2C_ADDR_OFFSET); +- +- if (id->recv_count > CDNS_I2C_TRANSFER_SIZE) { +- cdns_i2c_writereg(CDNS_I2C_TRANSFER_SIZE, +- CDNS_I2C_XFER_SIZE_OFFSET); +- id->curr_recv_count = CDNS_I2C_TRANSFER_SIZE; +- } else { +- cdns_i2c_writereg(id->recv_count, +- CDNS_I2C_XFER_SIZE_OFFSET); +- id->curr_recv_count = id->recv_count; +- } + } + + /* Clear hold (if not repeated start) and signal completion */ +-- +2.35.1 + diff --git a/queue-4.9/igmp-fix-a-data-race-around-sysctl_igmp_max_membersh.patch b/queue-4.9/igmp-fix-a-data-race-around-sysctl_igmp_max_membersh.patch new file mode 100644 index 00000000000..8722cc2fdaf --- /dev/null +++ b/queue-4.9/igmp-fix-a-data-race-around-sysctl_igmp_max_membersh.patch @@ -0,0 +1,36 @@ +From 49daa12e71a31f9793d3a29f6942535b2df3eedd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 15 Jul 2022 10:17:42 -0700 +Subject: igmp: Fix a data-race around sysctl_igmp_max_memberships. + +From: Kuniyuki Iwashima + +[ Upstream commit 6305d821e3b9b5379d348528e5b5faf316383bc2 ] + +While reading sysctl_igmp_max_memberships, it can be changed concurrently. +Thus, we need to add READ_ONCE() to its reader. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Kuniyuki Iwashima +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/ipv4/igmp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c +index 6e217424e0ff..3c09bee931b7 100644 +--- a/net/ipv4/igmp.c ++++ b/net/ipv4/igmp.c +@@ -2171,7 +2171,7 @@ int ip_mc_join_group(struct sock *sk, struct ip_mreqn *imr) + count++; + } + err = -ENOBUFS; +- if (count >= net->ipv4.sysctl_igmp_max_memberships) ++ if (count >= READ_ONCE(net->ipv4.sysctl_igmp_max_memberships)) + goto done; + iml = sock_kmalloc(sk, sizeof(*iml), GFP_KERNEL); + if (!iml) +-- +2.35.1 + diff --git a/queue-4.9/igmp-fix-data-races-around-sysctl_igmp_llm_reports.patch b/queue-4.9/igmp-fix-data-races-around-sysctl_igmp_llm_reports.patch new file mode 100644 index 00000000000..104da1c1caf --- /dev/null +++ b/queue-4.9/igmp-fix-data-races-around-sysctl_igmp_llm_reports.patch @@ -0,0 +1,110 @@ +From f9f04006e5d96242dd18427b029d21f2690ed020 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 15 Jul 2022 10:17:41 -0700 +Subject: igmp: Fix data-races around sysctl_igmp_llm_reports. + +From: Kuniyuki Iwashima + +[ Upstream commit f6da2267e71106474fbc0943dc24928b9cb79119 ] + +While reading sysctl_igmp_llm_reports, it can be changed concurrently. +Thus, we need to add READ_ONCE() to its readers. + +This test can be packed into a helper, so such changes will be in the +follow-up series after net is merged into net-next. + + if (ipv4_is_local_multicast(pmc->multiaddr) && + !READ_ONCE(net->ipv4.sysctl_igmp_llm_reports)) + +Fixes: df2cf4a78e48 ("IGMP: Inhibit reports for local multicast groups") +Signed-off-by: Kuniyuki Iwashima +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/ipv4/igmp.c | 21 +++++++++++++-------- + 1 file changed, 13 insertions(+), 8 deletions(-) + +diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c +index 75f961425639..6e217424e0ff 100644 +--- a/net/ipv4/igmp.c ++++ b/net/ipv4/igmp.c +@@ -474,7 +474,8 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc, + + if (pmc->multiaddr == IGMP_ALL_HOSTS) + return skb; +- if (ipv4_is_local_multicast(pmc->multiaddr) && !net->ipv4.sysctl_igmp_llm_reports) ++ if (ipv4_is_local_multicast(pmc->multiaddr) && ++ !READ_ONCE(net->ipv4.sysctl_igmp_llm_reports)) + return skb; + + mtu = READ_ONCE(dev->mtu); +@@ -600,7 +601,7 @@ static int igmpv3_send_report(struct in_device *in_dev, struct ip_mc_list *pmc) + if (pmc->multiaddr == IGMP_ALL_HOSTS) + continue; + if (ipv4_is_local_multicast(pmc->multiaddr) && +- !net->ipv4.sysctl_igmp_llm_reports) ++ !READ_ONCE(net->ipv4.sysctl_igmp_llm_reports)) + continue; + spin_lock_bh(&pmc->lock); + if (pmc->sfcount[MCAST_EXCLUDE]) +@@ -743,7 +744,8 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc, + if (type == IGMPV3_HOST_MEMBERSHIP_REPORT) + return igmpv3_send_report(in_dev, pmc); + +- if (ipv4_is_local_multicast(group) && !net->ipv4.sysctl_igmp_llm_reports) ++ if (ipv4_is_local_multicast(group) && ++ !READ_ONCE(net->ipv4.sysctl_igmp_llm_reports)) + return 0; + + if (type == IGMP_HOST_LEAVE_MESSAGE) +@@ -921,7 +923,8 @@ static bool igmp_heard_report(struct in_device *in_dev, __be32 group) + + if (group == IGMP_ALL_HOSTS) + return false; +- if (ipv4_is_local_multicast(group) && !net->ipv4.sysctl_igmp_llm_reports) ++ if (ipv4_is_local_multicast(group) && ++ !READ_ONCE(net->ipv4.sysctl_igmp_llm_reports)) + return false; + + rcu_read_lock(); +@@ -1031,7 +1034,7 @@ static bool igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb, + if (im->multiaddr == IGMP_ALL_HOSTS) + continue; + if (ipv4_is_local_multicast(im->multiaddr) && +- !net->ipv4.sysctl_igmp_llm_reports) ++ !READ_ONCE(net->ipv4.sysctl_igmp_llm_reports)) + continue; + spin_lock_bh(&im->lock); + if (im->tm_running) +@@ -1272,7 +1275,8 @@ static void igmp_group_dropped(struct ip_mc_list *im) + #ifdef CONFIG_IP_MULTICAST + if (im->multiaddr == IGMP_ALL_HOSTS) + return; +- if (ipv4_is_local_multicast(im->multiaddr) && !net->ipv4.sysctl_igmp_llm_reports) ++ if (ipv4_is_local_multicast(im->multiaddr) && ++ !READ_ONCE(net->ipv4.sysctl_igmp_llm_reports)) + return; + + reporter = im->reporter; +@@ -1309,7 +1313,8 @@ static void igmp_group_added(struct ip_mc_list *im) + #ifdef CONFIG_IP_MULTICAST + if (im->multiaddr == IGMP_ALL_HOSTS) + return; +- if (ipv4_is_local_multicast(im->multiaddr) && !net->ipv4.sysctl_igmp_llm_reports) ++ if (ipv4_is_local_multicast(im->multiaddr) && ++ !READ_ONCE(net->ipv4.sysctl_igmp_llm_reports)) + return; + + if (in_dev->dead) +@@ -1621,7 +1626,7 @@ static void ip_mc_rejoin_groups(struct in_device *in_dev) + if (im->multiaddr == IGMP_ALL_HOSTS) + continue; + if (ipv4_is_local_multicast(im->multiaddr) && +- !net->ipv4.sysctl_igmp_llm_reports) ++ !READ_ONCE(net->ipv4.sysctl_igmp_llm_reports)) + continue; + + /* a failover is happening and switches +-- +2.35.1 + diff --git a/queue-4.9/ip-fix-a-data-race-around-sysctl_fwmark_reflect.patch b/queue-4.9/ip-fix-a-data-race-around-sysctl_fwmark_reflect.patch new file mode 100644 index 00000000000..622ffa2f1b7 --- /dev/null +++ b/queue-4.9/ip-fix-a-data-race-around-sysctl_fwmark_reflect.patch @@ -0,0 +1,36 @@ +From 9cb847d9d9648dd7f0c1c16267bad9ef6dff2faa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 13 Jul 2022 13:51:57 -0700 +Subject: ip: Fix a data-race around sysctl_fwmark_reflect. + +From: Kuniyuki Iwashima + +[ Upstream commit 85d0b4dbd74b95cc492b1f4e34497d3f894f5d9a ] + +While reading sysctl_fwmark_reflect, it can be changed concurrently. +Thus, we need to add READ_ONCE() to its reader. + +Fixes: e110861f8609 ("net: add a sysctl to reflect the fwmark on replies") +Signed-off-by: Kuniyuki Iwashima +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + include/net/ip.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/net/ip.h b/include/net/ip.h +index c762fd047ef4..f0e13a256582 100644 +--- a/include/net/ip.h ++++ b/include/net/ip.h +@@ -283,7 +283,7 @@ void ipfrag_init(void); + void ip_static_sysctl_init(void); + + #define IP4_REPLY_MARK(net, mark) \ +- ((net)->ipv4.sysctl_fwmark_reflect ? (mark) : 0) ++ (READ_ONCE((net)->ipv4.sysctl_fwmark_reflect) ? (mark) : 0) + + static inline bool ip_is_fragment(const struct iphdr *iph) + { +-- +2.35.1 + diff --git a/queue-4.9/misc-rtsx_usb-fix-use-of-dma-mapped-buffer-for-usb-b.patch b/queue-4.9/misc-rtsx_usb-fix-use-of-dma-mapped-buffer-for-usb-b.patch new file mode 100644 index 00000000000..d19fd266b6f --- /dev/null +++ b/queue-4.9/misc-rtsx_usb-fix-use-of-dma-mapped-buffer-for-usb-b.patch @@ -0,0 +1,94 @@ +From 4d35fd55c8579a771dcc9904e03a774dddbdd10f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Jun 2022 20:32:55 -0600 +Subject: misc: rtsx_usb: fix use of dma mapped buffer for usb bulk transfer + +From: Shuah Khan + +[ Upstream commit eb7f8e28420372787933eec079735c35034bda7d ] + +rtsx_usb driver allocates coherent dma buffer for urb transfers. +This buffer is passed to usb_bulk_msg() and usb core tries to +map already mapped buffer running into a dma mapping error. + +xhci_hcd 0000:01:00.0: rejecting DMA map of vmalloc memory +WARNING: CPU: 1 PID: 279 at include/linux/dma-mapping.h:326 usb_ hcd_map_urb_for_dma+0x7d6/0x820 + +... + +xhci_map_urb_for_dma+0x291/0x4e0 +usb_hcd_submit_urb+0x199/0x12b0 +... +usb_submit_urb+0x3b8/0x9e0 +usb_start_wait_urb+0xe3/0x2d0 +usb_bulk_msg+0x115/0x240 +rtsx_usb_transfer_data+0x185/0x1a8 [rtsx_usb] +rtsx_usb_send_cmd+0xbb/0x123 [rtsx_usb] +rtsx_usb_write_register+0x12c/0x143 [rtsx_usb] +rtsx_usb_probe+0x226/0x4b2 [rtsx_usb] + +Fix it to use kmalloc() to get DMA-able memory region instead. + +Signed-off-by: Shuah Khan +Cc: stable +Link: https://lore.kernel.org/r/667d627d502e1ba9ff4f9b94966df3299d2d3c0d.1656642167.git.skhan@linuxfoundation.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/mfd/rtsx_usb.c | 13 +++++++------ + include/linux/mfd/rtsx_usb.h | 1 - + 2 files changed, 7 insertions(+), 7 deletions(-) + +diff --git a/drivers/mfd/rtsx_usb.c b/drivers/mfd/rtsx_usb.c +index e94f855eac15..b0ebd2299599 100644 +--- a/drivers/mfd/rtsx_usb.c ++++ b/drivers/mfd/rtsx_usb.c +@@ -642,8 +642,7 @@ static int rtsx_usb_probe(struct usb_interface *intf, + + ucr->pusb_dev = usb_dev; + +- ucr->iobuf = usb_alloc_coherent(ucr->pusb_dev, IOBUF_SIZE, +- GFP_KERNEL, &ucr->iobuf_dma); ++ ucr->iobuf = kmalloc(IOBUF_SIZE, GFP_KERNEL); + if (!ucr->iobuf) + return -ENOMEM; + +@@ -679,8 +678,9 @@ static int rtsx_usb_probe(struct usb_interface *intf, + + out_init_fail: + usb_set_intfdata(ucr->pusb_intf, NULL); +- usb_free_coherent(ucr->pusb_dev, IOBUF_SIZE, ucr->iobuf, +- ucr->iobuf_dma); ++ kfree(ucr->iobuf); ++ ucr->iobuf = NULL; ++ ucr->cmd_buf = ucr->rsp_buf = NULL; + return ret; + } + +@@ -693,8 +693,9 @@ static void rtsx_usb_disconnect(struct usb_interface *intf) + mfd_remove_devices(&intf->dev); + + usb_set_intfdata(ucr->pusb_intf, NULL); +- usb_free_coherent(ucr->pusb_dev, IOBUF_SIZE, ucr->iobuf, +- ucr->iobuf_dma); ++ kfree(ucr->iobuf); ++ ucr->iobuf = NULL; ++ ucr->cmd_buf = ucr->rsp_buf = NULL; + } + + #ifdef CONFIG_PM +diff --git a/include/linux/mfd/rtsx_usb.h b/include/linux/mfd/rtsx_usb.h +index c446e4fd6b5c..d3d231afb17c 100644 +--- a/include/linux/mfd/rtsx_usb.h ++++ b/include/linux/mfd/rtsx_usb.h +@@ -66,7 +66,6 @@ struct rtsx_ucr { + struct usb_interface *pusb_intf; + struct usb_sg_request current_sg; + unsigned char *iobuf; +- dma_addr_t iobuf_dma; + + struct timer_list sg_timer; + struct mutex dev_mutex; +-- +2.35.1 + diff --git a/queue-4.9/misc-rtsx_usb-set-return-value-in-rsp_buf-alloc-err-.patch b/queue-4.9/misc-rtsx_usb-set-return-value-in-rsp_buf-alloc-err-.patch new file mode 100644 index 00000000000..dbf2402980f --- /dev/null +++ b/queue-4.9/misc-rtsx_usb-set-return-value-in-rsp_buf-alloc-err-.patch @@ -0,0 +1,56 @@ +From 63de97bdc0a8f0fe677f5773e61576abd24d93a0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 1 Jul 2022 10:53:52 -0600 +Subject: misc: rtsx_usb: set return value in rsp_buf alloc err path + +From: Shuah Khan + +[ Upstream commit 2cd37c2e72449a7add6da1183d20a6247d6db111 ] + +Set return value in rsp_buf alloc error path before going to +error handling. + +drivers/misc/cardreader/rtsx_usb.c:639:6: warning: variable 'ret' is used uninitialized whenever 'if' condition is true [-Wsometimes-uninitialized] + if (!ucr->rsp_buf) + ^~~~~~~~~~~~~ + drivers/misc/cardreader/rtsx_usb.c:678:9: note: uninitialized use occurs here + return ret; + ^~~ + drivers/misc/cardreader/rtsx_usb.c:639:2: note: remove the 'if' if its condition is always false + if (!ucr->rsp_buf) + ^~~~~~~~~~~~~~~~~~ + drivers/misc/cardreader/rtsx_usb.c:622:9: note: initialize the variable 'ret' to silence this warning + int ret; + ^ + = 0 + +Fixes: 3776c7855985 ("misc: rtsx_usb: use separate command and response buffers") +Reported-by: kernel test robot +Cc: stable +Signed-off-by: Shuah Khan +Link: https://lore.kernel.org/r/20220701165352.15687-1-skhan@linuxfoundation.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/mfd/rtsx_usb.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/mfd/rtsx_usb.c b/drivers/mfd/rtsx_usb.c +index 134c6fbd9c50..fd859a7872a6 100644 +--- a/drivers/mfd/rtsx_usb.c ++++ b/drivers/mfd/rtsx_usb.c +@@ -647,8 +647,10 @@ static int rtsx_usb_probe(struct usb_interface *intf, + return -ENOMEM; + + ucr->rsp_buf = kmalloc(IOBUF_SIZE, GFP_KERNEL); +- if (!ucr->rsp_buf) ++ if (!ucr->rsp_buf) { ++ ret = -ENOMEM; + goto out_free_cmd_buf; ++ } + + usb_set_intfdata(intf, ucr); + +-- +2.35.1 + diff --git a/queue-4.9/misc-rtsx_usb-use-separate-command-and-response-buff.patch b/queue-4.9/misc-rtsx_usb-use-separate-command-and-response-buff.patch new file mode 100644 index 00000000000..2ab785b07ac --- /dev/null +++ b/queue-4.9/misc-rtsx_usb-use-separate-command-and-response-buff.patch @@ -0,0 +1,97 @@ +From cc81235eaf4f15f7f827fe7f253c8cc02a6166fe Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Jun 2022 20:32:56 -0600 +Subject: misc: rtsx_usb: use separate command and response buffers + +From: Shuah Khan + +[ Upstream commit 3776c78559853fd151be7c41e369fd076fb679d5 ] + +rtsx_usb uses same buffer for command and response. There could +be a potential conflict using the same buffer for both especially +if retries and timeouts are involved. + +Use separate command and response buffers to avoid conflicts. + +Signed-off-by: Shuah Khan +Cc: stable +Link: https://lore.kernel.org/r/07e3721804ff07aaab9ef5b39a5691d0718b9ade.1656642167.git.skhan@linuxfoundation.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/mfd/rtsx_usb.c | 26 +++++++++++++++++--------- + include/linux/mfd/rtsx_usb.h | 1 - + 2 files changed, 17 insertions(+), 10 deletions(-) + +diff --git a/drivers/mfd/rtsx_usb.c b/drivers/mfd/rtsx_usb.c +index b0ebd2299599..134c6fbd9c50 100644 +--- a/drivers/mfd/rtsx_usb.c ++++ b/drivers/mfd/rtsx_usb.c +@@ -642,15 +642,18 @@ static int rtsx_usb_probe(struct usb_interface *intf, + + ucr->pusb_dev = usb_dev; + +- ucr->iobuf = kmalloc(IOBUF_SIZE, GFP_KERNEL); +- if (!ucr->iobuf) ++ ucr->cmd_buf = kmalloc(IOBUF_SIZE, GFP_KERNEL); ++ if (!ucr->cmd_buf) + return -ENOMEM; + ++ ucr->rsp_buf = kmalloc(IOBUF_SIZE, GFP_KERNEL); ++ if (!ucr->rsp_buf) ++ goto out_free_cmd_buf; ++ + usb_set_intfdata(intf, ucr); + + ucr->vendor_id = id->idVendor; + ucr->product_id = id->idProduct; +- ucr->cmd_buf = ucr->rsp_buf = ucr->iobuf; + + mutex_init(&ucr->dev_mutex); + +@@ -678,9 +681,11 @@ static int rtsx_usb_probe(struct usb_interface *intf, + + out_init_fail: + usb_set_intfdata(ucr->pusb_intf, NULL); +- kfree(ucr->iobuf); +- ucr->iobuf = NULL; +- ucr->cmd_buf = ucr->rsp_buf = NULL; ++ kfree(ucr->rsp_buf); ++ ucr->rsp_buf = NULL; ++out_free_cmd_buf: ++ kfree(ucr->cmd_buf); ++ ucr->cmd_buf = NULL; + return ret; + } + +@@ -693,9 +698,12 @@ static void rtsx_usb_disconnect(struct usb_interface *intf) + mfd_remove_devices(&intf->dev); + + usb_set_intfdata(ucr->pusb_intf, NULL); +- kfree(ucr->iobuf); +- ucr->iobuf = NULL; +- ucr->cmd_buf = ucr->rsp_buf = NULL; ++ ++ kfree(ucr->cmd_buf); ++ ucr->cmd_buf = NULL; ++ ++ kfree(ucr->rsp_buf); ++ ucr->rsp_buf = NULL; + } + + #ifdef CONFIG_PM +diff --git a/include/linux/mfd/rtsx_usb.h b/include/linux/mfd/rtsx_usb.h +index d3d231afb17c..09b08ff08830 100644 +--- a/include/linux/mfd/rtsx_usb.h ++++ b/include/linux/mfd/rtsx_usb.h +@@ -65,7 +65,6 @@ struct rtsx_ucr { + struct usb_device *pusb_dev; + struct usb_interface *pusb_intf; + struct usb_sg_request current_sg; +- unsigned char *iobuf; + + struct timer_list sg_timer; + struct mutex dev_mutex; +-- +2.35.1 + diff --git a/queue-4.9/perf-core-fix-data-race-between-perf_event_set_outpu.patch b/queue-4.9/perf-core-fix-data-race-between-perf_event_set_outpu.patch new file mode 100644 index 00000000000..26b268cb258 --- /dev/null +++ b/queue-4.9/perf-core-fix-data-race-between-perf_event_set_outpu.patch @@ -0,0 +1,167 @@ +From 91facf917dc3744e9a06a6f466f458b275ce06db Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 5 Jul 2022 15:07:26 +0200 +Subject: perf/core: Fix data race between perf_event_set_output() and + perf_mmap_close() + +From: Peter Zijlstra + +[ Upstream commit 68e3c69803dada336893640110cb87221bb01dcf ] + +Yang Jihing reported a race between perf_event_set_output() and +perf_mmap_close(): + + CPU1 CPU2 + + perf_mmap_close(e2) + if (atomic_dec_and_test(&e2->rb->mmap_count)) // 1 - > 0 + detach_rest = true + + ioctl(e1, IOC_SET_OUTPUT, e2) + perf_event_set_output(e1, e2) + + ... + list_for_each_entry_rcu(e, &e2->rb->event_list, rb_entry) + ring_buffer_attach(e, NULL); + // e1 isn't yet added and + // therefore not detached + + ring_buffer_attach(e1, e2->rb) + list_add_rcu(&e1->rb_entry, + &e2->rb->event_list) + +After this; e1 is attached to an unmapped rb and a subsequent +perf_mmap() will loop forever more: + + again: + mutex_lock(&e->mmap_mutex); + if (event->rb) { + ... + if (!atomic_inc_not_zero(&e->rb->mmap_count)) { + ... + mutex_unlock(&e->mmap_mutex); + goto again; + } + } + +The loop in perf_mmap_close() holds e2->mmap_mutex, while the attach +in perf_event_set_output() holds e1->mmap_mutex. As such there is no +serialization to avoid this race. + +Change perf_event_set_output() to take both e1->mmap_mutex and +e2->mmap_mutex to alleviate that problem. Additionally, have the loop +in perf_mmap() detach the rb directly, this avoids having to wait for +the concurrent perf_mmap_close() to get around to doing it to make +progress. + +Fixes: 9bb5d40cd93c ("perf: Fix mmap() accounting hole") +Reported-by: Yang Jihong +Signed-off-by: Peter Zijlstra (Intel) +Tested-by: Yang Jihong +Link: https://lkml.kernel.org/r/YsQ3jm2GR38SW7uD@worktop.programming.kicks-ass.net +Signed-off-by: Sasha Levin +--- + kernel/events/core.c | 45 ++++++++++++++++++++++++++++++-------------- + 1 file changed, 31 insertions(+), 14 deletions(-) + +diff --git a/kernel/events/core.c b/kernel/events/core.c +index 2466e2ae54dc..58ef731d52c7 100644 +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -5291,10 +5291,10 @@ static int perf_mmap(struct file *file, struct vm_area_struct *vma) + + if (!atomic_inc_not_zero(&event->rb->mmap_count)) { + /* +- * Raced against perf_mmap_close() through +- * perf_event_set_output(). Try again, hope for better +- * luck. ++ * Raced against perf_mmap_close(); remove the ++ * event and try again. + */ ++ ring_buffer_attach(event, NULL); + mutex_unlock(&event->mmap_mutex); + goto again; + } +@@ -9542,14 +9542,25 @@ static int perf_copy_attr(struct perf_event_attr __user *uattr, + goto out; + } + ++static void mutex_lock_double(struct mutex *a, struct mutex *b) ++{ ++ if (b < a) ++ swap(a, b); ++ ++ mutex_lock(a); ++ mutex_lock_nested(b, SINGLE_DEPTH_NESTING); ++} ++ + static int + perf_event_set_output(struct perf_event *event, struct perf_event *output_event) + { + struct ring_buffer *rb = NULL; + int ret = -EINVAL; + +- if (!output_event) ++ if (!output_event) { ++ mutex_lock(&event->mmap_mutex); + goto set; ++ } + + /* don't allow circular references */ + if (event == output_event) +@@ -9587,8 +9598,15 @@ perf_event_set_output(struct perf_event *event, struct perf_event *output_event) + event->pmu != output_event->pmu) + goto out; + ++ /* ++ * Hold both mmap_mutex to serialize against perf_mmap_close(). Since ++ * output_event is already on rb->event_list, and the list iteration ++ * restarts after every removal, it is guaranteed this new event is ++ * observed *OR* if output_event is already removed, it's guaranteed we ++ * observe !rb->mmap_count. ++ */ ++ mutex_lock_double(&event->mmap_mutex, &output_event->mmap_mutex); + set: +- mutex_lock(&event->mmap_mutex); + /* Can't redirect output if we've got an active mmap() */ + if (atomic_read(&event->mmap_count)) + goto unlock; +@@ -9598,6 +9616,12 @@ perf_event_set_output(struct perf_event *event, struct perf_event *output_event) + rb = ring_buffer_get(output_event); + if (!rb) + goto unlock; ++ ++ /* did we race against perf_mmap_close() */ ++ if (!atomic_read(&rb->mmap_count)) { ++ ring_buffer_put(rb); ++ goto unlock; ++ } + } + + ring_buffer_attach(event, rb); +@@ -9605,20 +9629,13 @@ perf_event_set_output(struct perf_event *event, struct perf_event *output_event) + ret = 0; + unlock: + mutex_unlock(&event->mmap_mutex); ++ if (output_event) ++ mutex_unlock(&output_event->mmap_mutex); + + out: + return ret; + } + +-static void mutex_lock_double(struct mutex *a, struct mutex *b) +-{ +- if (b < a) +- swap(a, b); +- +- mutex_lock(a); +- mutex_lock_nested(b, SINGLE_DEPTH_NESTING); +-} +- + static int perf_event_set_clock(struct perf_event *event, clockid_t clk_id) + { + bool nmi_safe = false; +-- +2.35.1 + diff --git a/queue-4.9/power-reset-arm-versatile-fix-refcount-leak-in-versa.patch b/queue-4.9/power-reset-arm-versatile-fix-refcount-leak-in-versa.patch new file mode 100644 index 00000000000..2b5bd1e4bca --- /dev/null +++ b/queue-4.9/power-reset-arm-versatile-fix-refcount-leak-in-versa.patch @@ -0,0 +1,38 @@ +From bd3c0f75ab1274ac9f4b744fcaba6c016dd82197 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 23 May 2022 18:10:09 +0400 +Subject: power/reset: arm-versatile: Fix refcount leak in + versatile_reboot_probe + +From: Miaoqian Lin + +[ Upstream commit 80192eff64eee9b3bc0594a47381937b94b9d65a ] + +of_find_matching_node_and_match() returns a node pointer with refcount +incremented, we should use of_node_put() on it when not need anymore. +Add missing of_node_put() to avoid refcount leak. + +Fixes: 0e545f57b708 ("power: reset: driver for the Versatile syscon reboot") +Signed-off-by: Miaoqian Lin +Reviewed-by: Linus Walleij +Signed-off-by: Sebastian Reichel +Signed-off-by: Sasha Levin +--- + drivers/power/reset/arm-versatile-reboot.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/power/reset/arm-versatile-reboot.c b/drivers/power/reset/arm-versatile-reboot.c +index 06d34ab47df5..8022c782f6ff 100644 +--- a/drivers/power/reset/arm-versatile-reboot.c ++++ b/drivers/power/reset/arm-versatile-reboot.c +@@ -150,6 +150,7 @@ static int __init versatile_reboot_probe(void) + versatile_reboot_type = (enum versatile_reboot)reboot_id->data; + + syscon_regmap = syscon_node_to_regmap(np); ++ of_node_put(np); + if (IS_ERR(syscon_regmap)) + return PTR_ERR(syscon_regmap); + +-- +2.35.1 + diff --git a/queue-4.9/series b/queue-4.9/series index 83664fd12b3..3adf8fb74a8 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -1,2 +1,16 @@ security-selinux-smack-kill-security_task_wait-hook.patch xen-gntdev-ignore-failure-to-unmap-invalid_grant_handle.patch +misc-rtsx_usb-fix-use-of-dma-mapped-buffer-for-usb-b.patch +misc-rtsx_usb-use-separate-command-and-response-buff.patch +misc-rtsx_usb-set-return-value-in-rsp_buf-alloc-err-.patch +xfrm-xfrm_policy-fix-a-possible-double-xfrm_pols_put.patch +power-reset-arm-versatile-fix-refcount-leak-in-versa.patch +perf-core-fix-data-race-between-perf_event_set_outpu.patch +ip-fix-a-data-race-around-sysctl_fwmark_reflect.patch +tcp-dccp-fix-a-data-race-around-sysctl_tcp_fwmark_ac.patch +tcp-fix-a-data-race-around-sysctl_tcp_probe_threshol.patch +i2c-cadence-change-large-transfer-count-reset-logic-.patch +igmp-fix-data-races-around-sysctl_igmp_llm_reports.patch +igmp-fix-a-data-race-around-sysctl_igmp_max_membersh.patch +tcp-fix-a-data-race-around-sysctl_tcp_notsent_lowat.patch +be2net-fix-buffer-overflow-in-be_get_module_eeprom.patch diff --git a/queue-4.9/tcp-dccp-fix-a-data-race-around-sysctl_tcp_fwmark_ac.patch b/queue-4.9/tcp-dccp-fix-a-data-race-around-sysctl_tcp_fwmark_ac.patch new file mode 100644 index 00000000000..35aafda6b96 --- /dev/null +++ b/queue-4.9/tcp-dccp-fix-a-data-race-around-sysctl_tcp_fwmark_ac.patch @@ -0,0 +1,37 @@ +From f85e44618393db6be5da75a3be826cabd577f65c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 13 Jul 2022 13:51:58 -0700 +Subject: tcp/dccp: Fix a data-race around sysctl_tcp_fwmark_accept. + +From: Kuniyuki Iwashima + +[ Upstream commit 1a0008f9df59451d0a17806c1ee1a19857032fa8 ] + +While reading sysctl_tcp_fwmark_accept, it can be changed concurrently. +Thus, we need to add READ_ONCE() to its reader. + +Fixes: 84f39b08d786 ("net: support marking accepting TCP sockets") +Signed-off-by: Kuniyuki Iwashima +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + include/net/inet_sock.h | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h +index 6213a90a8cec..f5dbee53fb85 100644 +--- a/include/net/inet_sock.h ++++ b/include/net/inet_sock.h +@@ -113,7 +113,8 @@ static inline struct inet_request_sock *inet_rsk(const struct request_sock *sk) + + static inline u32 inet_request_mark(const struct sock *sk, struct sk_buff *skb) + { +- if (!sk->sk_mark && sock_net(sk)->ipv4.sysctl_tcp_fwmark_accept) ++ if (!sk->sk_mark && ++ READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_fwmark_accept)) + return skb->mark; + + return sk->sk_mark; +-- +2.35.1 + diff --git a/queue-4.9/tcp-fix-a-data-race-around-sysctl_tcp_notsent_lowat.patch b/queue-4.9/tcp-fix-a-data-race-around-sysctl_tcp_notsent_lowat.patch new file mode 100644 index 00000000000..8a82779d106 --- /dev/null +++ b/queue-4.9/tcp-fix-a-data-race-around-sysctl_tcp_notsent_lowat.patch @@ -0,0 +1,36 @@ +From 9ec162f621b0c92b2e0b4dc4090633f255460d00 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 15 Jul 2022 10:17:51 -0700 +Subject: tcp: Fix a data-race around sysctl_tcp_notsent_lowat. + +From: Kuniyuki Iwashima + +[ Upstream commit 55be873695ed8912eb77ff46d1d1cadf028bd0f3 ] + +While reading sysctl_tcp_notsent_lowat, it can be changed concurrently. +Thus, we need to add READ_ONCE() to its reader. + +Fixes: c9bee3b7fdec ("tcp: TCP_NOTSENT_LOWAT socket option") +Signed-off-by: Kuniyuki Iwashima +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + include/net/tcp.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/net/tcp.h b/include/net/tcp.h +index 97df2f6fcbd7..164dc4f04d0f 100644 +--- a/include/net/tcp.h ++++ b/include/net/tcp.h +@@ -1788,7 +1788,7 @@ void __tcp_v4_send_check(struct sk_buff *skb, __be32 saddr, __be32 daddr); + static inline u32 tcp_notsent_lowat(const struct tcp_sock *tp) + { + struct net *net = sock_net((struct sock *)tp); +- return tp->notsent_lowat ?: net->ipv4.sysctl_tcp_notsent_lowat; ++ return tp->notsent_lowat ?: READ_ONCE(net->ipv4.sysctl_tcp_notsent_lowat); + } + + static inline bool tcp_stream_memory_free(const struct sock *sk) +-- +2.35.1 + diff --git a/queue-4.9/tcp-fix-a-data-race-around-sysctl_tcp_probe_threshol.patch b/queue-4.9/tcp-fix-a-data-race-around-sysctl_tcp_probe_threshol.patch new file mode 100644 index 00000000000..7a385ade6c2 --- /dev/null +++ b/queue-4.9/tcp-fix-a-data-race-around-sysctl_tcp_probe_threshol.patch @@ -0,0 +1,36 @@ +From 7cabf011c8c98126fab9a5fba6948204b19fb89d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 13 Jul 2022 13:52:04 -0700 +Subject: tcp: Fix a data-race around sysctl_tcp_probe_threshold. + +From: Kuniyuki Iwashima + +[ Upstream commit 92c0aa4175474483d6cf373314343d4e624e882a ] + +While reading sysctl_tcp_probe_threshold, it can be changed concurrently. +Thus, we need to add READ_ONCE() to its reader. + +Fixes: 6b58e0a5f32d ("ipv4: Use binary search to choose tcp PMTU probe_size") +Signed-off-by: Kuniyuki Iwashima +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/ipv4/tcp_output.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c +index e0009cd69da7..5b6d935a028c 100644 +--- a/net/ipv4/tcp_output.c ++++ b/net/ipv4/tcp_output.c +@@ -2005,7 +2005,7 @@ static int tcp_mtu_probe(struct sock *sk) + * probing process by not resetting search range to its orignal. + */ + if (probe_size > tcp_mtu_to_mss(sk, icsk->icsk_mtup.search_high) || +- interval < net->ipv4.sysctl_tcp_probe_threshold) { ++ interval < READ_ONCE(net->ipv4.sysctl_tcp_probe_threshold)) { + /* Check whether enough time has elaplased for + * another round of probing. + */ +-- +2.35.1 + diff --git a/queue-4.9/xfrm-xfrm_policy-fix-a-possible-double-xfrm_pols_put.patch b/queue-4.9/xfrm-xfrm_policy-fix-a-possible-double-xfrm_pols_put.patch new file mode 100644 index 00000000000..fbbd884c01f --- /dev/null +++ b/queue-4.9/xfrm-xfrm_policy-fix-a-possible-double-xfrm_pols_put.patch @@ -0,0 +1,58 @@ +From 08b946c8060ed16a0e21aa5e425c271899ccb834 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 1 Jun 2022 14:46:25 +0800 +Subject: xfrm: xfrm_policy: fix a possible double xfrm_pols_put() in + xfrm_bundle_lookup() + +From: Hangyu Hua + +[ Upstream commit f85daf0e725358be78dfd208dea5fd665d8cb901 ] + +xfrm_policy_lookup() will call xfrm_pol_hold_rcu() to get a refcount of +pols[0]. This refcount can be dropped in xfrm_expand_policies() when +xfrm_expand_policies() return error. pols[0]'s refcount is balanced in +here. But xfrm_bundle_lookup() will also call xfrm_pols_put() with +num_pols == 1 to drop this refcount when xfrm_expand_policies() return +error. + +This patch also fix an illegal address access. pols[0] will save a error +point when xfrm_policy_lookup fails. This lead to xfrm_pols_put to resolve +an illegal address in xfrm_bundle_lookup's error path. + +Fix these by setting num_pols = 0 in xfrm_expand_policies()'s error path. + +Fixes: 80c802f3073e ("xfrm: cache bundles instead of policies for outgoing flows") +Signed-off-by: Hangyu Hua +Signed-off-by: Steffen Klassert +Signed-off-by: Sasha Levin +--- + net/xfrm/xfrm_policy.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c +index 9179b47e8b61..0894108f561c 100644 +--- a/net/xfrm/xfrm_policy.c ++++ b/net/xfrm/xfrm_policy.c +@@ -1819,8 +1819,10 @@ static int xfrm_expand_policies(const struct flowi *fl, u16 family, + *num_xfrms = 0; + return 0; + } +- if (IS_ERR(pols[0])) ++ if (IS_ERR(pols[0])) { ++ *num_pols = 0; + return PTR_ERR(pols[0]); ++ } + + *num_xfrms = pols[0]->xfrm_nr; + +@@ -1834,6 +1836,7 @@ static int xfrm_expand_policies(const struct flowi *fl, u16 family, + if (pols[1]) { + if (IS_ERR(pols[1])) { + xfrm_pols_put(pols, *num_pols); ++ *num_pols = 0; + return PTR_ERR(pols[1]); + } + (*num_pols)++; +-- +2.35.1 + -- 2.47.3