BPF LSM prevent program unload

Casey Schaufler casey at schaufler-ca.com
Thu Dec 7 20:05:51 UTC 2023


On 12/7/2023 9:34 AM, Paul Moore wrote:
> On Wed, Dec 6, 2023 at 9:28 PM Yafang Shao <laoar.shao at gmail.com> wrote:
>> On Wed, Dec 6, 2023 at 11:02 PM Frederick Lawler <fred at cloudflare.com> wrote:
>>> On Wed, Dec 06, 2023 at 10:42:50AM +0800, Yafang Shao wrote:
>>>> On Wed, Dec 6, 2023 at 4:39 AM Frederick Lawler wrote:
>>>>> Hi,
>>>>>
>>>>> IIUC, LSMs are supposed to give us the ability to design policy around
>>>>> unprivileged users and in addition to privileged users. As we expand
>>>>> our usage of BPF LSM's, there are cases where we want to restrict
>>>>> privileged users from unloading our progs. For instance, any privileged
>>>>> user that wants to remove restrictions we've placed on privileged users.
>>>>>
>>>>> We currently have a loader application doesn't leverage BPF skeletons. We
>>>>> instead load BPF object files, and then pin the progs to a mount point that
>>>>> is a bpf filesystem. On next run, if we have new policies, load in new
>>>>> policies, and finally unload the old.
>>>>>
>>>>> Here are some conditions a privileged user may unload programs:
>>>>>
>>>>>         umount /sys/fs/bpf
>>>>>         rm -rf /sys/fs/bpf/lsm
>>>>>         rm /sys/fs/bpf/lsm/some_prog
>>>>>         unlink /sys/fs/bpf/lsm/some_prog
>>>>>
>>>>> This works because once we remove the last reference, the programs and
>>>>> pinned maps are cleaned up.
>>>>>
>>>>> Moving individual pins or moving the mount entirely with mount --move
>>>>> do not perform any clean up operations. Lastly, bpftool doesn't currently
>>>>> have the ability to unload LSM's AFAIK.
> If you haven't already, I would suggest talking with KP Singh as he is
> the BPF LSM maintainer; I see him on the To/CC line so I'm sure he'll
> comment when he has the chance to do so.
>
>>>>> The few ideas I have floating around are:
>>>>>
>>>>> 1. Leverage some LSM hooks (BPF or otherwise) to restrict on the functions
>>>>>    security_sb_umount(), security_path_unlink(), security_inode_unlink().
>>>>>
>>>>>    Both security_path_unlink() and security_inode_unlink() handle the
>>>>>    unlink/remove case, but not the umount case.
> I'm not a BPF expert, but this seems like the most obvious solution,
> although as Tetsuo already mentioned you probably don't want to block
> all unmount operations as that would be bad for obvious reasons.  I'm
> guessing that a BPF LSM would have access to things like the current
> task credentials and enough of the mounted filesystem's state (BPF
> prog pinning?) to make a reasonable decision about granting or denying
> the umount operation request.
>
>>>>> 3. Leverage SELinux/Apparmor to possibly handle these cases.
> SELinux has support for restricting unmount operations as well BPF
> program loading.  I see that AppArmor also has controls around
> unmount, but I am less familiar with how that works.  It is also worth
> mentioning that Tomoyo and Landlock provide unmount hook
> implementations although both LSMs are fairly unique so I can't say if
> they would be a good fit for your proposed use case.
>
>>>>> 4. Introduce a security_bpf_prog_unload() to target hopefully the
>>>>>    umount and unlink cases at the same time.
> At first glance that seems reasonable, but I guess we would need to
> see it discussed a bit before I could promise to commit to that.
>
> As a FYI, we have some documented guidelines on creating new LSM
> hooks; it's worth a quick read if you haven't seen it already.
>
> https://github.com/LinuxSecurityModule/kernel?tab=readme-ov-file#new-lsm-hook-guidelines
>
>>>> All the above programs can also be removed by privileged users.
>>>>
>>> I should probably clarify the "BPF or otherwise" a bit better. Even a
>>> compiled in LSM module? If so, where can I find a bit more information
>>> about that?
> I'm not quite sure what you are asking about here, but we don't
> currently support "unloading" built-in LSM modules and I don't see us
> changing that anytime soon.  The closest one could get would be with a
> LSM that supports runtime configuration of its security policy; one
> could go from a restrictive or an allow-all, permissive policy
> effectively disabling the LSM from an access control standpoint.
>
> I don't want to speak for all the LSMs here, but at least SELinux has
> the ability to restrict policy loading so that one could prevent
> replacing a relatively strict policy with a more permissive policy.
> Although it is worth noting that enabling this restriction has a
> number of caveats, i.e. policy updates require a reboot, and isn't
> something I would recommend for a general purpose system.

You can prevent Smack from making policy changes using the "onlycap"
mechanism. It restricts what process labels can use CAP_MAC_ADMIN,
which is required to update Smack rules. As with SELinux, it isn't
recommended for general use.





More information about the Linux-security-module-archive mailing list