Skip to content

Commit

Permalink
bpf: Add BTF_SET_START/END macros
Browse files Browse the repository at this point in the history
Adding support to define sorted set of BTF ID values.

Following defines sorted set of BTF ID values:

  BTF_SET_START(btf_allowlist_d_path)
  BTF_ID(func, vfs_truncate)
  BTF_ID(func, vfs_fallocate)
  BTF_ID(func, dentry_open)
  BTF_ID(func, vfs_getattr)
  BTF_ID(func, filp_close)
  BTF_SET_END(btf_allowlist_d_path)

It defines following 'struct btf_id_set' variable to access
values and count:

  struct btf_id_set btf_allowlist_d_path;

Adding 'allowed' callback to struct bpf_func_proto, to allow
verifier the check on allowed callers.

Adding btf_id_set_contains function, which will be used by
allowed callbacks to verify the caller's BTF ID value is
within allowed set.

Also removing extra '\' in __BTF_ID_LIST macro.

Added BTF_SET_START_GLOBAL macro for global sets.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: Andrii Nakryiko <andriin@fb.com>
Link: https://lore.kernel.org/bpf/20200825192124.710397-10-jolsa@kernel.org
  • Loading branch information
olsajiri authored and Alexei Starovoitov committed Aug 25, 2020
1 parent faaf4a7 commit eae2e83
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 2 deletions.
4 changes: 4 additions & 0 deletions include/linux/bpf.h
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,7 @@ struct bpf_func_proto {
* for this argument.
*/
int *ret_btf_id; /* return value btf_id */
bool (*allowed)(const struct bpf_prog *prog);
};

/* bpf_context is intentionally undefined structure. Pointer to bpf_context is
Expand Down Expand Up @@ -1878,4 +1879,7 @@ enum bpf_text_poke_type {
int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type t,
void *addr1, void *addr2);

struct btf_id_set;
bool btf_id_set_contains(struct btf_id_set *set, u32 id);

#endif /* _LINUX_BPF_H */
51 changes: 50 additions & 1 deletion include/linux/btf_ids.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
#ifndef _LINUX_BTF_IDS_H
#define _LINUX_BTF_IDS_H

struct btf_id_set {
u32 cnt;
u32 ids[];
};

#ifdef CONFIG_DEBUG_INFO_BTF

#include <linux/compiler.h> /* for __PASTE */
Expand Down Expand Up @@ -62,7 +67,7 @@ asm( \
".pushsection " BTF_IDS_SECTION ",\"a\"; \n" \
"." #scope " " #name "; \n" \
#name ":; \n" \
".popsection; \n"); \
".popsection; \n");

#define BTF_ID_LIST(name) \
__BTF_ID_LIST(name, local) \
Expand All @@ -88,12 +93,56 @@ asm( \
".zero 4 \n" \
".popsection; \n");

/*
* The BTF_SET_START/END macros pair defines sorted list of
* BTF IDs plus its members count, with following layout:
*
* BTF_SET_START(list)
* BTF_ID(type1, name1)
* BTF_ID(type2, name2)
* BTF_SET_END(list)
*
* __BTF_ID__set__list:
* .zero 4
* list:
* __BTF_ID__type1__name1__3:
* .zero 4
* __BTF_ID__type2__name2__4:
* .zero 4
*
*/
#define __BTF_SET_START(name, scope) \
asm( \
".pushsection " BTF_IDS_SECTION ",\"a\"; \n" \
"." #scope " __BTF_ID__set__" #name "; \n" \
"__BTF_ID__set__" #name ":; \n" \
".zero 4 \n" \
".popsection; \n");

#define BTF_SET_START(name) \
__BTF_ID_LIST(name, local) \
__BTF_SET_START(name, local)

#define BTF_SET_START_GLOBAL(name) \
__BTF_ID_LIST(name, globl) \
__BTF_SET_START(name, globl)

#define BTF_SET_END(name) \
asm( \
".pushsection " BTF_IDS_SECTION ",\"a\"; \n" \
".size __BTF_ID__set__" #name ", .-" #name " \n" \
".popsection; \n"); \
extern struct btf_id_set name;

#else

#define BTF_ID_LIST(name) static u32 name[5];
#define BTF_ID(prefix, name)
#define BTF_ID_UNUSED
#define BTF_ID_LIST_GLOBAL(name) u32 name[1];
#define BTF_SET_START(name) static struct btf_id_set name = { 0 };
#define BTF_SET_START_GLOBAL(name) static struct btf_id_set name = { 0 };
#define BTF_SET_END(name)

#endif /* CONFIG_DEBUG_INFO_BTF */

Expand Down
14 changes: 14 additions & 0 deletions kernel/bpf/btf.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
#include <linux/btf_ids.h>
#include <linux/skmsg.h>
#include <linux/perf_event.h>
#include <linux/bsearch.h>
#include <linux/btf_ids.h>
#include <net/sock.h>

/* BTF (BPF Type Format) is the meta data format which describes
Expand Down Expand Up @@ -4762,3 +4764,15 @@ u32 btf_id(const struct btf *btf)
{
return btf->id;
}

static int btf_id_cmp_func(const void *a, const void *b)
{
const int *pa = a, *pb = b;

return *pa - *pb;
}

bool btf_id_set_contains(struct btf_id_set *set, u32 id)
{
return bsearch(&id, set->ids, set->cnt, sizeof(u32), btf_id_cmp_func) != NULL;
}
5 changes: 5 additions & 0 deletions kernel/bpf/verifier.c
Original file line number Diff line number Diff line change
Expand Up @@ -4859,6 +4859,11 @@ static int check_helper_call(struct bpf_verifier_env *env, int func_id, int insn
return -EINVAL;
}

if (fn->allowed && !fn->allowed(env->prog)) {
verbose(env, "helper call is not allowed in probe\n");
return -EINVAL;
}

/* With LD_ABS/IND some JITs save/restore skb from r1. */
changes_data = bpf_helper_changes_pkt_data(fn->func);
if (changes_data && fn->arg1_type != ARG_PTR_TO_CTX) {
Expand Down
51 changes: 50 additions & 1 deletion tools/include/linux/btf_ids.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
#ifndef _LINUX_BTF_IDS_H
#define _LINUX_BTF_IDS_H

struct btf_id_set {
u32 cnt;
u32 ids[];
};

#ifdef CONFIG_DEBUG_INFO_BTF

#include <linux/compiler.h> /* for __PASTE */
Expand Down Expand Up @@ -62,7 +67,7 @@ asm( \
".pushsection " BTF_IDS_SECTION ",\"a\"; \n" \
"." #scope " " #name "; \n" \
#name ":; \n" \
".popsection; \n"); \
".popsection; \n");

#define BTF_ID_LIST(name) \
__BTF_ID_LIST(name, local) \
Expand All @@ -88,12 +93,56 @@ asm( \
".zero 4 \n" \
".popsection; \n");

/*
* The BTF_SET_START/END macros pair defines sorted list of
* BTF IDs plus its members count, with following layout:
*
* BTF_SET_START(list)
* BTF_ID(type1, name1)
* BTF_ID(type2, name2)
* BTF_SET_END(list)
*
* __BTF_ID__set__list:
* .zero 4
* list:
* __BTF_ID__type1__name1__3:
* .zero 4
* __BTF_ID__type2__name2__4:
* .zero 4
*
*/
#define __BTF_SET_START(name, scope) \
asm( \
".pushsection " BTF_IDS_SECTION ",\"a\"; \n" \
"." #scope " __BTF_ID__set__" #name "; \n" \
"__BTF_ID__set__" #name ":; \n" \
".zero 4 \n" \
".popsection; \n");

#define BTF_SET_START(name) \
__BTF_ID_LIST(name, local) \
__BTF_SET_START(name, local)

#define BTF_SET_START_GLOBAL(name) \
__BTF_ID_LIST(name, globl) \
__BTF_SET_START(name, globl)

#define BTF_SET_END(name) \
asm( \
".pushsection " BTF_IDS_SECTION ",\"a\"; \n" \
".size __BTF_ID__set__" #name ", .-" #name " \n" \
".popsection; \n"); \
extern struct btf_id_set name;

#else

#define BTF_ID_LIST(name) static u32 name[5];
#define BTF_ID(prefix, name)
#define BTF_ID_UNUSED
#define BTF_ID_LIST_GLOBAL(name) u32 name[1];
#define BTF_SET_START(name) static struct btf_id_set name = { 0 };
#define BTF_SET_START_GLOBAL(name) static struct btf_id_set name = { 0 };
#define BTF_SET_END(name)

#endif /* CONFIG_DEBUG_INFO_BTF */

Expand Down

0 comments on commit eae2e83

Please sign in to comment.