From 33e40dedeb115be239d7bf052e80cb1a48b30382 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 2 Jul 2026 10:40:41 +0200 Subject: [PATCH] 7.1-stable patches added patches: apparmor-fix-use-after-free-in-rawdata-dedup-loop.patch apparmor-mediate-the-implicit-connect-of-tcp-fast-open-sendmsg.patch mac802154-llsec-add-skb_cow_data-before-in-place-crypto.patch net-ip_gre-require-cap_net_admin-in-the-device-netns-for-changelink.patch net-skmsg-preserve-sg.copy-across-sg-transforms.patch pci-p2pdma-add-intel-qat-dsa-iaa-devices-to-whitelist.patch --- ...use-after-free-in-rawdata-dedup-loop.patch | 107 +++++++ ...cit-connect-of-tcp-fast-open-sendmsg.patch | 55 ++++ ...-skb_cow_data-before-in-place-crypto.patch | 98 ++++++ ...n-in-the-device-netns-for-changelink.patch | 95 ++++++ ...reserve-sg.copy-across-sg-transforms.patch | 288 ++++++++++++++++++ ...tel-qat-dsa-iaa-devices-to-whitelist.patch | 134 ++++++++ queue-7.1/series | 6 + 7 files changed, 783 insertions(+) create mode 100644 queue-7.1/apparmor-fix-use-after-free-in-rawdata-dedup-loop.patch create mode 100644 queue-7.1/apparmor-mediate-the-implicit-connect-of-tcp-fast-open-sendmsg.patch create mode 100644 queue-7.1/mac802154-llsec-add-skb_cow_data-before-in-place-crypto.patch create mode 100644 queue-7.1/net-ip_gre-require-cap_net_admin-in-the-device-netns-for-changelink.patch create mode 100644 queue-7.1/net-skmsg-preserve-sg.copy-across-sg-transforms.patch create mode 100644 queue-7.1/pci-p2pdma-add-intel-qat-dsa-iaa-devices-to-whitelist.patch diff --git a/queue-7.1/apparmor-fix-use-after-free-in-rawdata-dedup-loop.patch b/queue-7.1/apparmor-fix-use-after-free-in-rawdata-dedup-loop.patch new file mode 100644 index 0000000000..9094046752 --- /dev/null +++ b/queue-7.1/apparmor-fix-use-after-free-in-rawdata-dedup-loop.patch @@ -0,0 +1,107 @@ +From 6f060496d03e4dc560a40f73770bd08335cb7a27 Mon Sep 17 00:00:00 2001 +From: Ruslan Valiyev +Date: Tue, 26 May 2026 00:04:46 +0200 +Subject: apparmor: fix use-after-free in rawdata dedup loop + +From: Ruslan Valiyev + +commit 6f060496d03e4dc560a40f73770bd08335cb7a27 upstream. + +aa_replace_profiles() walks ns->rawdata_list to dedup the incoming +policy blob against entries already attached to existing profiles. +Per the kernel-doc on struct aa_loaddata, list membership does not +hold a reference: profiles hold pcount, and when the last pcount +drops, do_ploaddata_rmfs() is queued on a workqueue that takes +ns->lock and removes the entry. Between dropping the last pcount +and the workqueue running, an entry remains on the list with +pcount == 0. + +aa_get_profile_loaddata() is an unconditional kref_get() on +pcount, so when the dedup loop hits such an entry, refcount +hardening reports + + refcount_t: addition on 0; use-after-free. + +inside aa_replace_profiles(), and the poisoned counter then +trips "saturated" and "underflow" warnings on the subsequent +uses of the same loaddata. + +Before commit a0b7091c4de4 ("apparmor: fix race on rawdata +dereference") the dedup path used a get_unless_zero-style helper +on a single counter, so the existing "if (tmp)" guard was +meaningful. The split-refcount refactor introduced +aa_get_profile_loaddata(), which has plain kref_get() semantics, +and the guard quietly became a no-op. + +Introduce aa_get_profile_loaddata_not0(), matching the existing +_not0 convention used by aa_get_profile_not0(), and use it for +the rawdata_list dedup lookup so dying entries are skipped. + +Reproduced on x86_64 with v7.1-rc5 in QEMU+KVM running Ubuntu +24.04 + stress-ng 0.17.06: + + stress-ng --apparmor 1 --klog-check --timeout 60s + +Without this patch the three refcount_t warnings fire within a +few seconds. With it the same 60 s run is clean. Coverage is a +smoke-test only; a longer soak with CONFIG_KASAN, CONFIG_KCSAN +and CONFIG_PROVE_LOCKING would be welcome from anyone with the +cycles. + +Fixes: a0b7091c4de4 ("apparmor: fix race on rawdata dereference") +Reported-by: Colin Ian King +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=221513 +Cc: stable@vger.kernel.org +Signed-off-by: Ruslan Valiyev +Signed-off-by: John Johansen +Signed-off-by: Greg Kroah-Hartman +--- + security/apparmor/include/policy_unpack.h | 19 +++++++++++++++++++ + security/apparmor/policy.c | 8 ++++++-- + 2 files changed, 25 insertions(+), 2 deletions(-) + +--- a/security/apparmor/include/policy_unpack.h ++++ b/security/apparmor/include/policy_unpack.h +@@ -163,6 +163,25 @@ aa_get_profile_loaddata(struct aa_loadda + return data; + } + ++/** ++ * aa_get_profile_loaddata_not0 - get a profile reference count if not zero ++ * @data: reference to get a count on ++ * ++ * Like aa_get_profile_loaddata(), but safe to call on an entry that may ++ * be on a list (e.g. ns->rawdata_list) where the last pcount has already ++ * dropped and the deferred cleanup has not yet run. ++ * ++ * Returns: pointer to reference, or %NULL if @data is NULL or its ++ * profile refcount has already reached zero. ++ */ ++static inline struct aa_loaddata * ++aa_get_profile_loaddata_not0(struct aa_loaddata *data) ++{ ++ if (data && kref_get_unless_zero(&data->pcount)) ++ return data; ++ return NULL; ++} ++ + void __aa_loaddata_update(struct aa_loaddata *data, long revision); + bool aa_rawdata_eq(struct aa_loaddata *l, struct aa_loaddata *r); + void aa_loaddata_kref(struct kref *kref); +--- a/security/apparmor/policy.c ++++ b/security/apparmor/policy.c +@@ -1223,8 +1223,12 @@ ssize_t aa_replace_profiles(struct aa_ns + if (aa_rawdata_eq(rawdata_ent, udata)) { + struct aa_loaddata *tmp; + +- tmp = aa_get_profile_loaddata(rawdata_ent); +- /* check we didn't fail the race */ ++ /* ++ * Entries remain on rawdata_list with ++ * pcount == 0 until do_ploaddata_rmfs() ++ * runs; only take a live profile ref. ++ */ ++ tmp = aa_get_profile_loaddata_not0(rawdata_ent); + if (tmp) { + aa_put_profile_loaddata(udata); + udata = tmp; diff --git a/queue-7.1/apparmor-mediate-the-implicit-connect-of-tcp-fast-open-sendmsg.patch b/queue-7.1/apparmor-mediate-the-implicit-connect-of-tcp-fast-open-sendmsg.patch new file mode 100644 index 0000000000..8264a45991 --- /dev/null +++ b/queue-7.1/apparmor-mediate-the-implicit-connect-of-tcp-fast-open-sendmsg.patch @@ -0,0 +1,55 @@ +From 4d587cd8a72155089a627130bbd4716ec0856e21 Mon Sep 17 00:00:00 2001 +From: Bryam Vargas +Date: Mon, 22 Jun 2026 15:57:38 -0500 +Subject: apparmor: mediate the implicit connect of TCP fast open sendmsg + +From: Bryam Vargas + +commit 4d587cd8a72155089a627130bbd4716ec0856e21 upstream. + +sendmsg()/sendto() with MSG_FASTOPEN is a combination of connect(2) and +write(2): it opens the connection in the SYN. apparmor_socket_sendmsg() +only checks AA_MAY_SEND, so a profile that grants send but denies connect +lets a confined task open an outbound TCP/MPTCP connection that connect(2) +would have refused, bypassing connect mediation. + +Mediate the implicit connect when MSG_FASTOPEN is set and a destination +is supplied. Add it to apparmor_socket_sendmsg() (not the shared +aa_sock_msg_perm() helper, which recvmsg also uses) and call aa_sk_perm() +directly, mirroring the selinux and tomoyo fixes. sk_is_tcp() does not +cover MPTCP fast open, so the SOCK_STREAM/IPPROTO_MPTCP arm is explicit. + +Fixes: cf60af03ca4e ("net-tcp: Fast Open client - sendmsg(MSG_FASTOPEN)") +Cc: stable@vger.kernel.org +Signed-off-by: Bryam Vargas +Signed-off-by: John Johansen +Signed-off-by: Greg Kroah-Hartman +--- + security/apparmor/lsm.c | 16 +++++++++++++++- + 1 file changed, 15 insertions(+), 1 deletion(-) + +--- a/security/apparmor/lsm.c ++++ b/security/apparmor/lsm.c +@@ -1422,7 +1422,21 @@ static int aa_sock_msg_perm(const char * + static int apparmor_socket_sendmsg(struct socket *sock, + struct msghdr *msg, int size) + { +- return aa_sock_msg_perm(OP_SENDMSG, AA_MAY_SEND, sock, msg, size); ++ int error = aa_sock_msg_perm(OP_SENDMSG, AA_MAY_SEND, sock, msg, size); ++ ++ if (error) ++ return error; ++ ++ /* TCP fast open carries connect() semantics in sendmsg(); mediate ++ * the implicit connect so it cannot bypass the connect permission. ++ */ ++ if ((msg->msg_flags & MSG_FASTOPEN) && msg->msg_name && ++ (sk_is_tcp(sock->sk) || ++ (sk_is_inet(sock->sk) && sock->sk->sk_type == SOCK_STREAM && ++ sock->sk->sk_protocol == IPPROTO_MPTCP))) ++ error = aa_sk_perm(OP_CONNECT, AA_MAY_CONNECT, sock->sk); ++ ++ return error; + } + + static int apparmor_socket_recvmsg(struct socket *sock, diff --git a/queue-7.1/mac802154-llsec-add-skb_cow_data-before-in-place-crypto.patch b/queue-7.1/mac802154-llsec-add-skb_cow_data-before-in-place-crypto.patch new file mode 100644 index 0000000000..b37ace26a5 --- /dev/null +++ b/queue-7.1/mac802154-llsec-add-skb_cow_data-before-in-place-crypto.patch @@ -0,0 +1,98 @@ +From 84a04eb5b210643bd67aab81ff805d32f62aa865 Mon Sep 17 00:00:00 2001 +From: Doruk Tan Ozturk +Date: Tue, 26 May 2026 20:37:26 +0200 +Subject: mac802154: llsec: add skb_cow_data() before in-place crypto + +From: Doruk Tan Ozturk + +commit 84a04eb5b210643bd67aab81ff805d32f62aa865 upstream. + +llsec_do_encrypt_unauth(), llsec_do_encrypt_auth(), +llsec_do_decrypt_unauth(), and llsec_do_decrypt_auth() all perform +in-place cryptographic transformations on skb data. They build a +scatterlist with sg_init_one() pointing into the skb's linear data area +and then pass the same scatterlist as both src and dst to the crypto API +(e.g. crypto_skcipher_encrypt/decrypt, crypto_aead_encrypt/decrypt). + +On the RX path, __ieee802154_rx_handle_packet() clones the received skb +before handing it to each subscriber via ieee802154_subif_frame(). The +cloned skb shares the same underlying data buffer via reference +counting. When llsec_do_decrypt() subsequently modifies this shared +buffer in place, it corrupts data that other clones -- potentially +belonging to other sockets or subsystems -- still reference. + +On the TX path, similar data sharing can occur when an skb's head has +been cloned (skb_cloned() returns true). + +The fix is to call skb_cow_data() before performing any in-place crypto +operation. skb_cow_data() ensures that the skb's data area is not +shared: if the skb head is cloned or the data spans multiple fragments, +it copies the data into a private buffer that can be safely modified in +place. This is the same pattern used by: + + - ESP (net/ipv4/esp4.c, net/ipv6/esp6.c) + - MACsec (drivers/net/macsec.c) + - WireGuard (drivers/net/wireguard/receive.c) + - TIPC (net/tipc/crypto.c) + +Without this guard, in-place crypto on shared skb data leads to: + - Silent data corruption of other skb clones + - Use-after-free when the crypto API scatterwalk writes through a + page that has already been freed by another clone's kfree_skb() + - Kernel crashes under concurrent 802.15.4 traffic with security + enabled (KASAN/KMSAN reports slab-use-after-free) + +Found by 0sec (https://0sec.ai) using automated source analysis. + +Fixes: 4c14a2fb5d14 ("mac802154: add llsec decryption method") +Fixes: 03556e4d0dbb ("mac802154: add llsec encryption method") +Cc: stable@vger.kernel.org +Reported-by: Doruk Tan Ozturk +Closes: https://lore.kernel.org/linux-wpan/20260525161806.96158-1-doruk@0sec.ai/ +Reviewed-by: Alexander Lobakin +Signed-off-by: Doruk Tan Ozturk +Closes: +Link: https://lore.kernel.org/20260526183726.56100-1-doruk@0sec.ai +Signed-off-by: Stefan Schmidt +Signed-off-by: Greg Kroah-Hartman +--- + net/mac802154/llsec.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +--- a/net/mac802154/llsec.c ++++ b/net/mac802154/llsec.c +@@ -710,6 +710,7 @@ int mac802154_llsec_encrypt(struct mac80 + { + struct ieee802154_hdr hdr; + int rc, authlen, hlen; ++ struct sk_buff *trailer; + struct mac802154_llsec_key *key; + u32 frame_ctr; + +@@ -769,6 +770,12 @@ int mac802154_llsec_encrypt(struct mac80 + skb->mac_len = ieee802154_hdr_push(skb, &hdr); + skb_reset_mac_header(skb); + ++ rc = skb_cow_data(skb, 0, &trailer); ++ if (rc < 0) { ++ llsec_key_put(key); ++ return rc; ++ } ++ + rc = llsec_do_encrypt(skb, sec, &hdr, key); + llsec_key_put(key); + +@@ -908,6 +915,13 @@ llsec_do_decrypt(struct sk_buff *skb, co + const struct ieee802154_hdr *hdr, + struct mac802154_llsec_key *key, __le64 dev_addr) + { ++ struct sk_buff *trailer; ++ int err; ++ ++ err = skb_cow_data(skb, 0, &trailer); ++ if (err < 0) ++ return err; ++ + if (hdr->sec.level == IEEE802154_SCF_SECLEVEL_ENC) + return llsec_do_decrypt_unauth(skb, sec, hdr, key, dev_addr); + else diff --git a/queue-7.1/net-ip_gre-require-cap_net_admin-in-the-device-netns-for-changelink.patch b/queue-7.1/net-ip_gre-require-cap_net_admin-in-the-device-netns-for-changelink.patch new file mode 100644 index 0000000000..28e3b33f46 --- /dev/null +++ b/queue-7.1/net-ip_gre-require-cap_net_admin-in-the-device-netns-for-changelink.patch @@ -0,0 +1,95 @@ +From 8165f7ff57d9667d2bb477ef6af83ede7fed4ad7 Mon Sep 17 00:00:00 2001 +From: Maoyi Xie +Date: Fri, 12 Jun 2026 16:59:35 +0800 +Subject: net: ip_gre: require CAP_NET_ADMIN in the device netns for changelink + +From: Maoyi Xie + +commit 8165f7ff57d9667d2bb477ef6af83ede7fed4ad7 upstream. + +A tunnel changelink() operates on at most two netns, dev_net(dev) and +the tunnel link netns t->net. They differ once the device is created in +or moved to a netns other than the one the request runs in. The rtnl +changelink path checks CAP_NET_ADMIN only against dev_net(dev), so a +caller privileged there but not in t->net can rewrite a tunnel that +lives in t->net. + +Add rtnl_dev_link_net_capable() next to rtnl_get_net_ns_capable() in +net/core/rtnetlink.c. It requires CAP_NET_ADMIN in the link netns and is +skipped when the link netns is dev_net(dev), where the rtnl path already +checked it. The other patches in this series use the same helper. + +Gate ipgre_changelink() and erspan_changelink() with it, at the top of +the op before any attribute is parsed, because the parsers update live +tunnel fields first. ipgre_netlink_parms() sets t->collect_md before +ip_tunnel_changelink() runs. + +Commit 8b484efd5cb4 ("ip6: vti: Use ip6_tnl.net in +vti6_siocdevprivate().") added the same check on the ioctl path. This +adds it on RTM_NEWLINK. + +Reported-by: Xiao Liang +Closes: https://lore.kernel.org/netdev/CABAhCOSzP1vaThGV35_VnsRCb=87_CPjPVsTHbq905k8A+BuUg@mail.gmail.com/ +Fixes: b57708add314 ("gre: add x-netns support") +Cc: stable@vger.kernel.org +Signed-off-by: Maoyi Xie +Reviewed-by: Kuniyuki Iwashima +Link: https://patch.msgid.link/20260612085941.3158249-2-maoyixie.tju@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + include/net/rtnetlink.h | 2 ++ + net/core/rtnetlink.c | 8 ++++++++ + net/ipv4/ip_gre.c | 6 ++++++ + 3 files changed, 16 insertions(+) + +--- a/include/net/rtnetlink.h ++++ b/include/net/rtnetlink.h +@@ -256,6 +256,8 @@ int rtnl_configure_link(struct net_devic + int rtnl_nla_parse_ifinfomsg(struct nlattr **tb, const struct nlattr *nla_peer, + struct netlink_ext_ack *exterr); + struct net *rtnl_get_net_ns_capable(struct sock *sk, int netnsid); ++bool rtnl_dev_link_net_capable(const struct net_device *dev, ++ const struct net *link_net); + + #define MODULE_ALIAS_RTNL_LINK(kind) MODULE_ALIAS("rtnl-link-" kind) + +--- a/net/core/rtnetlink.c ++++ b/net/core/rtnetlink.c +@@ -2421,6 +2421,14 @@ struct net *rtnl_get_net_ns_capable(stru + } + EXPORT_SYMBOL_GPL(rtnl_get_net_ns_capable); + ++bool rtnl_dev_link_net_capable(const struct net_device *dev, ++ const struct net *link_net) ++{ ++ return net_eq(link_net, dev_net(dev)) || ++ ns_capable(link_net->user_ns, CAP_NET_ADMIN); ++} ++EXPORT_SYMBOL_GPL(rtnl_dev_link_net_capable); ++ + static int rtnl_valid_dump_ifinfo_req(const struct nlmsghdr *nlh, + bool strict_check, struct nlattr **tb, + struct netlink_ext_ack *extack) +--- a/net/ipv4/ip_gre.c ++++ b/net/ipv4/ip_gre.c +@@ -1457,6 +1457,9 @@ static int ipgre_changelink(struct net_d + __u32 fwmark = t->fwmark; + int err; + ++ if (!rtnl_dev_link_net_capable(dev, t->net)) ++ return -EPERM; ++ + err = ipgre_newlink_encap_setup(dev, data); + if (err) + return err; +@@ -1486,6 +1489,9 @@ static int erspan_changelink(struct net_ + __u32 fwmark = t->fwmark; + int err; + ++ if (!rtnl_dev_link_net_capable(dev, t->net)) ++ return -EPERM; ++ + err = ipgre_newlink_encap_setup(dev, data); + if (err) + return err; diff --git a/queue-7.1/net-skmsg-preserve-sg.copy-across-sg-transforms.patch b/queue-7.1/net-skmsg-preserve-sg.copy-across-sg-transforms.patch new file mode 100644 index 0000000000..c6a44f4e91 --- /dev/null +++ b/queue-7.1/net-skmsg-preserve-sg.copy-across-sg-transforms.patch @@ -0,0 +1,288 @@ +From 406e8a651a7b854c41fecd5117bb282b3a6c2c6b Mon Sep 17 00:00:00 2001 +From: Yiming Qian +Date: Wed, 10 Jun 2026 06:21:36 +0000 +Subject: net: skmsg: preserve sg.copy across SG transforms + +From: Yiming Qian + +commit 406e8a651a7b854c41fecd5117bb282b3a6c2c6b upstream. + +The sk_msg sg.copy bitmap is part of the scatterlist entry ownership +state. A set bit tells sk_msg_compute_data_pointers() not to expose the +entry through writable BPF ctx->data. This protects entries backed by +pages that are not private to the sk_msg, such as splice-backed file +page-cache pages. + +Several sk_msg transform paths move, copy, split, or compact +msg->sg.data[] entries without moving the matching sg.copy bit. This can +make an externally backed entry arrive at a new slot with a clear copy +bit. A later SK_MSG verdict can then expose sg_virt(sge) as writable +ctx->data and BPF stores can modify the original page cache. + +Keep sg.copy synchronized with sg.data[] whenever entries are +transferred, shifted, split, or copied into a new sk_msg. Clear the bit +when an entry is replaced by a newly allocated private page or freed. +This covers the BPF pull/push/pop helpers, sk_msg_shift_left/right(), +sk_msg_xfer(), and tls_split_open_record(), including the partial tail +entry created during TLS open-record splitting. + +Fixes: d3b18ad31f93 ("tls: add bpf support to sk_msg handling") +Cc: stable@vger.kernel.org +Reported-by: Yiming Qian +Reported-by: Keenan Dong +Signed-off-by: Yiming Qian +Link: https://patch.msgid.link/20260610062137.49075-1-yimingqian591@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/skmsg.h | 15 +++++++++++---- + net/core/filter.c | 27 +++++++++++++++++++++++++++ + net/core/skmsg.c | 2 ++ + net/tls/tls_sw.c | 4 ++++ + 4 files changed, 44 insertions(+), 4 deletions(-) + +--- a/include/linux/skmsg.h ++++ b/include/linux/skmsg.h +@@ -4,6 +4,7 @@ + #ifndef _LINUX_SKMSG_H + #define _LINUX_SKMSG_H + ++#include + #include + #include + #include +@@ -199,11 +200,14 @@ static inline void sk_msg_xfer(struct sk + int which, u32 size) + { + dst->sg.data[which] = src->sg.data[which]; ++ __assign_bit(which, dst->sg.copy, test_bit(which, src->sg.copy)); + dst->sg.data[which].length = size; + dst->sg.size += size; + src->sg.size -= size; + src->sg.data[which].length -= size; + src->sg.data[which].offset += size; ++ if (!src->sg.data[which].length) ++ __clear_bit(which, src->sg.copy); + } + + static inline void sk_msg_xfer_full(struct sk_msg *dst, struct sk_msg *src) +@@ -273,16 +277,19 @@ static inline void sk_msg_page_add(struc + static inline void sk_msg_sg_copy(struct sk_msg *msg, u32 i, bool copy_state) + { + do { +- if (copy_state) +- __set_bit(i, msg->sg.copy); +- else +- __clear_bit(i, msg->sg.copy); ++ __assign_bit(i, msg->sg.copy, copy_state); + sk_msg_iter_var_next(i); + if (i == msg->sg.end) + break; + } while (1); + } + ++static inline void sk_msg_sg_copy_assign(struct sk_msg *dst, u32 dst_i, ++ const struct sk_msg *src, u32 src_i) ++{ ++ __assign_bit(dst_i, dst->sg.copy, test_bit(src_i, src->sg.copy)); ++} ++ + static inline void sk_msg_sg_copy_set(struct sk_msg *msg, u32 start) + { + sk_msg_sg_copy(msg, start, true); +--- a/net/core/filter.c ++++ b/net/core/filter.c +@@ -2733,11 +2733,13 @@ BPF_CALL_4(bpf_msg_pull_data, struct sk_ + poffset += len; + sge->length = 0; + put_page(sg_page(sge)); ++ __clear_bit(i, msg->sg.copy); + + sk_msg_iter_var_next(i); + } while (i != last_sge); + + sg_set_page(&msg->sg.data[first_sge], page, copy, 0); ++ __clear_bit(first_sge, msg->sg.copy); + + /* To repair sg ring we need to shift entries. If we only + * had a single entry though we can just replace it and +@@ -2763,9 +2765,11 @@ BPF_CALL_4(bpf_msg_pull_data, struct sk_ + break; + + msg->sg.data[i] = msg->sg.data[move_from]; ++ sk_msg_sg_copy_assign(msg, i, msg, move_from); + msg->sg.data[move_from].length = 0; + msg->sg.data[move_from].page_link = 0; + msg->sg.data[move_from].offset = 0; ++ __clear_bit(move_from, msg->sg.copy); + sk_msg_iter_var_next(i); + } while (1); + +@@ -2794,6 +2798,7 @@ BPF_CALL_4(bpf_msg_push_data, struct sk_ + { + struct scatterlist sge, nsge, nnsge, rsge = {0}, *psge; + u32 new, i = 0, l = 0, space, copy = 0, offset = 0; ++ bool sge_copy, nsge_copy, nnsge_copy, rsge_copy = false; + u8 *raw, *to, *from; + struct page *page; + +@@ -2866,6 +2871,7 @@ BPF_CALL_4(bpf_msg_push_data, struct sk_ + sk_msg_iter_var_prev(i); + psge = sk_msg_elem(msg, i); + rsge = sk_msg_elem_cpy(msg, i); ++ rsge_copy = test_bit(i, msg->sg.copy); + + psge->length = start - offset; + rsge.length -= psge->length; +@@ -2890,24 +2896,32 @@ BPF_CALL_4(bpf_msg_push_data, struct sk_ + + /* Shift one or two slots as needed */ + sge = sk_msg_elem_cpy(msg, new); ++ sge_copy = test_bit(new, msg->sg.copy); + sg_unmark_end(&sge); + + nsge = sk_msg_elem_cpy(msg, i); ++ nsge_copy = test_bit(i, msg->sg.copy); + if (rsge.length) { + sk_msg_iter_var_next(i); + nnsge = sk_msg_elem_cpy(msg, i); ++ nnsge_copy = test_bit(i, msg->sg.copy); + sk_msg_iter_next(msg, end); + } + + while (i != msg->sg.end) { + msg->sg.data[i] = sge; ++ __assign_bit(i, msg->sg.copy, sge_copy); + sge = nsge; ++ sge_copy = nsge_copy; + sk_msg_iter_var_next(i); + if (rsge.length) { + nsge = nnsge; ++ nsge_copy = nnsge_copy; + nnsge = sk_msg_elem_cpy(msg, i); ++ nnsge_copy = test_bit(i, msg->sg.copy); + } else { + nsge = sk_msg_elem_cpy(msg, i); ++ nsge_copy = test_bit(i, msg->sg.copy); + } + } + +@@ -2921,6 +2935,7 @@ place_new: + get_page(sg_page(&rsge)); + sk_msg_iter_var_next(new); + msg->sg.data[new] = rsge; ++ __assign_bit(new, msg->sg.copy, rsge_copy); + } + + sk_msg_reset_curr(msg); +@@ -2948,25 +2963,33 @@ static void sk_msg_shift_left(struct sk_ + prev = i; + sk_msg_iter_var_next(i); + msg->sg.data[prev] = msg->sg.data[i]; ++ sk_msg_sg_copy_assign(msg, prev, msg, i); + } while (i != msg->sg.end); + + sk_msg_iter_prev(msg, end); ++ __clear_bit(msg->sg.end, msg->sg.copy); + } + + static void sk_msg_shift_right(struct sk_msg *msg, int i) + { + struct scatterlist tmp, sge; ++ bool tmp_copy, sge_copy; + + sk_msg_iter_next(msg, end); + sge = sk_msg_elem_cpy(msg, i); ++ sge_copy = test_bit(i, msg->sg.copy); + sk_msg_iter_var_next(i); + tmp = sk_msg_elem_cpy(msg, i); ++ tmp_copy = test_bit(i, msg->sg.copy); + + while (i != msg->sg.end) { + msg->sg.data[i] = sge; ++ __assign_bit(i, msg->sg.copy, sge_copy); + sk_msg_iter_var_next(i); + sge = tmp; ++ sge_copy = tmp_copy; + tmp = sk_msg_elem_cpy(msg, i); ++ tmp_copy = test_bit(i, msg->sg.copy); + } + } + +@@ -3026,6 +3049,8 @@ BPF_CALL_4(bpf_msg_pop_data, struct sk_m + struct scatterlist *nsge, *sge = sk_msg_elem(msg, i); + int a = start - offset; + int b = sge->length - pop - a; ++ u32 sge_i = i; ++ bool sge_copy = test_bit(i, msg->sg.copy); + + sk_msg_iter_var_next(i); + +@@ -3038,6 +3063,7 @@ BPF_CALL_4(bpf_msg_pop_data, struct sk_m + sg_set_page(nsge, + sg_page(sge), + b, sge->offset + pop + a); ++ __assign_bit(i, msg->sg.copy, sge_copy); + } else { + struct page *page, *orig; + u8 *to, *from; +@@ -3054,6 +3080,7 @@ BPF_CALL_4(bpf_msg_pop_data, struct sk_m + memcpy(to, from, a); + memcpy(to + a, from + a + pop, b); + sg_set_page(sge, page, a + b, 0); ++ __clear_bit(sge_i, msg->sg.copy); + put_page(orig); + } + pop = 0; +--- a/net/core/skmsg.c ++++ b/net/core/skmsg.c +@@ -66,6 +66,7 @@ int sk_msg_alloc(struct sock *sk, struct + sge = &msg->sg.data[msg->sg.end]; + sg_unmark_end(sge); + sg_set_page(sge, pfrag->page, use, orig_offset); ++ __clear_bit(msg->sg.end, msg->sg.copy); + get_page(pfrag->page); + sk_msg_iter_next(msg, end); + } +@@ -186,6 +187,7 @@ static int sk_msg_free_elem(struct sock + sk_mem_uncharge(sk, len); + put_page(sg_page(sge)); + } ++ __clear_bit(i, msg->sg.copy); + memset(sge, 0, sizeof(*sge)); + return len; + } +--- a/net/tls/tls_sw.c ++++ b/net/tls/tls_sw.c +@@ -623,6 +623,7 @@ static int tls_split_open_record(struct + struct scatterlist *sge, *osge, *nsge; + u32 orig_size = msg_opl->sg.size; + struct scatterlist tmp = { }; ++ u32 tmp_i = 0; + struct sk_msg *msg_npl; + struct tls_rec *new; + int ret; +@@ -644,6 +645,7 @@ static int tls_split_open_record(struct + if (sge->length > apply) { + u32 len = sge->length - apply; + ++ tmp_i = i; + get_page(sg_page(sge)); + sg_set_page(&tmp, sg_page(sge), len, + sge->offset + apply); +@@ -675,6 +677,7 @@ static int tls_split_open_record(struct + nsge = sk_msg_elem(msg_npl, j); + if (tmp.length) { + memcpy(nsge, &tmp, sizeof(*nsge)); ++ sk_msg_sg_copy_assign(msg_npl, j, msg_opl, tmp_i); + sk_msg_iter_var_next(j); + nsge = sk_msg_elem(msg_npl, j); + } +@@ -682,6 +685,7 @@ static int tls_split_open_record(struct + osge = sk_msg_elem(msg_opl, i); + while (osge->length) { + memcpy(nsge, osge, sizeof(*nsge)); ++ sk_msg_sg_copy_assign(msg_npl, j, msg_opl, i); + sg_unmark_end(nsge); + sk_msg_iter_var_next(i); + sk_msg_iter_var_next(j); diff --git a/queue-7.1/pci-p2pdma-add-intel-qat-dsa-iaa-devices-to-whitelist.patch b/queue-7.1/pci-p2pdma-add-intel-qat-dsa-iaa-devices-to-whitelist.patch new file mode 100644 index 0000000000..68b5209c2b --- /dev/null +++ b/queue-7.1/pci-p2pdma-add-intel-qat-dsa-iaa-devices-to-whitelist.patch @@ -0,0 +1,134 @@ +From 0ba76b19fd4c7256787eab0283c759b18eb76876 Mon Sep 17 00:00:00 2001 +From: Lukas Wunner +Date: Thu, 4 Jun 2026 17:12:08 +0200 +Subject: PCI/P2PDMA: Add Intel QAT, DSA, IAA devices to whitelist + +From: Lukas Wunner + +commit 0ba76b19fd4c7256787eab0283c759b18eb76876 upstream. + +The first device on a PCI root bus determines whether the host bridge is +whitelisted for P2PDMA. All Intel Xeon chips since Ice Lake (ICX, 2021) +expose a device with ID 0x09a2 as first device. It is loosely associated +with the IOMMU. All these Xeon chips support P2PDMA, so since the addition +of the device with commit feaea1fe8b36 ("PCI/P2PDMA: Add Intel 3rd Gen +Intel Xeon Scalable Processors to whitelist"), P2PDMA has been allowed on +all new Xeons without the need to amend the whitelist: + +Xeons with Performance Cores: + Sapphire Rapids (SPR, 2023) + Emerald Rapids (EMR, 2023) + Granite Rapids (GNR, 2024) + Diamond Rapids (DMR, 2026) + +Xeons with Efficiency Cores: + Sierra Forest (SRF, 2024) + Clearwater Forest (CWF, 2026) + +However these Xeons also expose accelerators as first device on a root bus +of its own: + + QuickAssist Technology (QAT, crypto & compression accelerator) + Data Streaming Accelerator (DSA, dma engine) + In-Memory Analytics Accelerator (IAA, compression accelerator) + +Whitelist them for P2PDMA as well. Move their Device ID macros from the +accelerator drivers to for reuse by P2PDMA code. + +Unfortunately the Device IDs vary across Xeon generations as additional +features were added to the accelerators. This currently necessitates an +amendment for each new Xeon chip. + +For future chips, this need shall be avoided by an ongoing effort to extend +ACPI HMAT with PCIe P2PDMA characteristics (latency, bandwidth, ordering +constraints). The PCI core will be able look up in this BIOS-provided ACPI +table whether P2PDMA is supported, instead of relying on a whitelist that +needs to be amended continuously. + +Signed-off-by: Lukas Wunner +Signed-off-by: Bjorn Helgaas +Acked-by: Vinicius Costa Gomes +Acked-by: Giovanni Cabiddu # QAT +Cc: stable@vger.kernel.org +Link: https://patch.msgid.link/6aac4922b5fe7070b11874427a9285e42ddd05a4.1780585518.git.lukas@wunner.de +Signed-off-by: Greg Kroah-Hartman +--- + drivers/crypto/intel/qat/qat_common/adf_accel_devices.h | 5 ----- + drivers/dma/idxd/registers.h | 3 --- + drivers/pci/p2pdma.c | 10 ++++++++++ + include/linux/pci_ids.h | 8 ++++++++ + 4 files changed, 18 insertions(+), 8 deletions(-) + +--- a/drivers/crypto/intel/qat/qat_common/adf_accel_devices.h ++++ b/drivers/crypto/intel/qat/qat_common/adf_accel_devices.h +@@ -28,15 +28,10 @@ + #define ADF_4XXX_DEVICE_NAME "4xxx" + #define ADF_420XX_DEVICE_NAME "420xx" + #define ADF_6XXX_DEVICE_NAME "6xxx" +-#define PCI_DEVICE_ID_INTEL_QAT_4XXX 0x4940 + #define PCI_DEVICE_ID_INTEL_QAT_4XXXIOV 0x4941 +-#define PCI_DEVICE_ID_INTEL_QAT_401XX 0x4942 + #define PCI_DEVICE_ID_INTEL_QAT_401XXIOV 0x4943 +-#define PCI_DEVICE_ID_INTEL_QAT_402XX 0x4944 + #define PCI_DEVICE_ID_INTEL_QAT_402XXIOV 0x4945 +-#define PCI_DEVICE_ID_INTEL_QAT_420XX 0x4946 + #define PCI_DEVICE_ID_INTEL_QAT_420XXIOV 0x4947 +-#define PCI_DEVICE_ID_INTEL_QAT_6XXX 0x4948 + #define PCI_DEVICE_ID_INTEL_QAT_6XXX_IOV 0x4949 + + #define ADF_DEVICE_FUSECTL_OFFSET 0x40 +--- a/drivers/dma/idxd/registers.h ++++ b/drivers/dma/idxd/registers.h +@@ -10,9 +10,6 @@ + #endif + + /* PCI Config */ +-#define PCI_DEVICE_ID_INTEL_DSA_GNRD 0x11fb +-#define PCI_DEVICE_ID_INTEL_DSA_DMR 0x1212 +-#define PCI_DEVICE_ID_INTEL_IAA_DMR 0x1216 + #define PCI_DEVICE_ID_INTEL_IAA_PTL 0xb02d + #define PCI_DEVICE_ID_INTEL_IAA_WCL 0xfd2d + +--- a/drivers/pci/p2pdma.c ++++ b/drivers/pci/p2pdma.c +@@ -548,6 +548,16 @@ static const struct pci_p2pdma_whitelist + {PCI_VENDOR_ID_INTEL, 0x2033, 0}, + {PCI_VENDOR_ID_INTEL, 0x2020, 0}, + {PCI_VENDOR_ID_INTEL, 0x09a2, 0}, ++ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_DSA_SPR0, 0}, ++ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IAX_SPR0, 0}, ++ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_DSA_GNRD, 0}, ++ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_DSA_DMR, 0}, ++ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IAA_DMR, 0}, ++ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_QAT_4XXX, 0}, ++ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_QAT_401XX, 0}, ++ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_QAT_402XX, 0}, ++ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_QAT_420XX, 0}, ++ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_QAT_6XXX, 0}, + /* Google SoCs. */ + {PCI_VENDOR_ID_GOOGLE, PCI_ANY_ID, 0}, + {} +--- a/include/linux/pci_ids.h ++++ b/include/linux/pci_ids.h +@@ -2732,6 +2732,9 @@ + #define PCI_DEVICE_ID_INTEL_82815_MC 0x1130 + #define PCI_DEVICE_ID_INTEL_82815_CGC 0x1132 + #define PCI_DEVICE_ID_INTEL_SST_TNG 0x119a ++#define PCI_DEVICE_ID_INTEL_DSA_GNRD 0x11fb ++#define PCI_DEVICE_ID_INTEL_DSA_DMR 0x1212 ++#define PCI_DEVICE_ID_INTEL_IAA_DMR 0x1216 + #define PCI_DEVICE_ID_INTEL_82092AA_0 0x1221 + #define PCI_DEVICE_ID_INTEL_82437 0x122d + #define PCI_DEVICE_ID_INTEL_82371FB_0 0x122e +@@ -3052,6 +3055,11 @@ + #define PCI_DEVICE_ID_INTEL_5400_FBD1 0x4036 + #define PCI_DEVICE_ID_INTEL_HDA_TGL_H 0x43c8 + #define PCI_DEVICE_ID_INTEL_HDA_DG1 0x490d ++#define PCI_DEVICE_ID_INTEL_QAT_4XXX 0x4940 ++#define PCI_DEVICE_ID_INTEL_QAT_401XX 0x4942 ++#define PCI_DEVICE_ID_INTEL_QAT_402XX 0x4944 ++#define PCI_DEVICE_ID_INTEL_QAT_420XX 0x4946 ++#define PCI_DEVICE_ID_INTEL_QAT_6XXX 0x4948 + #define PCI_DEVICE_ID_INTEL_HDA_EHL_0 0x4b55 + #define PCI_DEVICE_ID_INTEL_HDA_EHL_3 0x4b58 + #define PCI_DEVICE_ID_INTEL_HDA_WCL 0x4d28 diff --git a/queue-7.1/series b/queue-7.1/series index 3443ebc53d..d2928bab6c 100644 --- a/queue-7.1/series +++ b/queue-7.1/series @@ -29,3 +29,9 @@ ipv6-account-for-fraggap-on-the-paged-allocation-path.patch ipv4-account-for-fraggap-on-the-paged-allocation-pat.patch ntfs3-reject-direct-userspace-writes-to-reserved-lx-xattrs.patch wifi-mt76-add-wcid-publish-check-in-mt76_sta_add.patch +mac802154-llsec-add-skb_cow_data-before-in-place-crypto.patch +net-skmsg-preserve-sg.copy-across-sg-transforms.patch +net-ip_gre-require-cap_net_admin-in-the-device-netns-for-changelink.patch +pci-p2pdma-add-intel-qat-dsa-iaa-devices-to-whitelist.patch +apparmor-mediate-the-implicit-connect-of-tcp-fast-open-sendmsg.patch +apparmor-fix-use-after-free-in-rawdata-dedup-loop.patch -- 2.47.3