Skip to content

[Deepin-Kernel-SIG] [linux 6.6.y] bpf: fix recent three come up with bugs from upstream#1513

Merged
opsiff merged 3 commits into
deepin-community:linux-6.6.yfrom
xu-lang:linux-6.6.y
Feb 27, 2026
Merged

[Deepin-Kernel-SIG] [linux 6.6.y] bpf: fix recent three come up with bugs from upstream#1513
opsiff merged 3 commits into
deepin-community:linux-6.6.yfrom
xu-lang:linux-6.6.y

Conversation

@xu-lang
Copy link
Copy Markdown
Contributor

@xu-lang xu-lang commented Feb 27, 2026

bug1: https://lore.kernel.org/all/fa2be179-bad7-4ee3-8668-4903d1853461@hust.edu.cn/
bug2: https://lore.kernel.org/all/de98e423-a113-4a11-853d-9706cbc07e37@hust.edu.cn/
bug3: https://lore.kernel.org/all/3c4ebb0b.46ff8.19abab8abe2.Coremail.kaiyanm@hust.edu.cn/

fix1(a86d5ab): from upstream
fix2(4a98882): is a temporary fix
fix3(c923ab1): is being commited to upstream

Summary by Sourcery

Fix multiple BPF-related bugs in XDP test infrastructure, LWT BPF encapsulation, and cgroup trampoline shim handling.

Bug Fixes:

  • Correct XDP page layout handling in test_run to use an embedded xdp_frame and adjust buffer/headroom usage accordingly.
  • Prevent a potential NULL-pointer dereference in LWT BPF IP encapsulation by validating skb_dst() before using LL_RESERVED_SPACE().
  • Ensure safe reuse of existing cgroup shim links in the BPF trampoline by only proceeding when the link refcount can be incremented.

Enhancements:

  • Adjust XDP maximum packet size calculations to account for the updated xdp_page_head layout.

Tests:

  • Update XDP redirect selftest maximum packet size limits to match the revised XDP buffer and header layout.

mannkafai and others added 3 commits February 27, 2026 13:54
When testing XDP programs with LIVE_FRAMES mode, if the metalen is set
to >= (XDP_PACKET_HEADROOM - sizeof(struct xdp_frame)), there won't be
enough space for the xdp_frame conversion in xdp_update_frame_from_buff().
Additionally, the xdp_frame structure may be filled with user-provided data,
which can lead to a memory access vulnerability when converting to skb.

This fix reverts to the original version and ensures data_hard_start
correctly points to the xdp_frame structure, eliminating the security risk.

bug-url: https://lore.kernel.org/all/fa2be179-bad7-4ee3-8668-4903d1853461@hust.edu.cn/
upstream-patch: https://lore.kernel.org/all/20260104162350.347403-2-kafai.wan@linux.dev/

Reported-by: Yinhao Hu <dddddd@hust.edu.cn>
Reported-by: Kaiyan Mei <M202472210@hust.edu.cn>
Reviewed-by: Dongliang Mu <dzm91@hust.edu.cn>
Fixes: 294635a ("bpf, test_run: fix &xdp_frame misplacement for LIVE_FRAMES")
Signed-off-by: KaFai Wan <kafai.wan@linux.dev>
Signed-off-by: xulang <xulang@uniontech.com>
@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented Feb 27, 2026

Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

This PR backports/fixes three upstream BPF/XDP issues: adjusts xdp_page_head layout and users to fix XDP test context handling and max packet size, hardens lwt BPF IP encapsulation against missing dst, and makes cgroup shim trampoline link reuse safe with refcount checks.

Sequence diagram for lwt BPF IP encapsulation with dst safety check

sequenceDiagram
  title bpf_lwt_push_ip_encap handling ingress and egress with dst validation
  participant Caller
  participant bpf_lwt_push_ip_encap
  participant sk_buff as skb
  participant dst_entry as dst
  participant net_device as dev

  Caller->>bpf_lwt_push_ip_encap: bpf_lwt_push_ip_encap(skb, hdr, len, ingress)
  alt ingress path
    bpf_lwt_push_ip_encap->>bpf_lwt_push_ip_encap: err = skb_cow_head(skb, len + skb.mac_len)
  else egress path
    bpf_lwt_push_ip_encap->>sk_buff: skb_dst(skb)
    alt dst missing
      bpf_lwt_push_ip_encap-->>Caller: return -EINVAL
    else dst present
      sk_buff-->>bpf_lwt_push_ip_encap: dst
      bpf_lwt_push_ip_encap->>dst_entry: access dev
      dst_entry-->>bpf_lwt_push_ip_encap: dev
      bpf_lwt_push_ip_encap->>bpf_lwt_push_ip_encap: err = skb_cow_head(skb, len + LL_RESERVED_SPACE(dev))
    end
  end
  alt err is nonzero
    bpf_lwt_push_ip_encap-->>Caller: return err
  else success
    bpf_lwt_push_ip_encap-->>Caller: continue with encapsulation
  end
Loading

Sequence diagram for safe cgroup shim trampoline link reuse with refcount check

sequenceDiagram
  title bpf_trampoline_link_cgroup_shim link reuse with atomic refcount increment
  participant Caller
  participant bpf_trampoline_link_cgroup_shim
  participant bpf_trampoline as tr
  participant cgroup_shim_find
  participant cgroup_shim_link as shim_link
  participant atomic64_inc_not_zero

  Caller->>bpf_trampoline_link_cgroup_shim: bpf_trampoline_link_cgroup_shim(prog, bpf_func, tr)
  bpf_trampoline_link_cgroup_shim->>bpf_trampoline as tr: mutex_lock(tr.mutex)
  bpf_trampoline_link_cgroup_shim->>cgroup_shim_find: cgroup_shim_find(tr, bpf_func)
  cgroup_shim_find-->>bpf_trampoline_link_cgroup_shim: shim_link or null

  alt shim_link exists
    bpf_trampoline_link_cgroup_shim->>atomic64_inc_not_zero: atomic64_inc_not_zero(shim_link.link.link.refcnt)
    alt refcount increment succeeded
      bpf_trampoline_link_cgroup_shim->>bpf_trampoline as tr: mutex_unlock(tr.mutex)
      bpf_trampoline_link_cgroup_shim-->>Caller: return 0 (reuse existing shim)
    else refcount increment failed
      bpf_trampoline_link_cgroup_shim->>bpf_trampoline as tr: continue to allocate new shim link
      bpf_trampoline_link_cgroup_shim-->>Caller: proceed with new shim setup
    end
  else no existing shim_link
    bpf_trampoline_link_cgroup_shim->>bpf_trampoline as tr: allocate and attach new shim
    bpf_trampoline_link_cgroup_shim-->>Caller: return (new shim attached)
  end
Loading

Class diagram for updated BPF trampoline and skb handling structures

classDiagram
  title Updated structures for bpf_trampoline and skb dst safety

  class sk_buff {
    +int mac_len
    +pointer dst
    +int skb_cow_head(pointer skb, unsigned int headroom)
    +pointer skb_dst(pointer skb)
  }

  class dst_entry {
    +pointer dev
  }

  class net_device {
    +unsigned int LL_RESERVED_SPACE(pointer dev)
  }

  class bpf_link {
    +atomic64_t refcnt
  }

  class cgroup_shim_link {
    +bpf_link link
  }

  class bpf_trampoline {
    +mutex mutex
    +int bpf_trampoline_link_cgroup_shim(pointer prog, pointer bpf_func, pointer tr)
    +pointer cgroup_shim_find(pointer tr, pointer bpf_func)
  }

  sk_buff --> dst_entry : dst
  dst_entry --> net_device : dev
  cgroup_shim_link --> bpf_link : contains
  bpf_trampoline --> cgroup_shim_link : manages shim_link

  class atomic64_t {
    +bool atomic64_inc_not_zero(pointer v)
  }

  bpf_link --> atomic64_t : uses refcnt

  class bpf_lwt_helpers {
    +int bpf_lwt_push_ip_encap(pointer skb, pointer hdr, u32 len, bool ingress)
  }

  bpf_lwt_helpers --> sk_buff : manipulates headroom
  bpf_lwt_helpers --> net_device : uses LL_RESERVED_SPACE
  bpf_lwt_helpers --> dst_entry : reads dst
  bpf_trampoline --> bpf_link : reuses existing link via refcnt
  bpf_trampoline --> atomic64_t : calls atomic64_inc_not_zero
Loading

File-Level Changes

Change Details Files
Refactor xdp_page_head layout and adjust XDP test helpers to use an embedded xdp_frame instead of a flex-array, fixing context/frame handling and derived max packet size limits.
  • Change xdp_page_head to contain a concrete struct xdp_frame plus a trailing flex-array data buffer instead of a union of flex-array frame/data
  • Update xdp_test_run_init_page to account for sizeof(struct xdp_frame) in headroom calculations and to initialize frame and data pointers correctly
  • Adjust frame_was_changed, reset_ctx, and xdp_test_run_batch to use the embedded frame field with direct member access
  • Reduce MAX_PKT_SIZE constants in xdp_do_redirect selftest to reflect the additional xdp_frame space in the page head
net/bpf/test_run.c
tools/testing/selftests/bpf/prog_tests/xdp_do_redirect.c
Harden bpf_lwt_push_ip_encap for egress by validating skb_dst before using LL_RESERVED_SPACE, returning -EINVAL if no dst is present.
  • Wrap the egress skb_cow_head() path in a block that first checks skb_dst(skb) and bails out with -EINVAL if it is NULL
  • Leave ingress skb_cow_head() behavior unchanged
net/core/lwt_bpf.c
Make cgroup shim trampoline link reuse safe by only reusing an existing shim link when its refcount can be incremented atomically.
  • Change shim_link reuse condition to require both a found shim and a successful atomic64_inc_not_zero on its refcnt
  • Remove the unconditional bpf_link_inc call, relying on the atomic refcount bump instead
kernel/bpf/trampoline.c

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@deepin-ci-robot
Copy link
Copy Markdown

Hi @xu-lang. Thanks for your PR.

I'm waiting for a deepin-community member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've left some high level feedback:

  • The xdp_page_head layout and pointer arithmetic in xdp_test_run_init_page() (e.g., headroom += sizeof(head->frame); and data = frm;) are quite subtle; consider using explicit casts/offset calculations (like offsetof(struct xdp_page_head, data) or (u8 *)&head->data[0]) to make the data/metadata placement easier to reason about and less error-prone for future maintainers.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The xdp_page_head layout and pointer arithmetic in xdp_test_run_init_page() (e.g., `headroom += sizeof(head->frame);` and `data = frm;`) are quite subtle; consider using explicit casts/offset calculations (like `offsetof(struct xdp_page_head, data)` or `(u8 *)&head->data[0]`) to make the data/metadata placement easier to reason about and less error-prone for future maintainers.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR backports/fixes three upstream-reported BPF issues affecting XDP test-run page layout, LWT BPF IP encapsulation safety, and cgroup trampoline shim link reuse/refcounting.

Changes:

  • Update XDP test-run page layout handling to use an embedded struct xdp_frame and adjust headroom/buffer usage.
  • Add a skb_dst() presence check before using LL_RESERVED_SPACE(skb_dst(skb)->dev) in LWT BPF egress encapsulation.
  • Make cgroup shim reuse safe by only reusing an existing shim when its link refcount can be incremented from non-zero.
  • Adjust XDP redirect selftest max packet size limits to match the updated XDP layout.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
tools/testing/selftests/bpf/prog_tests/xdp_do_redirect.c Updates MAX_PKT_SIZE limits for XDP live-frame selftest.
net/core/lwt_bpf.c Prevents NULL deref by validating skb_dst() before accessing dst->dev.
net/bpf/test_run.c Changes XDP test-run page header/layout to embed struct xdp_frame and adjusts headroom/data placement.
kernel/bpf/trampoline.c Prevents reusing a cgroup shim link that is already being freed by using atomic64_inc_not_zero().
Comments suppressed due to low confidence (1)

net/bpf/test_run.c:149

  • In this layout xdp_prepare_buff() uses hard_start = &head->frame and headroom was increased by sizeof(head->frame) to account for the embedded struct xdp_frame. With that, xdp_init_buff()'s frame_sz should cover the whole region starting at &head->frame (i.e., PAGE_SIZE - offsetof(struct xdp_page_head, frame)), otherwise the available data area is reduced by an extra sizeof(struct xdp_frame) and the MAX_PKT_SIZE math in the selftest won't match the real limit. Consider adjusting TEST_XDP_FRAME_SIZE (or the xdp_init_buff() argument) to be based on offsetof(..., frame) instead of sizeof(struct xdp_page_head).
	xdp_init_buff(new_ctx, TEST_XDP_FRAME_SIZE, &xdp->rxq);
	xdp_prepare_buff(new_ctx, data, headroom, frm_len, true);

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

/* The maximum permissible size is: PAGE_SIZE - sizeof(struct xdp_page_head) -
* SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) - XDP_PACKET_HEADROOM =
* 3408 bytes for 64-byte cacheline and 3216 for 256-byte one.
* 3368 bytes for 64-byte cacheline and 3216 for 256-byte one.
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment documents the 256-byte cacheline limit as 3216 bytes, but __s390x__ now defines MAX_PKT_SIZE as 3176. Please update the comment so the documented limits match the actual constants (or adjust the constant if 3216 is still intended).

Suggested change
* 3368 bytes for 64-byte cacheline and 3216 for 256-byte one.
* 3368 bytes for 64-byte cacheline and 3176 for 256-byte one.

Copilot uses AI. Check for mistakes.
@opsiff opsiff merged commit ca6d9e6 into deepin-community:linux-6.6.y Feb 27, 2026
17 checks passed
@deepin-ci-robot
Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: opsiff

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants