From: Greg Kroah-Hartman Date: Thu, 23 May 2024 11:48:16 +0000 (+0200) Subject: 5.15-stable patches X-Git-Tag: v4.19.315~16 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ebfa9cfcbb75cfa4751da88d3823521c56f6a575;p=thirdparty%2Fkernel%2Fstable-queue.git 5.15-stable patches added patches: net-bcmgenet-synchronize-ext_rgmii_oob_ctrl-access.patch net-bcmgenet-synchronize-umac_cmd-access.patch net-tls-factor-out-tls_-crypt_async_wait.patch net-tls-handle-backlogging-of-crypto-requests.patch revert-selftests-mm-fix-map_hugetlb-failure-on-64k-page-size-systems.patch tls-extract-context-alloc-initialization-out-of-tls_set_sw_offload.patch tls-fix-race-between-async-notify-and-socket-close.patch tls-rx-simplify-async-wait.patch --- diff --git a/queue-5.15/net-bcmgenet-synchronize-ext_rgmii_oob_ctrl-access.patch b/queue-5.15/net-bcmgenet-synchronize-ext_rgmii_oob_ctrl-access.patch new file mode 100644 index 00000000000..0ae8c9ef972 --- /dev/null +++ b/queue-5.15/net-bcmgenet-synchronize-ext_rgmii_oob_ctrl-access.patch @@ -0,0 +1,48 @@ +From d85cf67a339685beae1d0aee27b7f61da95455be Mon Sep 17 00:00:00 2001 +From: Doug Berger +Date: Thu, 25 Apr 2024 15:27:19 -0700 +Subject: net: bcmgenet: synchronize EXT_RGMII_OOB_CTRL access + +From: Doug Berger + +commit d85cf67a339685beae1d0aee27b7f61da95455be upstream. + +The EXT_RGMII_OOB_CTRL register can be written from different +contexts. It is predominantly written from the adjust_link +handler which is synchronized by the phydev->lock, but can +also be written from a different context when configuring the +mii in bcmgenet_mii_config(). + +The chances of contention are quite low, but it is conceivable +that adjust_link could occur during resume when WoL is enabled +so use the phydev->lock synchronizer in bcmgenet_mii_config() +to be sure. + +Fixes: afe3f907d20f ("net: bcmgenet: power on MII block for all MII modes") +Cc: stable@vger.kernel.org +Signed-off-by: Doug Berger +Acked-by: Florian Fainelli +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/broadcom/genet/bcmmii.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/net/ethernet/broadcom/genet/bcmmii.c ++++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c +@@ -264,6 +264,7 @@ int bcmgenet_mii_config(struct net_devic + * block for the interface to work + */ + if (priv->ext_phy) { ++ mutex_lock(&phydev->lock); + reg = bcmgenet_ext_readl(priv, EXT_RGMII_OOB_CTRL); + reg &= ~ID_MODE_DIS; + reg |= id_mode_dis; +@@ -272,6 +273,7 @@ int bcmgenet_mii_config(struct net_devic + else + reg |= RGMII_MODE_EN; + bcmgenet_ext_writel(priv, reg, EXT_RGMII_OOB_CTRL); ++ mutex_unlock(&phydev->lock); + } + + if (init) diff --git a/queue-5.15/net-bcmgenet-synchronize-umac_cmd-access.patch b/queue-5.15/net-bcmgenet-synchronize-umac_cmd-access.patch new file mode 100644 index 00000000000..325585d4ecc --- /dev/null +++ b/queue-5.15/net-bcmgenet-synchronize-umac_cmd-access.patch @@ -0,0 +1,167 @@ +From 0d5e2a82232605b337972fb2c7d0cbc46898aca1 Mon Sep 17 00:00:00 2001 +From: Doug Berger +Date: Thu, 25 Apr 2024 15:27:21 -0700 +Subject: net: bcmgenet: synchronize UMAC_CMD access + +From: Doug Berger + +commit 0d5e2a82232605b337972fb2c7d0cbc46898aca1 upstream. + +The UMAC_CMD register is written from different execution +contexts and has insufficient synchronization protections to +prevent possible corruption. Of particular concern are the +acceses from the phy_device delayed work context used by the +adjust_link call and the BH context that may be used by the +ndo_set_rx_mode call. + +A spinlock is added to the driver to protect contended register +accesses (i.e. reg_lock) and it is used to synchronize accesses +to UMAC_CMD. + +Fixes: 1c1008c793fa ("net: bcmgenet: add main driver file") +Cc: stable@vger.kernel.org +Signed-off-by: Doug Berger +Acked-by: Florian Fainelli +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/broadcom/genet/bcmgenet.c | 12 +++++++++++- + drivers/net/ethernet/broadcom/genet/bcmgenet.h | 2 ++ + drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c | 6 ++++++ + drivers/net/ethernet/broadcom/genet/bcmmii.c | 2 ++ + 4 files changed, 21 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c ++++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c +@@ -2424,14 +2424,18 @@ static void umac_enable_set(struct bcmge + { + u32 reg; + ++ spin_lock_bh(&priv->reg_lock); + reg = bcmgenet_umac_readl(priv, UMAC_CMD); +- if (reg & CMD_SW_RESET) ++ if (reg & CMD_SW_RESET) { ++ spin_unlock_bh(&priv->reg_lock); + return; ++ } + if (enable) + reg |= mask; + else + reg &= ~mask; + bcmgenet_umac_writel(priv, reg, UMAC_CMD); ++ spin_unlock_bh(&priv->reg_lock); + + /* UniMAC stops on a packet boundary, wait for a full-size packet + * to be processed +@@ -2447,8 +2451,10 @@ static void reset_umac(struct bcmgenet_p + udelay(10); + + /* issue soft reset and disable MAC while updating its registers */ ++ spin_lock_bh(&priv->reg_lock); + bcmgenet_umac_writel(priv, CMD_SW_RESET, UMAC_CMD); + udelay(2); ++ spin_unlock_bh(&priv->reg_lock); + } + + static void bcmgenet_intr_disable(struct bcmgenet_priv *priv) +@@ -3576,16 +3582,19 @@ static void bcmgenet_set_rx_mode(struct + * 3. The number of filters needed exceeds the number filters + * supported by the hardware. + */ ++ spin_lock(&priv->reg_lock); + reg = bcmgenet_umac_readl(priv, UMAC_CMD); + if ((dev->flags & (IFF_PROMISC | IFF_ALLMULTI)) || + (nfilter > MAX_MDF_FILTER)) { + reg |= CMD_PROMISC; + bcmgenet_umac_writel(priv, reg, UMAC_CMD); ++ spin_unlock(&priv->reg_lock); + bcmgenet_umac_writel(priv, 0, UMAC_MDF_CTRL); + return; + } else { + reg &= ~CMD_PROMISC; + bcmgenet_umac_writel(priv, reg, UMAC_CMD); ++ spin_unlock(&priv->reg_lock); + } + + /* update MDF filter */ +@@ -3979,6 +3988,7 @@ static int bcmgenet_probe(struct platfor + goto err; + } + ++ spin_lock_init(&priv->reg_lock); + spin_lock_init(&priv->lock); + + SET_NETDEV_DEV(dev, &pdev->dev); +--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h ++++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h +@@ -572,6 +572,8 @@ struct bcmgenet_rxnfc_rule { + /* device context */ + struct bcmgenet_priv { + void __iomem *base; ++ /* reg_lock: lock to serialize access to shared registers */ ++ spinlock_t reg_lock; + enum bcmgenet_version version; + struct net_device *dev; + +--- a/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c ++++ b/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c +@@ -133,6 +133,7 @@ int bcmgenet_wol_power_down_cfg(struct b + } + + /* Can't suspend with WoL if MAC is still in reset */ ++ spin_lock_bh(&priv->reg_lock); + reg = bcmgenet_umac_readl(priv, UMAC_CMD); + if (reg & CMD_SW_RESET) + reg &= ~CMD_SW_RESET; +@@ -140,6 +141,7 @@ int bcmgenet_wol_power_down_cfg(struct b + /* disable RX */ + reg &= ~CMD_RX_EN; + bcmgenet_umac_writel(priv, reg, UMAC_CMD); ++ spin_unlock_bh(&priv->reg_lock); + mdelay(10); + + if (priv->wolopts & (WAKE_MAGIC | WAKE_MAGICSECURE)) { +@@ -185,6 +187,7 @@ int bcmgenet_wol_power_down_cfg(struct b + } + + /* Enable CRC forward */ ++ spin_lock_bh(&priv->reg_lock); + reg = bcmgenet_umac_readl(priv, UMAC_CMD); + priv->crc_fwd_en = 1; + reg |= CMD_CRC_FWD; +@@ -192,6 +195,7 @@ int bcmgenet_wol_power_down_cfg(struct b + /* Receiver must be enabled for WOL MP detection */ + reg |= CMD_RX_EN; + bcmgenet_umac_writel(priv, reg, UMAC_CMD); ++ spin_unlock_bh(&priv->reg_lock); + + reg = UMAC_IRQ_MPD_R; + if (hfb_enable) +@@ -238,7 +242,9 @@ void bcmgenet_wol_power_up_cfg(struct bc + } + + /* Disable CRC Forward */ ++ spin_lock_bh(&priv->reg_lock); + reg = bcmgenet_umac_readl(priv, UMAC_CMD); + reg &= ~CMD_CRC_FWD; + bcmgenet_umac_writel(priv, reg, UMAC_CMD); ++ spin_unlock_bh(&priv->reg_lock); + } +--- a/drivers/net/ethernet/broadcom/genet/bcmmii.c ++++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c +@@ -91,6 +91,7 @@ void bcmgenet_mii_setup(struct net_devic + reg |= RGMII_LINK; + bcmgenet_ext_writel(priv, reg, EXT_RGMII_OOB_CTRL); + ++ spin_lock_bh(&priv->reg_lock); + reg = bcmgenet_umac_readl(priv, UMAC_CMD); + reg &= ~((CMD_SPEED_MASK << CMD_SPEED_SHIFT) | + CMD_HD_EN | +@@ -103,6 +104,7 @@ void bcmgenet_mii_setup(struct net_devic + reg |= CMD_TX_EN | CMD_RX_EN; + } + bcmgenet_umac_writel(priv, reg, UMAC_CMD); ++ spin_unlock_bh(&priv->reg_lock); + + priv->eee.eee_active = phy_init_eee(phydev, 0) >= 0; + bcmgenet_eee_enable_set(dev, diff --git a/queue-5.15/net-tls-factor-out-tls_-crypt_async_wait.patch b/queue-5.15/net-tls-factor-out-tls_-crypt_async_wait.patch new file mode 100644 index 00000000000..dda20e43428 --- /dev/null +++ b/queue-5.15/net-tls-factor-out-tls_-crypt_async_wait.patch @@ -0,0 +1,167 @@ +From c57ca512f3b68ddcd62bda9cc24a8f5584ab01b1 Mon Sep 17 00:00:00 2001 +From: Jakub Kicinski +Date: Tue, 6 Feb 2024 17:18:18 -0800 +Subject: net: tls: factor out tls_*crypt_async_wait() + +From: Jakub Kicinski + +commit c57ca512f3b68ddcd62bda9cc24a8f5584ab01b1 upstream. + +Factor out waiting for async encrypt and decrypt to finish. +There are already multiple copies and a subsequent fix will +need more. No functional changes. + +Note that crypto_wait_req() returns wait->err + +Signed-off-by: Jakub Kicinski +Reviewed-by: Simon Horman +Reviewed-by: Sabrina Dubroca +Signed-off-by: David S. Miller +Stable-dep-of: aec7961916f3 ("tls: fix race between async notify and socket close") +[v5.15: removed changes in tls_sw_splice_eof and adjusted waiting factor out for +async descrypt in tls_sw_recvmsg] +Cc: # 5.15 +Signed-off-by: Shaoying Xu +Signed-off-by: Greg Kroah-Hartman +--- + net/tls/tls_sw.c | 90 +++++++++++++++++++++++++++++-------------------------- + 1 file changed, 49 insertions(+), 41 deletions(-) + +--- a/net/tls/tls_sw.c ++++ b/net/tls/tls_sw.c +@@ -226,6 +226,20 @@ static void tls_decrypt_done(struct cryp + spin_unlock_bh(&ctx->decrypt_compl_lock); + } + ++static int tls_decrypt_async_wait(struct tls_sw_context_rx *ctx) ++{ ++ int pending; ++ ++ spin_lock_bh(&ctx->decrypt_compl_lock); ++ reinit_completion(&ctx->async_wait.completion); ++ pending = atomic_read(&ctx->decrypt_pending); ++ spin_unlock_bh(&ctx->decrypt_compl_lock); ++ if (pending) ++ crypto_wait_req(-EINPROGRESS, &ctx->async_wait); ++ ++ return ctx->async_wait.err; ++} ++ + static int tls_do_decryption(struct sock *sk, + struct sk_buff *skb, + struct scatterlist *sgin, +@@ -496,6 +510,28 @@ static void tls_encrypt_done(struct cryp + schedule_delayed_work(&ctx->tx_work.work, 1); + } + ++static int tls_encrypt_async_wait(struct tls_sw_context_tx *ctx) ++{ ++ int pending; ++ ++ spin_lock_bh(&ctx->encrypt_compl_lock); ++ ctx->async_notify = true; ++ ++ pending = atomic_read(&ctx->encrypt_pending); ++ spin_unlock_bh(&ctx->encrypt_compl_lock); ++ if (pending) ++ crypto_wait_req(-EINPROGRESS, &ctx->async_wait); ++ else ++ reinit_completion(&ctx->async_wait.completion); ++ ++ /* There can be no concurrent accesses, since we have no ++ * pending encrypt operations ++ */ ++ WRITE_ONCE(ctx->async_notify, false); ++ ++ return ctx->async_wait.err; ++} ++ + static int tls_do_encryption(struct sock *sk, + struct tls_context *tls_ctx, + struct tls_sw_context_tx *ctx, +@@ -946,7 +982,6 @@ int tls_sw_sendmsg(struct sock *sk, stru + int num_zc = 0; + int orig_size; + int ret = 0; +- int pending; + + if (msg->msg_flags & ~(MSG_MORE | MSG_DONTWAIT | MSG_NOSIGNAL | + MSG_CMSG_COMPAT)) +@@ -1115,24 +1150,12 @@ trim_sgl: + if (!num_async) { + goto send_end; + } else if (num_zc) { +- /* Wait for pending encryptions to get completed */ +- spin_lock_bh(&ctx->encrypt_compl_lock); +- ctx->async_notify = true; +- +- pending = atomic_read(&ctx->encrypt_pending); +- spin_unlock_bh(&ctx->encrypt_compl_lock); +- if (pending) +- crypto_wait_req(-EINPROGRESS, &ctx->async_wait); +- else +- reinit_completion(&ctx->async_wait.completion); ++ int err; + +- /* There can be no concurrent accesses, since we have no +- * pending encrypt operations +- */ +- WRITE_ONCE(ctx->async_notify, false); +- +- if (ctx->async_wait.err) { +- ret = ctx->async_wait.err; ++ /* Wait for pending encryptions to get completed */ ++ err = tls_encrypt_async_wait(ctx); ++ if (err) { ++ ret = err; + copied = 0; + } + } +@@ -1910,22 +1933,14 @@ pick_next_record: + + recv_end: + if (async) { +- int pending; +- + /* Wait for all previously submitted records to be decrypted */ +- spin_lock_bh(&ctx->decrypt_compl_lock); +- reinit_completion(&ctx->async_wait.completion); +- pending = atomic_read(&ctx->decrypt_pending); +- spin_unlock_bh(&ctx->decrypt_compl_lock); +- if (pending) { +- err = crypto_wait_req(-EINPROGRESS, &ctx->async_wait); +- if (err) { +- /* one of async decrypt failed */ +- tls_err_abort(sk, err); +- copied = 0; +- decrypted = 0; +- goto end; +- } ++ err = tls_decrypt_async_wait(ctx); ++ if (err) { ++ /* one of async decrypt failed */ ++ tls_err_abort(sk, err); ++ copied = 0; ++ decrypted = 0; ++ goto end; + } + + /* Drain records from the rx_list & copy if required */ +@@ -2144,16 +2159,9 @@ void tls_sw_release_resources_tx(struct + struct tls_context *tls_ctx = tls_get_ctx(sk); + struct tls_sw_context_tx *ctx = tls_sw_ctx_tx(tls_ctx); + struct tls_rec *rec, *tmp; +- int pending; + + /* Wait for any pending async encryptions to complete */ +- spin_lock_bh(&ctx->encrypt_compl_lock); +- ctx->async_notify = true; +- pending = atomic_read(&ctx->encrypt_pending); +- spin_unlock_bh(&ctx->encrypt_compl_lock); +- +- if (pending) +- crypto_wait_req(-EINPROGRESS, &ctx->async_wait); ++ tls_encrypt_async_wait(ctx); + + tls_tx_records(sk, -1); + diff --git a/queue-5.15/net-tls-handle-backlogging-of-crypto-requests.patch b/queue-5.15/net-tls-handle-backlogging-of-crypto-requests.patch new file mode 100644 index 00000000000..4de05d87285 --- /dev/null +++ b/queue-5.15/net-tls-handle-backlogging-of-crypto-requests.patch @@ -0,0 +1,91 @@ +From 8590541473188741055d27b955db0777569438e3 Mon Sep 17 00:00:00 2001 +From: Jakub Kicinski +Date: Tue, 6 Feb 2024 17:18:21 -0800 +Subject: net: tls: handle backlogging of crypto requests + +From: Jakub Kicinski + +commit 8590541473188741055d27b955db0777569438e3 upstream. + +Since we're setting the CRYPTO_TFM_REQ_MAY_BACKLOG flag on our +requests to the crypto API, crypto_aead_{encrypt,decrypt} can return + -EBUSY instead of -EINPROGRESS in valid situations. For example, when +the cryptd queue for AESNI is full (easy to trigger with an +artificially low cryptd.cryptd_max_cpu_qlen), requests will be enqueued +to the backlog but still processed. In that case, the async callback +will also be called twice: first with err == -EINPROGRESS, which it +seems we can just ignore, then with err == 0. + +Compared to Sabrina's original patch this version uses the new +tls_*crypt_async_wait() helpers and converts the EBUSY to +EINPROGRESS to avoid having to modify all the error handling +paths. The handling is identical. + +Fixes: a54667f6728c ("tls: Add support for encryption using async offload accelerator") +Fixes: 94524d8fc965 ("net/tls: Add support for async decryption of tls records") +Co-developed-by: Sabrina Dubroca +Signed-off-by: Sabrina Dubroca +Link: https://lore.kernel.org/netdev/9681d1febfec295449a62300938ed2ae66983f28.1694018970.git.sd@queasysnail.net/ +Signed-off-by: Jakub Kicinski +Reviewed-by: Simon Horman +Signed-off-by: David S. Miller +[v5.15: fixed contextual merge-conflicts in tls_decrypt_done and tls_encrypt_done] +Cc: # 5.15 +Signed-off-by: Shaoying Xu +Signed-off-by: Greg Kroah-Hartman +--- + net/tls/tls_sw.c | 22 ++++++++++++++++++++++ + 1 file changed, 22 insertions(+) + +--- a/net/tls/tls_sw.c ++++ b/net/tls/tls_sw.c +@@ -175,6 +175,17 @@ static void tls_decrypt_done(struct cryp + struct sk_buff *skb; + unsigned int pages; + ++ /* If requests get too backlogged crypto API returns -EBUSY and calls ++ * ->complete(-EINPROGRESS) immediately followed by ->complete(0) ++ * to make waiting for backlog to flush with crypto_wait_req() easier. ++ * First wait converts -EBUSY -> -EINPROGRESS, and the second one ++ * -EINPROGRESS -> 0. ++ * We have a single struct crypto_async_request per direction, this ++ * scheme doesn't help us, so just ignore the first ->complete(). ++ */ ++ if (err == -EINPROGRESS) ++ return; ++ + skb = (struct sk_buff *)req->data; + tls_ctx = tls_get_ctx(skb->sk); + ctx = tls_sw_ctx_rx(tls_ctx); +@@ -273,6 +284,10 @@ static int tls_do_decryption(struct sock + } + + ret = crypto_aead_decrypt(aead_req); ++ if (ret == -EBUSY) { ++ ret = tls_decrypt_async_wait(ctx); ++ ret = ret ?: -EINPROGRESS; ++ } + if (ret == -EINPROGRESS) { + if (darg->async) + return 0; +@@ -455,6 +470,9 @@ static void tls_encrypt_done(struct cryp + struct tls_rec *rec; + bool ready = false; + ++ if (err == -EINPROGRESS) /* see the comment in tls_decrypt_done() */ ++ return; ++ + rec = container_of(aead_req, struct tls_rec, aead_req); + msg_en = &rec->msg_encrypted; + +@@ -551,6 +569,10 @@ static int tls_do_encryption(struct sock + atomic_inc(&ctx->encrypt_pending); + + rc = crypto_aead_encrypt(aead_req); ++ if (rc == -EBUSY) { ++ rc = tls_encrypt_async_wait(ctx); ++ rc = rc ?: -EINPROGRESS; ++ } + if (!rc || rc != -EINPROGRESS) { + atomic_dec(&ctx->encrypt_pending); + sge->offset -= prot->prepend_size; diff --git a/queue-5.15/revert-selftests-mm-fix-map_hugetlb-failure-on-64k-page-size-systems.patch b/queue-5.15/revert-selftests-mm-fix-map_hugetlb-failure-on-64k-page-size-systems.patch new file mode 100644 index 00000000000..db2daf9e680 --- /dev/null +++ b/queue-5.15/revert-selftests-mm-fix-map_hugetlb-failure-on-64k-page-size-systems.patch @@ -0,0 +1,53 @@ +From harshit.m.mogalapalli@oracle.com Thu May 23 13:27:11 2024 +From: Harshit Mogalapalli +Date: Mon, 6 May 2024 01:46:35 -0700 +Subject: Revert "selftests: mm: fix map_hugetlb failure on 64K page size systems" +To: stable@vger.kernel.org +Cc: sashal@kernel.org, vegard.nossum@oracle.com, darren.kenny@oracle.com, Harshit Mogalapalli +Message-ID: <20240506084635.2942238-1-harshit.m.mogalapalli@oracle.com> + + +This reverts commit 0d29b474fb90ff35920642f378d9baace9b47edd which is +commit 91b80cc5b39f00399e8e2d17527cad2c7fa535e2 upstream. + +map_hugetlb.c:18:10: fatal error: vm_util.h: No such file or directory + 18 | #include "vm_util.h" + | ^~~~~~~~~~~ +compilation terminated. + +vm_util.h is not present in 5.15.y, as commit:642bc52aed9c ("selftests: +vm: bring common functions to a new file") is not present in stable +kernels <=6.1.y + +Signed-off-by: Harshit Mogalapalli +--- + tools/testing/selftests/vm/map_hugetlb.c | 7 ------- + 1 file changed, 7 deletions(-) + +--- a/tools/testing/selftests/vm/map_hugetlb.c ++++ b/tools/testing/selftests/vm/map_hugetlb.c +@@ -15,7 +15,6 @@ + #include + #include + #include +-#include "vm_util.h" + + #define LENGTH (256UL*1024*1024) + #define PROTECTION (PROT_READ | PROT_WRITE) +@@ -71,16 +70,10 @@ int main(int argc, char **argv) + { + void *addr; + int ret; +- size_t hugepage_size; + size_t length = LENGTH; + int flags = FLAGS; + int shift = 0; + +- hugepage_size = default_huge_page_size(); +- /* munmap with fail if the length is not page aligned */ +- if (hugepage_size > length) +- length = hugepage_size; +- + if (argc > 1) + length = atol(argv[1]) << 20; + if (argc > 2) { diff --git a/queue-5.15/series b/queue-5.15/series index e1ceebb111c..86490018187 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -2,3 +2,11 @@ drm-amd-display-fix-division-by-zero-in-setup_dsc_config.patch pinctrl-core-handle-radix_tree_insert-errors-in-pinctrl_register_one_pin.patch nfsd-don-t-allow-nfsd-threads-to-be-signalled.patch keys-trusted-fix-memory-leak-in-tpm2_key_encode.patch +revert-selftests-mm-fix-map_hugetlb-failure-on-64k-page-size-systems.patch +net-bcmgenet-synchronize-ext_rgmii_oob_ctrl-access.patch +net-bcmgenet-synchronize-umac_cmd-access.patch +tls-rx-simplify-async-wait.patch +tls-extract-context-alloc-initialization-out-of-tls_set_sw_offload.patch +net-tls-factor-out-tls_-crypt_async_wait.patch +tls-fix-race-between-async-notify-and-socket-close.patch +net-tls-handle-backlogging-of-crypto-requests.patch diff --git a/queue-5.15/tls-extract-context-alloc-initialization-out-of-tls_set_sw_offload.patch b/queue-5.15/tls-extract-context-alloc-initialization-out-of-tls_set_sw_offload.patch new file mode 100644 index 00000000000..7130671755e --- /dev/null +++ b/queue-5.15/tls-extract-context-alloc-initialization-out-of-tls_set_sw_offload.patch @@ -0,0 +1,128 @@ +From 615580cbc99af0da2d1c7226fab43a3d5003eb97 Mon Sep 17 00:00:00 2001 +From: Sabrina Dubroca +Date: Mon, 9 Oct 2023 22:50:46 +0200 +Subject: tls: extract context alloc/initialization out of tls_set_sw_offload + +From: Sabrina Dubroca + +commit 615580cbc99af0da2d1c7226fab43a3d5003eb97 upstream. + +Simplify tls_set_sw_offload a bit. + +Signed-off-by: Sabrina Dubroca +Signed-off-by: David S. Miller +Stable-dep-of: aec7961916f3 ("tls: fix race between async notify and socket close") +[v5.15: fixed contextual conflicts from unavailable init_waitqueue_head and +skb_queue_head_init calls in tls_set_sw_offload and init_ctx_rx] +Cc: # 5.15 +Signed-off-by: Shaoying Xu +Signed-off-by: Greg Kroah-Hartman +--- + net/tls/tls_sw.c | 82 ++++++++++++++++++++++++++++++++----------------------- + 1 file changed, 49 insertions(+), 33 deletions(-) + +--- a/net/tls/tls_sw.c ++++ b/net/tls/tls_sw.c +@@ -2291,6 +2291,46 @@ void tls_sw_strparser_arm(struct sock *s + strp_check_rcv(&rx_ctx->strp); + } + ++static struct tls_sw_context_tx *init_ctx_tx(struct tls_context *ctx, struct sock *sk) ++{ ++ struct tls_sw_context_tx *sw_ctx_tx; ++ ++ if (!ctx->priv_ctx_tx) { ++ sw_ctx_tx = kzalloc(sizeof(*sw_ctx_tx), GFP_KERNEL); ++ if (!sw_ctx_tx) ++ return NULL; ++ } else { ++ sw_ctx_tx = ctx->priv_ctx_tx; ++ } ++ ++ crypto_init_wait(&sw_ctx_tx->async_wait); ++ spin_lock_init(&sw_ctx_tx->encrypt_compl_lock); ++ INIT_LIST_HEAD(&sw_ctx_tx->tx_list); ++ INIT_DELAYED_WORK(&sw_ctx_tx->tx_work.work, tx_work_handler); ++ sw_ctx_tx->tx_work.sk = sk; ++ ++ return sw_ctx_tx; ++} ++ ++static struct tls_sw_context_rx *init_ctx_rx(struct tls_context *ctx) ++{ ++ struct tls_sw_context_rx *sw_ctx_rx; ++ ++ if (!ctx->priv_ctx_rx) { ++ sw_ctx_rx = kzalloc(sizeof(*sw_ctx_rx), GFP_KERNEL); ++ if (!sw_ctx_rx) ++ return NULL; ++ } else { ++ sw_ctx_rx = ctx->priv_ctx_rx; ++ } ++ ++ crypto_init_wait(&sw_ctx_rx->async_wait); ++ spin_lock_init(&sw_ctx_rx->decrypt_compl_lock); ++ skb_queue_head_init(&sw_ctx_rx->rx_list); ++ ++ return sw_ctx_rx; ++} ++ + int tls_set_sw_offload(struct sock *sk, struct tls_context *ctx, int tx) + { + struct tls_context *tls_ctx = tls_get_ctx(sk); +@@ -2317,46 +2357,22 @@ int tls_set_sw_offload(struct sock *sk, + } + + if (tx) { +- if (!ctx->priv_ctx_tx) { +- sw_ctx_tx = kzalloc(sizeof(*sw_ctx_tx), GFP_KERNEL); +- if (!sw_ctx_tx) { +- rc = -ENOMEM; +- goto out; +- } +- ctx->priv_ctx_tx = sw_ctx_tx; +- } else { +- sw_ctx_tx = +- (struct tls_sw_context_tx *)ctx->priv_ctx_tx; +- } +- } else { +- if (!ctx->priv_ctx_rx) { +- sw_ctx_rx = kzalloc(sizeof(*sw_ctx_rx), GFP_KERNEL); +- if (!sw_ctx_rx) { +- rc = -ENOMEM; +- goto out; +- } +- ctx->priv_ctx_rx = sw_ctx_rx; +- } else { +- sw_ctx_rx = +- (struct tls_sw_context_rx *)ctx->priv_ctx_rx; +- } +- } ++ ctx->priv_ctx_tx = init_ctx_tx(ctx, sk); ++ if (!ctx->priv_ctx_tx) ++ return -ENOMEM; + +- if (tx) { +- crypto_init_wait(&sw_ctx_tx->async_wait); +- spin_lock_init(&sw_ctx_tx->encrypt_compl_lock); ++ sw_ctx_tx = ctx->priv_ctx_tx; + crypto_info = &ctx->crypto_send.info; + cctx = &ctx->tx; + aead = &sw_ctx_tx->aead_send; +- INIT_LIST_HEAD(&sw_ctx_tx->tx_list); +- INIT_DELAYED_WORK(&sw_ctx_tx->tx_work.work, tx_work_handler); +- sw_ctx_tx->tx_work.sk = sk; + } else { +- crypto_init_wait(&sw_ctx_rx->async_wait); +- spin_lock_init(&sw_ctx_rx->decrypt_compl_lock); ++ ctx->priv_ctx_rx = init_ctx_rx(ctx); ++ if (!ctx->priv_ctx_rx) ++ return -ENOMEM; ++ ++ sw_ctx_rx = ctx->priv_ctx_rx; + crypto_info = &ctx->crypto_recv.info; + cctx = &ctx->rx; +- skb_queue_head_init(&sw_ctx_rx->rx_list); + aead = &sw_ctx_rx->aead_recv; + } + diff --git a/queue-5.15/tls-fix-race-between-async-notify-and-socket-close.patch b/queue-5.15/tls-fix-race-between-async-notify-and-socket-close.patch new file mode 100644 index 00000000000..da5ee5b15f1 --- /dev/null +++ b/queue-5.15/tls-fix-race-between-async-notify-and-socket-close.patch @@ -0,0 +1,169 @@ +From aec7961916f3f9e88766e2688992da6980f11b8d Mon Sep 17 00:00:00 2001 +From: Jakub Kicinski +Date: Tue, 6 Feb 2024 17:18:19 -0800 +Subject: tls: fix race between async notify and socket close + +From: Jakub Kicinski + +commit aec7961916f3f9e88766e2688992da6980f11b8d upstream. + +The submitting thread (one which called recvmsg/sendmsg) +may exit as soon as the async crypto handler calls complete() +so any code past that point risks touching already freed data. + +Try to avoid the locking and extra flags altogether. +Have the main thread hold an extra reference, this way +we can depend solely on the atomic ref counter for +synchronization. + +Don't futz with reiniting the completion, either, we are now +tightly controlling when completion fires. + +Reported-by: valis +Fixes: 0cada33241d9 ("net/tls: fix race condition causing kernel panic") +Signed-off-by: Jakub Kicinski +Reviewed-by: Simon Horman +Reviewed-by: Eric Dumazet +Reviewed-by: Sabrina Dubroca +Signed-off-by: David S. Miller +[v5.15: fixed contextual conflicts in struct tls_sw_context_rx and func +init_ctx_rx; replaced DEBUG_NET_WARN_ON_ONCE with BUILD_BUG_ON_INVALID +since they're equivalent when DEBUG_NET is not defined] +Cc: # 5.15 +Signed-off-by: Shaoying Xu +Signed-off-by: Greg Kroah-Hartman +--- + include/net/tls.h | 5 ----- + net/tls/tls_sw.c | 43 ++++++++++--------------------------------- + 2 files changed, 10 insertions(+), 38 deletions(-) + +--- a/include/net/tls.h ++++ b/include/net/tls.h +@@ -128,9 +128,6 @@ struct tls_sw_context_tx { + struct tls_rec *open_rec; + struct list_head tx_list; + atomic_t encrypt_pending; +- /* protect crypto_wait with encrypt_pending */ +- spinlock_t encrypt_compl_lock; +- int async_notify; + u8 async_capable:1; + + #define BIT_TX_SCHEDULED 0 +@@ -148,8 +145,6 @@ struct tls_sw_context_rx { + struct sk_buff *recv_pkt; + u8 async_capable:1; + atomic_t decrypt_pending; +- /* protect crypto_wait with decrypt_pending*/ +- spinlock_t decrypt_compl_lock; + }; + + struct tls_record_info { +--- a/net/tls/tls_sw.c ++++ b/net/tls/tls_sw.c +@@ -220,22 +220,15 @@ static void tls_decrypt_done(struct cryp + + kfree(aead_req); + +- spin_lock_bh(&ctx->decrypt_compl_lock); +- if (!atomic_dec_return(&ctx->decrypt_pending)) ++ if (atomic_dec_and_test(&ctx->decrypt_pending)) + complete(&ctx->async_wait.completion); +- spin_unlock_bh(&ctx->decrypt_compl_lock); + } + + static int tls_decrypt_async_wait(struct tls_sw_context_rx *ctx) + { +- int pending; +- +- spin_lock_bh(&ctx->decrypt_compl_lock); +- reinit_completion(&ctx->async_wait.completion); +- pending = atomic_read(&ctx->decrypt_pending); +- spin_unlock_bh(&ctx->decrypt_compl_lock); +- if (pending) ++ if (!atomic_dec_and_test(&ctx->decrypt_pending)) + crypto_wait_req(-EINPROGRESS, &ctx->async_wait); ++ atomic_inc(&ctx->decrypt_pending); + + return ctx->async_wait.err; + } +@@ -271,6 +264,7 @@ static int tls_do_decryption(struct sock + aead_request_set_callback(aead_req, + CRYPTO_TFM_REQ_MAY_BACKLOG, + tls_decrypt_done, skb); ++ BUILD_BUG_ON_INVALID(atomic_read(&ctx->decrypt_pending) < 1); + atomic_inc(&ctx->decrypt_pending); + } else { + aead_request_set_callback(aead_req, +@@ -460,7 +454,6 @@ static void tls_encrypt_done(struct cryp + struct sk_msg *msg_en; + struct tls_rec *rec; + bool ready = false; +- int pending; + + rec = container_of(aead_req, struct tls_rec, aead_req); + msg_en = &rec->msg_encrypted; +@@ -495,12 +488,8 @@ static void tls_encrypt_done(struct cryp + ready = true; + } + +- spin_lock_bh(&ctx->encrypt_compl_lock); +- pending = atomic_dec_return(&ctx->encrypt_pending); +- +- if (!pending && ctx->async_notify) ++ if (atomic_dec_and_test(&ctx->encrypt_pending)) + complete(&ctx->async_wait.completion); +- spin_unlock_bh(&ctx->encrypt_compl_lock); + + if (!ready) + return; +@@ -512,22 +501,9 @@ static void tls_encrypt_done(struct cryp + + static int tls_encrypt_async_wait(struct tls_sw_context_tx *ctx) + { +- int pending; +- +- spin_lock_bh(&ctx->encrypt_compl_lock); +- ctx->async_notify = true; +- +- pending = atomic_read(&ctx->encrypt_pending); +- spin_unlock_bh(&ctx->encrypt_compl_lock); +- if (pending) ++ if (!atomic_dec_and_test(&ctx->encrypt_pending)) + crypto_wait_req(-EINPROGRESS, &ctx->async_wait); +- else +- reinit_completion(&ctx->async_wait.completion); +- +- /* There can be no concurrent accesses, since we have no +- * pending encrypt operations +- */ +- WRITE_ONCE(ctx->async_notify, false); ++ atomic_inc(&ctx->encrypt_pending); + + return ctx->async_wait.err; + } +@@ -571,6 +547,7 @@ static int tls_do_encryption(struct sock + + /* Add the record in tx_list */ + list_add_tail((struct list_head *)&rec->list, &ctx->tx_list); ++ BUILD_BUG_ON_INVALID(atomic_read(&ctx->encrypt_pending) < 1); + atomic_inc(&ctx->encrypt_pending); + + rc = crypto_aead_encrypt(aead_req); +@@ -2312,7 +2289,7 @@ static struct tls_sw_context_tx *init_ct + } + + crypto_init_wait(&sw_ctx_tx->async_wait); +- spin_lock_init(&sw_ctx_tx->encrypt_compl_lock); ++ atomic_set(&sw_ctx_tx->encrypt_pending, 1); + INIT_LIST_HEAD(&sw_ctx_tx->tx_list); + INIT_DELAYED_WORK(&sw_ctx_tx->tx_work.work, tx_work_handler); + sw_ctx_tx->tx_work.sk = sk; +@@ -2333,7 +2310,7 @@ static struct tls_sw_context_rx *init_ct + } + + crypto_init_wait(&sw_ctx_rx->async_wait); +- spin_lock_init(&sw_ctx_rx->decrypt_compl_lock); ++ atomic_set(&sw_ctx_rx->decrypt_pending, 1); + skb_queue_head_init(&sw_ctx_rx->rx_list); + + return sw_ctx_rx; diff --git a/queue-5.15/tls-rx-simplify-async-wait.patch b/queue-5.15/tls-rx-simplify-async-wait.patch new file mode 100644 index 00000000000..79d713a5bce --- /dev/null +++ b/queue-5.15/tls-rx-simplify-async-wait.patch @@ -0,0 +1,79 @@ +From 37943f047bfb88ba4dfc7a522563f57c86d088a0 Mon Sep 17 00:00:00 2001 +From: Jakub Kicinski +Date: Fri, 8 Apr 2022 11:31:27 -0700 +Subject: tls: rx: simplify async wait + +From: Jakub Kicinski + +commit 37943f047bfb88ba4dfc7a522563f57c86d088a0 upstream. + +Since we are protected from async completions by decrypt_compl_lock +we can drop the async_notify and reinit the completion before we +start waiting. + +Signed-off-by: Jakub Kicinski +Signed-off-by: David S. Miller +Stable-dep-of: aec7961916f3 ("tls: fix race between async notify and socket close") +Signed-off-by: Shaoying Xu +Signed-off-by: Greg Kroah-Hartman +--- + include/net/tls.h | 1 - + net/tls/tls_sw.c | 14 ++------------ + 2 files changed, 2 insertions(+), 13 deletions(-) + +--- a/include/net/tls.h ++++ b/include/net/tls.h +@@ -150,7 +150,6 @@ struct tls_sw_context_rx { + atomic_t decrypt_pending; + /* protect crypto_wait with decrypt_pending*/ + spinlock_t decrypt_compl_lock; +- bool async_notify; + }; + + struct tls_record_info { +--- a/net/tls/tls_sw.c ++++ b/net/tls/tls_sw.c +@@ -174,7 +174,6 @@ static void tls_decrypt_done(struct cryp + struct scatterlist *sg; + struct sk_buff *skb; + unsigned int pages; +- int pending; + + skb = (struct sk_buff *)req->data; + tls_ctx = tls_get_ctx(skb->sk); +@@ -222,9 +221,7 @@ static void tls_decrypt_done(struct cryp + kfree(aead_req); + + spin_lock_bh(&ctx->decrypt_compl_lock); +- pending = atomic_dec_return(&ctx->decrypt_pending); +- +- if (!pending && ctx->async_notify) ++ if (!atomic_dec_return(&ctx->decrypt_pending)) + complete(&ctx->async_wait.completion); + spin_unlock_bh(&ctx->decrypt_compl_lock); + } +@@ -1917,7 +1914,7 @@ recv_end: + + /* Wait for all previously submitted records to be decrypted */ + spin_lock_bh(&ctx->decrypt_compl_lock); +- ctx->async_notify = true; ++ reinit_completion(&ctx->async_wait.completion); + pending = atomic_read(&ctx->decrypt_pending); + spin_unlock_bh(&ctx->decrypt_compl_lock); + if (pending) { +@@ -1929,15 +1926,8 @@ recv_end: + decrypted = 0; + goto end; + } +- } else { +- reinit_completion(&ctx->async_wait.completion); + } + +- /* There can be no concurrent accesses, since we have no +- * pending decrypt operations +- */ +- WRITE_ONCE(ctx->async_notify, false); +- + /* Drain records from the rx_list & copy if required */ + if (is_peek || is_kvec) + err = process_rx_list(ctx, msg, &control, copied,