This series attempts to clean up part of the mess that has grown around
the LSM mount option handling across different subsystems.
The original motivation was to fix a NFS+SELinux bug that I found while
trying to get the NFS part of the selinux-testsuite [1] to work, which
is fixed by patch 2.
The first patch paves the way for the second one by eliminating the
special case workaround in selinux_set_mnt_opts(), while also
simplifying BTRFS's LSM mount option handling.
I tested the patches by running the NFS part of the SELinux testsuite
(which is now fully passing). I also added the pending patch for
broken BTRFS LSM options support with fsconfig(2) [2] and ran the
proposed BTRFS SELinux tests for selinux-testsuite [3] (still passing
with all patches).
[1] https://github.com/SELinuxProject/selinux-testsuite/
[2] https://lore.kernel.org/selinux/[email protected]/T/
[3] https://lore.kernel.org/selinux/[email protected]/
^^ the original patch no longer applies - a rebased version is here:
https://github.com/WOnder93/selinux-testsuite/commit/212e76b5bd0775c7507c1996bd172de3bcbff139.patch
Ondrej Mosnacek (2):
vfs,LSM: introduce the FS_HANDLES_LSM_OPTS flag
selinux: fix SECURITY_LSM_NATIVE_LABELS flag handling on double mount
fs/btrfs/super.c | 35 ++++++-----------------------------
fs/nfs/fs_context.c | 6 ++++--
fs/super.c | 10 ++++++----
include/linux/fs.h | 3 ++-
security/selinux/hooks.c | 32 +++++++++++++++++---------------
5 files changed, 35 insertions(+), 51 deletions(-)
--
2.30.2
When mounting an NFS export that is a mountpoint on the host, doing the
same mount a second time leads to a security_sb_set_mnt_opts() call on
an already intialized superblock, which leaves the
SECURITY_LSM_NATIVE_LABELS flag unset even if it's provided by the FS.
NFS then obediently clears NFS_CAP_SECURITY_LABEL from its server
capability set, leading to any newly created inodes for this superblock
to end up without labels.
To fix this, make sure to return the SECURITY_LSM_NATIVE_LABELS flag
when security_sb_set_mnt_opts() is called on an already initialized
superblock with matching security options.
While there, also do a sanity check to ensure that
SECURITY_LSM_NATIVE_LABELS is set in kflags if and only if
sbsec->behavior == SECURITY_FS_USE_NATIVE.
Minimal reproducer:
# systemctl start nfs-server
# exportfs -o rw,no_root_squash,security_label localhost:/
# mount -t nfs -o "nfsvers=4.2" localhost:/etc /mnt
# mount -t nfs -o "nfsvers=4.2" localhost:/etc /mnt
# ls -lZ /mnt
[all labels are system_u:object_r:unlabeled_t:s0]
Signed-off-by: Ondrej Mosnacek <[email protected]>
---
security/selinux/hooks.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 1daf7bec4bb0..b8efb14a1d1a 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -741,7 +741,24 @@ static int selinux_set_mnt_opts(struct super_block *sb,
/* previously mounted with options, but not on this attempt? */
if ((sbsec->flags & SE_MNTMASK) && !opts)
goto out_double_mount;
+
+ /*
+ * If we are checking an already initialized mount and the
+ * options match, make sure to return back the
+ * SECURITY_LSM_NATIVE_LABELS flag if applicable. If the
+ * superblock has the NATIVE behavior set and the FS is not
+ * signaling its support (or vice versa), then it is a
+ * programmer error, so emit a WARNING and return -EINVAL.
+ */
rc = 0;
+ if (sbsec->behavior == SECURITY_FS_USE_NATIVE) {
+ if (WARN_ON(!(kern_flags & SECURITY_LSM_NATIVE_LABELS)))
+ rc = -EINVAL;
+ else
+ *set_kern_flags |= SECURITY_LSM_NATIVE_LABELS;
+ } else if (WARN_ON(kern_flags & SECURITY_LSM_NATIVE_LABELS)) {
+ rc = -EINVAL;
+ }
goto out;
}
--
2.30.2
On Fri, Apr 09, 2021 at 01:12:52PM +0200, Ondrej Mosnacek wrote:
> This series attempts to clean up part of the mess that has grown around
> the LSM mount option handling across different subsystems.
I would not describe growing another FS_... flag *AND* spreading the
FS_BINARY_MOUNTDATA further, with rather weird semantics at that,
as a cleanup of any sort.
I still very much dislike that approach.
On 4/9/2021 4:12 AM, Ondrej Mosnacek wrote:
> This series attempts to clean up part of the mess that has grown around
> the LSM mount option handling across different subsystems.
>
> The original motivation was to fix a NFS+SELinux bug that I found while
> trying to get the NFS part of the selinux-testsuite [1] to work, which
> is fixed by patch 2.
>
> The first patch paves the way for the second one by eliminating the
> special case workaround in selinux_set_mnt_opts(), while also
> simplifying BTRFS's LSM mount option handling.
>
> I tested the patches by running the NFS part of the SELinux testsuite
> (which is now fully passing). I also added the pending patch for
> broken BTRFS LSM options support with fsconfig(2) [2] and ran the
> proposed BTRFS SELinux tests for selinux-testsuite [3] (still passing
> with all patches).
The Smack testsuite can be found at:
https://github.com/smack-team/smack-testsuite.git
It might provide another layer of confidence.
>
> [1] https://github.com/SELinuxProject/selinux-testsuite/
> [2] https://lore.kernel.org/selinux/[email protected]/T/
> [3] https://lore.kernel.org/selinux/[email protected]/
> ^^ the original patch no longer applies - a rebased version is here:
> https://github.com/WOnder93/selinux-testsuite/commit/212e76b5bd0775c7507c1996bd172de3bcbff139.patch
>
> Ondrej Mosnacek (2):
> vfs,LSM: introduce the FS_HANDLES_LSM_OPTS flag
> selinux: fix SECURITY_LSM_NATIVE_LABELS flag handling on double mount
>
> fs/btrfs/super.c | 35 ++++++-----------------------------
> fs/nfs/fs_context.c | 6 ++++--
> fs/super.c | 10 ++++++----
> include/linux/fs.h | 3 ++-
> security/selinux/hooks.c | 32 +++++++++++++++++---------------
> 5 files changed, 35 insertions(+), 51 deletions(-)
>
On Fri, Apr 9, 2021 at 2:28 PM Al Viro <[email protected]> wrote:
> On Fri, Apr 09, 2021 at 01:12:52PM +0200, Ondrej Mosnacek wrote:
> > This series attempts to clean up part of the mess that has grown around
> > the LSM mount option handling across different subsystems.
>
> I would not describe growing another FS_... flag
Why is that necessarily a bad thing?
> *AND* spreading the
> FS_BINARY_MOUNTDATA further, with rather weird semantics at that,
> as a cleanup of any sort.
How is this spreading it further? The patches remove one (rather bad)
use of it in SELinux and somewhat reduce its use in btrfs.
Hold on... actually I just realized that with FS_HANDLES_LSM_OPTS it
is possible to do btrfs without FS_BINARY_MOUNTDATA and also eliminate
the need for the workaround in vfs_parse_fs_param() (i.e. [2]).
Basically instead of setting FS_BINARY_MOUNTDATA | FS_HANDLES_LSM_OPTS
in btrfs_fs_type and neither in btrfs_root_fs_type, it is enough to
set neither in btrfs_fs_type and only FS_HANDLES_LSM_OPTS in
btrfs_root_fs_type. The security opts are then applied in the outer
vfs_get_tree() call instead of the inner one, but the net effect is
the same.
That should pretty much do away with both the non-legit users of
FS_BINARY_MOUNTDATA (selinux_set_mnt_opts() and btrfs). All the rest
seem to be in line with the semantic.
Would [something like] the above stand any chance of getting your approval?
[2] https://lore.kernel.org/selinux/[email protected]/T/
--
Ondrej Mosnacek
Software Engineer, Linux Security - SELinux kernel
Red Hat, Inc.
On Fri, Apr 9, 2021 at 7:00 PM Casey Schaufler <[email protected]> wrote:
> On 4/9/2021 4:12 AM, Ondrej Mosnacek wrote:
> > This series attempts to clean up part of the mess that has grown around
> > the LSM mount option handling across different subsystems.
> >
> > The original motivation was to fix a NFS+SELinux bug that I found while
> > trying to get the NFS part of the selinux-testsuite [1] to work, which
> > is fixed by patch 2.
> >
> > The first patch paves the way for the second one by eliminating the
> > special case workaround in selinux_set_mnt_opts(), while also
> > simplifying BTRFS's LSM mount option handling.
> >
> > I tested the patches by running the NFS part of the SELinux testsuite
> > (which is now fully passing). I also added the pending patch for
> > broken BTRFS LSM options support with fsconfig(2) [2] and ran the
> > proposed BTRFS SELinux tests for selinux-testsuite [3] (still passing
> > with all patches).
>
> The Smack testsuite can be found at:
> https://github.com/smack-team/smack-testsuite.git
>
> It might provide another layer of confidence.
Thanks, but that doesn't seem to exercise mounting/remounting btrfs
nor nfs with security options. Anything else should be unaffected.
>
> >
> > [1] https://github.com/SELinuxProject/selinux-testsuite/
> > [2] https://lore.kernel.org/selinux/[email protected]/T/
> > [3] https://lore.kernel.org/selinux/[email protected]/
> > ^^ the original patch no longer applies - a rebased version is here:
> > https://github.com/WOnder93/selinux-testsuite/commit/212e76b5bd0775c7507c1996bd172de3bcbff139.patch
> >
> > Ondrej Mosnacek (2):
> > vfs,LSM: introduce the FS_HANDLES_LSM_OPTS flag
> > selinux: fix SECURITY_LSM_NATIVE_LABELS flag handling on double mount
> >
> > fs/btrfs/super.c | 35 ++++++-----------------------------
> > fs/nfs/fs_context.c | 6 ++++--
> > fs/super.c | 10 ++++++----
> > include/linux/fs.h | 3 ++-
> > security/selinux/hooks.c | 32 +++++++++++++++++---------------
> > 5 files changed, 35 insertions(+), 51 deletions(-)
> >
>
--
Ondrej Mosnacek
Software Engineer, Linux Security - SELinux kernel
Red Hat, Inc.
On Fri, Apr 9, 2021 at 7:39 PM Ondrej Mosnacek <[email protected]> wrote:
> On Fri, Apr 9, 2021 at 2:28 PM Al Viro <[email protected]> wrote:
> > On Fri, Apr 09, 2021 at 01:12:52PM +0200, Ondrej Mosnacek wrote:
> > > This series attempts to clean up part of the mess that has grown around
> > > the LSM mount option handling across different subsystems.
> >
> > I would not describe growing another FS_... flag
>
> Why is that necessarily a bad thing?
>
> > *AND* spreading the
> > FS_BINARY_MOUNTDATA further, with rather weird semantics at that,
> > as a cleanup of any sort.
>
> How is this spreading it further? The patches remove one (rather bad)
> use of it in SELinux and somewhat reduce its use in btrfs.
>
> Hold on... actually I just realized that with FS_HANDLES_LSM_OPTS it
> is possible to do btrfs without FS_BINARY_MOUNTDATA and also eliminate
> the need for the workaround in vfs_parse_fs_param() (i.e. [2]).
>
> Basically instead of setting FS_BINARY_MOUNTDATA | FS_HANDLES_LSM_OPTS
> in btrfs_fs_type and neither in btrfs_root_fs_type, it is enough to
> set neither in btrfs_fs_type and only FS_HANDLES_LSM_OPTS in
> btrfs_root_fs_type. The security opts are then applied in the outer
> vfs_get_tree() call instead of the inner one, but the net effect is
> the same.
>
> That should pretty much do away with both the non-legit users of
> FS_BINARY_MOUNTDATA (selinux_set_mnt_opts() and btrfs). All the rest
> seem to be in line with the semantic.
>
> Would [something like] the above stand any chance of getting your approval?
So I posted this variant as v2 now:
https://lore.kernel.org/selinux/[email protected]/T/
>
> [2] https://lore.kernel.org/selinux/[email protected]/T/
--
Ondrej Mosnacek
Software Engineer, Linux Security - SELinux kernel
Red Hat, Inc.