diff for duplicates of <20260607095730.969886994@linuxfoundation.org> diff --git a/a/1.txt b/N1/1.txt index 2dc9b0d..98f6112 100644 --- a/a/1.txt +++ b/N1/1.txt @@ -1,87 +1,80 @@ -6.18-stable review patch. If anyone has any objections, please let me know. +6.12-stable review patch. If anyone has any objections, please let me know. ------------------ -From: Jingguo Tan <tanjingguo@huawei.com> +From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> -[ Upstream commit 1e584c304cfb94a759417130b1fc6d30b30c4cce ] +[ Upstream commit 41c2713b204e6cb6a94587bc6bf6935107df5479 ] -virtio_transport_send_pkt_info() allocates or reuses the zerocopy uarg -before entering the send loop, but virtio_transport_alloc_skb() still -fills the skb before it inherits that uarg. When fixed-buffer vectored -zerocopy hits MAX_SKB_FRAGS, io_sg_from_iter() may partially attach -managed frags and return -EMSGSIZE. The rollback path call kfree_skb() -to free an skb that carries SKBFL_MANAGED_FRAG_REFS but no uarg, so -skb_release_data() falls through to ordinary frag unref. +If dcid is received for an already-assigned destination CID the spec +requires that both channels to be discarded, but calling l2cap_chan_del +may invalidate the tmp cursor created by list_for_each_entry_safe and +in fact it is the wrong procedure as the chan->dcid may be assigned +previously it really needs to be disconnected. -Pass the uarg into virtio_transport_alloc_skb() and bind it immediately -before virtio_transport_fill_skb(). This keeps control or no-payload skbs -untouched while ensuring success and rollback share one lifetime rule. +Calling l2cap_chan_clone directly may still lead to l2cap_chan_del so +instead schedule l2cap_chan_timeout with delay 0 to close the channel +asynchronously. -Fixes: 581512a6dc93 ("vsock/virtio: MSG_ZEROCOPY flag support") -Signed-off-by: Lin Ma <malin89@huawei.com> -Signed-off-by: Rongzhen Cui <cuirongzhen@huawei.com> -Signed-off-by: Jingguo Tan <tanjingguo@huawei.com> -Acked-by: Arseniy Krasnov <avkrasnov@salutedevices.com> -Acked-by: Michael S. Tsirkin <mst@redhat.com> -Reviewed-by: Stefano Garzarella <sgarzare@redhat.com> -Link: https://patch.msgid.link/20260527023301.1075581-1-malin89@huawei.com -Signed-off-by: Jakub Kicinski <kuba@kernel.org> +Fixes: 15f02b910562 ("Bluetooth: L2CAP: Add initial code for Enhanced Credit Based Mode") +Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Signed-off-by: Sasha Levin <sashal@kernel.org> --- - net/vmw_vsock/virtio_transport_common.c | 12 +++++++++--- - 1 file changed, 9 insertions(+), 3 deletions(-) + net/bluetooth/l2cap_core.c | 27 ++++++++++++++++++++++----- + 1 file changed, 22 insertions(+), 5 deletions(-) -diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c -index 1e07d3b1a0e800..c925b5c5b35a57 100644 ---- a/net/vmw_vsock/virtio_transport_common.c -+++ b/net/vmw_vsock/virtio_transport_common.c -@@ -207,6 +207,7 @@ static u16 virtio_transport_get_type(struct sock *sk) - static struct sk_buff *virtio_transport_alloc_skb(struct virtio_vsock_pkt_info *info, - size_t payload_len, - bool zcopy, -+ struct ubuf_info *uarg, - u32 src_cid, - u32 src_port, - u32 dst_cid, -@@ -247,6 +248,12 @@ static struct sk_buff *virtio_transport_alloc_skb(struct virtio_vsock_pkt_info * - if (info->msg && payload_len > 0) { - int err; +diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c +index 9de5d545966d60..f0b0f347ebc10a 100644 +--- a/net/bluetooth/l2cap_core.c ++++ b/net/bluetooth/l2cap_core.c +@@ -5194,6 +5194,7 @@ static inline int l2cap_ecred_conn_rsp(struct l2cap_conn *conn, + cmd_len -= sizeof(*rsp); -+ /* Bind the zerocopy lifetime before filling frags so error -+ * rollback frees managed fixed-buffer pages through -+ * the uarg-aware path. -+ */ -+ skb_zcopy_set(skb, uarg, NULL); -+ - err = virtio_transport_fill_skb(skb, info, payload_len, zcopy); - if (err) - goto out; -@@ -366,6 +373,7 @@ static int virtio_transport_send_pkt_info(struct vsock_sock *vsk, - skb_len = min(max_skb_len, rest_len); + list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) { ++ struct l2cap_chan *orig; + u16 dcid; - skb = virtio_transport_alloc_skb(info, skb_len, can_zcopy, -+ uarg, - src_cid, src_port, - dst_cid, dst_port); - if (!skb) { -@@ -373,8 +381,6 @@ static int virtio_transport_send_pkt_info(struct vsock_sock *vsk, - break; - } + if (chan->ident != cmd->ident || +@@ -5215,8 +5216,10 @@ static inline int l2cap_ecred_conn_rsp(struct l2cap_conn *conn, -- skb_zcopy_set(skb, uarg, NULL); -- - virtio_transport_inc_tx_pkt(vvs, skb); + BT_DBG("dcid[%d] 0x%4.4x", i, dcid); - ret = t_ops->send_pkt(skb); -@@ -1161,7 +1167,7 @@ static int virtio_transport_reset_no_sock(const struct virtio_transport *t, - if (!t) - return -ENOTCONN; ++ orig = __l2cap_get_chan_by_dcid(conn, dcid); ++ + /* Check if dcid is already in use */ +- if (dcid && __l2cap_get_chan_by_dcid(conn, dcid)) { ++ if (dcid && orig) { + /* If a device receives a + * L2CAP_CREDIT_BASED_CONNECTION_RSP packet with an + * already-assigned Destination CID, then both the +@@ -5225,10 +5228,24 @@ static inline int l2cap_ecred_conn_rsp(struct l2cap_conn *conn, + */ + l2cap_chan_del(chan, ECONNREFUSED); + l2cap_chan_unlock(chan); +- chan = __l2cap_get_chan_by_dcid(conn, dcid); +- l2cap_chan_lock(chan); +- l2cap_chan_del(chan, ECONNRESET); +- l2cap_chan_unlock(chan); ++ ++ /* Check that the dcid channel mode is ++ * L2CAP_MODE_EXT_FLOWCTL since this procedure is only ++ * valid for that mode and shouldn't disconnect a dcid ++ * in other modes. ++ */ ++ if (orig->mode == L2CAP_MODE_EXT_FLOWCTL) { ++ l2cap_chan_lock(orig); ++ /* Disconnect the original channel as it may be ++ * considered connected since dcid has already ++ * been assigned; don't call l2cap_chan_close ++ * directly since that could lead to ++ * l2cap_chan_del and then removing the channel ++ * from the list while we're iterating over it. ++ */ ++ __set_chan_timer(orig, 0); ++ l2cap_chan_unlock(orig); ++ } + continue; + } -- reply = virtio_transport_alloc_skb(&info, 0, false, -+ reply = virtio_transport_alloc_skb(&info, 0, false, NULL, - le64_to_cpu(hdr->dst_cid), - le32_to_cpu(hdr->dst_port), - le64_to_cpu(hdr->src_cid), -- 2.53.0 diff --git a/a/content_digest b/N1/content_digest index 07e7966..4602a38 100644 --- a/a/content_digest +++ b/N1/content_digest @@ -1,106 +1,93 @@ - "ref\020260607095727.528828913@linuxfoundation.org\0" + "ref\020260607095727.647295505@linuxfoundation.org\0" "From\0Greg Kroah-Hartman <gregkh@linuxfoundation.org>\0" - "Subject\0[PATCH 6.18 091/315] vsock/virtio: bind uarg before filling zerocopy skb\0" - "Date\0Sun, 7 Jun 2026 11:57:58 +0200\0" + "Subject\0[PATCH 6.12 087/307] Bluetooth: L2CAP: Fix possible crash on l2cap_ecred_conn_rsp\0" + "Date\0Sun, 7 Jun 2026 11:58:04 +0200\0" "To\0stable@vger.kernel.org\0" "Cc\0Greg Kroah-Hartman <gregkh@linuxfoundation.org>" patches@lists.linux.dev - Lin Ma <malin89@huawei.com> - Rongzhen Cui <cuirongzhen@huawei.com> - Jingguo Tan <tanjingguo@huawei.com> - Arseniy Krasnov <avkrasnov@salutedevices.com> - Michael S. Tsirkin <mst@redhat.com> - Stefano Garzarella <sgarzare@redhat.com> - Jakub Kicinski <kuba@kernel.org> + Luiz Augusto von Dentz <luiz.von.dentz@intel.com> " Sasha Levin <sashal@kernel.org>\0" "\00:1\0" "b\0" - "6.18-stable review patch. If anyone has any objections, please let me know.\n" + "6.12-stable review patch. If anyone has any objections, please let me know.\n" "\n" "------------------\n" "\n" - "From: Jingguo Tan <tanjingguo@huawei.com>\n" + "From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>\n" "\n" - "[ Upstream commit 1e584c304cfb94a759417130b1fc6d30b30c4cce ]\n" + "[ Upstream commit 41c2713b204e6cb6a94587bc6bf6935107df5479 ]\n" "\n" - "virtio_transport_send_pkt_info() allocates or reuses the zerocopy uarg\n" - "before entering the send loop, but virtio_transport_alloc_skb() still\n" - "fills the skb before it inherits that uarg. When fixed-buffer vectored\n" - "zerocopy hits MAX_SKB_FRAGS, io_sg_from_iter() may partially attach\n" - "managed frags and return -EMSGSIZE. The rollback path call kfree_skb()\n" - "to free an skb that carries SKBFL_MANAGED_FRAG_REFS but no uarg, so\n" - "skb_release_data() falls through to ordinary frag unref.\n" + "If dcid is received for an already-assigned destination CID the spec\n" + "requires that both channels to be discarded, but calling l2cap_chan_del\n" + "may invalidate the tmp cursor created by list_for_each_entry_safe and\n" + "in fact it is the wrong procedure as the chan->dcid may be assigned\n" + "previously it really needs to be disconnected.\n" "\n" - "Pass the uarg into virtio_transport_alloc_skb() and bind it immediately\n" - "before virtio_transport_fill_skb(). This keeps control or no-payload skbs\n" - "untouched while ensuring success and rollback share one lifetime rule.\n" + "Calling l2cap_chan_clone directly may still lead to l2cap_chan_del so\n" + "instead schedule l2cap_chan_timeout with delay 0 to close the channel\n" + "asynchronously.\n" "\n" - "Fixes: 581512a6dc93 (\"vsock/virtio: MSG_ZEROCOPY flag support\")\n" - "Signed-off-by: Lin Ma <malin89@huawei.com>\n" - "Signed-off-by: Rongzhen Cui <cuirongzhen@huawei.com>\n" - "Signed-off-by: Jingguo Tan <tanjingguo@huawei.com>\n" - "Acked-by: Arseniy Krasnov <avkrasnov@salutedevices.com>\n" - "Acked-by: Michael S. Tsirkin <mst@redhat.com>\n" - "Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>\n" - "Link: https://patch.msgid.link/20260527023301.1075581-1-malin89@huawei.com\n" - "Signed-off-by: Jakub Kicinski <kuba@kernel.org>\n" + "Fixes: 15f02b910562 (\"Bluetooth: L2CAP: Add initial code for Enhanced Credit Based Mode\")\n" + "Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>\n" "Signed-off-by: Sasha Levin <sashal@kernel.org>\n" "---\n" - " net/vmw_vsock/virtio_transport_common.c | 12 +++++++++---\n" - " 1 file changed, 9 insertions(+), 3 deletions(-)\n" + " net/bluetooth/l2cap_core.c | 27 ++++++++++++++++++++++-----\n" + " 1 file changed, 22 insertions(+), 5 deletions(-)\n" "\n" - "diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c\n" - "index 1e07d3b1a0e800..c925b5c5b35a57 100644\n" - "--- a/net/vmw_vsock/virtio_transport_common.c\n" - "+++ b/net/vmw_vsock/virtio_transport_common.c\n" - "@@ -207,6 +207,7 @@ static u16 virtio_transport_get_type(struct sock *sk)\n" - " static struct sk_buff *virtio_transport_alloc_skb(struct virtio_vsock_pkt_info *info,\n" - " \t\t\t\t\t\t size_t payload_len,\n" - " \t\t\t\t\t\t bool zcopy,\n" - "+\t\t\t\t\t\t struct ubuf_info *uarg,\n" - " \t\t\t\t\t\t u32 src_cid,\n" - " \t\t\t\t\t\t u32 src_port,\n" - " \t\t\t\t\t\t u32 dst_cid,\n" - "@@ -247,6 +248,12 @@ static struct sk_buff *virtio_transport_alloc_skb(struct virtio_vsock_pkt_info *\n" - " \tif (info->msg && payload_len > 0) {\n" - " \t\tint err;\n" + "diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c\n" + "index 9de5d545966d60..f0b0f347ebc10a 100644\n" + "--- a/net/bluetooth/l2cap_core.c\n" + "+++ b/net/bluetooth/l2cap_core.c\n" + "@@ -5194,6 +5194,7 @@ static inline int l2cap_ecred_conn_rsp(struct l2cap_conn *conn,\n" + " \tcmd_len -= sizeof(*rsp);\n" " \n" - "+\t\t/* Bind the zerocopy lifetime before filling frags so error\n" - "+\t\t * rollback frees managed fixed-buffer pages through\n" - "+\t\t * the uarg-aware path.\n" - "+\t\t */\n" - "+\t\tskb_zcopy_set(skb, uarg, NULL);\n" - "+\n" - " \t\terr = virtio_transport_fill_skb(skb, info, payload_len, zcopy);\n" - " \t\tif (err)\n" - " \t\t\tgoto out;\n" - "@@ -366,6 +373,7 @@ static int virtio_transport_send_pkt_info(struct vsock_sock *vsk,\n" - " \t\tskb_len = min(max_skb_len, rest_len);\n" + " \tlist_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {\n" + "+\t\tstruct l2cap_chan *orig;\n" + " \t\tu16 dcid;\n" " \n" - " \t\tskb = virtio_transport_alloc_skb(info, skb_len, can_zcopy,\n" - "+\t\t\t\t\t\t uarg,\n" - " \t\t\t\t\t\t src_cid, src_port,\n" - " \t\t\t\t\t\t dst_cid, dst_port);\n" - " \t\tif (!skb) {\n" - "@@ -373,8 +381,6 @@ static int virtio_transport_send_pkt_info(struct vsock_sock *vsk,\n" - " \t\t\tbreak;\n" - " \t\t}\n" + " \t\tif (chan->ident != cmd->ident ||\n" + "@@ -5215,8 +5216,10 @@ static inline int l2cap_ecred_conn_rsp(struct l2cap_conn *conn,\n" " \n" - "-\t\tskb_zcopy_set(skb, uarg, NULL);\n" - "-\n" - " \t\tvirtio_transport_inc_tx_pkt(vvs, skb);\n" + " \t\tBT_DBG(\"dcid[%d] 0x%4.4x\", i, dcid);\n" " \n" - " \t\tret = t_ops->send_pkt(skb);\n" - "@@ -1161,7 +1167,7 @@ static int virtio_transport_reset_no_sock(const struct virtio_transport *t,\n" - " \tif (!t)\n" - " \t\treturn -ENOTCONN;\n" + "+\t\torig = __l2cap_get_chan_by_dcid(conn, dcid);\n" + "+\n" + " \t\t/* Check if dcid is already in use */\n" + "-\t\tif (dcid && __l2cap_get_chan_by_dcid(conn, dcid)) {\n" + "+\t\tif (dcid && orig) {\n" + " \t\t\t/* If a device receives a\n" + " \t\t\t * L2CAP_CREDIT_BASED_CONNECTION_RSP packet with an\n" + " \t\t\t * already-assigned Destination CID, then both the\n" + "@@ -5225,10 +5228,24 @@ static inline int l2cap_ecred_conn_rsp(struct l2cap_conn *conn,\n" + " \t\t\t */\n" + " \t\t\tl2cap_chan_del(chan, ECONNREFUSED);\n" + " \t\t\tl2cap_chan_unlock(chan);\n" + "-\t\t\tchan = __l2cap_get_chan_by_dcid(conn, dcid);\n" + "-\t\t\tl2cap_chan_lock(chan);\n" + "-\t\t\tl2cap_chan_del(chan, ECONNRESET);\n" + "-\t\t\tl2cap_chan_unlock(chan);\n" + "+\n" + "+\t\t\t/* Check that the dcid channel mode is\n" + "+\t\t\t * L2CAP_MODE_EXT_FLOWCTL since this procedure is only\n" + "+\t\t\t * valid for that mode and shouldn't disconnect a dcid\n" + "+\t\t\t * in other modes.\n" + "+\t\t\t */\n" + "+\t\t\tif (orig->mode == L2CAP_MODE_EXT_FLOWCTL) {\n" + "+\t\t\t\tl2cap_chan_lock(orig);\n" + "+\t\t\t\t/* Disconnect the original channel as it may be\n" + "+\t\t\t\t * considered connected since dcid has already\n" + "+\t\t\t\t * been assigned; don't call l2cap_chan_close\n" + "+\t\t\t\t * directly since that could lead to\n" + "+\t\t\t\t * l2cap_chan_del and then removing the channel\n" + "+\t\t\t\t * from the list while we're iterating over it.\n" + "+\t\t\t\t */\n" + "+\t\t\t\t__set_chan_timer(orig, 0);\n" + "+\t\t\t\tl2cap_chan_unlock(orig);\n" + "+\t\t\t}\n" + " \t\t\tcontinue;\n" + " \t\t}\n" " \n" - "-\treply = virtio_transport_alloc_skb(&info, 0, false,\n" - "+\treply = virtio_transport_alloc_skb(&info, 0, false, NULL,\n" - " \t\t\t\t\t le64_to_cpu(hdr->dst_cid),\n" - " \t\t\t\t\t le32_to_cpu(hdr->dst_port),\n" - " \t\t\t\t\t le64_to_cpu(hdr->src_cid),\n" "-- \n" 2.53.0 -bbdae866bd7ead1ee4f259a04c4a5e3abadc321ff30b6272a28e77449a9482b6 +cf8ea8d7c295b358a8df4eb7b30edb32673b7e6e69df785e19edbe235f59d917
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox