From: Sasha Levin Date: Mon, 1 Jan 2024 18:11:06 +0000 (-0500) Subject: Fixes for 5.10 X-Git-Tag: v5.10.206~30 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7da0e03cb8c95a7619ba824015818ab73da5fd9a;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 5.10 Signed-off-by: Sasha Levin --- diff --git a/queue-5.10/arm-dts-fix-occasional-boot-hang-for-am3-usb.patch b/queue-5.10/arm-dts-fix-occasional-boot-hang-for-am3-usb.patch new file mode 100644 index 00000000000..7eec60de183 --- /dev/null +++ b/queue-5.10/arm-dts-fix-occasional-boot-hang-for-am3-usb.patch @@ -0,0 +1,40 @@ +From adecb7fe6e1f69765eac56bd6a648a855717a747 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 12 Dec 2023 15:50:35 +0200 +Subject: ARM: dts: Fix occasional boot hang for am3 usb + +From: Tony Lindgren + +[ Upstream commit 9b6a51aab5f5f9f71d2fa16e8b4d530e1643dfcb ] + +With subtle timings changes, we can now sometimes get an external abort on +non-linefetch error booting am3 devices at sysc_reset(). This is because +of a missing reset delay needed for the usb target module. + +Looks like we never enabled the delay earlier for am3, although a similar +issue was seen earlier with a similar usb setup for dm814x as described in +commit ebf244148092 ("ARM: OMAP2+: Use srst_udelay for USB on dm814x"). + +Cc: stable@vger.kernel.org +Fixes: 0782e8572ce4 ("ARM: dts: Probe am335x musb with ti-sysc") +Signed-off-by: Tony Lindgren +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/am33xx.dtsi | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi +index f09a61cac2dc9..3d064eb290997 100644 +--- a/arch/arm/boot/dts/am33xx.dtsi ++++ b/arch/arm/boot/dts/am33xx.dtsi +@@ -347,6 +347,7 @@ usb: target-module@47400000 { + , + , + ; ++ ti,sysc-delay-us = <2>; + clocks = <&l3s_clkctrl AM3_L3S_USB_OTG_HS_CLKCTRL 0>; + clock-names = "fck"; + #address-cells = <1>; +-- +2.43.0 + diff --git a/queue-5.10/bluetooth-af_bluetooth-fix-use-after-free-in-bt_sock.patch b/queue-5.10/bluetooth-af_bluetooth-fix-use-after-free-in-bt_sock.patch new file mode 100644 index 00000000000..21c12d3786e --- /dev/null +++ b/queue-5.10/bluetooth-af_bluetooth-fix-use-after-free-in-bt_sock.patch @@ -0,0 +1,60 @@ +From f888fc7421c35c4746469250188e4a395bc654a3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 9 Dec 2023 05:55:18 -0500 +Subject: Bluetooth: af_bluetooth: Fix Use-After-Free in bt_sock_recvmsg + +From: Hyunwoo Kim + +[ Upstream commit 2e07e8348ea454615e268222ae3fc240421be768 ] + +This can cause a race with bt_sock_ioctl() because +bt_sock_recvmsg() gets the skb from sk->sk_receive_queue +and then frees it without holding lock_sock. +A use-after-free for a skb occurs with the following flow. +``` +bt_sock_recvmsg() -> skb_recv_datagram() -> skb_free_datagram() +bt_sock_ioctl() -> skb_peek() +``` +Add lock_sock to bt_sock_recvmsg() to fix this issue. + +Cc: stable@vger.kernel.org +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Hyunwoo Kim +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + net/bluetooth/af_bluetooth.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c +index 2f87f57e7a4fd..14a917e70f3ee 100644 +--- a/net/bluetooth/af_bluetooth.c ++++ b/net/bluetooth/af_bluetooth.c +@@ -263,11 +263,14 @@ int bt_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, + if (flags & MSG_OOB) + return -EOPNOTSUPP; + ++ lock_sock(sk); ++ + skb = skb_recv_datagram(sk, flags, noblock, &err); + if (!skb) { + if (sk->sk_shutdown & RCV_SHUTDOWN) +- return 0; ++ err = 0; + ++ release_sock(sk); + return err; + } + +@@ -293,6 +296,8 @@ int bt_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, + + skb_free_datagram(sk, skb); + ++ release_sock(sk); ++ + if (flags & MSG_TRUNC) + copied = skblen; + +-- +2.43.0 + diff --git a/queue-5.10/bluetooth-mgmt-smp-fix-address-type-when-using-smp-o.patch b/queue-5.10/bluetooth-mgmt-smp-fix-address-type-when-using-smp-o.patch new file mode 100644 index 00000000000..42babd44738 --- /dev/null +++ b/queue-5.10/bluetooth-mgmt-smp-fix-address-type-when-using-smp-o.patch @@ -0,0 +1,265 @@ +From 7636c9fd1b65c72bf332e2dd4bf090a937000c81 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 12 Dec 2023 00:27:18 +0800 +Subject: Bluetooth: MGMT/SMP: Fix address type when using SMP over BREDR/LE + +From: Xiao Yao + +[ Upstream commit 59b047bc98084f8af2c41483e4d68a5adf2fa7f7 ] + +If two Bluetooth devices both support BR/EDR and BLE, and also +support Secure Connections, then they only need to pair once. +The LTK generated during the LE pairing process may be converted +into a BR/EDR link key for BR/EDR transport, and conversely, a +link key generated during the BR/EDR SSP pairing process can be +converted into an LTK for LE transport. Hence, the link type of +the link key and LTK is not fixed, they can be either an LE LINK +or an ACL LINK. + +Currently, in the mgmt_new_irk/ltk/crsk/link_key functions, the +link type is fixed, which could lead to incorrect address types +being reported to the application layer. Therefore, it is necessary +to add link_type/addr_type to the smp_irk/ltk/crsk and link_key, +to ensure the generation of the correct address type. + +SMP over BREDR: +Before Fix: +> ACL Data RX: Handle 11 flags 0x02 dlen 12 + BR/EDR SMP: Identity Address Information (0x09) len 7 + Address: F8:7D:76:F2:12:F3 (OUI F8-7D-76) +@ MGMT Event: New Identity Resolving Key (0x0018) plen 30 + Random address: 00:00:00:00:00:00 (Non-Resolvable) + LE Address: F8:7D:76:F2:12:F3 (OUI F8-7D-76) +@ MGMT Event: New Long Term Key (0x000a) plen 37 + LE Address: F8:7D:76:F2:12:F3 (OUI F8-7D-76) + Key type: Authenticated key from P-256 (0x03) + +After Fix: +> ACL Data RX: Handle 11 flags 0x02 dlen 12 + BR/EDR SMP: Identity Address Information (0x09) len 7 + Address: F8:7D:76:F2:12:F3 (OUI F8-7D-76) +@ MGMT Event: New Identity Resolving Key (0x0018) plen 30 + Random address: 00:00:00:00:00:00 (Non-Resolvable) + BR/EDR Address: F8:7D:76:F2:12:F3 (OUI F8-7D-76) +@ MGMT Event: New Long Term Key (0x000a) plen 37 + BR/EDR Address: F8:7D:76:F2:12:F3 (OUI F8-7D-76) + Key type: Authenticated key from P-256 (0x03) + +SMP over LE: +Before Fix: +@ MGMT Event: New Identity Resolving Key (0x0018) plen 30 + Random address: 5F:5C:07:37:47:D5 (Resolvable) + LE Address: F8:7D:76:F2:12:F3 (OUI F8-7D-76) +@ MGMT Event: New Long Term Key (0x000a) plen 37 + LE Address: F8:7D:76:F2:12:F3 (OUI F8-7D-76) + Key type: Authenticated key from P-256 (0x03) +@ MGMT Event: New Link Key (0x0009) plen 26 + BR/EDR Address: F8:7D:76:F2:12:F3 (OUI F8-7D-76) + Key type: Authenticated Combination key from P-256 (0x08) + +After Fix: +@ MGMT Event: New Identity Resolving Key (0x0018) plen 30 + Random address: 5E:03:1C:00:38:21 (Resolvable) + LE Address: F8:7D:76:F2:12:F3 (OUI F8-7D-76) +@ MGMT Event: New Long Term Key (0x000a) plen 37 + LE Address: F8:7D:76:F2:12:F3 (OUI F8-7D-76) + Key type: Authenticated key from P-256 (0x03) +@ MGMT Event: New Link Key (0x0009) plen 26 + Store hint: Yes (0x01) + LE Address: F8:7D:76:F2:12:F3 (OUI F8-7D-76) + Key type: Authenticated Combination key from P-256 (0x08) + +Cc: stable@vger.kernel.org +Signed-off-by: Xiao Yao +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + include/net/bluetooth/hci_core.h | 5 +++++ + net/bluetooth/mgmt.c | 25 ++++++++++++++++++------- + net/bluetooth/smp.c | 7 +++++++ + 3 files changed, 30 insertions(+), 7 deletions(-) + +diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h +index e33433ec4a98f..a168a64696b6b 100644 +--- a/include/net/bluetooth/hci_core.h ++++ b/include/net/bluetooth/hci_core.h +@@ -174,6 +174,7 @@ struct blocked_key { + struct smp_csrk { + bdaddr_t bdaddr; + u8 bdaddr_type; ++ u8 link_type; + u8 type; + u8 val[16]; + }; +@@ -183,6 +184,7 @@ struct smp_ltk { + struct rcu_head rcu; + bdaddr_t bdaddr; + u8 bdaddr_type; ++ u8 link_type; + u8 authenticated; + u8 type; + u8 enc_size; +@@ -197,6 +199,7 @@ struct smp_irk { + bdaddr_t rpa; + bdaddr_t bdaddr; + u8 addr_type; ++ u8 link_type; + u8 val[16]; + }; + +@@ -204,6 +207,8 @@ struct link_key { + struct list_head list; + struct rcu_head rcu; + bdaddr_t bdaddr; ++ u8 bdaddr_type; ++ u8 link_type; + u8 type; + u8 val[HCI_LINK_KEY_SIZE]; + u8 pin_len; +diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c +index c62ea4c954645..bd8cfcfca7aef 100644 +--- a/net/bluetooth/mgmt.c ++++ b/net/bluetooth/mgmt.c +@@ -2373,7 +2373,8 @@ static int load_link_keys(struct sock *sk, struct hci_dev *hdev, void *data, + for (i = 0; i < key_count; i++) { + struct mgmt_link_key_info *key = &cp->keys[i]; + +- if (key->addr.type != BDADDR_BREDR || key->type > 0x08) ++ /* Considering SMP over BREDR/LE, there is no need to check addr_type */ ++ if (key->type > 0x08) + return mgmt_cmd_status(sk, hdev->id, + MGMT_OP_LOAD_LINK_KEYS, + MGMT_STATUS_INVALID_PARAMS); +@@ -5914,6 +5915,7 @@ static int load_irks(struct sock *sk, struct hci_dev *hdev, void *cp_data, + + for (i = 0; i < irk_count; i++) { + struct mgmt_irk_info *irk = &cp->irks[i]; ++ u8 addr_type = le_addr_type(irk->addr.type); + + if (hci_is_blocked_key(hdev, + HCI_BLOCKED_KEY_TYPE_IRK, +@@ -5923,8 +5925,12 @@ static int load_irks(struct sock *sk, struct hci_dev *hdev, void *cp_data, + continue; + } + ++ /* When using SMP over BR/EDR, the addr type should be set to BREDR */ ++ if (irk->addr.type == BDADDR_BREDR) ++ addr_type = BDADDR_BREDR; ++ + hci_add_irk(hdev, &irk->addr.bdaddr, +- le_addr_type(irk->addr.type), irk->val, ++ addr_type, irk->val, + BDADDR_ANY); + } + +@@ -6005,6 +6011,7 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev, + for (i = 0; i < key_count; i++) { + struct mgmt_ltk_info *key = &cp->keys[i]; + u8 type, authenticated; ++ u8 addr_type = le_addr_type(key->addr.type); + + if (hci_is_blocked_key(hdev, + HCI_BLOCKED_KEY_TYPE_LTK, +@@ -6039,8 +6046,12 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev, + continue; + } + ++ /* When using SMP over BR/EDR, the addr type should be set to BREDR */ ++ if (key->addr.type == BDADDR_BREDR) ++ addr_type = BDADDR_BREDR; ++ + hci_add_ltk(hdev, &key->addr.bdaddr, +- le_addr_type(key->addr.type), type, authenticated, ++ addr_type, type, authenticated, + key->val, key->enc_size, key->ediv, key->rand); + } + +@@ -8043,7 +8054,7 @@ void mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key, + + ev.store_hint = persistent; + bacpy(&ev.key.addr.bdaddr, &key->bdaddr); +- ev.key.addr.type = BDADDR_BREDR; ++ ev.key.addr.type = link_to_bdaddr(key->link_type, key->bdaddr_type); + ev.key.type = key->type; + memcpy(ev.key.val, key->val, HCI_LINK_KEY_SIZE); + ev.key.pin_len = key->pin_len; +@@ -8094,7 +8105,7 @@ void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, bool persistent) + ev.store_hint = persistent; + + bacpy(&ev.key.addr.bdaddr, &key->bdaddr); +- ev.key.addr.type = link_to_bdaddr(LE_LINK, key->bdaddr_type); ++ ev.key.addr.type = link_to_bdaddr(key->link_type, key->bdaddr_type); + ev.key.type = mgmt_ltk_type(key); + ev.key.enc_size = key->enc_size; + ev.key.ediv = key->ediv; +@@ -8123,7 +8134,7 @@ void mgmt_new_irk(struct hci_dev *hdev, struct smp_irk *irk, bool persistent) + + bacpy(&ev.rpa, &irk->rpa); + bacpy(&ev.irk.addr.bdaddr, &irk->bdaddr); +- ev.irk.addr.type = link_to_bdaddr(LE_LINK, irk->addr_type); ++ ev.irk.addr.type = link_to_bdaddr(irk->link_type, irk->addr_type); + memcpy(ev.irk.val, irk->val, sizeof(irk->val)); + + mgmt_event(MGMT_EV_NEW_IRK, hdev, &ev, sizeof(ev), NULL); +@@ -8152,7 +8163,7 @@ void mgmt_new_csrk(struct hci_dev *hdev, struct smp_csrk *csrk, + ev.store_hint = persistent; + + bacpy(&ev.key.addr.bdaddr, &csrk->bdaddr); +- ev.key.addr.type = link_to_bdaddr(LE_LINK, csrk->bdaddr_type); ++ ev.key.addr.type = link_to_bdaddr(csrk->link_type, csrk->bdaddr_type); + ev.key.type = csrk->type; + memcpy(ev.key.val, csrk->val, sizeof(csrk->val)); + +diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c +index af6cc2e8c0284..0a95ccb160181 100644 +--- a/net/bluetooth/smp.c ++++ b/net/bluetooth/smp.c +@@ -1059,6 +1059,7 @@ static void smp_notify_keys(struct l2cap_conn *conn) + } + + if (smp->remote_irk) { ++ smp->remote_irk->link_type = hcon->type; + mgmt_new_irk(hdev, smp->remote_irk, persistent); + + /* Now that user space can be considered to know the +@@ -1073,24 +1074,28 @@ static void smp_notify_keys(struct l2cap_conn *conn) + } + + if (smp->csrk) { ++ smp->csrk->link_type = hcon->type; + smp->csrk->bdaddr_type = hcon->dst_type; + bacpy(&smp->csrk->bdaddr, &hcon->dst); + mgmt_new_csrk(hdev, smp->csrk, persistent); + } + + if (smp->responder_csrk) { ++ smp->responder_csrk->link_type = hcon->type; + smp->responder_csrk->bdaddr_type = hcon->dst_type; + bacpy(&smp->responder_csrk->bdaddr, &hcon->dst); + mgmt_new_csrk(hdev, smp->responder_csrk, persistent); + } + + if (smp->ltk) { ++ smp->ltk->link_type = hcon->type; + smp->ltk->bdaddr_type = hcon->dst_type; + bacpy(&smp->ltk->bdaddr, &hcon->dst); + mgmt_new_ltk(hdev, smp->ltk, persistent); + } + + if (smp->responder_ltk) { ++ smp->responder_ltk->link_type = hcon->type; + smp->responder_ltk->bdaddr_type = hcon->dst_type; + bacpy(&smp->responder_ltk->bdaddr, &hcon->dst); + mgmt_new_ltk(hdev, smp->responder_ltk, persistent); +@@ -1110,6 +1115,8 @@ static void smp_notify_keys(struct l2cap_conn *conn) + key = hci_add_link_key(hdev, smp->conn->hcon, &hcon->dst, + smp->link_key, type, 0, &persistent); + if (key) { ++ key->link_type = hcon->type; ++ key->bdaddr_type = hcon->dst_type; + mgmt_new_link_key(hdev, key, persistent); + + /* Don't keep debug keys around if the relevant +-- +2.43.0 + diff --git a/queue-5.10/bluetooth-smp-convert-bt_err-bt_dbg-to-bt_dev_err-bt.patch b/queue-5.10/bluetooth-smp-convert-bt_err-bt_dbg-to-bt_dev_err-bt.patch new file mode 100644 index 00000000000..d89a4c785d9 --- /dev/null +++ b/queue-5.10/bluetooth-smp-convert-bt_err-bt_dbg-to-bt_dev_err-bt.patch @@ -0,0 +1,448 @@ +From 121a11a0995838bb8bbd3070156625e7ecc9eaeb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 15 Mar 2021 14:39:29 -0700 +Subject: Bluetooth: SMP: Convert BT_ERR/BT_DBG to bt_dev_err/bt_dev_dbg + +From: Luiz Augusto von Dentz + +[ Upstream commit 2e1614f7d61e407f1a8e7935a2903a6fa3cb0b11 ] + +This converts instances of BT_ERR and BT_DBG to bt_dev_err and +bt_dev_dbg which can be enabled at runtime when BT_FEATURE_DEBUG is +enabled. + +Note: Not all instances could be converted as some are exercised by +selftest. + +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Marcel Holtmann +Stable-dep-of: 59b047bc9808 ("Bluetooth: MGMT/SMP: Fix address type when using SMP over BREDR/LE") +Signed-off-by: Sasha Levin +--- + net/bluetooth/smp.c | 98 ++++++++++++++++++++++++--------------------- + 1 file changed, 52 insertions(+), 46 deletions(-) + +diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c +index b7374dbee23a3..1c1dc2d2b7d59 100644 +--- a/net/bluetooth/smp.c ++++ b/net/bluetooth/smp.c +@@ -596,7 +596,7 @@ static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data) + if (!chan) + return; + +- BT_DBG("code 0x%2.2x", code); ++ bt_dev_dbg(conn->hcon->hdev, "code 0x%2.2x", code); + + iv[0].iov_base = &code; + iv[0].iov_len = 1; +@@ -860,7 +860,8 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth, + memset(smp->tk, 0, sizeof(smp->tk)); + clear_bit(SMP_FLAG_TK_VALID, &smp->flags); + +- BT_DBG("tk_request: auth:%d lcl:%d rem:%d", auth, local_io, remote_io); ++ bt_dev_dbg(hcon->hdev, "auth:%d lcl:%d rem:%d", auth, local_io, ++ remote_io); + + /* If neither side wants MITM, either "just" confirm an incoming + * request or use just-works for outgoing ones. The JUST_CFM +@@ -925,7 +926,7 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth, + get_random_bytes(&passkey, sizeof(passkey)); + passkey %= 1000000; + put_unaligned_le32(passkey, smp->tk); +- BT_DBG("PassKey: %d", passkey); ++ bt_dev_dbg(hcon->hdev, "PassKey: %d", passkey); + set_bit(SMP_FLAG_TK_VALID, &smp->flags); + } + +@@ -950,7 +951,7 @@ static u8 smp_confirm(struct smp_chan *smp) + struct smp_cmd_pairing_confirm cp; + int ret; + +- BT_DBG("conn %p", conn); ++ bt_dev_dbg(conn->hcon->hdev, "conn %p", conn); + + ret = smp_c1(smp->tk, smp->prnd, smp->preq, smp->prsp, + conn->hcon->init_addr_type, &conn->hcon->init_addr, +@@ -978,7 +979,8 @@ static u8 smp_random(struct smp_chan *smp) + u8 confirm[16]; + int ret; + +- BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave"); ++ bt_dev_dbg(conn->hcon->hdev, "conn %p %s", conn, ++ conn->hcon->out ? "master" : "slave"); + + ret = smp_c1(smp->tk, smp->rrnd, smp->preq, smp->prsp, + hcon->init_addr_type, &hcon->init_addr, +@@ -1237,7 +1239,7 @@ static void smp_distribute_keys(struct smp_chan *smp) + struct hci_dev *hdev = hcon->hdev; + __u8 *keydist; + +- BT_DBG("conn %p", conn); ++ bt_dev_dbg(hdev, "conn %p", conn); + + rsp = (void *) &smp->prsp[1]; + +@@ -1267,7 +1269,7 @@ static void smp_distribute_keys(struct smp_chan *smp) + *keydist &= ~SMP_SC_NO_DIST; + } + +- BT_DBG("keydist 0x%x", *keydist); ++ bt_dev_dbg(hdev, "keydist 0x%x", *keydist); + + if (*keydist & SMP_DIST_ENC_KEY) { + struct smp_cmd_encrypt_info enc; +@@ -1367,13 +1369,14 @@ static void smp_timeout(struct work_struct *work) + security_timer.work); + struct l2cap_conn *conn = smp->conn; + +- BT_DBG("conn %p", conn); ++ bt_dev_dbg(conn->hcon->hdev, "conn %p", conn); + + hci_disconnect(conn->hcon, HCI_ERROR_REMOTE_USER_TERM); + } + + static struct smp_chan *smp_chan_create(struct l2cap_conn *conn) + { ++ struct hci_conn *hcon = conn->hcon; + struct l2cap_chan *chan = conn->smp; + struct smp_chan *smp; + +@@ -1383,13 +1386,13 @@ static struct smp_chan *smp_chan_create(struct l2cap_conn *conn) + + smp->tfm_cmac = crypto_alloc_shash("cmac(aes)", 0, 0); + if (IS_ERR(smp->tfm_cmac)) { +- BT_ERR("Unable to create CMAC crypto context"); ++ bt_dev_err(hcon->hdev, "Unable to create CMAC crypto context"); + goto zfree_smp; + } + + smp->tfm_ecdh = crypto_alloc_kpp("ecdh", 0, 0); + if (IS_ERR(smp->tfm_ecdh)) { +- BT_ERR("Unable to create ECDH crypto context"); ++ bt_dev_err(hcon->hdev, "Unable to create ECDH crypto context"); + goto free_shash; + } + +@@ -1400,7 +1403,7 @@ static struct smp_chan *smp_chan_create(struct l2cap_conn *conn) + + INIT_DELAYED_WORK(&smp->security_timer, smp_timeout); + +- hci_conn_hold(conn->hcon); ++ hci_conn_hold(hcon); + + return smp; + +@@ -1565,8 +1568,8 @@ static u8 sc_passkey_round(struct smp_chan *smp, u8 smp_op) + if (!hcon->out) + return 0; + +- BT_DBG("%s Starting passkey round %u", hdev->name, +- smp->passkey_round + 1); ++ bt_dev_dbg(hdev, "Starting passkey round %u", ++ smp->passkey_round + 1); + + SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM); + +@@ -1626,7 +1629,7 @@ int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey) + u32 value; + int err; + +- BT_DBG(""); ++ bt_dev_dbg(conn->hcon->hdev, ""); + + if (!conn) + return -ENOTCONN; +@@ -1652,7 +1655,7 @@ int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey) + case MGMT_OP_USER_PASSKEY_REPLY: + value = le32_to_cpu(passkey); + memset(smp->tk, 0, sizeof(smp->tk)); +- BT_DBG("PassKey: %d", value); ++ bt_dev_dbg(conn->hcon->hdev, "PassKey: %d", value); + put_unaligned_le32(value, smp->tk); + fallthrough; + case MGMT_OP_USER_CONFIRM_REPLY: +@@ -1734,7 +1737,7 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb) + u8 key_size, auth, sec_level; + int ret; + +- BT_DBG("conn %p", conn); ++ bt_dev_dbg(hdev, "conn %p", conn); + + if (skb->len < sizeof(*req)) + return SMP_INVALID_PARAMS; +@@ -1888,7 +1891,7 @@ static u8 sc_send_public_key(struct smp_chan *smp) + } + + if (hci_dev_test_flag(hdev, HCI_USE_DEBUG_KEYS)) { +- BT_DBG("Using debug keys"); ++ bt_dev_dbg(hdev, "Using debug keys"); + if (set_ecdh_privkey(smp->tfm_ecdh, debug_sk)) + return SMP_UNSPECIFIED; + memcpy(smp->local_pk, debug_pk, 64); +@@ -1925,7 +1928,7 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) + u8 key_size, auth; + int ret; + +- BT_DBG("conn %p", conn); ++ bt_dev_dbg(hdev, "conn %p", conn); + + if (skb->len < sizeof(*rsp)) + return SMP_INVALID_PARAMS; +@@ -2020,7 +2023,7 @@ static u8 sc_check_confirm(struct smp_chan *smp) + { + struct l2cap_conn *conn = smp->conn; + +- BT_DBG(""); ++ bt_dev_dbg(conn->hcon->hdev, ""); + + if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY) + return sc_passkey_round(smp, SMP_CMD_PAIRING_CONFIRM); +@@ -2079,8 +2082,10 @@ static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb) + { + struct l2cap_chan *chan = conn->smp; + struct smp_chan *smp = chan->data; ++ struct hci_conn *hcon = conn->hcon; ++ struct hci_dev *hdev = hcon->hdev; + +- BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave"); ++ bt_dev_dbg(hdev, "conn %p %s", conn, hcon->out ? "master" : "slave"); + + if (skb->len < sizeof(smp->pcnf)) + return SMP_INVALID_PARAMS; +@@ -2095,7 +2100,7 @@ static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb) + if (test_bit(SMP_FLAG_REMOTE_PK, &smp->flags)) + return sc_check_confirm(smp); + +- BT_ERR("Unexpected SMP Pairing Confirm"); ++ bt_dev_err(hdev, "Unexpected SMP Pairing Confirm"); + + ret = fixup_sc_false_positive(smp); + if (ret) +@@ -2126,7 +2131,7 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb) + u32 passkey; + int err; + +- BT_DBG("conn %p", conn); ++ bt_dev_dbg(hcon->hdev, "conn %p", conn); + + if (skb->len < sizeof(smp->rrnd)) + return SMP_INVALID_PARAMS; +@@ -2285,7 +2290,7 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb) + struct smp_chan *smp; + u8 sec_level, auth; + +- BT_DBG("conn %p", conn); ++ bt_dev_dbg(hdev, "conn %p", conn); + + if (skb->len < sizeof(*rp)) + return SMP_INVALID_PARAMS; +@@ -2348,7 +2353,8 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level) + __u8 authreq; + int ret; + +- BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level); ++ bt_dev_dbg(hcon->hdev, "conn %p hcon %p level 0x%2.2x", conn, hcon, ++ sec_level); + + /* This may be NULL if there's an unexpected disconnection */ + if (!conn) +@@ -2484,7 +2490,7 @@ static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb) + struct l2cap_chan *chan = conn->smp; + struct smp_chan *smp = chan->data; + +- BT_DBG("conn %p", conn); ++ bt_dev_dbg(conn->hcon->hdev, "conn %p", conn); + + if (skb->len < sizeof(*rp)) + return SMP_INVALID_PARAMS; +@@ -2517,7 +2523,7 @@ static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb) + struct smp_ltk *ltk; + u8 authenticated; + +- BT_DBG("conn %p", conn); ++ bt_dev_dbg(hdev, "conn %p", conn); + + if (skb->len < sizeof(*rp)) + return SMP_INVALID_PARAMS; +@@ -2549,7 +2555,7 @@ static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb) + struct l2cap_chan *chan = conn->smp; + struct smp_chan *smp = chan->data; + +- BT_DBG(""); ++ bt_dev_dbg(conn->hcon->hdev, ""); + + if (skb->len < sizeof(*info)) + return SMP_INVALID_PARAMS; +@@ -2581,7 +2587,7 @@ static int smp_cmd_ident_addr_info(struct l2cap_conn *conn, + struct hci_conn *hcon = conn->hcon; + bdaddr_t rpa; + +- BT_DBG(""); ++ bt_dev_dbg(hcon->hdev, ""); + + if (skb->len < sizeof(*info)) + return SMP_INVALID_PARAMS; +@@ -2648,7 +2654,7 @@ static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb) + struct smp_chan *smp = chan->data; + struct smp_csrk *csrk; + +- BT_DBG("conn %p", conn); ++ bt_dev_dbg(conn->hcon->hdev, "conn %p", conn); + + if (skb->len < sizeof(*rp)) + return SMP_INVALID_PARAMS; +@@ -2728,7 +2734,7 @@ static int smp_cmd_public_key(struct l2cap_conn *conn, struct sk_buff *skb) + struct smp_cmd_pairing_confirm cfm; + int err; + +- BT_DBG("conn %p", conn); ++ bt_dev_dbg(hdev, "conn %p", conn); + + if (skb->len < sizeof(*key)) + return SMP_INVALID_PARAMS; +@@ -2792,7 +2798,7 @@ static int smp_cmd_public_key(struct l2cap_conn *conn, struct sk_buff *skb) + + smp->method = sc_select_method(smp); + +- BT_DBG("%s selected method 0x%02x", hdev->name, smp->method); ++ bt_dev_dbg(hdev, "selected method 0x%02x", smp->method); + + /* JUST_WORKS and JUST_CFM result in an unauthenticated key */ + if (smp->method == JUST_WORKS || smp->method == JUST_CFM) +@@ -2867,7 +2873,7 @@ static int smp_cmd_dhkey_check(struct l2cap_conn *conn, struct sk_buff *skb) + u8 io_cap[3], r[16], e[16]; + int err; + +- BT_DBG("conn %p", conn); ++ bt_dev_dbg(hcon->hdev, "conn %p", conn); + + if (skb->len < sizeof(*check)) + return SMP_INVALID_PARAMS; +@@ -2927,7 +2933,7 @@ static int smp_cmd_keypress_notify(struct l2cap_conn *conn, + { + struct smp_cmd_keypress_notify *kp = (void *) skb->data; + +- BT_DBG("value 0x%02x", kp->value); ++ bt_dev_dbg(conn->hcon->hdev, "value 0x%02x", kp->value); + + return 0; + } +@@ -3024,7 +3030,7 @@ static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb) + break; + + default: +- BT_DBG("Unknown command code 0x%2.2x", code); ++ bt_dev_dbg(hcon->hdev, "Unknown command code 0x%2.2x", code); + reason = SMP_CMD_NOTSUPP; + goto done; + } +@@ -3049,7 +3055,7 @@ static void smp_teardown_cb(struct l2cap_chan *chan, int err) + { + struct l2cap_conn *conn = chan->conn; + +- BT_DBG("chan %p", chan); ++ bt_dev_dbg(conn->hcon->hdev, "chan %p", chan); + + if (chan->data) + smp_chan_destroy(conn); +@@ -3066,7 +3072,7 @@ static void bredr_pairing(struct l2cap_chan *chan) + struct smp_cmd_pairing req; + struct smp_chan *smp; + +- BT_DBG("chan %p", chan); ++ bt_dev_dbg(hdev, "chan %p", chan); + + /* Only new pairings are interesting */ + if (!test_bit(HCI_CONN_NEW_LINK_KEY, &hcon->flags)) +@@ -3113,7 +3119,7 @@ static void bredr_pairing(struct l2cap_chan *chan) + + set_bit(SMP_FLAG_SC, &smp->flags); + +- BT_DBG("%s starting SMP over BR/EDR", hdev->name); ++ bt_dev_dbg(hdev, "starting SMP over BR/EDR"); + + /* Prepare and send the BR/EDR SMP Pairing Request */ + build_bredr_pairing_cmd(smp, &req, NULL); +@@ -3131,7 +3137,7 @@ static void smp_resume_cb(struct l2cap_chan *chan) + struct l2cap_conn *conn = chan->conn; + struct hci_conn *hcon = conn->hcon; + +- BT_DBG("chan %p", chan); ++ bt_dev_dbg(hcon->hdev, "chan %p", chan); + + if (hcon->type == ACL_LINK) { + bredr_pairing(chan); +@@ -3154,7 +3160,7 @@ static void smp_ready_cb(struct l2cap_chan *chan) + struct l2cap_conn *conn = chan->conn; + struct hci_conn *hcon = conn->hcon; + +- BT_DBG("chan %p", chan); ++ bt_dev_dbg(hcon->hdev, "chan %p", chan); + + /* No need to call l2cap_chan_hold() here since we already own + * the reference taken in smp_new_conn_cb(). This is just the +@@ -3172,7 +3178,7 @@ static int smp_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb) + { + int err; + +- BT_DBG("chan %p", chan); ++ bt_dev_dbg(chan->conn->hcon->hdev, "chan %p", chan); + + err = smp_sig_channel(chan, skb); + if (err) { +@@ -3224,7 +3230,7 @@ static inline struct l2cap_chan *smp_new_conn_cb(struct l2cap_chan *pchan) + { + struct l2cap_chan *chan; + +- BT_DBG("pchan %p", pchan); ++ bt_dev_dbg(pchan->conn->hcon->hdev, "pchan %p", pchan); + + chan = l2cap_chan_create(); + if (!chan) +@@ -3245,7 +3251,7 @@ static inline struct l2cap_chan *smp_new_conn_cb(struct l2cap_chan *pchan) + */ + atomic_set(&chan->nesting, L2CAP_NESTING_SMP); + +- BT_DBG("created chan %p", chan); ++ bt_dev_dbg(pchan->conn->hcon->hdev, "created chan %p", chan); + + return chan; + } +@@ -3286,14 +3292,14 @@ static struct l2cap_chan *smp_add_cid(struct hci_dev *hdev, u16 cid) + + tfm_cmac = crypto_alloc_shash("cmac(aes)", 0, 0); + if (IS_ERR(tfm_cmac)) { +- BT_ERR("Unable to create CMAC crypto context"); ++ bt_dev_err(hdev, "Unable to create CMAC crypto context"); + kfree_sensitive(smp); + return ERR_CAST(tfm_cmac); + } + + tfm_ecdh = crypto_alloc_kpp("ecdh", 0, 0); + if (IS_ERR(tfm_ecdh)) { +- BT_ERR("Unable to create ECDH crypto context"); ++ bt_dev_err(hdev, "Unable to create ECDH crypto context"); + crypto_free_shash(tfm_cmac); + kfree_sensitive(smp); + return ERR_CAST(tfm_ecdh); +@@ -3349,7 +3355,7 @@ static void smp_del_chan(struct l2cap_chan *chan) + { + struct smp_dev *smp; + +- BT_DBG("chan %p", chan); ++ bt_dev_dbg(chan->conn->hcon->hdev, "chan %p", chan); + + smp = chan->data; + if (smp) { +@@ -3422,7 +3428,7 @@ int smp_register(struct hci_dev *hdev) + { + struct l2cap_chan *chan; + +- BT_DBG("%s", hdev->name); ++ bt_dev_dbg(hdev, ""); + + /* If the controller does not support Low Energy operation, then + * there is also no need to register any SMP channel. +-- +2.43.0 + diff --git a/queue-5.10/bluetooth-use-inclusive-language-in-smp.patch b/queue-5.10/bluetooth-use-inclusive-language-in-smp.patch new file mode 100644 index 00000000000..8dca9a14113 --- /dev/null +++ b/queue-5.10/bluetooth-use-inclusive-language-in-smp.patch @@ -0,0 +1,316 @@ +From 402662a2f8a0195d17ec0e56eb8065621ed2824e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 31 May 2021 16:37:25 +0800 +Subject: Bluetooth: use inclusive language in SMP + +From: Archie Pusaka + +[ Upstream commit fad646e16d3cafd67d3cfff8e66f77401190957e ] + +This patch replaces some non-inclusive terms based on the appropriate +language mapping table compiled by the Bluetooth SIG: +https://specificationrefs.bluetooth.com/language-mapping/Appropriate_Language_Mapping_Table.pdf + +Specifically, these terms are replaced: +master -> initiator +slave -> responder + +Signed-off-by: Archie Pusaka +Signed-off-by: Marcel Holtmann +Stable-dep-of: 59b047bc9808 ("Bluetooth: MGMT/SMP: Fix address type when using SMP over BREDR/LE") +Signed-off-by: Sasha Levin +--- + include/net/bluetooth/mgmt.h | 2 +- + net/bluetooth/mgmt.c | 10 +++--- + net/bluetooth/smp.c | 66 +++++++++++++++++++----------------- + net/bluetooth/smp.h | 6 ++-- + 4 files changed, 43 insertions(+), 41 deletions(-) + +diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h +index 6b55155e05e97..faaba22e0d386 100644 +--- a/include/net/bluetooth/mgmt.h ++++ b/include/net/bluetooth/mgmt.h +@@ -202,7 +202,7 @@ struct mgmt_cp_load_link_keys { + struct mgmt_ltk_info { + struct mgmt_addr_info addr; + __u8 type; +- __u8 master; ++ __u8 initiator; + __u8 enc_size; + __le16 ediv; + __le64 rand; +diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c +index 878bf73822449..c62ea4c954645 100644 +--- a/net/bluetooth/mgmt.c ++++ b/net/bluetooth/mgmt.c +@@ -5939,7 +5939,7 @@ static int load_irks(struct sock *sk, struct hci_dev *hdev, void *cp_data, + + static bool ltk_is_valid(struct mgmt_ltk_info *key) + { +- if (key->master != 0x00 && key->master != 0x01) ++ if (key->initiator != 0x00 && key->initiator != 0x01) + return false; + + switch (key->addr.type) { +@@ -6017,11 +6017,11 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev, + switch (key->type) { + case MGMT_LTK_UNAUTHENTICATED: + authenticated = 0x00; +- type = key->master ? SMP_LTK : SMP_LTK_SLAVE; ++ type = key->initiator ? SMP_LTK : SMP_LTK_RESPONDER; + break; + case MGMT_LTK_AUTHENTICATED: + authenticated = 0x01; +- type = key->master ? SMP_LTK : SMP_LTK_SLAVE; ++ type = key->initiator ? SMP_LTK : SMP_LTK_RESPONDER; + break; + case MGMT_LTK_P256_UNAUTH: + authenticated = 0x00; +@@ -8055,7 +8055,7 @@ static u8 mgmt_ltk_type(struct smp_ltk *ltk) + { + switch (ltk->type) { + case SMP_LTK: +- case SMP_LTK_SLAVE: ++ case SMP_LTK_RESPONDER: + if (ltk->authenticated) + return MGMT_LTK_AUTHENTICATED; + return MGMT_LTK_UNAUTHENTICATED; +@@ -8101,7 +8101,7 @@ void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, bool persistent) + ev.key.rand = key->rand; + + if (key->type == SMP_LTK) +- ev.key.master = 1; ++ ev.key.initiator = 1; + + /* Make sure we copy only the significant bytes based on the + * encryption key size, and set the rest of the value to zeroes. +diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c +index 1c1dc2d2b7d59..af6cc2e8c0284 100644 +--- a/net/bluetooth/smp.c ++++ b/net/bluetooth/smp.c +@@ -112,9 +112,9 @@ struct smp_chan { + u8 id_addr_type; + u8 irk[16]; + struct smp_csrk *csrk; +- struct smp_csrk *slave_csrk; ++ struct smp_csrk *responder_csrk; + struct smp_ltk *ltk; +- struct smp_ltk *slave_ltk; ++ struct smp_ltk *responder_ltk; + struct smp_irk *remote_irk; + u8 *link_key; + unsigned long flags; +@@ -754,7 +754,7 @@ static void smp_chan_destroy(struct l2cap_conn *conn) + mgmt_smp_complete(hcon, complete); + + kfree_sensitive(smp->csrk); +- kfree_sensitive(smp->slave_csrk); ++ kfree_sensitive(smp->responder_csrk); + kfree_sensitive(smp->link_key); + + crypto_free_shash(smp->tfm_cmac); +@@ -777,9 +777,9 @@ static void smp_chan_destroy(struct l2cap_conn *conn) + kfree_rcu(smp->ltk, rcu); + } + +- if (smp->slave_ltk) { +- list_del_rcu(&smp->slave_ltk->list); +- kfree_rcu(smp->slave_ltk, rcu); ++ if (smp->responder_ltk) { ++ list_del_rcu(&smp->responder_ltk->list); ++ kfree_rcu(smp->responder_ltk, rcu); + } + + if (smp->remote_irk) { +@@ -980,7 +980,7 @@ static u8 smp_random(struct smp_chan *smp) + int ret; + + bt_dev_dbg(conn->hcon->hdev, "conn %p %s", conn, +- conn->hcon->out ? "master" : "slave"); ++ conn->hcon->out ? "initiator" : "responder"); + + ret = smp_c1(smp->tk, smp->rrnd, smp->preq, smp->prsp, + hcon->init_addr_type, &hcon->init_addr, +@@ -1022,8 +1022,8 @@ static u8 smp_random(struct smp_chan *smp) + else + auth = 0; + +- /* Even though there's no _SLAVE suffix this is the +- * slave STK we're adding for later lookup (the master ++ /* Even though there's no _RESPONDER suffix this is the ++ * responder STK we're adding for later lookup (the initiator + * STK never needs to be stored). + */ + hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type, +@@ -1078,10 +1078,10 @@ static void smp_notify_keys(struct l2cap_conn *conn) + mgmt_new_csrk(hdev, smp->csrk, persistent); + } + +- if (smp->slave_csrk) { +- smp->slave_csrk->bdaddr_type = hcon->dst_type; +- bacpy(&smp->slave_csrk->bdaddr, &hcon->dst); +- mgmt_new_csrk(hdev, smp->slave_csrk, persistent); ++ if (smp->responder_csrk) { ++ smp->responder_csrk->bdaddr_type = hcon->dst_type; ++ bacpy(&smp->responder_csrk->bdaddr, &hcon->dst); ++ mgmt_new_csrk(hdev, smp->responder_csrk, persistent); + } + + if (smp->ltk) { +@@ -1090,10 +1090,10 @@ static void smp_notify_keys(struct l2cap_conn *conn) + mgmt_new_ltk(hdev, smp->ltk, persistent); + } + +- if (smp->slave_ltk) { +- smp->slave_ltk->bdaddr_type = hcon->dst_type; +- bacpy(&smp->slave_ltk->bdaddr, &hcon->dst); +- mgmt_new_ltk(hdev, smp->slave_ltk, persistent); ++ if (smp->responder_ltk) { ++ smp->responder_ltk->bdaddr_type = hcon->dst_type; ++ bacpy(&smp->responder_ltk->bdaddr, &hcon->dst); ++ mgmt_new_ltk(hdev, smp->responder_ltk, persistent); + } + + if (smp->link_key) { +@@ -1273,7 +1273,7 @@ static void smp_distribute_keys(struct smp_chan *smp) + + if (*keydist & SMP_DIST_ENC_KEY) { + struct smp_cmd_encrypt_info enc; +- struct smp_cmd_master_ident ident; ++ struct smp_cmd_initiator_ident ident; + struct smp_ltk *ltk; + u8 authenticated; + __le16 ediv; +@@ -1294,14 +1294,15 @@ static void smp_distribute_keys(struct smp_chan *smp) + + authenticated = hcon->sec_level == BT_SECURITY_HIGH; + ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, +- SMP_LTK_SLAVE, authenticated, enc.ltk, ++ SMP_LTK_RESPONDER, authenticated, enc.ltk, + smp->enc_key_size, ediv, rand); +- smp->slave_ltk = ltk; ++ smp->responder_ltk = ltk; + + ident.ediv = ediv; + ident.rand = rand; + +- smp_send_cmd(conn, SMP_CMD_MASTER_IDENT, sizeof(ident), &ident); ++ smp_send_cmd(conn, SMP_CMD_INITIATOR_IDENT, sizeof(ident), ++ &ident); + + *keydist &= ~SMP_DIST_ENC_KEY; + } +@@ -1344,7 +1345,7 @@ static void smp_distribute_keys(struct smp_chan *smp) + csrk->type = MGMT_CSRK_LOCAL_UNAUTHENTICATED; + memcpy(csrk->val, sign.csrk, sizeof(csrk->val)); + } +- smp->slave_csrk = csrk; ++ smp->responder_csrk = csrk; + + smp_send_cmd(conn, SMP_CMD_SIGN_INFO, sizeof(sign), &sign); + +@@ -2049,7 +2050,7 @@ static int fixup_sc_false_positive(struct smp_chan *smp) + struct smp_cmd_pairing *req, *rsp; + u8 auth; + +- /* The issue is only observed when we're in slave role */ ++ /* The issue is only observed when we're in responder role */ + if (hcon->out) + return SMP_UNSPECIFIED; + +@@ -2085,7 +2086,8 @@ static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb) + struct hci_conn *hcon = conn->hcon; + struct hci_dev *hdev = hcon->hdev; + +- bt_dev_dbg(hdev, "conn %p %s", conn, hcon->out ? "master" : "slave"); ++ bt_dev_dbg(hdev, "conn %p %s", conn, ++ hcon->out ? "initiator" : "responder"); + + if (skb->len < sizeof(smp->pcnf)) + return SMP_INVALID_PARAMS; +@@ -2252,7 +2254,7 @@ static bool smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level) + hci_le_start_enc(hcon, key->ediv, key->rand, key->val, key->enc_size); + hcon->enc_key_size = key->enc_size; + +- /* We never store STKs for master role, so clear this flag */ ++ /* We never store STKs for initiator role, so clear this flag */ + clear_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags); + + return true; +@@ -2468,7 +2470,7 @@ int smp_cancel_and_remove_pairing(struct hci_dev *hdev, bdaddr_t *bdaddr, + /* Set keys to NULL to make sure smp_failure() does not try to + * remove and free already invalidated rcu list entries. */ + smp->ltk = NULL; +- smp->slave_ltk = NULL; ++ smp->responder_ltk = NULL; + smp->remote_irk = NULL; + + if (test_bit(SMP_FLAG_COMPLETE, &smp->flags)) +@@ -2504,7 +2506,7 @@ static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb) + return SMP_INVALID_PARAMS; + } + +- SMP_ALLOW_CMD(smp, SMP_CMD_MASTER_IDENT); ++ SMP_ALLOW_CMD(smp, SMP_CMD_INITIATOR_IDENT); + + skb_pull(skb, sizeof(*rp)); + +@@ -2513,9 +2515,9 @@ static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb) + return 0; + } + +-static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb) ++static int smp_cmd_initiator_ident(struct l2cap_conn *conn, struct sk_buff *skb) + { +- struct smp_cmd_master_ident *rp = (void *) skb->data; ++ struct smp_cmd_initiator_ident *rp = (void *)skb->data; + struct l2cap_chan *chan = conn->smp; + struct smp_chan *smp = chan->data; + struct hci_dev *hdev = conn->hcon->hdev; +@@ -2914,7 +2916,7 @@ static int smp_cmd_dhkey_check(struct l2cap_conn *conn, struct sk_buff *skb) + return 0; + } + +- /* Slave sends DHKey check as response to master */ ++ /* Responder sends DHKey check as response to initiator */ + sc_dhkey_check(smp); + } + +@@ -3001,8 +3003,8 @@ static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb) + reason = smp_cmd_encrypt_info(conn, skb); + break; + +- case SMP_CMD_MASTER_IDENT: +- reason = smp_cmd_master_ident(conn, skb); ++ case SMP_CMD_INITIATOR_IDENT: ++ reason = smp_cmd_initiator_ident(conn, skb); + break; + + case SMP_CMD_IDENT_INFO: +diff --git a/net/bluetooth/smp.h b/net/bluetooth/smp.h +index 121edadd5f8da..5fe68e255cb29 100644 +--- a/net/bluetooth/smp.h ++++ b/net/bluetooth/smp.h +@@ -79,8 +79,8 @@ struct smp_cmd_encrypt_info { + __u8 ltk[16]; + } __packed; + +-#define SMP_CMD_MASTER_IDENT 0x07 +-struct smp_cmd_master_ident { ++#define SMP_CMD_INITIATOR_IDENT 0x07 ++struct smp_cmd_initiator_ident { + __le16 ediv; + __le64 rand; + } __packed; +@@ -146,7 +146,7 @@ struct smp_cmd_keypress_notify { + enum { + SMP_STK, + SMP_LTK, +- SMP_LTK_SLAVE, ++ SMP_LTK_RESPONDER, + SMP_LTK_P256, + SMP_LTK_P256_DEBUG, + }; +-- +2.43.0 + diff --git a/queue-5.10/scsi-core-add-scsi_prot_ref_tag-helper.patch b/queue-5.10/scsi-core-add-scsi_prot_ref_tag-helper.patch new file mode 100644 index 00000000000..89bb9a54350 --- /dev/null +++ b/queue-5.10/scsi-core-add-scsi_prot_ref_tag-helper.patch @@ -0,0 +1,46 @@ +From f77fc8490ddd94125be1894caf9c7fa893648b19 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 8 Jun 2021 23:39:15 -0400 +Subject: scsi: core: Add scsi_prot_ref_tag() helper + +From: Martin K. Petersen + +[ Upstream commit 7ba46799d34695534666a3f71a2be10ea85ece6c ] + +We are about to remove the request pointer from struct scsi_cmnd and that +will complicate getting to the ref_tag via t10_pi_ref_tag() in the various +drivers. Introduce a helper function to retrieve the reference tag so +drivers will not have to worry about the details. + +Link: https://lore.kernel.org/r/20210609033929.3815-2-martin.petersen@oracle.com +Reviewed-by: Bart Van Assche +Reviewed-by: Benjamin Block +Signed-off-by: Martin K. Petersen +Message-Id: <20210609033929.3815-2-martin.petersen@oracle.com> +Stable-dep-of: 066c5b46b6ea ("scsi: core: Always send batch on reset or error handling command") +Signed-off-by: Sasha Levin +--- + include/scsi/scsi_cmnd.h | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h +index b1c9b52876f3c..6630464635330 100644 +--- a/include/scsi/scsi_cmnd.h ++++ b/include/scsi/scsi_cmnd.h +@@ -291,6 +291,13 @@ static inline sector_t scsi_get_lba(struct scsi_cmnd *scmd) + return blk_rq_pos(scmd->request); + } + ++static inline u32 scsi_prot_ref_tag(struct scsi_cmnd *scmd) ++{ ++ struct request *rq = blk_mq_rq_from_pdu(scmd); ++ ++ return t10_pi_ref_tag(rq); ++} ++ + static inline unsigned int scsi_prot_interval(struct scsi_cmnd *scmd) + { + return scmd->device->sector_size; +-- +2.43.0 + diff --git a/queue-5.10/scsi-core-always-send-batch-on-reset-or-error-handli.patch b/queue-5.10/scsi-core-always-send-batch-on-reset-or-error-handli.patch new file mode 100644 index 00000000000..6a9a9fbf0f3 --- /dev/null +++ b/queue-5.10/scsi-core-always-send-batch-on-reset-or-error-handli.patch @@ -0,0 +1,61 @@ +From 549390501ff6606dd2906726b60fafdb1f3e7f51 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 15 Dec 2023 14:10:08 +0200 +Subject: scsi: core: Always send batch on reset or error handling command + +From: Alexander Atanasov + +[ Upstream commit 066c5b46b6eaf2f13f80c19500dbb3b84baabb33 ] + +In commit 8930a6c20791 ("scsi: core: add support for request batching") the +block layer bd->last flag was mapped to SCMD_LAST and used as an indicator +to send the batch for the drivers that implement this feature. However, the +error handling code was not updated accordingly. + +scsi_send_eh_cmnd() is used to send error handling commands and request +sense. The problem is that request sense comes as a single command that +gets into the batch queue and times out. As a result the device goes +offline after several failed resets. This was observed on virtio_scsi +during a device resize operation. + +[ 496.316946] sd 0:0:4:0: [sdd] tag#117 scsi_eh_0: requesting sense +[ 506.786356] sd 0:0:4:0: [sdd] tag#117 scsi_send_eh_cmnd timeleft: 0 +[ 506.787981] sd 0:0:4:0: [sdd] tag#117 abort + +To fix this always set SCMD_LAST flag in scsi_send_eh_cmnd() and +scsi_reset_ioctl(). + +Fixes: 8930a6c20791 ("scsi: core: add support for request batching") +Cc: +Signed-off-by: Alexander Atanasov +Link: https://lore.kernel.org/r/20231215121008.2881653-1-alexander.atanasov@virtuozzo.com +Reviewed-by: Ming Lei +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/scsi_error.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c +index 93374173b9579..30eb8769dbab9 100644 +--- a/drivers/scsi/scsi_error.c ++++ b/drivers/scsi/scsi_error.c +@@ -1068,6 +1068,7 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd, + + scsi_log_send(scmd); + scmd->submitter = SUBMITTED_BY_SCSI_ERROR_HANDLER; ++ scmd->flags |= SCMD_LAST; + + /* + * Lock sdev->state_mutex to avoid that scsi_device_quiesce() can +@@ -2359,6 +2360,7 @@ scsi_ioctl_reset(struct scsi_device *dev, int __user *arg) + scmd->cmnd = scsi_req(rq)->cmd; + + scmd->submitter = SUBMITTED_BY_SCSI_RESET_IOCTL; ++ scmd->flags |= SCMD_LAST; + memset(&scmd->sdb, 0, sizeof(scmd->sdb)); + + scmd->cmd_len = 0; +-- +2.43.0 + diff --git a/queue-5.10/scsi-core-introduce-scsi_get_sector.patch b/queue-5.10/scsi-core-introduce-scsi_get_sector.patch new file mode 100644 index 00000000000..19d1298172e --- /dev/null +++ b/queue-5.10/scsi-core-introduce-scsi_get_sector.patch @@ -0,0 +1,48 @@ +From 41ce719a5d781bdb43352d9bb2639f134a58709d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 8 Jun 2021 23:39:24 -0400 +Subject: scsi: core: Introduce scsi_get_sector() + +From: Bart Van Assche + +[ Upstream commit f0f214fe8cd32224267ebea93817b8c32074623d ] + +Since scsi_get_lba() returns a sector_t value instead of the LBA, the name +of that function is confusing. Introduce an identical function +scsi_get_sector(). + +Link: https://lore.kernel.org/r/20210513223757.3938-2-bvanassche@acm.org +Link: https://lore.kernel.org/r/20210609033929.3815-11-martin.petersen@oracle.com +Cc: Christoph Hellwig +Cc: Ming Lei +Cc: Hannes Reinecke +Reviewed-by: Damien Le Moal +Reviewed-by: Benjamin Block +Signed-off-by: Bart Van Assche +Signed-off-by: Martin K. Petersen +Message-Id: <20210609033929.3815-11-martin.petersen@oracle.com> +Stable-dep-of: 066c5b46b6ea ("scsi: core: Always send batch on reset or error handling command") +Signed-off-by: Sasha Levin +--- + include/scsi/scsi_cmnd.h | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h +index 6630464635330..ddab0c580382b 100644 +--- a/include/scsi/scsi_cmnd.h ++++ b/include/scsi/scsi_cmnd.h +@@ -224,6 +224,11 @@ static inline int scsi_sg_copy_to_buffer(struct scsi_cmnd *cmd, + buf, buflen); + } + ++static inline sector_t scsi_get_sector(struct scsi_cmnd *scmd) ++{ ++ return blk_rq_pos(scmd->request); ++} ++ + /* + * The operations below are hints that tell the controller driver how + * to handle I/Os with DIF or similar types of protection information. +-- +2.43.0 + diff --git a/queue-5.10/scsi-core-make-scsi_get_lba-return-the-lba.patch b/queue-5.10/scsi-core-make-scsi_get_lba-return-the-lba.patch new file mode 100644 index 00000000000..32718262b96 --- /dev/null +++ b/queue-5.10/scsi-core-make-scsi_get_lba-return-the-lba.patch @@ -0,0 +1,57 @@ +From 542f7f9da871a2c553c8d774775fbac2680eb0d7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 8 Jun 2021 23:39:26 -0400 +Subject: scsi: core: Make scsi_get_lba() return the LBA + +From: Martin K. Petersen + +[ Upstream commit d2c945f01d233085fedc9e3cf7ec180eaa2b7a85 ] + +scsi_get_lba() confusingly returned the block layer sector number expressed +in units of 512 bytes. Now that we have a more aptly named +scsi_get_sector() function, make scsi_get_lba() return the actual LBA. + +Link: https://lore.kernel.org/r/20210609033929.3815-13-martin.petersen@oracle.com +Reviewed-by: Bart Van Assche +Reviewed-by: Benjamin Block +Signed-off-by: Martin K. Petersen +Message-Id: <20210609033929.3815-13-martin.petersen@oracle.com> +Stable-dep-of: 066c5b46b6ea ("scsi: core: Always send batch on reset or error handling command") +Signed-off-by: Sasha Levin +--- + include/scsi/scsi_cmnd.h | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h +index ddab0c580382b..162a53a39ac0d 100644 +--- a/include/scsi/scsi_cmnd.h ++++ b/include/scsi/scsi_cmnd.h +@@ -229,6 +229,13 @@ static inline sector_t scsi_get_sector(struct scsi_cmnd *scmd) + return blk_rq_pos(scmd->request); + } + ++static inline sector_t scsi_get_lba(struct scsi_cmnd *scmd) ++{ ++ unsigned int shift = ilog2(scmd->device->sector_size) - SECTOR_SHIFT; ++ ++ return blk_rq_pos(scmd->request) >> shift; ++} ++ + /* + * The operations below are hints that tell the controller driver how + * to handle I/Os with DIF or similar types of protection information. +@@ -291,11 +298,6 @@ static inline unsigned char scsi_get_prot_type(struct scsi_cmnd *scmd) + return scmd->prot_type; + } + +-static inline sector_t scsi_get_lba(struct scsi_cmnd *scmd) +-{ +- return blk_rq_pos(scmd->request); +-} +- + static inline u32 scsi_prot_ref_tag(struct scsi_cmnd *scmd) + { + struct request *rq = blk_mq_rq_from_pdu(scmd); +-- +2.43.0 + diff --git a/queue-5.10/scsi-core-use-a-structure-member-to-track-the-scsi-c.patch b/queue-5.10/scsi-core-use-a-structure-member-to-track-the-scsi-c.patch new file mode 100644 index 00000000000..627439134b5 --- /dev/null +++ b/queue-5.10/scsi-core-use-a-structure-member-to-track-the-scsi-c.patch @@ -0,0 +1,173 @@ +From 5c6ec2b16a843011ec57b71dc41b3fa72e372ff0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 7 Oct 2021 13:27:56 -0700 +Subject: scsi: core: Use a structure member to track the SCSI command + submitter + +From: Bart Van Assche + +[ Upstream commit bf23e619039d360d503b7282d030daf2277a5d47 ] + +Conditional statements are faster than indirect calls. Use a structure +member to track the SCSI command submitter such that later patches can call +scsi_done(scmd) instead of scmd->scsi_done(scmd). + +The asymmetric behavior that scsi_send_eh_cmnd() sets the submission +context to the SCSI error handler and that it does not restore the +submission context to the SCSI core is retained. + +Link: https://lore.kernel.org/r/20211007202923.2174984-2-bvanassche@acm.org +Cc: Hannes Reinecke +Cc: Ming Lei +Cc: Christoph Hellwig +Reviewed-by: Benjamin Block +Reviewed-by: Bean Huo +Signed-off-by: Bart Van Assche +Signed-off-by: Martin K. Petersen +Stable-dep-of: 066c5b46b6ea ("scsi: core: Always send batch on reset or error handling command") +Signed-off-by: Sasha Levin +--- + drivers/scsi/scsi_error.c | 17 ++++++----------- + drivers/scsi/scsi_lib.c | 10 ++++++++++ + drivers/scsi/scsi_priv.h | 1 + + include/scsi/scsi_cmnd.h | 7 +++++++ + 4 files changed, 24 insertions(+), 11 deletions(-) + +diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c +index 89189b65e5eb6..93374173b9579 100644 +--- a/drivers/scsi/scsi_error.c ++++ b/drivers/scsi/scsi_error.c +@@ -50,8 +50,6 @@ + + #include + +-static void scsi_eh_done(struct scsi_cmnd *scmd); +- + /* + * These should *probably* be handled by the host itself. + * Since it is allowed to sleep, it probably should. +@@ -500,7 +498,8 @@ int scsi_check_sense(struct scsi_cmnd *scmd) + /* handler does not care. Drop down to default handling */ + } + +- if (scmd->cmnd[0] == TEST_UNIT_READY && scmd->scsi_done != scsi_eh_done) ++ if (scmd->cmnd[0] == TEST_UNIT_READY && ++ scmd->submitter != SUBMITTED_BY_SCSI_ERROR_HANDLER) + /* + * nasty: for mid-layer issued TURs, we need to return the + * actual sense data without any recovery attempt. For eh +@@ -768,7 +767,7 @@ static int scsi_eh_completed_normally(struct scsi_cmnd *scmd) + * scsi_eh_done - Completion function for error handling. + * @scmd: Cmd that is done. + */ +-static void scsi_eh_done(struct scsi_cmnd *scmd) ++void scsi_eh_done(struct scsi_cmnd *scmd) + { + struct completion *eh_action; + +@@ -1068,7 +1067,7 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd, + shost->eh_action = &done; + + scsi_log_send(scmd); +- scmd->scsi_done = scsi_eh_done; ++ scmd->submitter = SUBMITTED_BY_SCSI_ERROR_HANDLER; + + /* + * Lock sdev->state_mutex to avoid that scsi_device_quiesce() can +@@ -1095,6 +1094,7 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd, + if (rtn) { + if (timeleft > stall_for) { + scsi_eh_restore_cmnd(scmd, &ses); ++ + timeleft -= stall_for; + msleep(jiffies_to_msecs(stall_for)); + goto retry; +@@ -2322,11 +2322,6 @@ void scsi_report_device_reset(struct Scsi_Host *shost, int channel, int target) + } + EXPORT_SYMBOL(scsi_report_device_reset); + +-static void +-scsi_reset_provider_done_command(struct scsi_cmnd *scmd) +-{ +-} +- + /** + * scsi_ioctl_reset: explicitly reset a host/bus/target/device + * @dev: scsi_device to operate on +@@ -2363,7 +2358,7 @@ scsi_ioctl_reset(struct scsi_device *dev, int __user *arg) + scmd->request = rq; + scmd->cmnd = scsi_req(rq)->cmd; + +- scmd->scsi_done = scsi_reset_provider_done_command; ++ scmd->submitter = SUBMITTED_BY_SCSI_RESET_IOCTL; + memset(&scmd->sdb, 0, sizeof(scmd->sdb)); + + scmd->cmd_len = 0; +diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c +index 78bc50cfdeaed..20c2700e1f639 100644 +--- a/drivers/scsi/scsi_lib.c ++++ b/drivers/scsi/scsi_lib.c +@@ -1596,6 +1596,15 @@ static blk_status_t scsi_prepare_cmd(struct request *req) + + static void scsi_mq_done(struct scsi_cmnd *cmd) + { ++ switch (cmd->submitter) { ++ case SUBMITTED_BY_BLOCK_LAYER: ++ break; ++ case SUBMITTED_BY_SCSI_ERROR_HANDLER: ++ return scsi_eh_done(cmd); ++ case SUBMITTED_BY_SCSI_RESET_IOCTL: ++ return; ++ } ++ + if (unlikely(blk_should_fake_timeout(scsi_cmd_to_rq(cmd)->q))) + return; + if (unlikely(test_and_set_bit(SCMD_STATE_COMPLETE, &cmd->state))) +@@ -1685,6 +1694,7 @@ static blk_status_t scsi_queue_rq(struct blk_mq_hw_ctx *hctx, + + scsi_set_resid(cmd, 0); + memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); ++ cmd->submitter = SUBMITTED_BY_BLOCK_LAYER; + cmd->scsi_done = scsi_mq_done; + + blk_mq_start_request(req); +diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h +index 180636d54982d..89992d8879acd 100644 +--- a/drivers/scsi/scsi_priv.h ++++ b/drivers/scsi/scsi_priv.h +@@ -82,6 +82,7 @@ void scsi_eh_ready_devs(struct Scsi_Host *shost, + int scsi_eh_get_sense(struct list_head *work_q, + struct list_head *done_q); + int scsi_noretry_cmd(struct scsi_cmnd *scmd); ++void scsi_eh_done(struct scsi_cmnd *scmd); + + /* scsi_lib.c */ + extern int scsi_maybe_unblock_host(struct scsi_device *sdev); +diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h +index 7173b209144b7..2e26eb0d353e8 100644 +--- a/include/scsi/scsi_cmnd.h ++++ b/include/scsi/scsi_cmnd.h +@@ -65,6 +65,12 @@ struct scsi_pointer { + #define SCMD_STATE_COMPLETE 0 + #define SCMD_STATE_INFLIGHT 1 + ++enum scsi_cmnd_submitter { ++ SUBMITTED_BY_BLOCK_LAYER = 0, ++ SUBMITTED_BY_SCSI_ERROR_HANDLER = 1, ++ SUBMITTED_BY_SCSI_RESET_IOCTL = 2, ++} __packed; ++ + struct scsi_cmnd { + struct scsi_request req; + struct scsi_device *device; +@@ -88,6 +94,7 @@ struct scsi_cmnd { + unsigned char prot_op; + unsigned char prot_type; + unsigned char prot_flags; ++ enum scsi_cmnd_submitter submitter; + + unsigned short cmd_len; + enum dma_data_direction sc_data_direction; +-- +2.43.0 + diff --git a/queue-5.10/scsi-core-use-scsi_cmd_to_rq-instead-of-scsi_cmnd.re.patch b/queue-5.10/scsi-core-use-scsi_cmd_to_rq-instead-of-scsi_cmnd.re.patch new file mode 100644 index 00000000000..d68571b73fc --- /dev/null +++ b/queue-5.10/scsi-core-use-scsi_cmd_to_rq-instead-of-scsi_cmnd.re.patch @@ -0,0 +1,340 @@ +From ad4539e77e13f7edf655d76dc67072205d5b0057 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Aug 2021 16:03:05 -0700 +Subject: scsi: core: Use scsi_cmd_to_rq() instead of scsi_cmnd.request + +From: Bart Van Assche + +[ Upstream commit aa8e25e5006aac52c943c84e9056ab488630ee19 ] + +Prepare for removal of the request pointer by using scsi_cmd_to_rq() +instead. Cast away constness where necessary when passing a SCSI command +pointer to scsi_cmd_to_rq(). This patch does not change any functionality. + +Link: https://lore.kernel.org/r/20210809230355.8186-3-bvanassche@acm.org +Cc: Christoph Hellwig +Cc: Hannes Reinecke +Cc: Ming Lei +Reviewed-by: Hannes Reinecke +Signed-off-by: Bart Van Assche +Signed-off-by: Martin K. Petersen +Stable-dep-of: 066c5b46b6ea ("scsi: core: Always send batch on reset or error handling command") +Signed-off-by: Sasha Levin +--- + drivers/scsi/scsi.c | 2 +- + drivers/scsi/scsi_error.c | 15 ++++++++------- + drivers/scsi/scsi_lib.c | 28 +++++++++++++++------------- + drivers/scsi/scsi_logging.c | 18 ++++++++++-------- + include/scsi/scsi_cmnd.h | 8 +++++--- + include/scsi/scsi_device.h | 16 +++++++++------- + 6 files changed, 48 insertions(+), 39 deletions(-) + +diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c +index d6c25a88cebc9..034f2c8a9e0b5 100644 +--- a/drivers/scsi/scsi.c ++++ b/drivers/scsi/scsi.c +@@ -197,7 +197,7 @@ void scsi_finish_command(struct scsi_cmnd *cmd) + "(result %x)\n", cmd->result)); + + good_bytes = scsi_bufflen(cmd); +- if (!blk_rq_is_passthrough(cmd->request)) { ++ if (!blk_rq_is_passthrough(scsi_cmd_to_rq(cmd))) { + int old_good_bytes = good_bytes; + drv = scsi_cmd_to_driver(cmd); + if (drv->done) +diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c +index 0c4bc42b55c20..89189b65e5eb6 100644 +--- a/drivers/scsi/scsi_error.c ++++ b/drivers/scsi/scsi_error.c +@@ -230,7 +230,7 @@ scsi_abort_command(struct scsi_cmnd *scmd) + */ + static void scsi_eh_reset(struct scsi_cmnd *scmd) + { +- if (!blk_rq_is_passthrough(scmd->request)) { ++ if (!blk_rq_is_passthrough(scsi_cmd_to_rq(scmd))) { + struct scsi_driver *sdrv = scsi_cmd_to_driver(scmd); + if (sdrv->eh_reset) + sdrv->eh_reset(scmd); +@@ -1167,7 +1167,7 @@ static int scsi_request_sense(struct scsi_cmnd *scmd) + + static int scsi_eh_action(struct scsi_cmnd *scmd, int rtn) + { +- if (!blk_rq_is_passthrough(scmd->request)) { ++ if (!blk_rq_is_passthrough(scsi_cmd_to_rq(scmd))) { + struct scsi_driver *sdrv = scsi_cmd_to_driver(scmd); + if (sdrv->eh_action) + rtn = sdrv->eh_action(scmd, rtn); +@@ -1733,22 +1733,24 @@ static void scsi_eh_offline_sdevs(struct list_head *work_q, + */ + int scsi_noretry_cmd(struct scsi_cmnd *scmd) + { ++ struct request *req = scsi_cmd_to_rq(scmd); ++ + switch (host_byte(scmd->result)) { + case DID_OK: + break; + case DID_TIME_OUT: + goto check_type; + case DID_BUS_BUSY: +- return (scmd->request->cmd_flags & REQ_FAILFAST_TRANSPORT); ++ return req->cmd_flags & REQ_FAILFAST_TRANSPORT; + case DID_PARITY: +- return (scmd->request->cmd_flags & REQ_FAILFAST_DEV); ++ return req->cmd_flags & REQ_FAILFAST_DEV; + case DID_ERROR: + if (msg_byte(scmd->result) == COMMAND_COMPLETE && + status_byte(scmd->result) == RESERVATION_CONFLICT) + return 0; + fallthrough; + case DID_SOFT_ERROR: +- return (scmd->request->cmd_flags & REQ_FAILFAST_DRIVER); ++ return req->cmd_flags & REQ_FAILFAST_DRIVER; + } + + if (status_byte(scmd->result) != CHECK_CONDITION) +@@ -1759,8 +1761,7 @@ int scsi_noretry_cmd(struct scsi_cmnd *scmd) + * assume caller has checked sense and determined + * the check condition was retryable. + */ +- if (scmd->request->cmd_flags & REQ_FAILFAST_DEV || +- blk_rq_is_passthrough(scmd->request)) ++ if (req->cmd_flags & REQ_FAILFAST_DEV || blk_rq_is_passthrough(req)) + return 1; + + return 0; +diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c +index 99b90031500b2..78bc50cfdeaed 100644 +--- a/drivers/scsi/scsi_lib.c ++++ b/drivers/scsi/scsi_lib.c +@@ -153,13 +153,15 @@ scsi_set_blocked(struct scsi_cmnd *cmd, int reason) + + static void scsi_mq_requeue_cmd(struct scsi_cmnd *cmd) + { +- if (cmd->request->rq_flags & RQF_DONTPREP) { +- cmd->request->rq_flags &= ~RQF_DONTPREP; ++ struct request *rq = scsi_cmd_to_rq(cmd); ++ ++ if (rq->rq_flags & RQF_DONTPREP) { ++ rq->rq_flags &= ~RQF_DONTPREP; + scsi_mq_uninit_cmd(cmd); + } else { + WARN_ON_ONCE(true); + } +- blk_mq_requeue_request(cmd->request, true); ++ blk_mq_requeue_request(rq, true); + } + + /** +@@ -198,7 +200,7 @@ static void __scsi_queue_insert(struct scsi_cmnd *cmd, int reason, bool unbusy) + */ + cmd->result = 0; + +- blk_mq_requeue_request(cmd->request, true); ++ blk_mq_requeue_request(scsi_cmd_to_rq(cmd), true); + } + + /** +@@ -508,7 +510,7 @@ void scsi_run_host_queues(struct Scsi_Host *shost) + + static void scsi_uninit_cmd(struct scsi_cmnd *cmd) + { +- if (!blk_rq_is_passthrough(cmd->request)) { ++ if (!blk_rq_is_passthrough(scsi_cmd_to_rq(cmd))) { + struct scsi_driver *drv = scsi_cmd_to_driver(cmd); + + if (drv->uninit_command) +@@ -658,7 +660,7 @@ static void scsi_io_completion_reprep(struct scsi_cmnd *cmd, + + static bool scsi_cmd_runtime_exceeced(struct scsi_cmnd *cmd) + { +- struct request *req = cmd->request; ++ struct request *req = scsi_cmd_to_rq(cmd); + unsigned long wait_for; + + if (cmd->allowed == SCSI_CMD_RETRIES_NO_LIMIT) +@@ -677,7 +679,7 @@ static bool scsi_cmd_runtime_exceeced(struct scsi_cmnd *cmd) + static void scsi_io_completion_action(struct scsi_cmnd *cmd, int result) + { + struct request_queue *q = cmd->device->request_queue; +- struct request *req = cmd->request; ++ struct request *req = scsi_cmd_to_rq(cmd); + int level = 0; + enum {ACTION_FAIL, ACTION_REPREP, ACTION_RETRY, + ACTION_DELAYED_RETRY} action; +@@ -849,7 +851,7 @@ static int scsi_io_completion_nz_result(struct scsi_cmnd *cmd, int result, + { + bool sense_valid; + bool sense_current = true; /* false implies "deferred sense" */ +- struct request *req = cmd->request; ++ struct request *req = scsi_cmd_to_rq(cmd); + struct scsi_sense_hdr sshdr; + + sense_valid = scsi_command_normalize_sense(cmd, &sshdr); +@@ -938,7 +940,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) + { + int result = cmd->result; + struct request_queue *q = cmd->device->request_queue; +- struct request *req = cmd->request; ++ struct request *req = scsi_cmd_to_rq(cmd); + blk_status_t blk_stat = BLK_STS_OK; + + if (unlikely(result)) /* a nz result may or may not be an error */ +@@ -1006,7 +1008,7 @@ static inline bool scsi_cmd_needs_dma_drain(struct scsi_device *sdev, + blk_status_t scsi_alloc_sgtables(struct scsi_cmnd *cmd) + { + struct scsi_device *sdev = cmd->device; +- struct request *rq = cmd->request; ++ struct request *rq = scsi_cmd_to_rq(cmd); + unsigned short nr_segs = blk_rq_nr_phys_segments(rq); + struct scatterlist *last_sg = NULL; + blk_status_t ret; +@@ -1135,7 +1137,7 @@ void scsi_init_command(struct scsi_device *dev, struct scsi_cmnd *cmd) + { + void *buf = cmd->sense_buffer; + void *prot = cmd->prot_sdb; +- struct request *rq = blk_mq_rq_from_pdu(cmd); ++ struct request *rq = scsi_cmd_to_rq(cmd); + unsigned int flags = cmd->flags & SCMD_PRESERVED_FLAGS; + unsigned long jiffies_at_alloc; + int retries, to_clear; +@@ -1594,12 +1596,12 @@ static blk_status_t scsi_prepare_cmd(struct request *req) + + static void scsi_mq_done(struct scsi_cmnd *cmd) + { +- if (unlikely(blk_should_fake_timeout(cmd->request->q))) ++ if (unlikely(blk_should_fake_timeout(scsi_cmd_to_rq(cmd)->q))) + return; + if (unlikely(test_and_set_bit(SCMD_STATE_COMPLETE, &cmd->state))) + return; + trace_scsi_dispatch_cmd_done(cmd); +- blk_mq_complete_request(cmd->request); ++ blk_mq_complete_request(scsi_cmd_to_rq(cmd)); + } + + static void scsi_mq_put_budget(struct request_queue *q) +diff --git a/drivers/scsi/scsi_logging.c b/drivers/scsi/scsi_logging.c +index 8ea44c6595efa..f0ae55ad09738 100644 +--- a/drivers/scsi/scsi_logging.c ++++ b/drivers/scsi/scsi_logging.c +@@ -28,8 +28,9 @@ static void scsi_log_release_buffer(char *bufptr) + + static inline const char *scmd_name(const struct scsi_cmnd *scmd) + { +- return scmd->request->rq_disk ? +- scmd->request->rq_disk->disk_name : NULL; ++ struct request *rq = scsi_cmd_to_rq((struct scsi_cmnd *)scmd); ++ ++ return rq->rq_disk ? rq->rq_disk->disk_name : NULL; + } + + static size_t sdev_format_header(char *logbuf, size_t logbuf_len, +@@ -91,7 +92,7 @@ void scmd_printk(const char *level, const struct scsi_cmnd *scmd, + if (!logbuf) + return; + off = sdev_format_header(logbuf, logbuf_len, scmd_name(scmd), +- scmd->request->tag); ++ scsi_cmd_to_rq((struct scsi_cmnd *)scmd)->tag); + if (off < logbuf_len) { + va_start(args, fmt); + off += vscnprintf(logbuf + off, logbuf_len - off, fmt, args); +@@ -188,7 +189,7 @@ void scsi_print_command(struct scsi_cmnd *cmd) + return; + + off = sdev_format_header(logbuf, logbuf_len, +- scmd_name(cmd), cmd->request->tag); ++ scmd_name(cmd), scsi_cmd_to_rq(cmd)->tag); + if (off >= logbuf_len) + goto out_printk; + off += scnprintf(logbuf + off, logbuf_len - off, "CDB: "); +@@ -210,7 +211,7 @@ void scsi_print_command(struct scsi_cmnd *cmd) + + off = sdev_format_header(logbuf, logbuf_len, + scmd_name(cmd), +- cmd->request->tag); ++ scsi_cmd_to_rq(cmd)->tag); + if (!WARN_ON(off > logbuf_len - 58)) { + off += scnprintf(logbuf + off, logbuf_len - off, + "CDB[%02x]: ", k); +@@ -373,7 +374,8 @@ EXPORT_SYMBOL(__scsi_print_sense); + /* Normalize and print sense buffer in SCSI command */ + void scsi_print_sense(const struct scsi_cmnd *cmd) + { +- scsi_log_print_sense(cmd->device, scmd_name(cmd), cmd->request->tag, ++ scsi_log_print_sense(cmd->device, scmd_name(cmd), ++ scsi_cmd_to_rq((struct scsi_cmnd *)cmd)->tag, + cmd->sense_buffer, SCSI_SENSE_BUFFERSIZE); + } + EXPORT_SYMBOL(scsi_print_sense); +@@ -392,8 +394,8 @@ void scsi_print_result(const struct scsi_cmnd *cmd, const char *msg, + if (!logbuf) + return; + +- off = sdev_format_header(logbuf, logbuf_len, +- scmd_name(cmd), cmd->request->tag); ++ off = sdev_format_header(logbuf, logbuf_len, scmd_name(cmd), ++ scsi_cmd_to_rq((struct scsi_cmnd *)cmd)->tag); + + if (off >= logbuf_len) + goto out_printk; +diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h +index 162a53a39ac0d..7173b209144b7 100644 +--- a/include/scsi/scsi_cmnd.h ++++ b/include/scsi/scsi_cmnd.h +@@ -162,7 +162,9 @@ static inline void *scsi_cmd_priv(struct scsi_cmnd *cmd) + /* make sure not to use it with passthrough commands */ + static inline struct scsi_driver *scsi_cmd_to_driver(struct scsi_cmnd *cmd) + { +- return *(struct scsi_driver **)cmd->request->rq_disk->private_data; ++ struct request *rq = scsi_cmd_to_rq(cmd); ++ ++ return *(struct scsi_driver **)rq->rq_disk->private_data; + } + + extern void scsi_finish_command(struct scsi_cmnd *cmd); +@@ -226,14 +228,14 @@ static inline int scsi_sg_copy_to_buffer(struct scsi_cmnd *cmd, + + static inline sector_t scsi_get_sector(struct scsi_cmnd *scmd) + { +- return blk_rq_pos(scmd->request); ++ return blk_rq_pos(scsi_cmd_to_rq(scmd)); + } + + static inline sector_t scsi_get_lba(struct scsi_cmnd *scmd) + { + unsigned int shift = ilog2(scmd->device->sector_size) - SECTOR_SHIFT; + +- return blk_rq_pos(scmd->request) >> shift; ++ return blk_rq_pos(scsi_cmd_to_rq(scmd)) >> shift; + } + + /* +diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h +index 1a5c9a3df6d69..993e1e79dd0ce 100644 +--- a/include/scsi/scsi_device.h ++++ b/include/scsi/scsi_device.h +@@ -264,13 +264,15 @@ sdev_prefix_printk(const char *, const struct scsi_device *, const char *, + __printf(3, 4) void + scmd_printk(const char *, const struct scsi_cmnd *, const char *, ...); + +-#define scmd_dbg(scmd, fmt, a...) \ +- do { \ +- if ((scmd)->request->rq_disk) \ +- sdev_dbg((scmd)->device, "[%s] " fmt, \ +- (scmd)->request->rq_disk->disk_name, ##a);\ +- else \ +- sdev_dbg((scmd)->device, fmt, ##a); \ ++#define scmd_dbg(scmd, fmt, a...) \ ++ do { \ ++ struct request *__rq = scsi_cmd_to_rq((scmd)); \ ++ \ ++ if (__rq->rq_disk) \ ++ sdev_dbg((scmd)->device, "[%s] " fmt, \ ++ __rq->rq_disk->disk_name, ##a); \ ++ else \ ++ sdev_dbg((scmd)->device, fmt, ##a); \ + } while (0) + + enum scsi_target_state { +-- +2.43.0 + diff --git a/queue-5.10/series b/queue-5.10/series index b3fe8ff7868..185c6972f40 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -49,3 +49,19 @@ bus-ti-sysc-flush-posted-write-only-after-srst_udelay.patch lib-vsprintf-fix-pfwf-when-current-node-refcount-0.patch x86-alternatives-sync-core-before-enabling-interrupts.patch 9p-net-fix-possible-memory-leak-in-p9_check_errors.patch +arm-dts-fix-occasional-boot-hang-for-am3-usb.patch +bluetooth-smp-convert-bt_err-bt_dbg-to-bt_dev_err-bt.patch +bluetooth-use-inclusive-language-in-smp.patch +bluetooth-mgmt-smp-fix-address-type-when-using-smp-o.patch +usb-fotg210-hcd-delete-an-incorrect-bounds-test.patch +smb-client-fix-oob-in-smb2_query_info_init.patch +smb-client-fix-oob-in-smbcalcsize.patch +bluetooth-af_bluetooth-fix-use-after-free-in-bt_sock.patch +spi-atmel-switch-to-transfer_one-transfer-method.patch +spi-atmel-fix-cs-and-initialization-bug.patch +scsi-core-add-scsi_prot_ref_tag-helper.patch +scsi-core-introduce-scsi_get_sector.patch +scsi-core-make-scsi_get_lba-return-the-lba.patch +scsi-core-use-scsi_cmd_to_rq-instead-of-scsi_cmnd.re.patch +scsi-core-use-a-structure-member-to-track-the-scsi-c.patch +scsi-core-always-send-batch-on-reset-or-error-handli.patch diff --git a/queue-5.10/smb-client-fix-oob-in-smb2_query_info_init.patch b/queue-5.10/smb-client-fix-oob-in-smb2_query_info_init.patch new file mode 100644 index 00000000000..51e0dec581f --- /dev/null +++ b/queue-5.10/smb-client-fix-oob-in-smb2_query_info_init.patch @@ -0,0 +1,183 @@ +From 8c0b1b4b670e915cb6bc73a02721c45668bd1f18 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 13 Dec 2023 12:25:57 -0300 +Subject: smb: client: fix OOB in SMB2_query_info_init() + +From: Paulo Alcantara + +[ Upstream commit 33eae65c6f49770fec7a662935d4eb4a6406d24b ] + +A small CIFS buffer (448 bytes) isn't big enough to hold +SMB2_QUERY_INFO request along with user's input data from +CIFS_QUERY_INFO ioctl. That is, if the user passed an input buffer > +344 bytes, the client will memcpy() off the end of @req->Buffer in +SMB2_query_info_init() thus causing the following KASAN splat: + + BUG: KASAN: slab-out-of-bounds in SMB2_query_info_init+0x242/0x250 [cifs] + Write of size 1023 at addr ffff88801308c5a8 by task a.out/1240 + + CPU: 1 PID: 1240 Comm: a.out Not tainted 6.7.0-rc4 #5 + Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS + rel-1.16.2-3-gd478f380-rebuilt.opensuse.org 04/01/2014 + Call Trace: + + dump_stack_lvl+0x4a/0x80 + print_report+0xcf/0x650 + ? srso_alias_return_thunk+0x5/0xfbef5 + ? srso_alias_return_thunk+0x5/0xfbef5 + ? srso_alias_return_thunk+0x5/0xfbef5 + ? __phys_addr+0x46/0x90 + kasan_report+0xd8/0x110 + ? SMB2_query_info_init+0x242/0x250 [cifs] + ? SMB2_query_info_init+0x242/0x250 [cifs] + kasan_check_range+0x105/0x1b0 + __asan_memcpy+0x3c/0x60 + SMB2_query_info_init+0x242/0x250 [cifs] + ? __pfx_SMB2_query_info_init+0x10/0x10 [cifs] + ? srso_alias_return_thunk+0x5/0xfbef5 + ? smb_rqst_len+0xa6/0xc0 [cifs] + smb2_ioctl_query_info+0x4f4/0x9a0 [cifs] + ? __pfx_smb2_ioctl_query_info+0x10/0x10 [cifs] + ? __pfx_cifsConvertToUTF16+0x10/0x10 [cifs] + ? kasan_set_track+0x25/0x30 + ? srso_alias_return_thunk+0x5/0xfbef5 + ? __kasan_kmalloc+0x8f/0xa0 + ? srso_alias_return_thunk+0x5/0xfbef5 + ? cifs_strndup_to_utf16+0x12d/0x1a0 [cifs] + ? __build_path_from_dentry_optional_prefix+0x19d/0x2d0 [cifs] + ? __pfx_smb2_ioctl_query_info+0x10/0x10 [cifs] + cifs_ioctl+0x11c7/0x1de0 [cifs] + ? __pfx_cifs_ioctl+0x10/0x10 [cifs] + ? srso_alias_return_thunk+0x5/0xfbef5 + ? rcu_is_watching+0x23/0x50 + ? srso_alias_return_thunk+0x5/0xfbef5 + ? __rseq_handle_notify_resume+0x6cd/0x850 + ? __pfx___schedule+0x10/0x10 + ? blkcg_iostat_update+0x250/0x290 + ? srso_alias_return_thunk+0x5/0xfbef5 + ? ksys_write+0xe9/0x170 + __x64_sys_ioctl+0xc9/0x100 + do_syscall_64+0x47/0xf0 + entry_SYSCALL_64_after_hwframe+0x6f/0x77 + RIP: 0033:0x7f893dde49cf + Code: 00 48 89 44 24 18 31 c0 48 8d 44 24 60 c7 04 24 10 00 00 00 48 + 89 44 24 08 48 8d 44 24 20 48 89 44 24 10 b8 10 00 00 00 0f 05 <89> + c2 3d 00 f0 ff ff 77 18 48 8b 44 24 18 64 48 2b 04 25 28 00 00 + RSP: 002b:00007ffc03ff4160 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 + RAX: ffffffffffffffda RBX: 00007ffc03ff4378 RCX: 00007f893dde49cf + RDX: 00007ffc03ff41d0 RSI: 00000000c018cf07 RDI: 0000000000000003 + RBP: 00007ffc03ff4260 R08: 0000000000000410 R09: 0000000000000001 + R10: 00007f893dce7300 R11: 0000000000000246 R12: 0000000000000000 + R13: 00007ffc03ff4388 R14: 00007f893df15000 R15: 0000000000406de0 + + +Fix this by increasing size of SMB2_QUERY_INFO request buffers and +validating input length to prevent other callers from overflowing @req +in SMB2_query_info_init() as well. + +Fixes: f5b05d622a3e ("cifs: add IOCTL for QUERY_INFO passthrough to userspace") +Cc: stable@vger.kernel.org +Reported-by: Robert Morris +Signed-off-by: Paulo Alcantara +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + fs/cifs/smb2pdu.c | 29 ++++++++++++++++++++++------- + 1 file changed, 22 insertions(+), 7 deletions(-) + +diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c +index 9a80047bc9b7b..76679dc4e6328 100644 +--- a/fs/cifs/smb2pdu.c ++++ b/fs/cifs/smb2pdu.c +@@ -373,10 +373,15 @@ static int __smb2_plain_req_init(__le16 smb2_command, struct cifs_tcon *tcon, + void **request_buf, unsigned int *total_len) + { + /* BB eventually switch this to SMB2 specific small buf size */ +- if (smb2_command == SMB2_SET_INFO) ++ switch (smb2_command) { ++ case SMB2_SET_INFO: ++ case SMB2_QUERY_INFO: + *request_buf = cifs_buf_get(); +- else ++ break; ++ default: + *request_buf = cifs_small_buf_get(); ++ break; ++ } + if (*request_buf == NULL) { + /* BB should we add a retry in here if not a writepage? */ + return -ENOMEM; +@@ -3346,8 +3351,13 @@ SMB2_query_info_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server, + struct smb2_query_info_req *req; + struct kvec *iov = rqst->rq_iov; + unsigned int total_len; ++ size_t len; + int rc; + ++ if (unlikely(check_add_overflow(input_len, sizeof(*req), &len) || ++ len > CIFSMaxBufSize)) ++ return -EINVAL; ++ + rc = smb2_plain_req_init(SMB2_QUERY_INFO, tcon, server, + (void **) &req, &total_len); + if (rc) +@@ -3369,7 +3379,7 @@ SMB2_query_info_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server, + + iov[0].iov_base = (char *)req; + /* 1 for Buffer */ +- iov[0].iov_len = total_len - 1 + input_len; ++ iov[0].iov_len = len; + return 0; + } + +@@ -3377,7 +3387,7 @@ void + SMB2_query_info_free(struct smb_rqst *rqst) + { + if (rqst && rqst->rq_iov) +- cifs_small_buf_release(rqst->rq_iov[0].iov_base); /* request */ ++ cifs_buf_release(rqst->rq_iov[0].iov_base); /* request */ + } + + static int +@@ -5104,6 +5114,11 @@ build_qfs_info_req(struct kvec *iov, struct cifs_tcon *tcon, + return 0; + } + ++static inline void free_qfs_info_req(struct kvec *iov) ++{ ++ cifs_buf_release(iov->iov_base); ++} ++ + int + SMB311_posix_qfs_info(const unsigned int xid, struct cifs_tcon *tcon, + u64 persistent_fid, u64 volatile_fid, struct kstatfs *fsdata) +@@ -5135,7 +5150,7 @@ SMB311_posix_qfs_info(const unsigned int xid, struct cifs_tcon *tcon, + + rc = cifs_send_recv(xid, ses, server, + &rqst, &resp_buftype, flags, &rsp_iov); +- cifs_small_buf_release(iov.iov_base); ++ free_qfs_info_req(&iov); + if (rc) { + cifs_stats_fail_inc(tcon, SMB2_QUERY_INFO_HE); + goto posix_qfsinf_exit; +@@ -5186,7 +5201,7 @@ SMB2_QFS_info(const unsigned int xid, struct cifs_tcon *tcon, + + rc = cifs_send_recv(xid, ses, server, + &rqst, &resp_buftype, flags, &rsp_iov); +- cifs_small_buf_release(iov.iov_base); ++ free_qfs_info_req(&iov); + if (rc) { + cifs_stats_fail_inc(tcon, SMB2_QUERY_INFO_HE); + goto qfsinf_exit; +@@ -5253,7 +5268,7 @@ SMB2_QFS_attr(const unsigned int xid, struct cifs_tcon *tcon, + + rc = cifs_send_recv(xid, ses, server, + &rqst, &resp_buftype, flags, &rsp_iov); +- cifs_small_buf_release(iov.iov_base); ++ free_qfs_info_req(&iov); + if (rc) { + cifs_stats_fail_inc(tcon, SMB2_QUERY_INFO_HE); + goto qfsattr_exit; +-- +2.43.0 + diff --git a/queue-5.10/smb-client-fix-oob-in-smbcalcsize.patch b/queue-5.10/smb-client-fix-oob-in-smbcalcsize.patch new file mode 100644 index 00000000000..a9e4f0b99b9 --- /dev/null +++ b/queue-5.10/smb-client-fix-oob-in-smbcalcsize.patch @@ -0,0 +1,84 @@ +From 7cb3147b11b02d3914c437962546c09534707d5d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 15 Dec 2023 19:59:14 -0300 +Subject: smb: client: fix OOB in smbCalcSize() + +From: Paulo Alcantara + +[ Upstream commit b35858b3786ddbb56e1c35138ba25d6adf8d0bef ] + +Validate @smb->WordCount to avoid reading off the end of @smb and thus +causing the following KASAN splat: + + BUG: KASAN: slab-out-of-bounds in smbCalcSize+0x32/0x40 [cifs] + Read of size 2 at addr ffff88801c024ec5 by task cifsd/1328 + + CPU: 1 PID: 1328 Comm: cifsd Not tainted 6.7.0-rc5 #9 + Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS + rel-1.16.2-3-gd478f380-rebuilt.opensuse.org 04/01/2014 + Call Trace: + + dump_stack_lvl+0x4a/0x80 + print_report+0xcf/0x650 + ? srso_alias_return_thunk+0x5/0xfbef5 + ? srso_alias_return_thunk+0x5/0xfbef5 + ? __phys_addr+0x46/0x90 + kasan_report+0xd8/0x110 + ? smbCalcSize+0x32/0x40 [cifs] + ? smbCalcSize+0x32/0x40 [cifs] + kasan_check_range+0x105/0x1b0 + smbCalcSize+0x32/0x40 [cifs] + checkSMB+0x162/0x370 [cifs] + ? __pfx_checkSMB+0x10/0x10 [cifs] + cifs_handle_standard+0xbc/0x2f0 [cifs] + ? srso_alias_return_thunk+0x5/0xfbef5 + cifs_demultiplex_thread+0xed1/0x1360 [cifs] + ? __pfx_cifs_demultiplex_thread+0x10/0x10 [cifs] + ? srso_alias_return_thunk+0x5/0xfbef5 + ? lockdep_hardirqs_on_prepare+0x136/0x210 + ? __pfx_lock_release+0x10/0x10 + ? srso_alias_return_thunk+0x5/0xfbef5 + ? mark_held_locks+0x1a/0x90 + ? lockdep_hardirqs_on_prepare+0x136/0x210 + ? srso_alias_return_thunk+0x5/0xfbef5 + ? srso_alias_return_thunk+0x5/0xfbef5 + ? __kthread_parkme+0xce/0xf0 + ? __pfx_cifs_demultiplex_thread+0x10/0x10 [cifs] + kthread+0x18d/0x1d0 + ? kthread+0xdb/0x1d0 + ? __pfx_kthread+0x10/0x10 + ret_from_fork+0x34/0x60 + ? __pfx_kthread+0x10/0x10 + ret_from_fork_asm+0x1b/0x30 + + +This fixes CVE-2023-6606. + +Reported-by: j51569436@gmail.com +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=218218 +Cc: stable@vger.kernel.org +Signed-off-by: Paulo Alcantara (SUSE) +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + fs/cifs/misc.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c +index 9044b0fca9a3d..2d46018b02839 100644 +--- a/fs/cifs/misc.c ++++ b/fs/cifs/misc.c +@@ -353,6 +353,10 @@ checkSMB(char *buf, unsigned int total_read, struct TCP_Server_Info *server) + cifs_dbg(VFS, "Length less than smb header size\n"); + } + return -EIO; ++ } else if (total_read < sizeof(*smb) + 2 * smb->WordCount) { ++ cifs_dbg(VFS, "%s: can't read BCC due to invalid WordCount(%u)\n", ++ __func__, smb->WordCount); ++ return -EIO; + } + + /* otherwise, there is enough to get to the BCC */ +-- +2.43.0 + diff --git a/queue-5.10/spi-atmel-fix-cs-and-initialization-bug.patch b/queue-5.10/spi-atmel-fix-cs-and-initialization-bug.patch new file mode 100644 index 00000000000..2a29d014465 --- /dev/null +++ b/queue-5.10/spi-atmel-fix-cs-and-initialization-bug.patch @@ -0,0 +1,70 @@ +From 2d87888822f3c1106160cb7aff72ce89b0f17e84 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 29 Jun 2021 12:22:18 -0700 +Subject: spi: atmel: Fix CS and initialization bug + +From: Dan Sneddon + +[ Upstream commit 69e1818ad27bae167eeaaf6829d4a08900ef5153 ] + +Commit 5fa5e6dec762 ("spi: atmel: Switch to transfer_one transfer +method") switched to using transfer_one and set_cs. The +core doesn't call set_cs when the chip select lines are gpios. Add the +SPI_MASTER_GPIO_SS flag to the driver to ensure the calls to set_cs +happen since the driver programs configuration registers there. + +Fixes: 5fa5e6dec762 ("spi: atmel: Switch to transfer_one transfer method") + +Signed-off-by: Dan Sneddon +Link: https://lore.kernel.org/r/20210629192218.32125-1-dan.sneddon@microchip.com +Signed-off-by: Mark Brown +Stable-dep-of: fc70d643a2f6 ("spi: atmel: Fix clock issue when using devices with different polarities") +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-atmel.c | 9 ++------- + 1 file changed, 2 insertions(+), 7 deletions(-) + +diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c +index 2dba2089f2b7e..19499131e5676 100644 +--- a/drivers/spi/spi-atmel.c ++++ b/drivers/spi/spi-atmel.c +@@ -352,8 +352,6 @@ static void cs_activate(struct atmel_spi *as, struct spi_device *spi) + } + + mr = spi_readl(as, MR); +- if (spi->cs_gpiod) +- gpiod_set_value(spi->cs_gpiod, 1); + } else { + u32 cpol = (spi->mode & SPI_CPOL) ? SPI_BIT(CPOL) : 0; + int i; +@@ -369,8 +367,6 @@ static void cs_activate(struct atmel_spi *as, struct spi_device *spi) + + mr = spi_readl(as, MR); + mr = SPI_BFINS(PCS, ~(1 << chip_select), mr); +- if (spi->cs_gpiod) +- gpiod_set_value(spi->cs_gpiod, 1); + spi_writel(as, MR, mr); + } + +@@ -400,8 +396,6 @@ static void cs_deactivate(struct atmel_spi *as, struct spi_device *spi) + + if (!spi->cs_gpiod) + spi_writel(as, CR, SPI_BIT(LASTXFER)); +- else +- gpiod_set_value(spi->cs_gpiod, 0); + } + + static void atmel_spi_lock(struct atmel_spi *as) __acquires(&as->lock) +@@ -1498,7 +1492,8 @@ static int atmel_spi_probe(struct platform_device *pdev) + master->bus_num = pdev->id; + master->num_chipselect = 4; + master->setup = atmel_spi_setup; +- master->flags = (SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX); ++ master->flags = (SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX | ++ SPI_MASTER_GPIO_SS); + master->transfer_one = atmel_spi_one_transfer; + master->set_cs = atmel_spi_set_cs; + master->cleanup = atmel_spi_cleanup; +-- +2.43.0 + diff --git a/queue-5.10/spi-atmel-switch-to-transfer_one-transfer-method.patch b/queue-5.10/spi-atmel-switch-to-transfer_one-transfer-method.patch new file mode 100644 index 00000000000..cc497b114c0 --- /dev/null +++ b/queue-5.10/spi-atmel-switch-to-transfer_one-transfer-method.patch @@ -0,0 +1,249 @@ +From 4a871e844156368339db8b58b55d56c21009936b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 2 Jun 2021 09:08:14 -0700 +Subject: spi: atmel: Switch to transfer_one transfer method + +From: Dan Sneddon + +[ Upstream commit 5fa5e6dec762305a783e918a90a05369fc10e346 ] + +Switch from using our own transfer_one_message routine to using the one +provided by the SPI core. + +Signed-off-by: Dan Sneddon +Link: https://lore.kernel.org/r/20210602160816.4890-1-dan.sneddon@microchip.com +Signed-off-by: Mark Brown +Stable-dep-of: fc70d643a2f6 ("spi: atmel: Fix clock issue when using devices with different polarities") +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-atmel.c | 124 +++++++++++----------------------------- + 1 file changed, 33 insertions(+), 91 deletions(-) + +diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c +index 1db43cbead575..2dba2089f2b7e 100644 +--- a/drivers/spi/spi-atmel.c ++++ b/drivers/spi/spi-atmel.c +@@ -867,7 +867,6 @@ static int atmel_spi_set_xfer_speed(struct atmel_spi *as, + * lock is held, spi irq is blocked + */ + static void atmel_spi_pdc_next_xfer(struct spi_master *master, +- struct spi_message *msg, + struct spi_transfer *xfer) + { + struct atmel_spi *as = spi_master_get_devdata(master); +@@ -883,12 +882,12 @@ static void atmel_spi_pdc_next_xfer(struct spi_master *master, + spi_writel(as, RPR, rx_dma); + spi_writel(as, TPR, tx_dma); + +- if (msg->spi->bits_per_word > 8) ++ if (xfer->bits_per_word > 8) + len >>= 1; + spi_writel(as, RCR, len); + spi_writel(as, TCR, len); + +- dev_dbg(&msg->spi->dev, ++ dev_dbg(&master->dev, + " start xfer %p: len %u tx %p/%08llx rx %p/%08llx\n", + xfer, xfer->len, xfer->tx_buf, + (unsigned long long)xfer->tx_dma, xfer->rx_buf, +@@ -902,12 +901,12 @@ static void atmel_spi_pdc_next_xfer(struct spi_master *master, + spi_writel(as, RNPR, rx_dma); + spi_writel(as, TNPR, tx_dma); + +- if (msg->spi->bits_per_word > 8) ++ if (xfer->bits_per_word > 8) + len >>= 1; + spi_writel(as, RNCR, len); + spi_writel(as, TNCR, len); + +- dev_dbg(&msg->spi->dev, ++ dev_dbg(&master->dev, + " next xfer %p: len %u tx %p/%08llx rx %p/%08llx\n", + xfer, xfer->len, xfer->tx_buf, + (unsigned long long)xfer->tx_dma, xfer->rx_buf, +@@ -1277,12 +1276,28 @@ static int atmel_spi_setup(struct spi_device *spi) + return 0; + } + ++static void atmel_spi_set_cs(struct spi_device *spi, bool enable) ++{ ++ struct atmel_spi *as = spi_master_get_devdata(spi->master); ++ /* the core doesn't really pass us enable/disable, but CS HIGH vs CS LOW ++ * since we already have routines for activate/deactivate translate ++ * high/low to active/inactive ++ */ ++ enable = (!!(spi->mode & SPI_CS_HIGH) == enable); ++ ++ if (enable) { ++ cs_activate(as, spi); ++ } else { ++ cs_deactivate(as, spi); ++ } ++ ++} ++ + static int atmel_spi_one_transfer(struct spi_master *master, +- struct spi_message *msg, ++ struct spi_device *spi, + struct spi_transfer *xfer) + { + struct atmel_spi *as; +- struct spi_device *spi = msg->spi; + u8 bits; + u32 len; + struct atmel_spi_device *asd; +@@ -1291,11 +1306,8 @@ static int atmel_spi_one_transfer(struct spi_master *master, + unsigned long dma_timeout; + + as = spi_master_get_devdata(master); +- +- if (!(xfer->tx_buf || xfer->rx_buf) && xfer->len) { +- dev_dbg(&spi->dev, "missing rx or tx buf\n"); +- return -EINVAL; +- } ++ /* This lock was orignally taken in atmel_spi_trasfer_one_message */ ++ atmel_spi_lock(as); + + asd = spi->controller_state; + bits = (asd->csr >> 4) & 0xf; +@@ -1309,13 +1321,13 @@ static int atmel_spi_one_transfer(struct spi_master *master, + * DMA map early, for performance (empties dcache ASAP) and + * better fault reporting. + */ +- if ((!msg->is_dma_mapped) ++ if ((!master->cur_msg_mapped) + && as->use_pdc) { + if (atmel_spi_dma_map_xfer(as, xfer) < 0) + return -ENOMEM; + } + +- atmel_spi_set_xfer_speed(as, msg->spi, xfer); ++ atmel_spi_set_xfer_speed(as, spi, xfer); + + as->done_status = 0; + as->current_transfer = xfer; +@@ -1324,7 +1336,7 @@ static int atmel_spi_one_transfer(struct spi_master *master, + reinit_completion(&as->xfer_completion); + + if (as->use_pdc) { +- atmel_spi_pdc_next_xfer(master, msg, xfer); ++ atmel_spi_pdc_next_xfer(master, xfer); + } else if (atmel_spi_use_dma(as, xfer)) { + len = as->current_remaining_bytes; + ret = atmel_spi_next_xfer_dma_submit(master, +@@ -1332,7 +1344,8 @@ static int atmel_spi_one_transfer(struct spi_master *master, + if (ret) { + dev_err(&spi->dev, + "unable to use DMA, fallback to PIO\n"); +- atmel_spi_next_xfer_pio(master, xfer); ++ as->done_status = ret; ++ break; + } else { + as->current_remaining_bytes -= len; + if (as->current_remaining_bytes < 0) +@@ -1385,90 +1398,18 @@ static int atmel_spi_one_transfer(struct spi_master *master, + } else if (atmel_spi_use_dma(as, xfer)) { + atmel_spi_stop_dma(master); + } +- +- if (!msg->is_dma_mapped +- && as->use_pdc) +- atmel_spi_dma_unmap_xfer(master, xfer); +- +- return 0; +- +- } else { +- /* only update length if no error */ +- msg->actual_length += xfer->len; + } + +- if (!msg->is_dma_mapped ++ if (!master->cur_msg_mapped + && as->use_pdc) + atmel_spi_dma_unmap_xfer(master, xfer); + +- spi_transfer_delay_exec(xfer); +- +- if (xfer->cs_change) { +- if (list_is_last(&xfer->transfer_list, +- &msg->transfers)) { +- as->keep_cs = true; +- } else { +- cs_deactivate(as, msg->spi); +- udelay(10); +- cs_activate(as, msg->spi); +- } +- } +- +- return 0; +-} +- +-static int atmel_spi_transfer_one_message(struct spi_master *master, +- struct spi_message *msg) +-{ +- struct atmel_spi *as; +- struct spi_transfer *xfer; +- struct spi_device *spi = msg->spi; +- int ret = 0; +- +- as = spi_master_get_devdata(master); +- +- dev_dbg(&spi->dev, "new message %p submitted for %s\n", +- msg, dev_name(&spi->dev)); +- +- atmel_spi_lock(as); +- cs_activate(as, spi); +- +- as->keep_cs = false; +- +- msg->status = 0; +- msg->actual_length = 0; +- +- list_for_each_entry(xfer, &msg->transfers, transfer_list) { +- trace_spi_transfer_start(msg, xfer); +- +- ret = atmel_spi_one_transfer(master, msg, xfer); +- if (ret) +- goto msg_done; +- +- trace_spi_transfer_stop(msg, xfer); +- } +- + if (as->use_pdc) + atmel_spi_disable_pdc_transfer(as); + +- list_for_each_entry(xfer, &msg->transfers, transfer_list) { +- dev_dbg(&spi->dev, +- " xfer %p: len %u tx %p/%pad rx %p/%pad\n", +- xfer, xfer->len, +- xfer->tx_buf, &xfer->tx_dma, +- xfer->rx_buf, &xfer->rx_dma); +- } +- +-msg_done: +- if (!as->keep_cs) +- cs_deactivate(as, msg->spi); +- + atmel_spi_unlock(as); + +- msg->status = as->done_status; +- spi_finalize_current_message(spi->master); +- +- return ret; ++ return as->done_status; + } + + static void atmel_spi_cleanup(struct spi_device *spi) +@@ -1558,7 +1499,8 @@ static int atmel_spi_probe(struct platform_device *pdev) + master->num_chipselect = 4; + master->setup = atmel_spi_setup; + master->flags = (SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX); +- master->transfer_one_message = atmel_spi_transfer_one_message; ++ master->transfer_one = atmel_spi_one_transfer; ++ master->set_cs = atmel_spi_set_cs; + master->cleanup = atmel_spi_cleanup; + master->auto_runtime_pm = true; + master->max_dma_len = SPI_MAX_DMA_XFER; +-- +2.43.0 + diff --git a/queue-5.10/usb-fotg210-hcd-delete-an-incorrect-bounds-test.patch b/queue-5.10/usb-fotg210-hcd-delete-an-incorrect-bounds-test.patch new file mode 100644 index 00000000000..74e2a381496 --- /dev/null +++ b/queue-5.10/usb-fotg210-hcd-delete-an-incorrect-bounds-test.patch @@ -0,0 +1,63 @@ +From 075d2a67983df017985e1ac14dd1028bce48ffde Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 13 Dec 2023 16:22:43 +0300 +Subject: usb: fotg210-hcd: delete an incorrect bounds test + +From: Dan Carpenter + +[ Upstream commit 7fbcd195e2b8cc952e4aeaeb50867b798040314c ] + +Here "temp" is the number of characters that we have written and "size" +is the size of the buffer. The intent was clearly to say that if we have +written to the end of the buffer then stop. + +However, for that to work the comparison should have been done on the +original "size" value instead of the "size -= temp" value. Not only +will that not trigger when we want to, but there is a small chance that +it will trigger incorrectly before we want it to and we break from the +loop slightly earlier than intended. + +This code was recently changed from using snprintf() to scnprintf(). With +snprintf() we likely would have continued looping and passed a negative +size parameter to snprintf(). This would have triggered an annoying +WARN(). Now that we have converted to scnprintf() "size" will never +drop below 1 and there is no real need for this test. We could change +the condition to "if (temp <= 1) goto done;" but just deleting the test +is cleanest. + +Fixes: 7d50195f6c50 ("usb: host: Faraday fotg210-hcd driver") +Cc: stable +Signed-off-by: Dan Carpenter +Reviewed-by: Linus Walleij +Reviewed-by: Lee Jones +Link: https://lore.kernel.org/r/ZXmwIwHe35wGfgzu@suswa +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/host/fotg210-hcd.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c +index ff0b3457fd342..de925433d4c5f 100644 +--- a/drivers/usb/host/fotg210-hcd.c ++++ b/drivers/usb/host/fotg210-hcd.c +@@ -429,8 +429,6 @@ static void qh_lines(struct fotg210_hcd *fotg210, struct fotg210_qh *qh, + temp = size; + size -= temp; + next += temp; +- if (temp == size) +- goto done; + } + + temp = snprintf(next, size, "\n"); +@@ -440,7 +438,6 @@ static void qh_lines(struct fotg210_hcd *fotg210, struct fotg210_qh *qh, + size -= temp; + next += temp; + +-done: + *sizep = size; + *nextp = next; + } +-- +2.43.0 +