diff options
author | Alexei Starovoitov <ast@kernel.org> | 2023-12-17 17:28:30 -0800 |
---|---|---|
committer | Alexei Starovoitov <ast@kernel.org> | 2023-12-17 17:31:20 -0800 |
commit | 5553ee524087f5ea1c5c5523f5ee2e53ee95a203 (patch) | |
tree | 6ea04a714f8aa086904e8fb8f3cee1672536f50a | |
parent | 2364a53aece9c1d291762b8ee1e6f9b1917a56d8 (diff) | |
download | bpf-optimize_example.tar.gz |
optimize BPF_CORE_READoptimize_example
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
-rw-r--r-- | tools/testing/selftests/bpf/progs/userns-restrict.bpf.c | 25 |
1 files changed, 14 insertions, 11 deletions
diff --git a/tools/testing/selftests/bpf/progs/userns-restrict.bpf.c b/tools/testing/selftests/bpf/progs/userns-restrict.bpf.c index 9050b6dcee9e11..c5422f97a2b41a 100644 --- a/tools/testing/selftests/bpf/progs/userns-restrict.bpf.c +++ b/tools/testing/selftests/bpf/progs/userns-restrict.bpf.c @@ -20,6 +20,8 @@ #include <bpf/bpf_core_read.h> #include <errno.h> +void *bpf_rdonly_cast(void *, __u32) __ksym; + /* BPF module that implements an allowlist of mounts (identified by mount ID) for user namespaces (identified * by their inode number in nsfs) that restricts creation of inodes (which would inherit the callers UID/GID) * or changing of ownership (similar). @@ -68,12 +70,12 @@ static int validate_inode_on_mount(struct inode *inode, struct vfsmount *v) { int mnt_id; /* Get user namespace from vfsmount */ - m = real_mount(v); - mount_userns = BPF_CORE_READ(m, mnt_ns, user_ns); + m = bpf_rdonly_cast(real_mount(v), bpf_core_type_id_kernel(struct mount)); + mount_userns = m->mnt_ns->user_ns; /* Get user namespace from task */ - task = (struct task_struct*) bpf_get_current_task(); - task_userns = BPF_CORE_READ(task, cred, user_ns); + task = (struct task_struct*) bpf_get_current_task_btf(); + task_userns = task->cred->user_ns; /* Is the file on a mount that belongs to our own user namespace or a child of it? If so, say * yes immediately. */ @@ -82,7 +84,7 @@ static int validate_inode_on_mount(struct inode *inode, struct vfsmount *v) { if (p == task_userns) return 0; /* our task's user namespace (or a child thereof) owns this superblock: allow! */ - p = BPF_CORE_READ(p, parent); + p = p->parent; if (!p) break; } @@ -93,13 +95,13 @@ static int validate_inode_on_mount(struct inode *inode, struct vfsmount *v) { return -EPERM; /* This is a mount foreign to our task's user namespace, let's consult our allow list */ - task_userns_inode = BPF_CORE_READ(task_userns, ns.inum); + task_userns_inode = task_userns->ns.inum; mnt_id_map = bpf_map_lookup_elem(&userns_mnt_id_hash, &task_userns_inode); if (!mnt_id_map) /* No rules installed for this userns? Then say yes, too! */ return 0; - mnt_id = BPF_CORE_READ(m, mnt_id); + mnt_id = m->mnt_id; /* Otherwise, say yes if the mount ID is allowlisted */ if (bpf_map_lookup_elem(mnt_id_map, &mnt_id)) @@ -115,8 +117,8 @@ static int validate_path(const struct path *path, int ret) { if (ret != 0) /* propagate earlier error */ return ret; - inode = BPF_CORE_READ(path, dentry, d_inode); - v = BPF_CORE_READ(path, mnt); + inode = path->dentry->d_inode; + v = path->mnt; return validate_inode_on_mount(inode, v); } @@ -155,9 +157,10 @@ void BPF_KPROBE(userns_restrict_free_user_ns, struct work_struct *work) { /* Inform userspace that a user namespace just went away. I wish there was a nicer way to hook into * user namespaces being deleted than using kprobes, but couldn't find any. */ - userns = container_of(work, struct user_namespace, work); + userns = bpf_rdonly_cast(container_of(work, struct user_namespace, work), + bpf_core_type_id_kernel(struct user_namespace)); - inode = BPF_CORE_READ(userns, ns.inum); + inode = userns->ns.inum; mnt_id_map = bpf_map_lookup_elem(&userns_mnt_id_hash, &inode); if (!mnt_id_map) /* No rules installed for this userns? Then send no notification. */ |