diff mbox series

[2/2] NFSv4 account for selinux security context when deciding to share superblock

Message ID 20210212211955.11239-2-olga.kornievskaia@gmail.com (mailing list archive)
State New, archived
Headers show
Series [1/2,security] Add new hook to compare new mount to an existing mount | expand

Commit Message

Olga Kornievskaia Feb. 12, 2021, 9:19 p.m. UTC
From: Olga Kornievskaia <kolga@netapp.com>

Keep track of whether or not there was an selinux context mount
options during the mount. While deciding if the superblock can be
shared for the new mount, check for if we had selinux context on
the existing mount and call into selinux to tell if new passed
in selinux context is compatible with the existing mount's options.

Previously, NFS wasn't able to do the following 2mounts:
mount -o vers=4.2,sec=sys,context=system_u:object_r:root_t:s0
<serverip>:/ /mnt
mount -o vers=4.2,sec=sys,context=system_u:object_r:swapfile_t:s0
<serverip>:/scratch /scratch

2nd mount would fail with "mount.nfs: an incorrect mount option was
specified" and var log messages would have:
"SElinux: mount invalid. Same superblock, different security
settings for.."

Signed-off-by: Olga Kornievskaia <kolga@netapp.com>
---
 fs/nfs/fs_context.c       | 3 +++
 fs/nfs/internal.h         | 1 +
 fs/nfs/super.c            | 4 ++++
 include/linux/nfs_fs_sb.h | 1 +
 4 files changed, 9 insertions(+)

Comments

kernel test robot Feb. 13, 2021, 12:10 a.m. UTC | #1
Hi Olga,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on nfs/linux-next]
[also build test ERROR on pcmoore-selinux/next linus/master security/next-testing v5.11-rc7 next-20210211]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Olga-Kornievskaia/Add-new-hook-to-compare-new-mount-to-an-existing-mount/20210213-052321
base:   git://git.linux-nfs.org/projects/trondmy/linux-nfs.git linux-next
config: x86_64-randconfig-r011-20210212 (attached as .config)
compiler: clang version 12.0.0 (https://github.com/llvm/llvm-project c9439ca36342fb6013187d0a69aef92736951476)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install x86_64 cross compiling tool for clang build
        # apt-get install binutils-x86-64-linux-gnu
        # https://github.com/0day-ci/linux/commit/ff69e0bcc99716695e11ed2741b2e01d6014f960
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Olga-Kornievskaia/Add-new-hook-to-compare-new-mount-to-an-existing-mount/20210213-052321
        git checkout ff69e0bcc99716695e11ed2741b2e01d6014f960
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=x86_64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

>> fs/nfs/super.c:1179:5: error: implicit declaration of function 'security_sb_do_mnt_opts_match' [-Werror,-Wimplicit-function-declaration]
                           !security_sb_do_mnt_opts_match(sb, fc->security))
                            ^
   fs/nfs/super.c:1179:5: note: did you mean 'security_sb_set_mnt_opts'?
   include/linux/security.h:673:19: note: 'security_sb_set_mnt_opts' declared here
   static inline int security_sb_set_mnt_opts(struct super_block *sb,
                     ^
   1 error generated.


vim +/security_sb_do_mnt_opts_match +1179 fs/nfs/super.c

  1164	
  1165	static int nfs_compare_super(struct super_block *sb, struct fs_context *fc)
  1166	{
  1167		struct nfs_server *server = fc->s_fs_info, *old = NFS_SB(sb);
  1168	
  1169		if (!nfs_compare_super_address(old, server))
  1170			return 0;
  1171		/* Note: NFS_MOUNT_UNSHARED == NFS4_MOUNT_UNSHARED */
  1172		if (old->flags & NFS_MOUNT_UNSHARED)
  1173			return 0;
  1174		if (memcmp(&old->fsid, &server->fsid, sizeof(old->fsid)) != 0)
  1175			return 0;
  1176		if (!nfs_compare_userns(old, server))
  1177			return 0;
  1178		if ((old->has_sec_mnt_opts || fc->security) &&
> 1179				!security_sb_do_mnt_opts_match(sb, fc->security))
  1180			return 0;
  1181		return nfs_compare_mount_options(sb, server, fc);
  1182	}
  1183	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
kernel test robot Feb. 13, 2021, 12:16 a.m. UTC | #2
Hi Olga,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on nfs/linux-next]
[also build test ERROR on pcmoore-selinux/next linus/master security/next-testing v5.11-rc7 next-20210211]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Olga-Kornievskaia/Add-new-hook-to-compare-new-mount-to-an-existing-mount/20210213-052321
base:   git://git.linux-nfs.org/projects/trondmy/linux-nfs.git linux-next
config: arm-defconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/ff69e0bcc99716695e11ed2741b2e01d6014f960
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Olga-Kornievskaia/Add-new-hook-to-compare-new-mount-to-an-existing-mount/20210213-052321
        git checkout ff69e0bcc99716695e11ed2741b2e01d6014f960
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=arm 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   fs/nfs/super.c: In function 'nfs_compare_super':
>> fs/nfs/super.c:1179:5: error: implicit declaration of function 'security_sb_do_mnt_opts_match'; did you mean 'security_sb_set_mnt_opts'? [-Werror=implicit-function-declaration]
    1179 |    !security_sb_do_mnt_opts_match(sb, fc->security))
         |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         |     security_sb_set_mnt_opts
   cc1: some warnings being treated as errors


vim +1179 fs/nfs/super.c

  1164	
  1165	static int nfs_compare_super(struct super_block *sb, struct fs_context *fc)
  1166	{
  1167		struct nfs_server *server = fc->s_fs_info, *old = NFS_SB(sb);
  1168	
  1169		if (!nfs_compare_super_address(old, server))
  1170			return 0;
  1171		/* Note: NFS_MOUNT_UNSHARED == NFS4_MOUNT_UNSHARED */
  1172		if (old->flags & NFS_MOUNT_UNSHARED)
  1173			return 0;
  1174		if (memcmp(&old->fsid, &server->fsid, sizeof(old->fsid)) != 0)
  1175			return 0;
  1176		if (!nfs_compare_userns(old, server))
  1177			return 0;
  1178		if ((old->has_sec_mnt_opts || fc->security) &&
> 1179				!security_sb_do_mnt_opts_match(sb, fc->security))
  1180			return 0;
  1181		return nfs_compare_mount_options(sb, server, fc);
  1182	}
  1183	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
diff mbox series

Patch

diff --git a/fs/nfs/fs_context.c b/fs/nfs/fs_context.c
index 06894bcdea2d..8067f055d842 100644
--- a/fs/nfs/fs_context.c
+++ b/fs/nfs/fs_context.c
@@ -448,6 +448,9 @@  static int nfs_fs_context_parse_param(struct fs_context *fc,
 	if (opt < 0)
 		return ctx->sloppy ? 1 : opt;
 
+	if (fc->security)
+		ctx->has_sec_mnt_opts = 1;
+
 	switch (opt) {
 	case Opt_source:
 		if (fc->source)
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 62d3189745cd..08f4f34e8cf5 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -96,6 +96,7 @@  struct nfs_fs_context {
 	char			*fscache_uniq;
 	unsigned short		protofamily;
 	unsigned short		mountfamily;
+	bool			has_sec_mnt_opts;
 
 	struct {
 		union {
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 4034102010f0..ea4e5252a1f0 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -1058,6 +1058,7 @@  static void nfs_fill_super(struct super_block *sb, struct nfs_fs_context *ctx)
 						 &sb->s_blocksize_bits);
 
 	nfs_super_set_maxbytes(sb, server->maxfilesize);
+	server->has_sec_mnt_opts = ctx->has_sec_mnt_opts;
 }
 
 static int nfs_compare_mount_options(const struct super_block *s, const struct nfs_server *b,
@@ -1174,6 +1175,9 @@  static int nfs_compare_super(struct super_block *sb, struct fs_context *fc)
 		return 0;
 	if (!nfs_compare_userns(old, server))
 		return 0;
+	if ((old->has_sec_mnt_opts || fc->security) &&
+			!security_sb_do_mnt_opts_match(sb, fc->security))
+		return 0;
 	return nfs_compare_mount_options(sb, server, fc);
 }
 
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index 38e60ec742df..3f0acada5794 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -254,6 +254,7 @@  struct nfs_server {
 
 	/* User namespace info */
 	const struct cred	*cred;
+	bool			has_sec_mnt_opts;
 };
 
 /* Server capabilities */