mirror of
https://github.com/torvalds/linux.git
synced 2026-07-29 18:51:21 +02:00
selftests/bpf: Test using slice after invalidating dynptr clone
The parent object of a cloned dynptr is skb not the original dynptr. Invalidate the original dynptr should not prevent the program from using the slice derived from the cloned dynptr. Signed-off-by: Amery Hung <ameryhung@gmail.com> Link: https://lore.kernel.org/r/20260529014936.2811085-12-ameryhung@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
parent
fbcc68af60
commit
925320666e
|
|
@ -8,6 +8,10 @@
|
|||
#include "bpf_qdisc_fifo.skel.h"
|
||||
#include "bpf_qdisc_fq.skel.h"
|
||||
#include "bpf_qdisc_fail__incompl_ops.skel.h"
|
||||
#include "bpf_qdisc_fail__invalid_dynptr.skel.h"
|
||||
#include "bpf_qdisc_fail__invalid_dynptr_slice.skel.h"
|
||||
#include "bpf_qdisc_fail__invalid_dynptr_cross_frame.skel.h"
|
||||
#include "bpf_qdisc_dynptr_use_after_invalidate_clone.skel.h"
|
||||
|
||||
#define LO_IFINDEX 1
|
||||
|
||||
|
|
@ -223,6 +227,10 @@ void test_ns_bpf_qdisc(void)
|
|||
test_qdisc_attach_to_non_root();
|
||||
if (test__start_subtest("incompl_ops"))
|
||||
test_incompl_ops();
|
||||
RUN_TESTS(bpf_qdisc_fail__invalid_dynptr);
|
||||
RUN_TESTS(bpf_qdisc_fail__invalid_dynptr_cross_frame);
|
||||
RUN_TESTS(bpf_qdisc_fail__invalid_dynptr_slice);
|
||||
RUN_TESTS(bpf_qdisc_dynptr_use_after_invalidate_clone);
|
||||
}
|
||||
|
||||
void serial_test_bpf_qdisc_default(void)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,74 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
#include <vmlinux.h>
|
||||
#include "bpf_experimental.h"
|
||||
#include "bpf_qdisc_common.h"
|
||||
#include "bpf_misc.h"
|
||||
|
||||
char _license[] SEC("license") = "GPL";
|
||||
|
||||
int proto;
|
||||
|
||||
SEC("struct_ops")
|
||||
__success
|
||||
int BPF_PROG(dynptr_use_after_invalidate_clone, struct sk_buff *skb, struct Qdisc *sch,
|
||||
struct bpf_sk_buff_ptr *to_free)
|
||||
{
|
||||
struct bpf_dynptr ptr, ptr_clone;
|
||||
struct ethhdr *hdr;
|
||||
|
||||
bpf_dynptr_from_skb((struct __sk_buff *)skb, 0, &ptr);
|
||||
|
||||
bpf_dynptr_clone(&ptr, &ptr_clone);
|
||||
|
||||
hdr = bpf_dynptr_slice(&ptr_clone, 0, NULL, sizeof(*hdr));
|
||||
if (!hdr) {
|
||||
bpf_qdisc_skb_drop(skb, to_free);
|
||||
return NET_XMIT_DROP;
|
||||
}
|
||||
|
||||
*(int *)&ptr = 0;
|
||||
|
||||
proto = hdr->h_proto;
|
||||
|
||||
bpf_qdisc_skb_drop(skb, to_free);
|
||||
|
||||
return NET_XMIT_DROP;
|
||||
}
|
||||
|
||||
SEC("struct_ops")
|
||||
__auxiliary
|
||||
struct sk_buff *BPF_PROG(bpf_qdisc_test_dequeue, struct Qdisc *sch)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SEC("struct_ops")
|
||||
__auxiliary
|
||||
int BPF_PROG(bpf_qdisc_test_init, struct Qdisc *sch, struct nlattr *opt,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
SEC("struct_ops")
|
||||
__auxiliary
|
||||
void BPF_PROG(bpf_qdisc_test_reset, struct Qdisc *sch)
|
||||
{
|
||||
}
|
||||
|
||||
SEC("struct_ops")
|
||||
__auxiliary
|
||||
void BPF_PROG(bpf_qdisc_test_destroy, struct Qdisc *sch)
|
||||
{
|
||||
}
|
||||
|
||||
SEC(".struct_ops")
|
||||
struct Qdisc_ops test = {
|
||||
.enqueue = (void *)dynptr_use_after_invalidate_clone,
|
||||
.dequeue = (void *)bpf_qdisc_test_dequeue,
|
||||
.init = (void *)bpf_qdisc_test_init,
|
||||
.reset = (void *)bpf_qdisc_test_reset,
|
||||
.destroy = (void *)bpf_qdisc_test_destroy,
|
||||
.id = "bpf_qdisc_test",
|
||||
};
|
||||
Loading…
Reference in New Issue
Block a user