Re: Closing the BPF map permission loophole

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

 



On Thu, 2022-09-22 at 17:21 +0100, Lorenz Bauer wrote:
> On Thu, 22 Sep 2022, at 16:39, Roberto Sassu wrote:
> > Yes, true. Not sure if it makes sense to backport it to stable
> > versions
> > (probably not). Or alternatively, for older versions we could
> > ensure
> > that the fd is for read/write, even if as you said, there is a risk
> > of
> > breakage of existing applications. It seems unlikely that this
> > could
> > happen, as libbpf still does not support requesting a read-only fd,
> > although one could create an ad-hoc function to set the appropriate
> > parameters for the bpf() system call.
> 
> You can create a r-o fd via bpf_map_create if you pass
> map_flags=BPF_F_RDONLY unfortunately. Were you thinking of OBJ_GET
> when you refer to libbpf?

Oh, right.

To be more precise, bpf_map_get_fd_by_id() does not support yet getting
a read-only fd. bpf_obj_get_opts() was recently introduced for this
purpose.

> Actually, if it may help, I could send my version of the fix I
> > developed to validate the idea. I also wrote the tests.
> 
> Yes please, I have also have a WIP patch that seems to work, but I'm
> curious what you came up with. Tests would also be great, mine are
> kinda janky.

Ok.

> The ability to access the path of a pinned map does not give you
> > the
> > ability to access the map itself.
> 
> I think there is a subtlety here I don't get.
> BPF_OBJ_GET(/sys/fs/bpf/foo) gives me an fd I can modify via syscall,
> no? Are you making a distinction between the inode and the bpf_map
> itself?

If you have write access to /sys/fs/bpf/foo, it does not mean that you
will have write access to the map, when you call OBJ_GET(). I don't
know if you could add more modes after getting a fd.

> You still need to pass
> > security_bpf_map(). With SELinux, you would need a rule like:
> > 
> > allow <ctx of subject accessing the pinned map> <ctx of the map
> > creator>: bpf { map_read map_write };
> > 
> > The inode is not passed to security_bpf_map(), so likely it is not
> > taken into account for the security decision.
> 
> Ok, you're saying that a user can prevent the escalation via SELinux?

Not only with SELinux, but with an eBPF program too (BPF LSM). What I
wanted to do is to deny write access to anyone except the eBPF program
that declares the map.

> What you say, I think it applies to map iterators. The ability to
> > access the path of an iterator gives you the ability to make
> > changes to
> > the map without further checks.
> 
> How? An example would really help me, I don't know much about
> iterators besides that I can pin them and that open() triggers the
> program.

I wrote an example here:

https://lore.kernel.org/bpf/8d7a713e500b5e3fce93e4c5c7b8841eb6dd28e4.camel@xxxxxxxxxxxxxxx/

It shows that you can actually write to a map, despite SELinux gives
you only read permission.

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