From: Roberto Sassu <roberto.sassu@huawei.com>
To: Casey Schaufler <casey@schaufler-ca.com>,
"corbet@lwn.net" <corbet@lwn.net>,
"viro@zeniv.linux.org.uk" <viro@zeniv.linux.org.uk>,
"ast@kernel.org" <ast@kernel.org>,
"daniel@iogearbox.net" <daniel@iogearbox.net>,
"andrii@kernel.org" <andrii@kernel.org>,
"kpsingh@kernel.org" <kpsingh@kernel.org>,
"tixxdz@gmail.com" <tixxdz@gmail.com>,
"shuah@kernel.org" <shuah@kernel.org>,
"mcoquelin.stm32@gmail.com" <mcoquelin.stm32@gmail.com>,
"alexandre.torgue@foss.st.com" <alexandre.torgue@foss.st.com>,
"zohar@linux.ibm.com" <zohar@linux.ibm.com>
Cc: "linux-doc@vger.kernel.org" <linux-doc@vger.kernel.org>,
"linux-fsdevel@vger.kernel.org" <linux-fsdevel@vger.kernel.org>,
"netdev@vger.kernel.org" <netdev@vger.kernel.org>,
"bpf@vger.kernel.org" <bpf@vger.kernel.org>,
"linux-kselftest@vger.kernel.org"
<linux-kselftest@vger.kernel.org>,
"linux-stm32@st-md-mailman.stormreply.com"
<linux-stm32@st-md-mailman.stormreply.com>,
"linux-arm-kernel@lists.infradead.org"
<linux-arm-kernel@lists.infradead.org>,
"linux-integrity@vger.kernel.org"
<linux-integrity@vger.kernel.org>,
"linux-security-module@vger.kernel.org"
<linux-security-module@vger.kernel.org>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Subject: RE: [POC][USER SPACE][PATCH] Introduce LSM to protect pinned objects
Date: Wed, 6 Apr 2022 06:55:51 +0000 [thread overview]
Message-ID: <5ed9f7c8fab7426daf400756b2d8ea89@huawei.com> (raw)
In-Reply-To: <5ce85845-824c-32fb-3807-6f9ab95ad6fe@schaufler-ca.com>
> From: Casey Schaufler [mailto:casey@schaufler-ca.com]
> Sent: Wednesday, April 6, 2022 12:48 AM
> On 4/5/2022 6:11 AM, Roberto Sassu wrote:
> > Introduce a new LSM to protect pinned objects in a bpf filesystem
>
> This is *not an LSM*. Do not call it an LSM. It is a set of
> eBPF programs. We have all the opportunities for confusion
> that we need. I suggested that you call this a BPF security
> module (BSM) earlier today. You have any number of things
> you can call this that won't be objectionable.
>
> > instance. This is useful for example to ensure that an LSM will always
> > enforce its policy, even despite root tries to unload the corresponding
> > eBPF program.
>
> How is this going to ensure that SELinux enforces its policy?
I should have said above: that an LSM implemented with eBPF.
Built-in LSMs are not affected by this change.
Ok, next time I call it BSM.
Thanks
Roberto
HUAWEI TECHNOLOGIES Duesseldorf GmbH, HRB 56063
Managing Director: Li Peng, Zhong Ronghua
> AppArmor has no eBPF program that corresponds to its policy,
> neither does any other existing LSM, save BPF. Your claim is
> nonsensical in the face of LSM behavior.
>
> > Achieve the protection by denying inode unlink and unmount of the
> > protected bpf filesystem instance. Since protected inodes hold a
> > reference of the link of loaded programs (e.g. LSM hooks), denying
> > operations on them will prevent the ref count of the links from reaching
> > zero, ensuring that the programs remain always active.
> >
> > Enable the protection only for the instance created by the user space
> > counterpart of the LSM, and don't interfere with other instances, so
> > that their behavior remains unchanged.
> >
> > Suggested-by: Djalal Harouni <tixxdz@gmail.com>
> > Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
> > ---
> > .gitignore | 4 +++
> > Makefile | 18 ++++++++++++++
> > bpffs_lsm_kern.c | 63
> ++++++++++++++++++++++++++++++++++++++++++++++++
> > bpffs_lsm_user.c | 60
> +++++++++++++++++++++++++++++++++++++++++++++
> > 4 files changed, 145 insertions(+)
> > create mode 100644 .gitignore
> > create mode 100644 Makefile
> > create mode 100644 bpffs_lsm_kern.c
> > create mode 100644 bpffs_lsm_user.c
> >
> > diff --git a/.gitignore b/.gitignore
> > new file mode 100644
> > index 000000000000..7fa02964f1dc
> > --- /dev/null
> > +++ b/.gitignore
> > @@ -0,0 +1,4 @@
> > +*.o
> > +vmlinux.h
> > +bpffs_lsm_kern.skel.h
> > +bpffs_lsm_user
> > diff --git a/Makefile b/Makefile
> > new file mode 100644
> > index 000000000000..c3d805759db3
> > --- /dev/null
> > +++ b/Makefile
> > @@ -0,0 +1,18 @@
> > +# SPDX-License-Identifier: GPL-2.0
> > +all: bpffs_lsm_user
> > +
> > +clean:
> > + rm -rf bpffs_lsm.skel.h vmlinux.h bpffs_lsm_kern.o bpffs_lsm_user
> > +
> > +vmlinux.h:
> > + /usr/sbin/bpftool btf dump file /sys/kernel/btf/vmlinux format c > \
> > + vmlinux.h
> > +
> > +bpffs_lsm_kern.skel.h: bpffs_lsm_kern.o
> > + bpftool gen skeleton $< > $@
> > +
> > +bpffs_lsm_kern.o: bpffs_lsm_kern.c vmlinux.h
> > + clang -Wall -Werror -g -O2 -target bpf -c $< -o $@
> > +
> > +bpffs_lsm_user: bpffs_lsm_user.c bpffs_lsm_kern.skel.h
> bpffs_lsm_kern.o
> > + cc -Wall -Werror -g -o $@ $< -lbpf
> > diff --git a/bpffs_lsm_kern.c b/bpffs_lsm_kern.c
> > new file mode 100644
> > index 000000000000..b3ccb2a75c95
> > --- /dev/null
> > +++ b/bpffs_lsm_kern.c
> > @@ -0,0 +1,63 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (C) 2022 Huawei Technologies Duesseldorf GmbH
> > + *
> > + * Authors:
> > + * Roberto Sassu <roberto.sassu@huawei.com>
> > + *
> > + * Implement an LSM to protect a bpf filesystem instance.
> > + */
> > +
> > +#include "vmlinux.h"
> > +#include <errno.h>
> > +#include <bpf/bpf_helpers.h>
> > +#include <bpf/bpf_tracing.h>
> > +#include <bpf/bpf_core_read.h>
> > +
> > +char _license[] SEC("license") = "GPL";
> > +
> > +uint32_t monitored_pid = 0;
> > +
> > +struct {
> > + __uint(type, BPF_MAP_TYPE_INODE_STORAGE);
> > + __uint(map_flags, BPF_F_NO_PREALLOC);
> > + __type(key, int);
> > + __type(value, sizeof(uint8_t));
> > +} inode_storage_map SEC(".maps");
> > +
> > +SEC("lsm/sb_set_mnt_opts")
> > +int BPF_PROG(sb_set_mnt_opts, struct super_block *sb, void
> *mnt_opts,
> > + unsigned long kern_flags, unsigned long *set_kern_flags)
> > +{
> > + u32 pid;
> > +
> > + pid = bpf_get_current_pid_tgid() >> 32;
> > + if (pid != monitored_pid)
> > + return 0;
> > +
> > + if (!bpf_inode_storage_get(&inode_storage_map, sb->s_root-
> >d_inode, 0,
> > + BPF_LOCAL_STORAGE_GET_F_CREATE))
> > + return -EPERM;
> > +
> > + return 0;
> > +}
> > +
> > +SEC("lsm/inode_unlink")
> > +int BPF_PROG(inode_unlink, struct inode *dir, struct dentry *dentry)
> > +{
> > + if (bpf_inode_storage_get(&inode_storage_map,
> > + dir->i_sb->s_root->d_inode, 0, 0))
> > + return -EPERM;
> > +
> > + return 0;
> > +}
> > +
> > +SEC("lsm/sb_umount")
> > +int BPF_PROG(sb_umount, struct vfsmount *mnt, int flags)
> > +{
> > + if (bpf_inode_storage_get(&inode_storage_map,
> > + mnt->mnt_sb->s_root->d_inode, 0, 0))
> > + return -EPERM;
> > +
> > + return 0;
> > +}
> > diff --git a/bpffs_lsm_user.c b/bpffs_lsm_user.c
> > new file mode 100644
> > index 000000000000..e20180cc5db9
> > --- /dev/null
> > +++ b/bpffs_lsm_user.c
> > @@ -0,0 +1,60 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (C) 2022 Huawei Technologies Duesseldorf GmbH
> > + *
> > + * Author: Roberto Sassu <roberto.sassu@huawei.com>
> > + *
> > + * Implement the user space side of the LSM for bpffs.
> > + */
> > +
> > +#include <fcntl.h>
> > +#include <unistd.h>
> > +#include <stdio.h>
> > +#include <errno.h>
> > +#include <stdlib.h>
> > +#include <unistd.h>
> > +#include <limits.h>
> > +#include <sys/mount.h>
> > +#include <sys/stat.h>
> > +
> > +#include "bpffs_lsm_kern.skel.h"
> > +
> > +#define MOUNT_FLAGS (MS_NOSUID | MS_NODEV | MS_NOEXEC |
> MS_RELATIME)
> > +
> > +int main(int argc, char *argv[])
> > +{
> > + char mntpoint[] = "/tmp/bpf_private_mountXXXXXX";
> > + char path[PATH_MAX];
> > + struct bpffs_lsm_kern *skel;
> > + int ret, i;
> > +
> > + skel = bpffs_lsm_kern__open_and_load();
> > + if (!skel)
> > + return -EINVAL;
> > +
> > + ret = bpffs_lsm_kern__attach(skel);
> > + if (ret < 0)
> > + goto out_destroy;
> > +
> > + mkdtemp(mntpoint);
> > +
> > + skel->bss->monitored_pid = getpid();
> > + ret = mount(mntpoint, mntpoint, "bpf", MOUNT_FLAGS, NULL);
> > + skel->bss->monitored_pid = 0;
> > +
> > + if (ret < 0)
> > + goto out_destroy;
> > +
> > + for (i = 0; i < skel->skeleton->prog_cnt; i++) {
> > + snprintf(path, sizeof(path), "%s/%s", mntpoint,
> > + skel->skeleton->progs[i].name);
> > + ret = bpf_link__pin(*skel->skeleton->progs[i].link, path);
> > + if (ret < 0)
> > + goto out_destroy;
> > + }
> > +
> > + ret = 0;
> > +out_destroy:
> > + bpffs_lsm_kern__destroy(skel);
> > + return ret;
> > +}
next prev parent reply other threads:[~2022-04-06 10:32 UTC|newest]
Thread overview: 45+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-03-28 17:50 [PATCH 00/18] bpf: Secure and authenticated preloading of eBPF programs Roberto Sassu
2022-03-28 17:50 ` [PATCH 01/18] bpf: Export bpf_link_inc() Roberto Sassu
2022-03-28 17:50 ` [PATCH 02/18] bpf-preload: Move bpf_preload.h to include/linux Roberto Sassu
2022-03-28 17:50 ` [PATCH 03/18] bpf-preload: Generalize object pinning from the kernel Roberto Sassu
2022-03-28 17:50 ` [PATCH 04/18] bpf-preload: Export and call bpf_obj_do_pin_kernel() Roberto Sassu
2022-03-28 17:50 ` [PATCH 05/18] bpf-preload: Generate static variables Roberto Sassu
2022-03-29 23:51 ` Andrii Nakryiko
2022-03-30 7:44 ` Roberto Sassu
2022-04-04 0:22 ` Andrii Nakryiko
2022-03-30 15:12 ` Roberto Sassu
2022-03-28 17:50 ` [PATCH 06/18] bpf-preload: Generate free_objs_and_skel() Roberto Sassu
2022-03-28 17:50 ` [PATCH 07/18] bpf-preload: Generate preload() Roberto Sassu
2022-03-28 17:50 ` [PATCH 08/18] bpf-preload: Generate load_skel() Roberto Sassu
2022-03-28 17:50 ` [PATCH 09/18] bpf-preload: Generate code to pin non-internal maps Roberto Sassu
2022-03-28 17:50 ` [PATCH 10/18] bpf-preload: Generate bpf_preload_ops Roberto Sassu
2022-03-28 17:50 ` [PATCH 11/18] bpf-preload: Store multiple bpf_preload_ops structures in a linked list Roberto Sassu
2022-03-28 17:50 ` [PATCH 12/18] bpf-preload: Implement new registration method for preloading eBPF programs Roberto Sassu
2022-03-28 17:50 ` [PATCH 13/18] bpf-preload: Move pinned links and maps to a dedicated directory in bpffs Roberto Sassu
2022-03-28 17:50 ` [PATCH 14/18] bpf-preload: Switch to new preload registration method Roberto Sassu
2022-03-29 2:35 ` kernel test robot
2022-03-29 3:27 ` kernel test robot
2022-03-28 17:50 ` [PATCH 15/18] bpf-preload: Generate code of kernel module to preload Roberto Sassu
2022-03-28 17:50 ` [PATCH 16/18] bpf-preload: Do kernel mount to ensure that pinned objects don't disappear Roberto Sassu
2022-03-29 2:15 ` kernel test robot
2022-03-29 4:08 ` kernel test robot
2022-03-28 17:50 ` [PATCH 17/18] bpf-preload/selftests: Add test for automatic generation of preload methods Roberto Sassu
2022-03-28 17:50 ` [PATCH 18/18] bpf-preload/selftests: Preload a test eBPF program and check pinned objects Roberto Sassu
2022-03-29 23:51 ` [PATCH 00/18] bpf: Secure and authenticated preloading of eBPF programs Andrii Nakryiko
2022-03-30 7:21 ` Roberto Sassu
2022-03-31 2:27 ` Alexei Starovoitov
2022-03-31 8:25 ` Roberto Sassu
2022-04-01 23:55 ` Alexei Starovoitov
2022-04-02 1:03 ` KP Singh
2022-04-04 7:44 ` Djalal Harouni
2022-04-04 17:20 ` Roberto Sassu
2022-04-04 22:49 ` Alexei Starovoitov
2022-04-05 0:00 ` KP Singh
2022-04-05 13:11 ` [POC][USER SPACE][PATCH] Introduce LSM to protect pinned objects Roberto Sassu
2022-04-05 22:47 ` Casey Schaufler
2022-04-06 6:55 ` Roberto Sassu [this message]
2022-04-05 14:49 ` [PATCH 00/18] bpf: Secure and authenticated preloading of eBPF programs Casey Schaufler
2022-04-05 15:29 ` Roberto Sassu
2022-04-05 16:21 ` Casey Schaufler
2022-04-05 16:37 ` KP Singh
2022-04-04 17:41 ` Roberto Sassu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5ed9f7c8fab7426daf400756b2d8ea89@huawei.com \
--to=roberto.sassu@huawei.com \
--cc=alexandre.torgue@foss.st.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=casey@schaufler-ca.com \
--cc=corbet@lwn.net \
--cc=daniel@iogearbox.net \
--cc=kpsingh@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-integrity@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=linux-security-module@vger.kernel.org \
--cc=linux-stm32@st-md-mailman.stormreply.com \
--cc=mcoquelin.stm32@gmail.com \
--cc=netdev@vger.kernel.org \
--cc=shuah@kernel.org \
--cc=tixxdz@gmail.com \
--cc=viro@zeniv.linux.org.uk \
--cc=zohar@linux.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).