lkml.org 
[lkml]   [2023]   [Aug]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Date
    Subject[PATCH RFC 1/4] bpf: add cgroup device guard to flag a cgroup device prog
    Introduce the BPF_F_CGROUP_DEVICE_GUARD flag for BPF_PROG_LOAD
    which allows to set a cgroup device program to be a device guard.
    Later this may be used to guard actions on device nodes in
    non-initial userns. For this reason we provide the helper function
    cgroup_bpf_device_guard_enabled() to check if a task has a cgroups
    device program which is a device guard in its effective set of bpf
    programs.

    Signed-off-by: Michael Weiß <michael.weiss@aisec.fraunhofer.de>
    ---
    include/linux/bpf-cgroup.h | 7 +++++++
    include/linux/bpf.h | 1 +
    include/uapi/linux/bpf.h | 5 +++++
    kernel/bpf/cgroup.c | 30 ++++++++++++++++++++++++++++++
    kernel/bpf/syscall.c | 5 ++++-
    tools/include/uapi/linux/bpf.h | 5 +++++
    6 files changed, 52 insertions(+), 1 deletion(-)

    diff --git a/include/linux/bpf-cgroup.h b/include/linux/bpf-cgroup.h
    index 57e9e109257e..112b6093f9fd 100644
    --- a/include/linux/bpf-cgroup.h
    +++ b/include/linux/bpf-cgroup.h
    @@ -184,6 +184,8 @@ static inline bool cgroup_bpf_sock_enabled(struct sock *sk,
    return array != &bpf_empty_prog_array.hdr;
    }

    +bool cgroup_bpf_device_guard_enabled(struct task_struct *task);
    +
    /* Wrappers for __cgroup_bpf_run_filter_skb() guarded by cgroup_bpf_enabled. */
    #define BPF_CGROUP_RUN_PROG_INET_INGRESS(sk, skb) \
    ({ \
    @@ -476,6 +478,11 @@ static inline int bpf_percpu_cgroup_storage_update(struct bpf_map *map,
    return 0;
    }

    +static bool cgroup_bpf_device_guard_enabled(struct task_struct *task)
    +{
    + return false;
    +}
    +
    #define cgroup_bpf_enabled(atype) (0)
    #define BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, atype, t_ctx) ({ 0; })
    #define BPF_CGROUP_RUN_SA_PROG(sk, uaddr, atype) ({ 0; })
    diff --git a/include/linux/bpf.h b/include/linux/bpf.h
    index f58895830ada..313cce8aee05 100644
    --- a/include/linux/bpf.h
    +++ b/include/linux/bpf.h
    @@ -1384,6 +1384,7 @@ struct bpf_prog_aux {
    bool sleepable;
    bool tail_call_reachable;
    bool xdp_has_frags;
    + bool cgroup_device_guard;
    /* BTF_KIND_FUNC_PROTO for valid attach_btf_id */
    const struct btf_type *attach_func_proto;
    /* function name for valid attach_btf_id */
    diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
    index 60a9d59beeab..3be57f7957b1 100644
    --- a/include/uapi/linux/bpf.h
    +++ b/include/uapi/linux/bpf.h
    @@ -1165,6 +1165,11 @@ enum bpf_link_type {
    */
    #define BPF_F_XDP_DEV_BOUND_ONLY (1U << 6)

    +/* If BPF_F_CGROUP_DEVICE_GUARD is used in BPF_PROG_LOAD command, the loaded
    + * program will be allowed to guard device access inside user namespaces.
    + */
    +#define BPF_F_CGROUP_DEVICE_GUARD (1U << 7)
    +
    /* link_create.kprobe_multi.flags used in LINK_CREATE command for
    * BPF_TRACE_KPROBE_MULTI attach type to create return probe.
    */
    diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c
    index 5b2741aa0d9b..230693ca4cdb 100644
    --- a/kernel/bpf/cgroup.c
    +++ b/kernel/bpf/cgroup.c
    @@ -2505,6 +2505,36 @@ const struct bpf_verifier_ops cg_sockopt_verifier_ops = {
    const struct bpf_prog_ops cg_sockopt_prog_ops = {
    };

    +bool
    +cgroup_bpf_device_guard_enabled(struct task_struct *task)
    +{
    + bool ret;
    + const struct bpf_prog_array *array;
    + const struct bpf_prog_array_item *item;
    + const struct bpf_prog *prog;
    + struct cgroup *cgrp = task_dfl_cgroup(task);
    +
    + ret = false;
    +
    + array = rcu_access_pointer(cgrp->bpf.effective[CGROUP_DEVICE]);
    + if (array == &bpf_empty_prog_array.hdr)
    + return ret;
    +
    + mutex_lock(&cgroup_mutex);
    + array = rcu_dereference_protected(cgrp->bpf.effective[CGROUP_DEVICE],
    + lockdep_is_held(&cgroup_mutex));
    + item = &array->items[0];
    + while ((prog = READ_ONCE(item->prog))) {
    + if (prog->aux->cgroup_device_guard) {
    + ret = true;
    + break;
    + }
    + item++;
    + }
    + mutex_unlock(&cgroup_mutex);
    + return ret;
    +}
    +
    /* Common helpers for cgroup hooks. */
    const struct bpf_func_proto *
    cgroup_common_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
    diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
    index a2aef900519c..33ea67c702c1 100644
    --- a/kernel/bpf/syscall.c
    +++ b/kernel/bpf/syscall.c
    @@ -2564,7 +2564,8 @@ static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size)
    BPF_F_SLEEPABLE |
    BPF_F_TEST_RND_HI32 |
    BPF_F_XDP_HAS_FRAGS |
    - BPF_F_XDP_DEV_BOUND_ONLY))
    + BPF_F_XDP_DEV_BOUND_ONLY |
    + BPF_F_CGROUP_DEVICE_GUARD))
    return -EINVAL;

    if (!IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) &&
    @@ -2651,6 +2652,8 @@ static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size)
    prog->aux->dev_bound = !!attr->prog_ifindex;
    prog->aux->sleepable = attr->prog_flags & BPF_F_SLEEPABLE;
    prog->aux->xdp_has_frags = attr->prog_flags & BPF_F_XDP_HAS_FRAGS;
    + prog->aux->cgroup_device_guard =
    + attr->prog_flags & BPF_F_CGROUP_DEVICE_GUARD;

    err = security_bpf_prog_alloc(prog->aux);
    if (err)
    diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
    index 60a9d59beeab..3be57f7957b1 100644
    --- a/tools/include/uapi/linux/bpf.h
    +++ b/tools/include/uapi/linux/bpf.h
    @@ -1165,6 +1165,11 @@ enum bpf_link_type {
    */
    #define BPF_F_XDP_DEV_BOUND_ONLY (1U << 6)

    +/* If BPF_F_CGROUP_DEVICE_GUARD is used in BPF_PROG_LOAD command, the loaded
    + * program will be allowed to guard device access inside user namespaces.
    + */
    +#define BPF_F_CGROUP_DEVICE_GUARD (1U << 7)
    +
    /* link_create.kprobe_multi.flags used in LINK_CREATE command for
    * BPF_TRACE_KPROBE_MULTI attach type to create return probe.
    */
    --
    2.30.2

    \
     
     \ /
      Last update: 2023-08-14 16:28    [W:3.738 / U:0.748 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site