This patch exposes the current_task_under_cgroup helper to Checmate
programs. It can be used to implement exemptions for certain policies
when using Checmate programs by wrapping a pre-compiled policy
in a tail call along with this helper.

Signed-off-by: Sargun Dhillon <sar...@sargun.me>
---
 include/linux/bpf.h              |  1 +
 kernel/bpf/helpers.c             | 29 +++++++++++++++++++++++++++++
 kernel/trace/bpf_trace.c         | 28 ----------------------------
 security/checmate/checmate_bpf.c |  2 ++
 4 files changed, 32 insertions(+), 28 deletions(-)

diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 4e1fa57..5c5ed16 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -316,6 +316,7 @@ extern const struct bpf_func_proto bpf_skb_vlan_pop_proto;
 extern const struct bpf_func_proto bpf_get_stackid_proto;
 extern const struct bpf_func_proto bpf_get_current_task_proto;
 extern const struct bpf_func_proto bpf_probe_read_proto;
+extern const struct bpf_func_proto bpf_current_task_under_cgroup_proto;
 
 /* Shared helpers among cBPF and eBPF. */
 void bpf_user_rnd_init_once(void);
diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
index c439afc..ffaaa4b 100644
--- a/kernel/bpf/helpers.c
+++ b/kernel/bpf/helpers.c
@@ -17,6 +17,7 @@
 #include <linux/sched.h>
 #include <linux/uidgid.h>
 #include <linux/uaccess.h>
+#include <linux/cgroup.h>
 
 /* If kernel subsystem is allowing eBPF programs to call this function,
  * inside its own verifier_ops->get_func_proto() callback it should return
@@ -212,6 +213,34 @@ static u64 bpf_probe_read(u64 r1, u64 r2, u64 r3, u64 r4, 
u64 r5)
        return ret;
 }
 
+static u64 bpf_current_task_under_cgroup(u64 r1, u64 r2, u64 r3, u64 r4, u64 
r5)
+{
+       struct bpf_map *map = (struct bpf_map *)(long)r1;
+       struct bpf_array *array = container_of(map, struct bpf_array, map);
+       struct cgroup *cgrp;
+       u32 idx = (u32)r2;
+
+       if (unlikely(in_interrupt()))
+               return -EINVAL;
+
+       if (unlikely(idx >= array->map.max_entries))
+               return -E2BIG;
+
+       cgrp = READ_ONCE(array->ptrs[idx]);
+       if (unlikely(!cgrp))
+               return -EAGAIN;
+
+       return task_under_cgroup_hierarchy(current, cgrp);
+}
+
+const struct bpf_func_proto bpf_current_task_under_cgroup_proto = {
+       .func           = bpf_current_task_under_cgroup,
+       .gpl_only       = false,
+       .ret_type       = RET_INTEGER,
+       .arg1_type      = ARG_CONST_MAP_PTR,
+       .arg2_type      = ARG_ANYTHING,
+};
+
 const struct bpf_func_proto bpf_probe_read_proto = {
        .func           = bpf_probe_read,
        .gpl_only       = true,
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
index cb96eda..3725df2 100644
--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@ -343,34 +343,6 @@ u64 bpf_event_output(struct bpf_map *map, u64 flags, void 
*meta, u64 meta_size,
        return __bpf_perf_event_output(regs, map, flags, &raw);
 }
 
-static u64 bpf_current_task_under_cgroup(u64 r1, u64 r2, u64 r3, u64 r4, u64 
r5)
-{
-       struct bpf_map *map = (struct bpf_map *)(long)r1;
-       struct bpf_array *array = container_of(map, struct bpf_array, map);
-       struct cgroup *cgrp;
-       u32 idx = (u32)r2;
-
-       if (unlikely(in_interrupt()))
-               return -EINVAL;
-
-       if (unlikely(idx >= array->map.max_entries))
-               return -E2BIG;
-
-       cgrp = READ_ONCE(array->ptrs[idx]);
-       if (unlikely(!cgrp))
-               return -EAGAIN;
-
-       return task_under_cgroup_hierarchy(current, cgrp);
-}
-
-static const struct bpf_func_proto bpf_current_task_under_cgroup_proto = {
-       .func           = bpf_current_task_under_cgroup,
-       .gpl_only       = false,
-       .ret_type       = RET_INTEGER,
-       .arg1_type      = ARG_CONST_MAP_PTR,
-       .arg2_type      = ARG_ANYTHING,
-};
-
 static const struct bpf_func_proto *tracing_func_proto(enum bpf_func_id 
func_id)
 {
        switch (func_id) {
diff --git a/security/checmate/checmate_bpf.c b/security/checmate/checmate_bpf.c
index 24d6935..37ea609 100644
--- a/security/checmate/checmate_bpf.c
+++ b/security/checmate/checmate_bpf.c
@@ -91,6 +91,8 @@ checmate_prog_func_proto(enum bpf_func_id func_id)
                return &bpf_probe_write_user_proto;
        case BPF_FUNC_trace_printk:
                return bpf_get_trace_printk_proto();
+       case BPF_FUNC_current_task_under_cgroup:
+               return &bpf_current_task_under_cgroup_proto;
        default:
                return NULL;
        }
-- 
2.7.4

Reply via email to