diff mbox series

[v3,bpf-next,1/2] bpf: refine kernel.unpriviliged_bpf_disabled behaviour

Message ID 1652880861-27373-2-git-send-email-alan.maguire@oracle.com (mailing list archive)
State Superseded
Delegated to: BPF
Headers show
Series bpf: refine kernel.unprivileged_bpf_disabled behaviour | expand

Checks

Context Check Description
netdev/tree_selection success Clearly marked for bpf-next
netdev/fixes_present success Fixes tag not required for -next series
netdev/subject_prefix success Link
netdev/cover_letter success Series has a cover letter
netdev/patch_count success Link
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 15 this patch: 15
netdev/cc_maintainers warning 1 maintainers not CCed: netdev@vger.kernel.org
netdev/build_clang success Errors and warnings before: 11 this patch: 11
netdev/module_param success Was 0 now: 0
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 15 this patch: 15
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 22 lines checked
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
bpf/vmtest-bpf-next-PR fail PR summary
bpf/vmtest-bpf-next-VM_Test-1 fail Logs for Kernel LATEST on ubuntu-latest with gcc
bpf/vmtest-bpf-next-VM_Test-2 fail Logs for Kernel LATEST on ubuntu-latest with llvm-15
bpf/vmtest-bpf-next-VM_Test-3 fail Logs for Kernel LATEST on z15 with gcc

Commit Message

Alan Maguire May 18, 2022, 1:34 p.m. UTC
With unprivileged BPF disabled, all cmds associated with the BPF syscall
are blocked to users without CAP_BPF/CAP_SYS_ADMIN.  However there are
use cases where we may wish to allow interactions with BPF programs
without being able to load and attach them.  So for example, a process
with required capabilities loads/attaches a BPF program, and a process
with less capabilities interacts with it; retrieving perf/ring buffer
events, modifying map-specified config etc.  With all BPF syscall
commands blocked as a result of unprivileged BPF being disabled,
this mode of interaction becomes impossible for processes without
CAP_BPF.

As Alexei notes

"The bpf ACL model is the same as traditional file's ACL.
The creds and ACLs are checked at open().  Then during file's write/read
additional checks might be performed. BPF has such functionality already.
Different map_creates have capability checks while map_lookup has:
map_get_sys_perms(map, f) & FMODE_CAN_READ.
In other words it's enough to gate FD-receiving parts of bpf
with unprivileged_bpf_disabled sysctl.
The rest is handled by availability of FD and access to files in bpffs."

So key fd creation syscall commands BPF_PROG_LOAD and BPF_MAP_CREATE
are blocked with unprivileged BPF disabled and no CAP_BPF.

And as Alexei notes, map creation with unprivileged BPF disabled off
blocks creation of maps aside from array, hash and ringbuf maps.

Programs responsible for loading and attaching the BPF program
can still control access to its pinned representation by restricting
permissions on the pin path, as with normal files.

Signed-off-by: Alan Maguire <alan.maguire@oracle.com>
Acked-by: Yonghong Song <yhs@fb.com>
---
 kernel/bpf/syscall.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

Comments

Shung-Hsi Yu May 18, 2022, 2:21 p.m. UTC | #1
On Wed, May 18, 2022 at 02:34:20PM +0100, Alan Maguire wrote:
> With unprivileged BPF disabled, all cmds associated with the BPF syscall
> are blocked to users without CAP_BPF/CAP_SYS_ADMIN.  However there are
> use cases where we may wish to allow interactions with BPF programs
> without being able to load and attach them.  So for example, a process
> with required capabilities loads/attaches a BPF program, and a process
> with less capabilities interacts with it; retrieving perf/ring buffer
> events, modifying map-specified config etc.  With all BPF syscall
> commands blocked as a result of unprivileged BPF being disabled,
> this mode of interaction becomes impossible for processes without
> CAP_BPF.
> 
> As Alexei notes
> 
> "The bpf ACL model is the same as traditional file's ACL.
> The creds and ACLs are checked at open().  Then during file's write/read
> additional checks might be performed. BPF has such functionality already.
> Different map_creates have capability checks while map_lookup has:
> map_get_sys_perms(map, f) & FMODE_CAN_READ.
> In other words it's enough to gate FD-receiving parts of bpf
> with unprivileged_bpf_disabled sysctl.
> The rest is handled by availability of FD and access to files in bpffs."
> 
> So key fd creation syscall commands BPF_PROG_LOAD and BPF_MAP_CREATE
> are blocked with unprivileged BPF disabled and no CAP_BPF.
> 
> And as Alexei notes, map creation with unprivileged BPF disabled off
> blocks creation of maps aside from array, hash and ringbuf maps.
> 
> Programs responsible for loading and attaching the BPF program
> can still control access to its pinned representation by restricting
> permissions on the pin path, as with normal files.
> 
> Signed-off-by: Alan Maguire <alan.maguire@oracle.com>
> Acked-by: Yonghong Song <yhs@fb.com>

Acked-by: Shung-Hsi Yu <shung-hsi.yu@suse.com>
KP Singh May 18, 2022, 2:58 p.m. UTC | #2
On Wed, May 18, 2022 at 4:21 PM Shung-Hsi Yu <shung-hsi.yu@suse.com> wrote:
>
> On Wed, May 18, 2022 at 02:34:20PM +0100, Alan Maguire wrote:
> > With unprivileged BPF disabled, all cmds associated with the BPF syscall
> > are blocked to users without CAP_BPF/CAP_SYS_ADMIN.  However there are
> > use cases where we may wish to allow interactions with BPF programs
> > without being able to load and attach them.  So for example, a process
> > with required capabilities loads/attaches a BPF program, and a process
> > with less capabilities interacts with it; retrieving perf/ring buffer
> > events, modifying map-specified config etc.  With all BPF syscall
> > commands blocked as a result of unprivileged BPF being disabled,
> > this mode of interaction becomes impossible for processes without
> > CAP_BPF.
> >
> > As Alexei notes
> >
> > "The bpf ACL model is the same as traditional file's ACL.
> > The creds and ACLs are checked at open().  Then during file's write/read
> > additional checks might be performed. BPF has such functionality already.
> > Different map_creates have capability checks while map_lookup has:
> > map_get_sys_perms(map, f) & FMODE_CAN_READ.
> > In other words it's enough to gate FD-receiving parts of bpf
> > with unprivileged_bpf_disabled sysctl.
> > The rest is handled by availability of FD and access to files in bpffs."
> >
> > So key fd creation syscall commands BPF_PROG_LOAD and BPF_MAP_CREATE
> > are blocked with unprivileged BPF disabled and no CAP_BPF.
> >
> > And as Alexei notes, map creation with unprivileged BPF disabled off
> > blocks creation of maps aside from array, hash and ringbuf maps.
> >
> > Programs responsible for loading and attaching the BPF program
> > can still control access to its pinned representation by restricting
> > permissions on the pin path, as with normal files.
> >
> > Signed-off-by: Alan Maguire <alan.maguire@oracle.com>
> > Acked-by: Yonghong Song <yhs@fb.com>
>
> Acked-by: Shung-Hsi Yu <shung-hsi.yu@suse.com>

Acked-by: KP Singh <kpsingh@kernel.org>
diff mbox series

Patch

diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 72e53489165d..2b69306d3c6e 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -4863,9 +4863,21 @@  static int bpf_prog_bind_map(union bpf_attr *attr)
 static int __sys_bpf(int cmd, bpfptr_t uattr, unsigned int size)
 {
 	union bpf_attr attr;
+	bool capable;
 	int err;
 
-	if (sysctl_unprivileged_bpf_disabled && !bpf_capable())
+	capable = bpf_capable() || !sysctl_unprivileged_bpf_disabled;
+
+	/* Intent here is for unprivileged_bpf_disabled to block key object
+	 * creation commands for unprivileged users; other actions depend
+	 * of fd availability and access to bpffs, so are dependent on
+	 * object creation success.  Capabilities are later verified for
+	 * operations such as load and map create, so even with unprivileged
+	 * BPF disabled, capability checks are still carried out for these
+	 * and other operations.
+	 */
+	if (!capable &&
+	    (cmd == BPF_MAP_CREATE || cmd == BPF_PROG_LOAD))
 		return -EPERM;
 
 	err = bpf_check_uarg_tail_zero(uattr, sizeof(attr), size);