[PATCH openEuler-1.0-LTS 0/5] CVE-2026-90049
Mike Pattrick (2): openvswitch: Fix double reporting of drops in dropwatch openvswitch: Fix overreporting of drops in dropwatch Norbert Szetei (3): openvswitch: only skb_tx_error() a packet we are about to drop net: skbuff: don't skb_tx_error() the source skb in skb_zerocopy() net: skbuff: don't touch shared zerocopy state in skb_tx_error() net/core/skbuff.c | 7 +++++-- net/openvswitch/datapath.c | 21 ++++++++++++++------- 2 files changed, 19 insertions(+), 9 deletions(-) -- 2.33.8
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://atomgit.com/openeuler/kernel/merge_requests/28499 邮件列表地址:https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/RQD... FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://atomgit.com/openeuler/kernel/merge_requests/28499 Mailing list address: https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/RQD...
From: Mike Pattrick <mkp@redhat.com> mainline inclusion from mainline-v6.1-rc1 commit 1100248a5c5ccd57059eb8d02ec077e839a23826 category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/19120 CVE: CVE-2026-90049 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i... -------------------------------- Frames sent to userspace can be reported as dropped in ovs_dp_process_packet, however, if they are dropped in the netlink code then netlink_attachskb will report the same frame as dropped. This patch checks for error codes which indicate that the frame has already been freed. Signed-off-by: Mike Pattrick <mkp@redhat.com> Link: https://bugzilla.redhat.com/show_bug.cgi?id=2109946 Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: JiangJieHua <jiangjiehua1@huawei.com> --- net/openvswitch/datapath.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index bd00e63603ca8..8eeb01936c10d 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c @@ -249,10 +249,17 @@ void ovs_dp_process_packet(struct sk_buff *skb, struct sw_flow_key *key) upcall.portid = ovs_vport_find_upcall_portid(p, skb); upcall.mru = OVS_CB(skb)->mru; error = ovs_dp_upcall(dp, skb, key, &upcall, 0); - if (unlikely(error)) - kfree_skb(skb); - else + switch (error) { + case 0: + case -EAGAIN: + case -ERESTARTSYS: + case -EINTR: consume_skb(skb); + break; + default: + kfree_skb(skb); + break; + } stats_counter = &stats->n_missed; goto out; } -- 2.33.8
From: Mike Pattrick <mkp@redhat.com> mainline inclusion from mainline-v6.1-rc1 commit c21ab2afa2c64896a7f0e3cbc6845ec63dcfad2e category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/19120 CVE: CVE-2026-90049 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i... -------------------------------- Currently queue_userspace_packet will call kfree_skb for all frames, whether or not an error occurred. This can result in a single dropped frame being reported as multiple drops in dropwatch. This functions caller may also call kfree_skb in case of an error. This patch will consume the skbs instead and allow caller's to use kfree_skb. Signed-off-by: Mike Pattrick <mkp@redhat.com> Link: https://bugzilla.redhat.com/show_bug.cgi?id=2109957 Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: JiangJieHua <jiangjiehua1@huawei.com> --- net/openvswitch/datapath.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index 8eeb01936c10d..c69145fc73599 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c @@ -541,8 +541,9 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb, out: if (err) skb_tx_error(skb); - kfree_skb(user_skb); - kfree_skb(nskb); + consume_skb(user_skb); + consume_skb(nskb); + return err; } -- 2.33.8
From: Norbert Szetei <norbert@doyensec.com> mainline inclusion from mainline-v7.3-rc1 commit 0dbc2398fca3bb33eda963849f865ddb1b3aa05e category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/19120 CVE: CVE-2026-90049 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i... -------------------------------- queue_userspace_packet() borrows the packet skb -- it only copies it into a private netlink message (user_skb) and does not own it; on return do_execute_actions() keeps forwarding it through the flow's remaining actions. Its error path nevertheless calls skb_tx_error(skb), which via skb_zcopy_clear() does skb_shinfo(skb)->flags &= ~SKBFL_ALL_ZEROCOPY, stripping SKBFL_SHARED_FRAG from that live skb (skb_tx_error()'s kerneldoc says "skb must be freed afterwards"). For a MSG_ZEROCOPY skb carrying page-cache frags, SKBFL_SHARED_FRAG is what makes esp_input() skb_cow_data() before in-place AEAD; once it is stripped a later local ESP-in-UDP delivery decrypts in place over pages the sender does not own -- an unprivileged page-cache write (the "Fragnesia" primitive). do_execute_actions() ignores output_userspace()'s return value, so any action after a failed USERSPACE upcall inherits the stripped skb. Move the skb_tx_error() to the flow-miss drop path - the "default" branch of ovs_dp_process_packet()'s switch(error), before kfree_skb(). The call has been here since commit 36d5fe6a0007 ("core, nfqueue, openvswitch: Orphan frags in skb_zerocopy and handle errors") but was harmless until esp_input() began relying on SKBFL_SHARED_FRAG to gate in-place decrypt; only then did stripping it on a still-forwarded skb become a page-cache write primitive. Fixes: 36d5fe6a0007 ("core, nfqueue, openvswitch: Orphan frags in skb_zerocopy and handle errors") Fixes: f4c50a4034e6 ("xfrm: esp: avoid in-place decrypt on shared skb frags") Cc: stable@vger.kernel.org Assisted-by: Claude:claude-opus-5 Signed-off-by: Norbert Szetei <norbert@doyensec.com> Reviewed-by: Ilya Maximets <i.maximets@ovn.org> Tested-by: Jongmin Jang <payload.jang@gmail.com> Link: https://patch.msgid.link/55A52703-7548-4A55-A9CE-2A37145BDCAD@doyensec.com Signed-off-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: JiangJieHua <jiangjiehua1@huawei.com> --- net/openvswitch/datapath.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index c69145fc73599..575896bb83d16 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c @@ -257,6 +257,7 @@ void ovs_dp_process_packet(struct sk_buff *skb, struct sw_flow_key *key) consume_skb(skb); break; default: + skb_tx_error(skb); kfree_skb(skb); break; } @@ -539,8 +540,6 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb, err = genlmsg_unicast(ovs_dp_get_net(dp), user_skb, upcall_info->portid); user_skb = NULL; out: - if (err) - skb_tx_error(skb); consume_skb(user_skb); consume_skb(nskb); -- 2.33.8
From: Norbert Szetei <norbert@doyensec.com> mainline inclusion from mainline-v7.3-rc1 commit 8ece906150128d5ec2462aabcc978c568433eca4 category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/19120 CVE: CVE-2026-90049 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i... -------------------------------- skb_zerocopy() copies frags from @from into @to. On an skb_orphan_frags() failure it calls skb_tx_error(@from), a destructive operation on the source skb the copy helper does not own. That completes @from's zerocopy uarg and clears SKBFL_ALL_ZEROCOPY, including the SKBFL_SHARED_FRAG page-ownership marker. Both callers already report the failure on their own drop path. nfnetlink_queue does it at nla_put_failure, and Open vSwitch does it in the flow-miss drop arm of ovs_dp_process_packet(), so nothing is lost by dropping it here. On Open vSwitch's OVS_ACTION_ATTR_USERSPACE path the skb is not freed on this error: do_execute_actions() ignores output_userspace()'s return value and, unless the upcall was the last action, keeps forwarding the same skb through the flow's remaining actions. The uarg is completed while that skb is still in flight, telling the producer its buffers are free, and SKBFL_SHARED_FRAG is cleared on an skb the rest of the stack still handles. That flag is what makes esp_input() call skb_cow_data() instead of decrypting in place, so a later local ESP delivery can decrypt over frags the skb does not own privately. Leave error reporting to the callers. Fixes: 36d5fe6a0007 ("core, nfqueue, openvswitch: Orphan frags in skb_zerocopy and handle errors") Cc: stable@vger.kernel.org Suggested-by: Ilya Maximets <i.maximets@ovn.org> Signed-off-by: Norbert Szetei <norbert@doyensec.com> Reviewed-by: Ilya Maximets <i.maximets@ovn.org> Reviewed-by: Willem de Bruijn <willemb@google.com> Link: https://patch.msgid.link/6E3A780D-FB87-421F-9964-B1D457D7D106@doyensec.com Signed-off-by: Paolo Abeni <pabeni@redhat.com> Conflicts: net/core/skbuff.c [Commit 68d8c6532659 ("net: core: propagate unreadable flag in skb_zerocopy") is not present in this tree, so only the removal of skb_tx_error(from) was applied; the j > 0 put_page() cleanup added by that later commit is not part of this fix and was not introduced.] Signed-off-by: JiangJieHua <jiangjiehua1@huawei.com> --- net/core/skbuff.c | 1 - 1 file changed, 1 deletion(-) diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 49f0b680ab8a0..17594aa4124d7 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -2829,7 +2829,6 @@ skb_zerocopy(struct sk_buff *to, struct sk_buff *from, int len, int hlen) to->data_len += len + plen; if (unlikely(skb_orphan_frags(from, GFP_ATOMIC))) { - skb_tx_error(from); return -ENOMEM; } skb_zerocopy_clone(to, from, GFP_ATOMIC); -- 2.33.8
From: Norbert Szetei <norbert@doyensec.com> mainline inclusion from mainline-v7.3-rc1 commit f66bdb1cc0fcd227a062378f8be0b5873aa5600a category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/19120 CVE: CVE-2026-90049 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i... -------------------------------- skb_tx_error() completes the zerocopy uarg and clears SKBFL_ALL_ZEROCOPY, and skb_zcopy_downgrade_managed() clears SKBFL_MANAGED_FRAG_REFS. Both live in skb_shinfo(), which every clone shares, while the caller only owns the reference it is about to drop. Through a clone it tells the producer its pages are free and drops SKBFL_SHARED_FRAG for an skb that is still in flight. Open vSwitch reaches this with a non-last OVS_ACTION_ATTR_RECIRC: clone_execute() sends a skb_clone() into ovs_dp_process_packet() while do_execute_actions() keeps forwarding the original, and skb_clone() does not privatise the frags here -- skb_orphan_frags() returns early on SKBFL_DONT_ORPHAN. A flow miss on the clone then strips the marker from the packet still being forwarded, and a later local ESP delivery decrypts in place over frags it does not own privately. Skip it for a cloned skb. Nothing is lost: skb_release_data() clears the zerocopy state once the last reference to the shared data goes. Fixes: 25121173f7b1 ("skb: api to report errors for zero copy skbs") Cc: stable@vger.kernel.org Suggested-by: Ilya Maximets <i.maximets@ovn.org> Signed-off-by: Norbert Szetei <norbert@doyensec.com> Reviewed-by: Ilya Maximets <i.maximets@ovn.org> Tested-by: Jongmin Jang <payload.jang@gmail.com> Reviewed-by: Willem de Bruijn <willemb@google.com> Link: https://patch.msgid.link/CFAB292A-674B-4C14-BB2C-BB8830AD5659@doyensec.com Signed-off-by: Paolo Abeni <pabeni@redhat.com> Conflicts: net/core/skbuff.c [Conflicts are caused by the following patches not being merged: skb_tx_error() lacks the if (skb) wrapper and the skb_zcopy_downgrade_managed() call (managed-frags infra absent): 753f1ca4e1e5 ("net: introduce managed frags infrastructure")] Signed-off-by: JiangJieHua <jiangjiehua1@huawei.com> --- net/core/skbuff.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 17594aa4124d7..63113e9176bbd 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -691,10 +691,14 @@ EXPORT_SYMBOL(kfree_skb_list); * * Report xmit error if a device callback is tracking this skb. * skb must be freed afterwards. + * + * Does nothing for a cloned skb: the zerocopy state lives in + * skb_shinfo(), which the clones share. */ void skb_tx_error(struct sk_buff *skb) { - skb_zcopy_clear(skb, true); + if (skb && !skb_cloned(skb)) + skb_zcopy_clear(skb, true); } EXPORT_SYMBOL(skb_tx_error); -- 2.33.8
participants (2)
-
JiangJieHua -
patchwork bot