Adding support to define sorted set of BTF ID values.

Following defines sorted set of BTF ID values:

  BTF_SET_START(btf_whitelist_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_whitelist_d_path)

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

  struct btf_id_set btf_whitelist_d_path;

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

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

Signed-off-by: Jiri Olsa <jo...@kernel.org>
---
 include/linux/bpf.h     |  4 ++++
 include/linux/btf_ids.h | 39 +++++++++++++++++++++++++++++++++++++++
 kernel/bpf/btf.c        | 14 ++++++++++++++
 kernel/bpf/verifier.c   |  5 +++++
 4 files changed, 62 insertions(+)

diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index c0fd1f3037dd..9efd0c23147d 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -294,6 +294,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
@@ -1771,4 +1772,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 */
diff --git a/include/linux/btf_ids.h b/include/linux/btf_ids.h
index f7f9dc4d9a9f..5eb8983ee0a0 100644
--- a/include/linux/btf_ids.h
+++ b/include/linux/btf_ids.h
@@ -66,4 +66,43 @@ asm(                                                 \
 __BTF_ID_LIST(name)                                    \
 extern int name[];
 
+struct btf_id_set {
+       u32 cnt;
+       u32 ids[];
+};
+
+/*
+ * 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)                            \
+__BTF_ID_LIST(name)                                    \
+asm(                                                   \
+".pushsection " BTF_IDS_SECTION ",\"a\";       \n"     \
+".local __BTF_ID__set__" #name ";              \n"     \
+"__BTF_ID__set__" #name ":;                    \n"     \
+".zero 4                                       \n"     \
+".popsection;                                  \n");   \
+
+#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;
+
 #endif
diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
index f87e5f1dc64d..201fe564bb84 100644
--- a/kernel/bpf/btf.c
+++ b/kernel/bpf/btf.c
@@ -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
@@ -4712,3 +4714,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(int), btf_id_cmp_func) 
!= NULL;
+}
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index da7351184295..b6f583e3e24f 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -4708,6 +4708,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) {
-- 
2.25.4

Reply via email to