Re: Closing the BPF map permission loophole

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, 2022-09-15 at 11:30 +0100, Lorenz Bauer wrote:
> Hi list,
> 
> Here is a summary of the talk I gave at LPC '22 titled "Closing the
> BPF map permission loophole", with slides at [0].
> 
> Problem #1: Read-only fds can be modified via a BPF program
> 
> 1. Craft a BPF program that executes bpf_map_update_elem(read-only
> fd, ...)
> 2. Load the program & execute it
> 
> The reason is that the verifier only checks bpf_map->map_flags in
> resolve_pseudo_ldimm64, but ignores fd->f_mode.
> 
> Fixing this problem is complicated by the fact that a user may use
> several distinct fds with differing permissions to refer to the same
> map, but that the verifier internally only tracks unique struct
> bpf_map. See [1].

Hi Lorenz

thanks for the detailed report. Unfortunately, I could not attend your
presentation at Linux Plumbers, and the recording is not yet available.
So, I rely on this and your slides.

I saw your fix #2, even if I didn't fully understand it. What do you
think instead about converting the fd modes to map flags (e.g.
BPF_F_RDONLY -> BPF_RDONLY_PROG), and we rely on the existing verifier
behavior for the _PROG counterparts? In this way, it will be the
verifier enforcing the decision made by security_bpf_map().

> Problem #2: Read-only fds can be "transmuted" into read-write fds via
> map in map
> 
> 1. BPF_MAP_UPDATE_ELEM(map in map fd, read-only fd)
> 2. BPF_MAP_LOOKUP_ELEM(map in map fd) = read-write fd
> 
> This was pointed out by Stanislav Fomichev during the LPC session.
> I've not yet tried this myself.

Didn't look into it yet.

> Problem #3: Read-only fds can be transmuted into read-write fds via
> object pinning
> 
> 1. BPF_OBJ_PIN(read-only fd, /sys/fs/bpf/foo)
> 2. BPF_OBJ_GET(/sys/fs/bpf/foo) = read-write fd
> 
> The problem is with BPF_OBJ_PIN semantics: regardless of fd->f_mode,
> pinning creates an inode that is owned by the current user, with mode
> o=rw. Even if we made the inode o=r, a user / attacker can still use
> chmod(2) to change it back to o=rw.

Maybe I'm missing something, but I consider pinning more like adding a
new reference to an eBPF object (like the ID).

You are still subject to access control decision by security_bpf_map(),
as for BPF_MAP_GET_FD_BY_ID().

Now, the security model is limited to two permissions (read, write). If
we want to add a new one to decide whether or not a new reference can
be added, we could revisit this.

Roberto




[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux