[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20220225234339.2386398-8-haoluo@google.com>
Date: Fri, 25 Feb 2022 15:43:37 -0800
From: Hao Luo <haoluo@...gle.com>
To: Alexei Starovoitov <ast@...nel.org>,
Andrii Nakryiko <andrii@...nel.org>,
Daniel Borkmann <daniel@...earbox.net>
Cc: Martin KaFai Lau <kafai@...com>, Song Liu <songliubraving@...com>,
Yonghong Song <yhs@...com>, KP Singh <kpsingh@...nel.org>,
Shakeel Butt <shakeelb@...gle.com>,
Joe Burton <jevburton.kernel@...il.com>,
Tejun Heo <tj@...nel.org>, joshdon@...gle.com, sdf@...gle.com,
bpf@...r.kernel.org, linux-kernel@...r.kernel.org,
Hao Luo <haoluo@...gle.com>
Subject: [PATCH bpf-next v1 7/9] bpf: Lift permission check in __sys_bpf when
called from kernel.
After we introduced sleepable tracing programs, we now have an
interesting problem. There are now three execution paths that can
reach bpf_sys_bpf:
1. called from bpf syscall.
2. called from kernel context (e.g. kernel modules).
3. called from bpf programs.
Ideally, capability check in bpf_sys_bpf is necessary for the first two
scenarios. But it may not be necessary for the third case.
The use case of sleepable tracepoints is to allow root user to deploy
bpf progs which run when a certain kernel tracepoints are triggered.
An example use case is to monitor cgroup creation and perform bpf
operations whenever a cgroup is created. These operations include
pinning an iter to export the cgroup's state. Using sleepable tracing
is preferred because it eliminates the need of a userspace daemon to
monitor cgroup changes.
However, in this use case, the current task who triggers the tracepoint
may be unprivileged and the permission check in __sys_bpf will thus
prevent it from making bpf syscalls. Therefore the tracing progs
deployed by root can not be used by non-root users.
A solution to this problem is to lift the permission check if the caller
of bpf_sys_bpf comes from either kernel context or bpf programs.
An alternative of lifting this permission check would be introducing an
'unpriv' version of bpf_sys_bpf, which doesn't check the current task's
capability. If the owner of the tracing prog wants it to be exclusively
used by root users, they can use the 'priv' version of bpf_sys_bpf; if
the owner wants it to be usable for non-root users, they can use the
'unpriv' version.
Signed-off-by: Hao Luo <haoluo@...gle.com>
---
kernel/bpf/syscall.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 0a12f52fe8a9..3bf88002ee56 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -4613,7 +4613,7 @@ static int __sys_bpf(int cmd, bpfptr_t uattr, unsigned int size)
union bpf_attr attr;
int err;
- if (sysctl_unprivileged_bpf_disabled && !bpf_capable())
+ if (sysctl_unprivileged_bpf_disabled && !bpf_capable() && !uattr.is_kernel)
return -EPERM;
err = bpf_check_uarg_tail_zero(uattr, sizeof(attr), size);
--
2.35.1.574.g5d30c73bfb-goog
Powered by blists - more mailing lists