LSM: Add flags field to security_sb_set_mnt_opts for in kernel mount data.
authorDavid Quigley <dpquigl@davequigley.com>
Wed, 22 May 2013 16:50:36 +0000 (12:50 -0400)
committerTrond Myklebust <Trond.Myklebust@netapp.com>
Sat, 8 Jun 2013 20:20:12 +0000 (16:20 -0400)
There is no way to differentiate if a text mount option is passed from user
space or the kernel. A flags field is being added to the
security_sb_set_mnt_opts hook to allow for in kernel security flags to be sent
to the LSM for processing in addition to the text options received from mount.
This patch also updated existing code to fix compilation errors.

Acked-by: Eric Paris <eparis@redhat.com>
Acked-by: James Morris <james.l.morris@oracle.com>
Signed-off-by: David P. Quigley <dpquigl@tycho.nsa.gov>
Signed-off-by: Miguel Rodel Felipe <Rodel_FM@dsi.a-star.edu.sg>
Signed-off-by: Phua Eu Gene <PHUA_Eu_Gene@dsi.a-star.edu.sg>
Signed-off-by: Khin Mi Mi Aung <Mi_Mi_AUNG@dsi.a-star.edu.sg>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
fs/nfs/super.c
include/linux/security.h
security/capability.c
security/security.c
security/selinux/hooks.c

index a366107a7331ad36864ba81b8b14ba940756ac70..c1bbb53d444ae11d22768271c95d2d540e64067f 100644 (file)
@@ -2411,7 +2411,8 @@ static int nfs_bdi_register(struct nfs_server *server)
 int nfs_set_sb_security(struct super_block *s, struct dentry *mntroot,
                        struct nfs_mount_info *mount_info)
 {
-       return security_sb_set_mnt_opts(s, &mount_info->parsed->lsm_opts);
+       return security_sb_set_mnt_opts(s, &mount_info->parsed->lsm_opts,
+                                                               0, NULL);
 }
 EXPORT_SYMBOL_GPL(nfs_set_sb_security);
 
index cff3e4fc428102aebc4a00e1dbada2beaf27c47e..aa656fbc430891b6a05bddc5236ce569b3dee445 100644 (file)
@@ -1456,7 +1456,9 @@ struct security_operations {
        int (*sb_pivotroot) (struct path *old_path,
                             struct path *new_path);
        int (*sb_set_mnt_opts) (struct super_block *sb,
-                               struct security_mnt_opts *opts);
+                               struct security_mnt_opts *opts,
+                               unsigned long kern_flags,
+                               unsigned long *set_kern_flags);
        int (*sb_clone_mnt_opts) (const struct super_block *oldsb,
                                   struct super_block *newsb);
        int (*sb_parse_opts_str) (char *options, struct security_mnt_opts *opts);
@@ -1747,7 +1749,10 @@ int security_sb_mount(const char *dev_name, struct path *path,
                      const char *type, unsigned long flags, void *data);
 int security_sb_umount(struct vfsmount *mnt, int flags);
 int security_sb_pivotroot(struct path *old_path, struct path *new_path);
-int security_sb_set_mnt_opts(struct super_block *sb, struct security_mnt_opts *opts);
+int security_sb_set_mnt_opts(struct super_block *sb,
+                               struct security_mnt_opts *opts,
+                               unsigned long kern_flags,
+                               unsigned long *set_kern_flags);
 int security_sb_clone_mnt_opts(const struct super_block *oldsb,
                                struct super_block *newsb);
 int security_sb_parse_opts_str(char *options, struct security_mnt_opts *opts);
@@ -2037,7 +2042,9 @@ static inline int security_sb_pivotroot(struct path *old_path,
 }
 
 static inline int security_sb_set_mnt_opts(struct super_block *sb,
-                                          struct security_mnt_opts *opts)
+                                          struct security_mnt_opts *opts,
+                                          unsigned long kern_flags,
+                                          unsigned long *set_kern_flags)
 {
        return 0;
 }
index 71f9682bfb54bd6e99dd9eb517cc0d574c89d6d1..d32e16e3c6ae661163359f70f1fcf6c66c49dae3 100644 (file)
@@ -91,7 +91,10 @@ static int cap_sb_pivotroot(struct path *old_path, struct path *new_path)
 }
 
 static int cap_sb_set_mnt_opts(struct super_block *sb,
-                              struct security_mnt_opts *opts)
+                              struct security_mnt_opts *opts,
+                              unsigned long kern_flags,
+                              unsigned long *set_kern_flags)
+
 {
        if (unlikely(opts->num_mnt_opts))
                return -EOPNOTSUPP;
index c3ceb754e7056bc7f946160f89df832f9c95da3a..8d0b9a79611a7437e2768e2f85e37f60b5852729 100644 (file)
@@ -294,9 +294,12 @@ int security_sb_pivotroot(struct path *old_path, struct path *new_path)
 }
 
 int security_sb_set_mnt_opts(struct super_block *sb,
-                               struct security_mnt_opts *opts)
+                               struct security_mnt_opts *opts,
+                               unsigned long kern_flags,
+                               unsigned long *set_kern_flags)
 {
-       return security_ops->sb_set_mnt_opts(sb, opts);
+       return security_ops->sb_set_mnt_opts(sb, opts, kern_flags,
+                                               set_kern_flags);
 }
 EXPORT_SYMBOL(security_sb_set_mnt_opts);
 
index bbf219a494d0eb7c031a37dc13a0412b27274a48..f3b54466a0378bae4004289170bdac49c00b8b08 100644 (file)
@@ -552,7 +552,9 @@ static int bad_option(struct superblock_security_struct *sbsec, char flag,
  * labeling information.
  */
 static int selinux_set_mnt_opts(struct super_block *sb,
-                               struct security_mnt_opts *opts)
+                               struct security_mnt_opts *opts,
+                               unsigned long kern_flags,
+                               unsigned long *set_kern_flags)
 {
        const struct cred *cred = current_cred();
        int rc = 0, i;
@@ -580,6 +582,12 @@ static int selinux_set_mnt_opts(struct super_block *sb,
                        "before the security server is initialized\n");
                goto out;
        }
+       if (kern_flags && !set_kern_flags) {
+               /* Specifying internal flags without providing a place to
+                * place the results is not allowed */
+               rc = -EINVAL;
+               goto out;
+       }
 
        /*
         * Binary mount data FS will come through this function twice.  Once
@@ -980,7 +988,7 @@ static int superblock_doinit(struct super_block *sb, void *data)
                goto out_err;
 
 out:
-       rc = selinux_set_mnt_opts(sb, &opts);
+       rc = selinux_set_mnt_opts(sb, &opts, 0, NULL);
 
 out_err:
        security_free_mnt_opts(&opts);