Commit 649f6e77 authored by David Quigley's avatar David Quigley Committed by Trond Myklebust

LSM: Add flags field to security_sb_set_mnt_opts for in kernel mount data.

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: default avatarEric Paris <eparis@redhat.com>
Acked-by: default avatarJames Morris <james.l.morris@oracle.com>
Signed-off-by: default avatarDavid P. Quigley <dpquigl@tycho.nsa.gov>
Signed-off-by: default avatarMiguel Rodel Felipe <Rodel_FM@dsi.a-star.edu.sg>
Signed-off-by: default avatarPhua Eu Gene <PHUA_Eu_Gene@dsi.a-star.edu.sg>
Signed-off-by: default avatarKhin Mi Mi Aung <Mi_Mi_AUNG@dsi.a-star.edu.sg>
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 746df9b5
...@@ -2411,7 +2411,8 @@ static int nfs_bdi_register(struct nfs_server *server) ...@@ -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, int nfs_set_sb_security(struct super_block *s, struct dentry *mntroot,
struct nfs_mount_info *mount_info) 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); EXPORT_SYMBOL_GPL(nfs_set_sb_security);
......
...@@ -1456,7 +1456,9 @@ struct security_operations { ...@@ -1456,7 +1456,9 @@ struct security_operations {
int (*sb_pivotroot) (struct path *old_path, int (*sb_pivotroot) (struct path *old_path,
struct path *new_path); struct path *new_path);
int (*sb_set_mnt_opts) (struct super_block *sb, 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, int (*sb_clone_mnt_opts) (const struct super_block *oldsb,
struct super_block *newsb); struct super_block *newsb);
int (*sb_parse_opts_str) (char *options, struct security_mnt_opts *opts); 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, ...@@ -1747,7 +1749,10 @@ int security_sb_mount(const char *dev_name, struct path *path,
const char *type, unsigned long flags, void *data); const char *type, unsigned long flags, void *data);
int security_sb_umount(struct vfsmount *mnt, int flags); int security_sb_umount(struct vfsmount *mnt, int flags);
int security_sb_pivotroot(struct path *old_path, struct path *new_path); 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, int security_sb_clone_mnt_opts(const struct super_block *oldsb,
struct super_block *newsb); struct super_block *newsb);
int security_sb_parse_opts_str(char *options, struct security_mnt_opts *opts); 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, ...@@ -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, 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; return 0;
} }
......
...@@ -91,7 +91,10 @@ static int cap_sb_pivotroot(struct path *old_path, struct path *new_path) ...@@ -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, 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)) if (unlikely(opts->num_mnt_opts))
return -EOPNOTSUPP; return -EOPNOTSUPP;
......
...@@ -294,9 +294,12 @@ int security_sb_pivotroot(struct path *old_path, struct path *new_path) ...@@ -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, 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); EXPORT_SYMBOL(security_sb_set_mnt_opts);
......
...@@ -552,7 +552,9 @@ static int bad_option(struct superblock_security_struct *sbsec, char flag, ...@@ -552,7 +552,9 @@ static int bad_option(struct superblock_security_struct *sbsec, char flag,
* labeling information. * labeling information.
*/ */
static int selinux_set_mnt_opts(struct super_block *sb, 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(); const struct cred *cred = current_cred();
int rc = 0, i; int rc = 0, i;
...@@ -580,6 +582,12 @@ static int selinux_set_mnt_opts(struct super_block *sb, ...@@ -580,6 +582,12 @@ static int selinux_set_mnt_opts(struct super_block *sb,
"before the security server is initialized\n"); "before the security server is initialized\n");
goto out; 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 * 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) ...@@ -980,7 +988,7 @@ static int superblock_doinit(struct super_block *sb, void *data)
goto out_err; goto out_err;
out: out:
rc = selinux_set_mnt_opts(sb, &opts); rc = selinux_set_mnt_opts(sb, &opts, 0, NULL);
out_err: out_err:
security_free_mnt_opts(&opts); security_free_mnt_opts(&opts);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment