diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c index e48791442acc5..6fa24109a07f6 100644 --- a/kernel/bpf/trampoline.c +++ b/kernel/bpf/trampoline.c @@ -701,10 +701,8 @@ int bpf_trampoline_link_cgroup_shim(struct bpf_prog *prog, mutex_lock(&tr->mutex); shim_link = cgroup_shim_find(tr, bpf_func); - if (shim_link) { + if (shim_link && atomic64_inc_not_zero(&shim_link->link.link.refcnt)) { /* Reusing existing shim attached by the other program. */ - bpf_link_inc(&shim_link->link.link); - mutex_unlock(&tr->mutex); bpf_trampoline_put(tr); /* bpf_trampoline_get above */ return 0; diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c index 3a1c82b797a30..f4b928c01d999 100644 --- a/net/bpf/test_run.c +++ b/net/bpf/test_run.c @@ -100,11 +100,9 @@ static bool bpf_test_timer_continue(struct bpf_test_timer *t, int iterations, struct xdp_page_head { struct xdp_buff orig_ctx; struct xdp_buff ctx; - union { - /* ::data_hard_start starts here */ - DECLARE_FLEX_ARRAY(struct xdp_frame, frame); - DECLARE_FLEX_ARRAY(u8, data); - }; + /* ::data_hard_start starts here */ + struct xdp_frame frame; + DECLARE_FLEX_ARRAY(u8, data); }; struct xdp_test_data { @@ -140,10 +138,11 @@ static void xdp_test_run_init_page(struct page *page, void *arg) frm_len = orig_ctx->data_end - orig_ctx->data_meta; meta_len = orig_ctx->data - orig_ctx->data_meta; headroom -= meta_len; + headroom += sizeof(head->frame); new_ctx = &head->ctx; - frm = head->frame; - data = head->data; + frm = &head->frame; + data = frm; memcpy(data + headroom, orig_ctx->data_meta, frm_len); xdp_init_buff(new_ctx, TEST_XDP_FRAME_SIZE, &xdp->rxq); @@ -224,8 +223,8 @@ static bool frame_was_changed(const struct xdp_page_head *head) * i.e. has the highest chances to be overwritten. If those two are * untouched, it's most likely safe to skip the context reset. */ - return head->frame->data != head->orig_ctx.data || - head->frame->flags != head->orig_ctx.flags; + return head->frame.data != head->orig_ctx.data || + head->frame.flags != head->orig_ctx.flags; } static bool ctx_was_changed(struct xdp_page_head *head) @@ -243,8 +242,8 @@ static void reset_ctx(struct xdp_page_head *head) head->ctx.data = head->orig_ctx.data; head->ctx.data_meta = head->orig_ctx.data_meta; head->ctx.data_end = head->orig_ctx.data_end; - xdp_update_frame_from_buff(&head->ctx, head->frame); - head->frame->mem = head->orig_ctx.rxq->mem; + xdp_update_frame_from_buff(&head->ctx, &head->frame); + head->frame.mem = head->orig_ctx.rxq->mem; } static int xdp_recv_frames(struct xdp_frame **frames, int nframes, @@ -306,7 +305,7 @@ static int xdp_test_run_batch(struct xdp_test_data *xdp, struct bpf_prog *prog, head = phys_to_virt(page_to_phys(page)); reset_ctx(head); ctx = &head->ctx; - frm = head->frame; + frm = &head->frame; xdp->frame_cnt++; act = bpf_prog_run_xdp(prog, ctx); diff --git a/net/core/lwt_bpf.c b/net/core/lwt_bpf.c index 4a0797f0a154b..914498d2fe95f 100644 --- a/net/core/lwt_bpf.c +++ b/net/core/lwt_bpf.c @@ -613,9 +613,12 @@ int bpf_lwt_push_ip_encap(struct sk_buff *skb, void *hdr, u32 len, bool ingress) if (ingress) err = skb_cow_head(skb, len + skb->mac_len); - else + else { + if (unlikely(!skb_dst(skb))) + return -EINVAL; err = skb_cow_head(skb, len + LL_RESERVED_SPACE(skb_dst(skb)->dev)); + } if (unlikely(err)) return err; diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_do_redirect.c b/tools/testing/selftests/bpf/prog_tests/xdp_do_redirect.c index bad0ea167be70..19716a43d833e 100644 --- a/tools/testing/selftests/bpf/prog_tests/xdp_do_redirect.c +++ b/tools/testing/selftests/bpf/prog_tests/xdp_do_redirect.c @@ -58,12 +58,12 @@ static int attach_tc_prog(struct bpf_tc_hook *hook, int fd) /* 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. */ #if defined(__s390x__) -#define MAX_PKT_SIZE 3216 +#define MAX_PKT_SIZE 3176 #else -#define MAX_PKT_SIZE 3408 +#define MAX_PKT_SIZE 3368 #endif static void test_max_pkt_size(int fd) {