diff options
Diffstat (limited to 'tools/testing/selftests/bpf/progs')
42 files changed, 690 insertions, 117 deletions
diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_existence.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_existence.c new file mode 100644 index 000000000000..0b62315ad46c --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_existence.c @@ -0,0 +1,3 @@ +#include "core_reloc_types.h" + +void f(struct core_reloc_existence x) {} diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_existence___err_wrong_arr_kind.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_existence___err_wrong_arr_kind.c new file mode 100644 index 000000000000..dd0ffa518f36 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_existence___err_wrong_arr_kind.c @@ -0,0 +1,3 @@ +#include "core_reloc_types.h" + +void f(struct core_reloc_existence___err_wrong_arr_kind x) {} diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_existence___err_wrong_arr_value_type.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_existence___err_wrong_arr_value_type.c new file mode 100644 index 000000000000..bc83372088ad --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_existence___err_wrong_arr_value_type.c @@ -0,0 +1,3 @@ +#include "core_reloc_types.h" + +void f(struct core_reloc_existence___err_wrong_arr_value_type x) {} diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_existence___err_wrong_int_kind.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_existence___err_wrong_int_kind.c new file mode 100644 index 000000000000..917bec41be08 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_existence___err_wrong_int_kind.c @@ -0,0 +1,3 @@ +#include "core_reloc_types.h" + +void f(struct core_reloc_existence___err_wrong_int_kind x) {} diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_existence___err_wrong_int_sz.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_existence___err_wrong_int_sz.c new file mode 100644 index 000000000000..6ec7e6ec1c91 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_existence___err_wrong_int_sz.c @@ -0,0 +1,3 @@ +#include "core_reloc_types.h" + +void f(struct core_reloc_existence___err_wrong_int_sz x) {} diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_existence___err_wrong_int_type.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_existence___err_wrong_int_type.c new file mode 100644 index 000000000000..7bbcacf2b0d1 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_existence___err_wrong_int_type.c @@ -0,0 +1,3 @@ +#include "core_reloc_types.h" + +void f(struct core_reloc_existence___err_wrong_int_type x) {} diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_existence___err_wrong_struct_type.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_existence___err_wrong_struct_type.c new file mode 100644 index 000000000000..f384dd38ec70 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_existence___err_wrong_struct_type.c @@ -0,0 +1,3 @@ +#include "core_reloc_types.h" + +void f(struct core_reloc_existence___err_wrong_struct_type x) {} diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_existence___minimal.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_existence___minimal.c new file mode 100644 index 000000000000..aec2dec20e90 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_existence___minimal.c @@ -0,0 +1,3 @@ +#include "core_reloc_types.h" + +void f(struct core_reloc_existence___minimal x) {} diff --git a/tools/testing/selftests/bpf/progs/btf_dump_test_case_padding.c b/tools/testing/selftests/bpf/progs/btf_dump_test_case_padding.c index 3a62119c7498..35c512818a56 100644 --- a/tools/testing/selftests/bpf/progs/btf_dump_test_case_padding.c +++ b/tools/testing/selftests/bpf/progs/btf_dump_test_case_padding.c @@ -62,6 +62,10 @@ struct padded_a_lot { * long: 64; * long: 64; * int b; + * long: 32; + * long: 64; + * long: 64; + * long: 64; *}; * */ @@ -95,7 +99,6 @@ struct zone_padding { struct zone { int a; short b; - short: 16; struct zone_padding __pad__; }; diff --git a/tools/testing/selftests/bpf/progs/core_reloc_types.h b/tools/testing/selftests/bpf/progs/core_reloc_types.h index f686a8138d90..f5939d9d5c61 100644 --- a/tools/testing/selftests/bpf/progs/core_reloc_types.h +++ b/tools/testing/selftests/bpf/progs/core_reloc_types.h @@ -1,5 +1,14 @@ #include <stdint.h> #include <stdbool.h> +/* + * KERNEL + */ + +struct core_reloc_kernel_output { + int valid[10]; + char comm[sizeof("test_progs")]; + int comm_len; +}; /* * FLAVORS @@ -665,3 +674,59 @@ struct core_reloc_misc_extensible { int c; int d; }; + +/* + * EXISTENCE + */ +struct core_reloc_existence_output { + int a_exists; + int a_value; + int b_exists; + int b_value; + int c_exists; + int c_value; + int arr_exists; + int arr_value; + int s_exists; + int s_value; +}; + +struct core_reloc_existence { + int a; + struct { + int b; + }; + int c; + int arr[1]; + struct { + int x; + } s; +}; + +struct core_reloc_existence___minimal { + int a; +}; + +struct core_reloc_existence___err_wrong_int_sz { + short a; +}; + +struct core_reloc_existence___err_wrong_int_type { + int b[1]; +}; + +struct core_reloc_existence___err_wrong_int_kind { + struct{ int x; } c; +}; + +struct core_reloc_existence___err_wrong_arr_kind { + int arr; +}; + +struct core_reloc_existence___err_wrong_arr_value_type { + short arr[1]; +}; + +struct core_reloc_existence___err_wrong_struct_type { + int s; +}; diff --git a/tools/testing/selftests/bpf/progs/kfree_skb.c b/tools/testing/selftests/bpf/progs/kfree_skb.c new file mode 100644 index 000000000000..489319ea1d6a --- /dev/null +++ b/tools/testing/selftests/bpf/progs/kfree_skb.c @@ -0,0 +1,103 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2019 Facebook +#include <linux/bpf.h> +#include "bpf_helpers.h" +#include "bpf_endian.h" + +char _license[] SEC("license") = "GPL"; +struct { + __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY); + __uint(key_size, sizeof(int)); + __uint(value_size, sizeof(int)); +} perf_buf_map SEC(".maps"); + +#define _(P) (__builtin_preserve_access_index(P)) + +/* define few struct-s that bpf program needs to access */ +struct callback_head { + struct callback_head *next; + void (*func)(struct callback_head *head); +}; +struct dev_ifalias { + struct callback_head rcuhead; +}; + +struct net_device /* same as kernel's struct net_device */ { + int ifindex; + struct dev_ifalias *ifalias; +}; + +typedef struct { + int counter; +} atomic_t; +typedef struct refcount_struct { + atomic_t refs; +} refcount_t; + +struct sk_buff { + /* field names and sizes should match to those in the kernel */ + unsigned int len, data_len; + __u16 mac_len, hdr_len, queue_mapping; + struct net_device *dev; + /* order of the fields doesn't matter */ + refcount_t users; + unsigned char *data; + char __pkt_type_offset[0]; +}; + +/* copy arguments from + * include/trace/events/skb.h: + * TRACE_EVENT(kfree_skb, + * TP_PROTO(struct sk_buff *skb, void *location), + * + * into struct below: + */ +struct trace_kfree_skb { + struct sk_buff *skb; + void *location; +}; + +SEC("tp_btf/kfree_skb") +int trace_kfree_skb(struct trace_kfree_skb *ctx) +{ + struct sk_buff *skb = ctx->skb; + struct net_device *dev; + int ifindex; + struct callback_head *ptr; + void *func; + int users; + unsigned char *data; + unsigned short pkt_data; + char pkt_type; + + __builtin_preserve_access_index(({ + users = skb->users.refs.counter; + data = skb->data; + dev = skb->dev; + ifindex = dev->ifindex; + ptr = dev->ifalias->rcuhead.next; + func = ptr->func; + })); + + bpf_probe_read_kernel(&pkt_type, sizeof(pkt_type), _(&skb->__pkt_type_offset)); + pkt_type &= 7; + + /* read eth proto */ + bpf_probe_read_kernel(&pkt_data, sizeof(pkt_data), data + 12); + + bpf_printk("rcuhead.next %llx func %llx\n", ptr, func); + bpf_printk("skb->len %d users %d pkt_type %x\n", + _(skb->len), users, pkt_type); + bpf_printk("skb->queue_mapping %d\n", _(skb->queue_mapping)); + bpf_printk("dev->ifindex %d data %llx pkt_data %x\n", + ifindex, data, pkt_data); + + if (users != 1 || pkt_data != bpf_htons(0x86dd) || ifindex != 1) + /* raw tp ignores return value */ + return 0; + + /* send first 72 byte of the packet to user space */ + bpf_skb_output(skb, &perf_buf_map, (72ull << 32) | BPF_F_CURRENT_CPU, + &ifindex, sizeof(ifindex)); + return 0; +} diff --git a/tools/testing/selftests/bpf/progs/loop1.c b/tools/testing/selftests/bpf/progs/loop1.c index 7cdb7f878310..40ac722a9da5 100644 --- a/tools/testing/selftests/bpf/progs/loop1.c +++ b/tools/testing/selftests/bpf/progs/loop1.c @@ -7,6 +7,7 @@ #include <stdbool.h> #include <linux/bpf.h> #include "bpf_helpers.h" +#include "bpf_tracing.h" char _license[] SEC("license") = "GPL"; diff --git a/tools/testing/selftests/bpf/progs/loop2.c b/tools/testing/selftests/bpf/progs/loop2.c index 9b2f808a2863..bb80f29aa7f7 100644 --- a/tools/testing/selftests/bpf/progs/loop2.c +++ b/tools/testing/selftests/bpf/progs/loop2.c @@ -7,6 +7,7 @@ #include <stdbool.h> #include <linux/bpf.h> #include "bpf_helpers.h" +#include "bpf_tracing.h" char _license[] SEC("license") = "GPL"; diff --git a/tools/testing/selftests/bpf/progs/loop3.c b/tools/testing/selftests/bpf/progs/loop3.c index d727657d51e2..2b9165a7afe1 100644 --- a/tools/testing/selftests/bpf/progs/loop3.c +++ b/tools/testing/selftests/bpf/progs/loop3.c @@ -7,6 +7,7 @@ #include <stdbool.h> #include <linux/bpf.h> #include "bpf_helpers.h" +#include "bpf_tracing.h" char _license[] SEC("license") = "GPL"; diff --git a/tools/testing/selftests/bpf/progs/pyperf.h b/tools/testing/selftests/bpf/progs/pyperf.h index 003fe106fc70..71d383cc9b85 100644 --- a/tools/testing/selftests/bpf/progs/pyperf.h +++ b/tools/testing/selftests/bpf/progs/pyperf.h @@ -72,9 +72,9 @@ static __always_inline void *get_thread_state(void *tls_base, PidData *pidData) void* thread_state; int key; - bpf_probe_read(&key, sizeof(key), (void*)(long)pidData->tls_key_addr); - bpf_probe_read(&thread_state, sizeof(thread_state), - tls_base + 0x310 + key * 0x10 + 0x08); + bpf_probe_read_user(&key, sizeof(key), (void*)(long)pidData->tls_key_addr); + bpf_probe_read_user(&thread_state, sizeof(thread_state), + tls_base + 0x310 + key * 0x10 + 0x08); return thread_state; } @@ -82,31 +82,33 @@ static __always_inline bool get_frame_data(void *frame_ptr, PidData *pidData, FrameData *frame, Symbol *symbol) { // read data from PyFrameObject - bpf_probe_read(&frame->f_back, - sizeof(frame->f_back), - frame_ptr + pidData->offsets.PyFrameObject_back); - bpf_probe_read(&frame->f_code, - sizeof(frame->f_code), - frame_ptr + pidData->offsets.PyFrameObject_code); + bpf_probe_read_user(&frame->f_back, + sizeof(frame->f_back), + frame_ptr + pidData->offsets.PyFrameObject_back); + bpf_probe_read_user(&frame->f_code, + sizeof(frame->f_code), + frame_ptr + pidData->offsets.PyFrameObject_code); // read data from PyCodeObject if (!frame->f_code) return false; - bpf_probe_read(&frame->co_filename, - sizeof(frame->co_filename), - frame->f_code + pidData->offsets.PyCodeObject_filename); - bpf_probe_read(&frame->co_name, - sizeof(frame->co_name), - frame->f_code + pidData->offsets.PyCodeObject_name); + bpf_probe_read_user(&frame->co_filename, + sizeof(frame->co_filename), + frame->f_code + pidData->offsets.PyCodeObject_filename); + bpf_probe_read_user(&frame->co_name, + sizeof(frame->co_name), + frame->f_code + pidData->offsets.PyCodeObject_name); // read actual names into symbol if (frame->co_filename) - bpf_probe_read_str(&symbol->file, - sizeof(symbol->file), - frame->co_filename + pidData->offsets.String_data); + bpf_probe_read_user_str(&symbol->file, + sizeof(symbol->file), + frame->co_filename + + pidData->offsets.String_data); if (frame->co_name) - bpf_probe_read_str(&symbol->name, - sizeof(symbol->name), - frame->co_name + pidData->offsets.String_data); + bpf_probe_read_user_str(&symbol->name, + sizeof(symbol->name), + frame->co_name + + pidData->offsets.String_data); return true; } @@ -174,9 +176,9 @@ static __always_inline int __on_event(struct pt_regs *ctx) event->kernel_stack_id = bpf_get_stackid(ctx, &stackmap, 0); void* thread_state_current = (void*)0; - bpf_probe_read(&thread_state_current, - sizeof(thread_state_current), - (void*)(long)pidData->current_state_addr); + bpf_probe_read_user(&thread_state_current, + sizeof(thread_state_current), + (void*)(long)pidData->current_state_addr); struct task_struct* task = (struct task_struct*)bpf_get_current_task(); void* tls_base = (void*)task; @@ -188,11 +190,13 @@ static __always_inline int __on_event(struct pt_regs *ctx) if (pidData->use_tls) { uint64_t pthread_created; uint64_t pthread_self; - bpf_probe_read(&pthread_self, sizeof(pthread_self), tls_base + 0x10); + bpf_probe_read_user(&pthread_self, sizeof(pthread_self), + tls_base + 0x10); - bpf_probe_read(&pthread_created, - sizeof(pthread_created), - thread_state + pidData->offsets.PyThreadState_thread); + bpf_probe_read_user(&pthread_created, + sizeof(pthread_created), + thread_state + + pidData->offsets.PyThreadState_thread); event->pthread_match = pthread_created == pthread_self; } else { event->pthread_match = 1; @@ -204,9 +208,10 @@ static __always_inline int __on_event(struct pt_regs *ctx) Symbol sym = {}; int cur_cpu = bpf_get_smp_processor_id(); - bpf_probe_read(&frame_ptr, - sizeof(frame_ptr), - thread_state + pidData->offsets.PyThreadState_frame); + bpf_probe_read_user(&frame_ptr, + sizeof(frame_ptr), + thread_state + + pidData->offsets.PyThreadState_frame); int32_t* symbol_counter = bpf_map_lookup_elem(&symbolmap, &sym); if (symbol_counter == NULL) diff --git a/tools/testing/selftests/bpf/progs/sockopt_sk.c b/tools/testing/selftests/bpf/progs/sockopt_sk.c index 9a3d1c79e6fe..1bafbb944e37 100644 --- a/tools/testing/selftests/bpf/progs/sockopt_sk.c +++ b/tools/testing/selftests/bpf/progs/sockopt_sk.c @@ -14,13 +14,12 @@ struct sockopt_sk { __u8 val; }; -struct bpf_map_def SEC("maps") socket_storage_map = { - .type = BPF_MAP_TYPE_SK_STORAGE, - .key_size = sizeof(int), - .value_size = sizeof(struct sockopt_sk), - .map_flags = BPF_F_NO_PREALLOC, -}; -BPF_ANNOTATE_KV_PAIR(socket_storage_map, int, struct sockopt_sk); +struct { + __uint(type, BPF_MAP_TYPE_SK_STORAGE); + __uint(map_flags, BPF_F_NO_PREALLOC); + __type(key, int); + __type(value, struct sockopt_sk); +} socket_storage_map SEC(".maps"); SEC("cgroup/getsockopt") int _getsockopt(struct bpf_sockopt *ctx) diff --git a/tools/testing/selftests/bpf/progs/strobemeta.h b/tools/testing/selftests/bpf/progs/strobemeta.h index 067eb625d01c..4bf16e0a1b0e 100644 --- a/tools/testing/selftests/bpf/progs/strobemeta.h +++ b/tools/testing/selftests/bpf/progs/strobemeta.h @@ -98,7 +98,7 @@ struct strobe_map_raw { /* * having volatile doesn't change anything on BPF side, but clang * emits warnings for passing `volatile const char *` into - * bpf_probe_read_str that expects just `const char *` + * bpf_probe_read_user_str that expects just `const char *` */ const char* tag; /* @@ -309,18 +309,18 @@ static __always_inline void *calc_location(struct strobe_value_loc *loc, dtv_t *dtv; void *tls_ptr; - bpf_probe_read(&tls_index, sizeof(struct tls_index), - (void *)loc->offset); + bpf_probe_read_user(&tls_index, sizeof(struct tls_index), + (void *)loc->offset); /* valid module index is always positive */ if (tls_index.module > 0) { /* dtv = ((struct tcbhead *)tls_base)->dtv[tls_index.module] */ - bpf_probe_read(&dtv, sizeof(dtv), - &((struct tcbhead *)tls_base)->dtv); + bpf_probe_read_user(&dtv, sizeof(dtv), + &((struct tcbhead *)tls_base)->dtv); dtv += tls_index.module; } else { dtv = NULL; } - bpf_probe_read(&tls_ptr, sizeof(void *), dtv); + bpf_probe_read_user(&tls_ptr, sizeof(void *), dtv); /* if pointer has (void *)-1 value, then TLS wasn't initialized yet */ return tls_ptr && tls_ptr != (void *)-1 ? tls_ptr + tls_index.offset @@ -336,7 +336,7 @@ static __always_inline void read_int_var(struct strobemeta_cfg *cfg, if (!location) return; - bpf_probe_read(value, sizeof(struct strobe_value_generic), location); + bpf_probe_read_user(value, sizeof(struct strobe_value_generic), location); data->int_vals[idx] = value->val; if (value->header.len) data->int_vals_set_mask |= (1 << idx); @@ -356,13 +356,13 @@ static __always_inline uint64_t read_str_var(struct strobemeta_cfg *cfg, if (!location) return 0; - bpf_probe_read(value, sizeof(struct strobe_value_generic), location); - len = bpf_probe_read_str(payload, STROBE_MAX_STR_LEN, value->ptr); + bpf_probe_read_user(value, sizeof(struct strobe_value_generic), location); + len = bpf_probe_read_user_str(payload, STROBE_MAX_STR_LEN, value->ptr); /* - * if bpf_probe_read_str returns error (<0), due to casting to + * if bpf_probe_read_user_str returns error (<0), due to casting to * unsinged int, it will become big number, so next check is * sufficient to check for errors AND prove to BPF verifier, that - * bpf_probe_read_str won't return anything bigger than + * bpf_probe_read_user_str won't return anything bigger than * STROBE_MAX_STR_LEN */ if (len > STROBE_MAX_STR_LEN) @@ -391,8 +391,8 @@ static __always_inline void *read_map_var(struct strobemeta_cfg *cfg, if (!location) return payload; - bpf_probe_read(value, sizeof(struct strobe_value_generic), location); - if (bpf_probe_read(&map, sizeof(struct strobe_map_raw), value->ptr)) + bpf_probe_read_user(value, sizeof(struct strobe_value_generic), location); + if (bpf_probe_read_user(&map, sizeof(struct strobe_map_raw), value->ptr)) return payload; descr->id = map.id; @@ -402,7 +402,7 @@ static __always_inline void *read_map_var(struct strobemeta_cfg *cfg, data->req_meta_valid = 1; } - len = bpf_probe_read_str(payload, STROBE_MAX_STR_LEN, map.tag); + len = bpf_probe_read_user_str(payload, STROBE_MAX_STR_LEN, map.tag); if (len <= STROBE_MAX_STR_LEN) { descr->tag_len = len; payload += len; @@ -418,15 +418,15 @@ static __always_inline void *read_map_var(struct strobemeta_cfg *cfg, break; descr->key_lens[i] = 0; - len = bpf_probe_read_str(payload, STROBE_MAX_STR_LEN, - map.entries[i].key); + len = bpf_probe_read_user_str(payload, STROBE_MAX_STR_LEN, + map.entries[i].key); if (len <= STROBE_MAX_STR_LEN) { descr->key_lens[i] = len; payload += len; } descr->val_lens[i] = 0; - len = bpf_probe_read_str(payload, STROBE_MAX_STR_LEN, - map.entries[i].val); + len = bpf_probe_read_user_str(payload, STROBE_MAX_STR_LEN, + map.entries[i].val); if (len <= STROBE_MAX_STR_LEN) { descr->val_lens[i] = len; payload += len; diff --git a/tools/testing/selftests/bpf/progs/tcp_rtt.c b/tools/testing/selftests/bpf/progs/tcp_rtt.c index 233bdcb1659e..2cf813a06b83 100644 --- a/tools/testing/selftests/bpf/progs/tcp_rtt.c +++ b/tools/testing/selftests/bpf/progs/tcp_rtt.c @@ -13,13 +13,12 @@ struct tcp_rtt_storage { __u32 icsk_retransmits; }; -struct bpf_map_def SEC("maps") socket_storage_map = { - .type = BPF_MAP_TYPE_SK_STORAGE, - .key_size = sizeof(int), - .value_size = sizeof(struct tcp_rtt_storage), - .map_flags = BPF_F_NO_PREALLOC, -}; -BPF_ANNOTATE_KV_PAIR(socket_storage_map, int, struct tcp_rtt_storage); +struct { + __uint(type, BPF_MAP_TYPE_SK_STORAGE); + __uint(map_flags, BPF_F_NO_PREALLOC); + __type(key, int); + __type(value, struct tcp_rtt_storage); +} socket_storage_map SEC(".maps"); SEC("sockops") int _sockops(struct bpf_sock_ops *ctx) diff --git a/tools/testing/selftests/bpf/progs/test_attach_probe.c b/tools/testing/selftests/bpf/progs/test_attach_probe.c index 63a8dfef893b..534621e38906 100644 --- a/tools/testing/selftests/bpf/progs/test_attach_probe.c +++ b/tools/testing/selftests/bpf/progs/test_attach_probe.c @@ -49,4 +49,3 @@ int handle_uprobe_return(struct pt_regs *ctx) } char _license[] SEC("license") = "GPL"; -__u32 _version SEC("version") = 1; diff --git a/tools/testing/selftests/bpf/progs/test_btf_haskv.c b/tools/testing/selftests/bpf/progs/test_btf_haskv.c index e5c79fe0ffdb..763c51447c19 100644 --- a/tools/testing/selftests/bpf/progs/test_btf_haskv.c +++ b/tools/testing/selftests/bpf/progs/test_btf_haskv.c @@ -2,6 +2,7 @@ /* Copyright (c) 2018 Facebook */ #include <linux/bpf.h> #include "bpf_helpers.h" +#include "bpf_legacy.h" int _version SEC("version") = 1; diff --git a/tools/testing/selftests/bpf/progs/test_btf_newkv.c b/tools/testing/selftests/bpf/progs/test_btf_newkv.c index 5ee3622ddebb..96f9e8451029 100644 --- a/tools/testing/selftests/bpf/progs/test_btf_newkv.c +++ b/tools/testing/selftests/bpf/progs/test_btf_newkv.c @@ -2,6 +2,7 @@ /* Copyright (c) 2018 Facebook */ #include <linux/bpf.h> #include "bpf_helpers.h" +#include "bpf_legacy.h" int _version SEC("version") = 1; diff --git a/tools/testing/selftests/bpf/progs/test_core_reloc_arrays.c b/tools/testing/selftests/bpf/progs/test_core_reloc_arrays.c index bf67f0fdf743..96b1f5f3b07a 100644 --- a/tools/testing/selftests/bpf/progs/test_core_reloc_arrays.c +++ b/tools/testing/selftests/bpf/progs/test_core_reloc_arrays.c @@ -4,6 +4,7 @@ #include <linux/bpf.h> #include <stdint.h> #include "bpf_helpers.h" +#include "bpf_core_read.h" char _license[] SEC("license") = "GPL"; @@ -31,6 +32,8 @@ struct core_reloc_arrays { struct core_reloc_arrays_substruct d[1][2]; }; +#define CORE_READ(dst, src) bpf_core_read(dst, sizeof(*(dst)), src) + SEC("raw_tracepoint/sys_enter") int test_core_arrays(void *ctx) { @@ -38,16 +41,16 @@ int test_core_arrays(void *ctx) struct core_reloc_arrays_output *out = (void *)&data.out; /* in->a[2] */ - if (BPF_CORE_READ(&out->a2, &in->a[2])) + if (CORE_READ(&out->a2, &in->a[2])) return 1; /* in->b[1][2][3] */ - if (BPF_CORE_READ(&out->b123, &in->b[1][2][3])) + if (CORE_READ(&out->b123, &in->b[1][2][3])) return 1; /* in->c[1].c */ - if (BPF_CORE_READ(&out->c1c, &in->c[1].c)) + if (CORE_READ(&out->c1c, &in->c[1].c)) return 1; /* in->d[0][0].d */ - if (BPF_CORE_READ(&out->d00d, &in->d[0][0].d)) + if (CORE_READ(&out->d00d, &in->d[0][0].d)) return 1; return 0; diff --git a/tools/testing/selftests/bpf/progs/test_core_reloc_existence.c b/tools/testing/selftests/bpf/progs/test_core_reloc_existence.c new file mode 100644 index 000000000000..c3cac95a19f1 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/test_core_reloc_existence.c @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2019 Facebook + +#include <linux/bpf.h> +#include <stdint.h> +#include "bpf_helpers.h" +#include "bpf_core_read.h" + +char _license[] SEC("license") = "GPL"; + +static volatile struct data { + char in[256]; + char out[256]; +} data; + +struct core_reloc_existence_output { + int a_exists; + int a_value; + int b_exists; + int b_value; + int c_exists; + int c_value; + int arr_exists; + int arr_value; + int s_exists; + int s_value; +}; + +struct core_reloc_existence { + struct { + int x; + } s; + int arr[1]; + int a; + struct { + int b; + }; + int c; +}; + +SEC("raw_tracepoint/sys_enter") +int test_core_existence(void *ctx) +{ + struct core_reloc_existence *in = (void *)&data.in; + struct core_reloc_existence_output *out = (void *)&data.out; + + out->a_exists = bpf_core_field_exists(in->a); + if (bpf_core_field_exists(in->a)) + out->a_value = BPF_CORE_READ(in, a); + else + out->a_value = 0xff000001u; + + out->b_exists = bpf_core_field_exists(in->b); + if (bpf_core_field_exists(in->b)) + out->b_value = BPF_CORE_READ(in, b); + else + out->b_value = 0xff000002u; + + out->c_exists = bpf_core_field_exists(in->c); + if (bpf_core_field_exists(in->c)) + out->c_value = BPF_CORE_READ(in, c); + else + out->c_value = 0xff000003u; + + out->arr_exists = bpf_core_field_exists(in->arr); + if (bpf_core_field_exists(in->arr)) + out->arr_value = BPF_CORE_READ(in, arr[0]); + else + out->arr_value = 0xff000004u; + + out->s_exists = bpf_core_field_exists(in->s); + if (bpf_core_field_exists(in->s)) + out->s_value = BPF_CORE_READ(in, s.x); + else + out->s_value = 0xff000005u; + + return 0; +} + diff --git a/tools/testing/selftests/bpf/progs/test_core_reloc_flavors.c b/tools/testing/selftests/bpf/progs/test_core_reloc_flavors.c index 9fda73e87972..71fd7cebc9d7 100644 --- a/tools/testing/selftests/bpf/progs/test_core_reloc_flavors.c +++ b/tools/testing/selftests/bpf/progs/test_core_reloc_flavors.c @@ -4,6 +4,7 @@ #include <linux/bpf.h> #include <stdint.h> #include "bpf_helpers.h" +#include "bpf_core_read.h" char _license[] SEC("license") = "GPL"; @@ -39,6 +40,8 @@ struct core_reloc_flavors___weird { }; }; +#define CORE_READ(dst, src) bpf_core_read(dst, sizeof(*(dst)), src) + SEC("raw_tracepoint/sys_enter") int test_core_flavors(void *ctx) { @@ -48,13 +51,13 @@ int test_core_flavors(void *ctx) struct core_reloc_flavors *out = (void *)&data.out; /* read a using weird layout */ - if (BPF_CORE_READ(&out->a, &in_weird->a)) + if (CORE_READ(&out->a, &in_weird->a)) return 1; /* read b using reversed layout */ - if (BPF_CORE_READ(&out->b, &in_rev->b)) + if (CORE_READ(&out->b, &in_rev->b)) return 1; /* read c using original layout */ - if (BPF_CORE_READ(&out->c, &in_orig->c)) + if (CORE_READ(&out->c, &in_orig->c)) return 1; return 0; diff --git a/tools/testing/selftests/bpf/progs/test_core_reloc_ints.c b/tools/testing/selftests/bpf/progs/test_core_reloc_ints.c index d99233c8008a..ad5c3f59c9c6 100644 --- a/tools/testing/selftests/bpf/progs/test_core_reloc_ints.c +++ b/tools/testing/selftests/bpf/progs/test_core_reloc_ints.c @@ -4,6 +4,7 @@ #include <linux/bpf.h> #include <stdint.h> #include "bpf_helpers.h" +#include "bpf_core_read.h" char _license[] SEC("license") = "GPL"; @@ -23,20 +24,22 @@ struct core_reloc_ints { int64_t s64_field; }; +#define CORE_READ(dst, src) bpf_core_read(dst, sizeof(*(dst)), src) + SEC("raw_tracepoint/sys_enter") int test_core_ints(void *ctx) { struct core_reloc_ints *in = (void *)&data.in; struct core_reloc_ints *out = (void *)&data.out; - if (BPF_CORE_READ(&out->u8_field, &in->u8_field) || - BPF_CORE_READ(&out->s8_field, &in->s8_field) || - BPF_CORE_READ(&out->u16_field, &in->u16_field) || - BPF_CORE_READ(&out->s16_field, &in->s16_field) || - BPF_CORE_READ(&out->u32_field, &in->u32_field) || - BPF_CORE_READ(&out->s32_field, &in->s32_field) || - BPF_CORE_READ(&out->u64_field, &in->u64_field) || - BPF_CORE_READ(&out->s64_field, &in->s64_field)) + if (CORE_READ(&out->u8_field, &in->u8_field) || + CORE_READ(&out->s8_field, &in->s8_field) || + CORE_READ(&out->u16_field, &in->u16_field) || + CORE_READ(&out->s16_field, &in->s16_field) || + CORE_READ(&out->u32_field, &in->u32_field) || + CORE_READ(&out->s32_field, &in->s32_field) || + CORE_READ(&out->u64_field, &in->u64_field) || + CORE_READ(&out->s64_field, &in->s64_field)) return 1; return 0; diff --git a/tools/testing/selftests/bpf/progs/test_core_reloc_kernel.c b/tools/testing/selftests/bpf/progs/test_core_reloc_kernel.c index 37e02aa3f0c8..a4b5e0562ed5 100644 --- a/tools/testing/selftests/bpf/progs/test_core_reloc_kernel.c +++ b/tools/testing/selftests/bpf/progs/test_core_reloc_kernel.c @@ -4,6 +4,7 @@ #include <linux/bpf.h> #include <stdint.h> #include "bpf_helpers.h" +#include "bpf_core_read.h" char _license[] SEC("license") = "GPL"; @@ -12,24 +13,79 @@ static volatile struct data { char out[256]; } data; +struct core_reloc_kernel_output { + int valid[10]; + /* we have test_progs[-flavor], so cut flavor part */ + char comm[sizeof("test_progs")]; + int comm_len; +}; + struct task_struct { int pid; int tgid; + char comm[16]; + struct task_struct *group_leader; }; +#define CORE_READ(dst, src) bpf_core_read(dst, sizeof(*(dst)), src) + SEC("raw_tracepoint/sys_enter") int test_core_kernel(void *ctx) { struct task_struct *task = (void *)bpf_get_current_task(); + struct core_reloc_kernel_output *out = (void *)&data.out; uint64_t pid_tgid = bpf_get_current_pid_tgid(); + uint32_t real_tgid = (uint32_t)pid_tgid; int pid, tgid; - if (BPF_CORE_READ(&pid, &task->pid) || - BPF_CORE_READ(&tgid, &task->tgid)) + if (CORE_READ(&pid, &task->pid) || + CORE_READ(&tgid, &task->tgid)) return 1; /* validate pid + tgid matches */ - data.out[0] = (((uint64_t)pid << 32) | tgid) == pid_tgid; + out->valid[0] = (((uint64_t)pid << 32) | tgid) == pid_tgid; + + /* test variadic BPF_CORE_READ macros */ + out->valid[1] = BPF_CORE_READ(task, + tgid) == real_tgid; + out->valid[2] = BPF_CORE_READ(task, + group_leader, + tgid) == real_tgid; + out->valid[3] = BPF_CORE_READ(task, + group_leader, group_leader, + tgid) == real_tgid; + out->valid[4] = BPF_CORE_READ(task, + group_leader, group_leader, group_leader, + tgid) == real_tgid; + out->valid[5] = BPF_CORE_READ(task, + group_leader, group_leader, group_leader, + group_leader, + tgid) == real_tgid; + out->valid[6] = BPF_CORE_READ(task, + group_leader, group_leader, group_leader, + group_leader, group_leader, + tgid) == real_tgid; + out->valid[7] = BPF_CORE_READ(task, + group_leader, group_leader, group_leader, + group_leader, group_leader, group_leader, + tgid) == real_tgid; + out->valid[8] = BPF_CORE_READ(task, + group_leader, group_leader, group_leader, + group_leader, group_leader, group_leader, + group_leader, + tgid) == real_tgid; + out->valid[9] = BPF_CORE_READ(task, + group_leader, group_leader, group_leader, + group_leader, group_leader, group_leader, + group_leader, group_leader, + tgid) == real_tgid; + + /* test BPF_CORE_READ_STR_INTO() returns correct code and contents */ + out->comm_len = BPF_CORE_READ_STR_INTO( + &out->comm, task, + group_leader, group_leader, group_leader, group_leader, + group_leader, group_leader, group_leader, group_leader, + comm); return 0; } diff --git a/tools/testing/selftests/bpf/progs/test_core_reloc_misc.c b/tools/testing/selftests/bpf/progs/test_core_reloc_misc.c index c59984bd3e23..1a36b0856653 100644 --- a/tools/testing/selftests/bpf/progs/test_core_reloc_misc.c +++ b/tools/testing/selftests/bpf/progs/test_core_reloc_misc.c @@ -4,6 +4,7 @@ #include <linux/bpf.h> #include <stdint.h> #include "bpf_helpers.h" +#include "bpf_core_read.h" char _license[] SEC("license") = "GPL"; @@ -32,6 +33,8 @@ struct core_reloc_misc_extensible { int b; }; +#define CORE_READ(dst, src) bpf_core_read(dst, sizeof(*(dst)), src) + SEC("raw_tracepoint/sys_enter") int test_core_misc(void *ctx) { @@ -41,15 +44,15 @@ int test_core_misc(void *ctx) struct core_reloc_misc_output *out = (void *)&data.out; /* record two different relocations with the same accessor string */ - if (BPF_CORE_READ(&out->a, &in_a->a1) || /* accessor: 0:0 */ - BPF_CORE_READ(&out->b, &in_b->b1)) /* accessor: 0:0 */ + if (CORE_READ(&out->a, &in_a->a1) || /* accessor: 0:0 */ + CORE_READ(&out->b, &in_b->b1)) /* accessor: 0:0 */ return 1; /* Validate relocations capture array-only accesses for structs with * fixed header, but with potentially extendable tail. This will read * first 4 bytes of 2nd element of in_ext array of potentially * variably sized struct core_reloc_misc_extensible. */ - if (BPF_CORE_READ(&out->c, &in_ext[2])) /* accessor: 2 */ + if (CORE_READ(&out->c, &in_ext[2])) /* accessor: 2 */ return 1; return 0; diff --git a/tools/testing/selftests/bpf/progs/test_core_reloc_mods.c b/tools/testing/selftests/bpf/progs/test_core_reloc_mods.c index f98b942c062b..3199fafede2c 100644 --- a/tools/testing/selftests/bpf/progs/test_core_reloc_mods.c +++ b/tools/testing/selftests/bpf/progs/test_core_reloc_mods.c @@ -4,6 +4,7 @@ #include <linux/bpf.h> #include <stdint.h> #include "bpf_helpers.h" +#include "bpf_core_read.h" char _license[] SEC("license") = "GPL"; @@ -41,20 +42,22 @@ struct core_reloc_mods { core_reloc_mods_substruct_t h; }; +#define CORE_READ(dst, src) bpf_core_read(dst, sizeof(*(dst)), src) + SEC("raw_tracepoint/sys_enter") int test_core_mods(void *ctx) { struct core_reloc_mods *in = (void *)&data.in; struct core_reloc_mods_output *out = (void *)&data.out; - if (BPF_CORE_READ(&out->a, &in->a) || - BPF_CORE_READ(&out->b, &in->b) || - BPF_CORE_READ(&out->c, &in->c) || - BPF_CORE_READ(&out->d, &in->d) || - BPF_CORE_READ(&out->e, &in->e[2]) || - BPF_CORE_READ(&out->f, &in->f[1]) || - BPF_CORE_READ(&out->g, &in->g.x) || - BPF_CORE_READ(&out->h, &in->h.y)) + if (CORE_READ(&out->a, &in->a) || + CORE_READ(&out->b, &in->b) || + CORE_READ(&out->c, &in->c) || + CORE_READ(&out->d, &in->d) || + CORE_READ(&out->e, &in->e[2]) || + CORE_READ(&out->f, &in->f[1]) || + CORE_READ(&out->g, &in->g.x) || + CORE_READ(&out->h, &in->h.y)) return 1; return 0; diff --git a/tools/testing/selftests/bpf/progs/test_core_reloc_nesting.c b/tools/testing/selftests/bpf/progs/test_core_reloc_nesting.c index 3ca30cec2b39..98238cb64fbd 100644 --- a/tools/testing/selftests/bpf/progs/test_core_reloc_nesting.c +++ b/tools/testing/selftests/bpf/progs/test_core_reloc_nesting.c @@ -4,6 +4,7 @@ #include <linux/bpf.h> #include <stdint.h> #include "bpf_helpers.h" +#include "bpf_core_read.h" char _license[] SEC("license") = "GPL"; @@ -30,15 +31,17 @@ struct core_reloc_nesting { } b; }; +#define CORE_READ(dst, src) bpf_core_read(dst, sizeof(*(dst)), src) + SEC("raw_tracepoint/sys_enter") int test_core_nesting(void *ctx) { struct core_reloc_nesting *in = (void *)&data.in; struct core_reloc_nesting *out = (void *)&data.out; - if (BPF_CORE_READ(&out->a.a.a, &in->a.a.a)) + if (CORE_READ(&out->a.a.a, &in->a.a.a)) return 1; - if (BPF_CORE_READ(&out->b.b.b, &in->b.b.b)) + if (CORE_READ(&out->b.b.b, &in->b.b.b)) return 1; return 0; diff --git a/tools/testing/selftests/bpf/progs/test_core_reloc_primitives.c b/tools/testing/selftests/bpf/progs/test_core_reloc_primitives.c index add52f23ab35..4f3ecb9127bb 100644 --- a/tools/testing/selftests/bpf/progs/test_core_reloc_primitives.c +++ b/tools/testing/selftests/bpf/progs/test_core_reloc_primitives.c @@ -4,6 +4,7 @@ #include <linux/bpf.h> #include <stdint.h> #include "bpf_helpers.h" +#include "bpf_core_read.h" char _license[] SEC("license") = "GPL"; @@ -25,17 +26,19 @@ struct core_reloc_primitives { int (*f)(const char *); }; +#define CORE_READ(dst, src) bpf_core_read(dst, sizeof(*(dst)), src) + SEC("raw_tracepoint/sys_enter") int test_core_primitives(void *ctx) { struct core_reloc_primitives *in = (void *)&data.in; struct core_reloc_primitives *out = (void *)&data.out; - if (BPF_CORE_READ(&out->a, &in->a) || - BPF_CORE_READ(&out->b, &in->b) || - BPF_CORE_READ(&out->c, &in->c) || - BPF_CORE_READ(&out->d, &in->d) || - BPF_CORE_READ(&out->f, &in->f)) + if (CORE_READ(&out->a, &in->a) || + CORE_READ(&out->b, &in->b) || + CORE_READ(&out->c, &in->c) || + CORE_READ(&out->d, &in->d) || + CORE_READ(&out->f, &in->f)) return 1; return 0; diff --git a/tools/testing/selftests/bpf/progs/test_core_reloc_ptr_as_arr.c b/tools/testing/selftests/bpf/progs/test_core_reloc_ptr_as_arr.c index 526b7ddc7ea1..27f602f00419 100644 --- a/tools/testing/selftests/bpf/progs/test_core_reloc_ptr_as_arr.c +++ b/tools/testing/selftests/bpf/progs/test_core_reloc_ptr_as_arr.c @@ -4,6 +4,7 @@ #include <linux/bpf.h> #include <stdint.h> #include "bpf_helpers.h" +#include "bpf_core_read.h" char _license[] SEC("license") = "GPL"; @@ -16,13 +17,15 @@ struct core_reloc_ptr_as_arr { int a; }; +#define CORE_READ(dst, src) bpf_core_read(dst, sizeof(*(dst)), src) + SEC("raw_tracepoint/sys_enter") int test_core_ptr_as_arr(void *ctx) { struct core_reloc_ptr_as_arr *in = (void *)&data.in; struct core_reloc_ptr_as_arr *out = (void *)&data.out; - if (BPF_CORE_READ(&out->a, &in[2].a)) + if (CORE_READ(&out->a, &in[2].a)) return 1; return 0; diff --git a/tools/testing/selftests/bpf/progs/test_get_stack_rawtp.c b/tools/testing/selftests/bpf/progs/test_get_stack_rawtp.c index f8ffa3f3d44b..6a4a8f57f174 100644 --- a/tools/testing/selftests/bpf/progs/test_get_stack_rawtp.c +++ b/tools/testing/selftests/bpf/progs/test_get_stack_rawtp.c @@ -47,12 +47,11 @@ struct { * issue and avoid complicated C programming massaging. * This is an acceptable workaround since there is one entry here. */ -typedef __u64 raw_stack_trace_t[2 * MAX_STACK_RAWTP]; struct { __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); __uint(max_entries, 1); __type(key, __u32); - __type(value, raw_stack_trace_t); + __type(value, __u64[2 * MAX_STACK_RAWTP]); } rawdata_map SEC(".maps"); SEC("raw_tracepoint/sys_enter") @@ -100,4 +99,3 @@ int bpf_prog1(void *ctx) } char _license[] SEC("license") = "GPL"; -__u32 _version SEC("version") = 1; /* ignored by tracepoints, required by libbpf.a */ diff --git a/tools/testing/selftests/bpf/progs/test_perf_buffer.c b/tools/testing/selftests/bpf/progs/test_perf_buffer.c index 876c27deb65a..07c09ca5546a 100644 --- a/tools/testing/selftests/bpf/progs/test_perf_buffer.c +++ b/tools/testing/selftests/bpf/progs/test_perf_buffer.c @@ -22,4 +22,3 @@ int handle_sys_nanosleep_entry(struct pt_regs *ctx) } char _license[] SEC("license") = "GPL"; -__u32 _version SEC("version") = 1; diff --git a/tools/testing/selftests/bpf/progs/test_pinning.c b/tools/testing/selftests/bpf/progs/test_pinning.c new file mode 100644 index 000000000000..f69a4a50d056 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/test_pinning.c @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <linux/bpf.h> +#include "bpf_helpers.h" + +int _version SEC("version") = 1; + +struct { + __uint(type, BPF_MAP_TYPE_ARRAY); + __uint(max_entries, 1); + __type(key, __u32); + __type(value, __u64); + __uint(pinning, LIBBPF_PIN_BY_NAME); +} pinmap SEC(".maps"); + +struct { + __uint(type, BPF_MAP_TYPE_HASH); + __uint(max_entries, 1); + __type(key, __u32); + __type(value, __u64); +} nopinmap SEC(".maps"); + +struct { + __uint(type, BPF_MAP_TYPE_ARRAY); + __uint(max_entries, 1); + __type(key, __u32); + __type(value, __u64); + __uint(pinning, LIBBPF_PIN_NONE); +} nopinmap2 SEC(".maps"); + +char _license[] SEC("license") = "GPL"; diff --git a/tools/testing/selftests/bpf/progs/test_pinning_invalid.c b/tools/testing/selftests/bpf/progs/test_pinning_invalid.c new file mode 100644 index 000000000000..51b38abe7ba1 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/test_pinning_invalid.c @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <linux/bpf.h> +#include "bpf_helpers.h" + +int _version SEC("version") = 1; + +struct { + __uint(type, BPF_MAP_TYPE_ARRAY); + __uint(max_entries, 1); + __type(key, __u32); + __type(value, __u64); + __uint(pinning, 2); /* invalid */ +} nopinmap3 SEC(".maps"); + +char _license[] SEC("license") = "GPL"; diff --git a/tools/testing/selftests/bpf/progs/test_probe_user.c b/tools/testing/selftests/bpf/progs/test_probe_user.c new file mode 100644 index 000000000000..1871e2ece0c4 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/test_probe_user.c @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <linux/ptrace.h> +#include <linux/bpf.h> + +#include <netinet/in.h> + +#include "bpf_helpers.h" +#include "bpf_tracing.h" + +static struct sockaddr_in old; + +SEC("kprobe/__sys_connect") +int handle_sys_connect(struct pt_regs *ctx) +{ + void *ptr = (void *)PT_REGS_PARM2(ctx); + struct sockaddr_in new; + + bpf_probe_read_user(&old, sizeof(old), ptr); + __builtin_memset(&new, 0xab, sizeof(new)); + bpf_probe_write_user(ptr, &new, sizeof(new)); + + return 0; +} + +char _license[] SEC("license") = "GPL"; diff --git a/tools/testing/selftests/bpf/progs/test_queue_stack_map.h b/tools/testing/selftests/bpf/progs/test_queue_stack_map.h new file mode 100644 index 000000000000..0e014d3b2b36 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/test_queue_stack_map.h @@ -0,0 +1,59 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +// Copyright (c) 2018 Politecnico di Torino +#include <stddef.h> +#include <string.h> +#include <linux/bpf.h> +#include <linux/if_ether.h> +#include <linux/ip.h> +#include <linux/pkt_cls.h> +#include "bpf_helpers.h" + +int _version SEC("version") = 1; + +struct { + __uint(type, MAP_TYPE); + __uint(max_entries, 32); + __uint(map_flags, 0); + __uint(key_size, 0); + __uint(value_size, sizeof(__u32)); +} map_in SEC(".maps"); + +struct { + __uint(type, MAP_TYPE); + __uint(max_entries, 32); + __uint(map_flags, 0); + __uint(key_size, 0); + __uint(value_size, sizeof(__u32)); +} map_out SEC(".maps"); + +SEC("test") +int _test(struct __sk_buff *skb) +{ + void *data_end = (void *)(long)skb->data_end; + void *data = (void *)(long)skb->data; + struct ethhdr *eth = (struct ethhdr *)(data); + __u32 value; + int err; + + if (eth + 1 > data_end) + return TC_ACT_SHOT; + + struct iphdr *iph = (struct iphdr *)(eth + 1); + + if (iph + 1 > data_end) + return TC_ACT_SHOT; + + err = bpf_map_pop_elem(&map_in, &value); + if (err) + return TC_ACT_SHOT; + + iph->daddr = value; + + err = bpf_map_push_elem(&map_out, &iph->saddr, 0); + if (err) + return TC_ACT_SHOT; + + return TC_ACT_OK; +} + +char _license[] SEC("license") = "GPL"; diff --git a/tools/testing/selftests/bpf/progs/test_rdonly_maps.c b/tools/testing/selftests/bpf/progs/test_rdonly_maps.c new file mode 100644 index 000000000000..52d94e8b214d --- /dev/null +++ b/tools/testing/selftests/bpf/progs/test_rdonly_maps.c @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2019 Facebook + +#include <linux/ptrace.h> +#include <linux/bpf.h> +#include "bpf_helpers.h" + +static volatile const struct { + unsigned a[4]; + /* + * if the struct's size is multiple of 16, compiler will put it into + * .rodata.cst16 section, which is not recognized by libbpf; work + * around this by ensuring we don't have 16-aligned struct + */ + char _y; +} rdonly_values = { .a = {2, 3, 4, 5} }; + +static volatile struct { + unsigned did_run; + unsigned iters; + unsigned sum; +} res; + +SEC("raw_tracepoint/sys_enter:skip_loop") +int skip_loop(struct pt_regs *ctx) +{ + /* prevent compiler to optimize everything out */ + unsigned * volatile p = (void *)&rdonly_values.a; + unsigned iters = 0, sum = 0; + + /* we should never enter this loop */ + while (*p & 1) { + iters++; + sum += *p; + p++; + } + res.did_run = 1; + res.iters = iters; + res.sum = sum; + return 0; +} + +SEC("raw_tracepoint/sys_enter:part_loop") +int part_loop(struct pt_regs *ctx) +{ + /* prevent compiler to optimize everything out */ + unsigned * volatile p = (void *)&rdonly_values.a; + unsigned iters = 0, sum = 0; + + /* validate verifier can derive loop termination */ + while (*p < 5) { + iters++; + sum += *p; + p++; + } + res.did_run = 1; + res.iters = iters; + res.sum = sum; + return 0; +} + +SEC("raw_tracepoint/sys_enter:full_loop") +int full_loop(struct pt_regs *ctx) +{ + /* prevent compiler to optimize everything out */ + unsigned * volatile p = (void *)&rdonly_values.a; + int i = sizeof(rdonly_values.a) / sizeof(rdonly_values.a[0]); + unsigned iters = 0, sum = 0; + + /* validate verifier can allow full loop as well */ + while (i > 0 ) { + iters++; + sum += *p; + p++; + i--; + } + res.did_run = 1; + res.iters = iters; + res.sum = sum; + return 0; +} + +char _license[] SEC("license") = "GPL"; diff --git a/tools/testing/selftests/bpf/progs/test_sk_lookup_kern.c b/tools/testing/selftests/bpf/progs/test_sk_lookup_kern.c index e21cd736c196..cb49ccb707d1 100644 --- a/tools/testing/selftests/bpf/progs/test_sk_lookup_kern.c +++ b/tools/testing/selftests/bpf/progs/test_sk_lookup_kern.c @@ -53,7 +53,7 @@ static struct bpf_sock_tuple *get_tuple(void *data, __u64 nh_off, return result; } -SEC("sk_lookup_success") +SEC("classifier/sk_lookup_success") int bpf_sk_lookup_test0(struct __sk_buff *skb) { void *data_end = (void *)(long)skb->data_end; @@ -78,7 +78,7 @@ int bpf_sk_lookup_test0(struct __sk_buff *skb) return sk ? TC_ACT_OK : TC_ACT_UNSPEC; } -SEC("sk_lookup_success_simple") +SEC("classifier/sk_lookup_success_simple") int bpf_sk_lookup_test1(struct __sk_buff *skb) { struct bpf_sock_tuple tuple = {}; @@ -90,7 +90,7 @@ int bpf_sk_lookup_test1(struct __sk_buff *skb) return 0; } -SEC("fail_use_after_free") +SEC("classifier/fail_use_after_free") int bpf_sk_lookup_uaf(struct __sk_buff *skb) { struct bpf_sock_tuple tuple = {}; @@ -105,7 +105,7 @@ int bpf_sk_lookup_uaf(struct __sk_buff *skb) return family; } -SEC("fail_modify_sk_pointer") +SEC("classifier/fail_modify_sk_pointer") int bpf_sk_lookup_modptr(struct __sk_buff *skb) { struct bpf_sock_tuple tuple = {}; @@ -120,7 +120,7 @@ int bpf_sk_lookup_modptr(struct __sk_buff *skb) return 0; } -SEC("fail_modify_sk_or_null_pointer") +SEC("classifier/fail_modify_sk_or_null_pointer") int bpf_sk_lookup_modptr_or_null(struct __sk_buff *skb) { struct bpf_sock_tuple tuple = {}; @@ -134,7 +134,7 @@ int bpf_sk_lookup_modptr_or_null(struct __sk_buff *skb) return 0; } -SEC("fail_no_release") +SEC("classifier/fail_no_release") int bpf_sk_lookup_test2(struct __sk_buff *skb) { struct bpf_sock_tuple tuple = {}; @@ -143,7 +143,7 @@ int bpf_sk_lookup_test2(struct __sk_buff *skb) return 0; } -SEC("fail_release_twice") +SEC("classifier/fail_release_twice") int bpf_sk_lookup_test3(struct __sk_buff *skb) { struct bpf_sock_tuple tuple = {}; @@ -155,7 +155,7 @@ int bpf_sk_lookup_test3(struct __sk_buff *skb) return 0; } -SEC("fail_release_unchecked") +SEC("classifier/fail_release_unchecked") int bpf_sk_lookup_test4(struct __sk_buff *skb) { struct bpf_sock_tuple tuple = {}; @@ -172,7 +172,7 @@ void lookup_no_release(struct __sk_buff *skb) bpf_sk_lookup_tcp(skb, &tuple, sizeof(tuple), BPF_F_CURRENT_NETNS, 0); } -SEC("fail_no_release_subcall") +SEC("classifier/fail_no_release_subcall") int bpf_sk_lookup_test5(struct __sk_buff *skb) { lookup_no_release(skb); diff --git a/tools/testing/selftests/bpf/progs/test_skb_ctx.c b/tools/testing/selftests/bpf/progs/test_skb_ctx.c index 7a80960d7df1..2a9f4c736ebc 100644 --- a/tools/testing/selftests/bpf/progs/test_skb_ctx.c +++ b/tools/testing/selftests/bpf/progs/test_skb_ctx.c @@ -16,6 +16,7 @@ int process(struct __sk_buff *skb) skb->cb[i]++; } skb->priority++; + skb->tstamp++; return 0; } diff --git a/tools/testing/selftests/bpf/progs/test_stacktrace_map.c b/tools/testing/selftests/bpf/progs/test_stacktrace_map.c index fa0be3e10a10..3b7e1dca8829 100644 --- a/tools/testing/selftests/bpf/progs/test_stacktrace_map.c +++ b/tools/testing/selftests/bpf/progs/test_stacktrace_map.c @@ -74,4 +74,3 @@ int oncpu(struct sched_switch_args *ctx) } char _license[] SEC("license") = "GPL"; -__u32 _version SEC("version") = 1; /* ignored by tracepoints, required by libbpf.a */ diff --git a/tools/testing/selftests/bpf/progs/test_tcp_estats.c b/tools/testing/selftests/bpf/progs/test_tcp_estats.c index c8c595da38d4..87b7d934ce73 100644 --- a/tools/testing/selftests/bpf/progs/test_tcp_estats.c +++ b/tools/testing/selftests/bpf/progs/test_tcp_estats.c @@ -38,7 +38,7 @@ #include <sys/socket.h> #include "bpf_helpers.h" -#define _(P) ({typeof(P) val = 0; bpf_probe_read(&val, sizeof(val), &P); val;}) +#define _(P) ({typeof(P) val = 0; bpf_probe_read_kernel(&val, sizeof(val), &P); val;}) #define TCP_ESTATS_MAGIC 0xBAADBEEF /* This test case needs "sock" and "pt_regs" data structure. |