Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/selinux-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/selinux-2.6: NFS: use new LSM interfaces to explicitly set mount options LSM/SELinux: Interfaces to allow FS to control mount options
This commit is contained in:
commit
da71aeb614
@ -3,6 +3,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/mount.h>
|
#include <linux/mount.h>
|
||||||
|
#include <linux/security.h>
|
||||||
|
|
||||||
struct nfs_string;
|
struct nfs_string;
|
||||||
|
|
||||||
@ -57,6 +58,8 @@ struct nfs_parsed_mount_data {
|
|||||||
char *export_path;
|
char *export_path;
|
||||||
int protocol;
|
int protocol;
|
||||||
} nfs_server;
|
} nfs_server;
|
||||||
|
|
||||||
|
struct security_mnt_opts lsm_opts;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* client.c */
|
/* client.c */
|
||||||
|
@ -684,8 +684,9 @@ static void nfs_parse_server_address(char *value,
|
|||||||
static int nfs_parse_mount_options(char *raw,
|
static int nfs_parse_mount_options(char *raw,
|
||||||
struct nfs_parsed_mount_data *mnt)
|
struct nfs_parsed_mount_data *mnt)
|
||||||
{
|
{
|
||||||
char *p, *string;
|
char *p, *string, *secdata;
|
||||||
unsigned short port = 0;
|
unsigned short port = 0;
|
||||||
|
int rc;
|
||||||
|
|
||||||
if (!raw) {
|
if (!raw) {
|
||||||
dfprintk(MOUNT, "NFS: mount options string was NULL.\n");
|
dfprintk(MOUNT, "NFS: mount options string was NULL.\n");
|
||||||
@ -693,6 +694,20 @@ static int nfs_parse_mount_options(char *raw,
|
|||||||
}
|
}
|
||||||
dfprintk(MOUNT, "NFS: nfs mount opts='%s'\n", raw);
|
dfprintk(MOUNT, "NFS: nfs mount opts='%s'\n", raw);
|
||||||
|
|
||||||
|
secdata = alloc_secdata();
|
||||||
|
if (!secdata)
|
||||||
|
goto out_nomem;
|
||||||
|
|
||||||
|
rc = security_sb_copy_data(raw, secdata);
|
||||||
|
if (rc)
|
||||||
|
goto out_security_failure;
|
||||||
|
|
||||||
|
rc = security_sb_parse_opts_str(secdata, &mnt->lsm_opts);
|
||||||
|
if (rc)
|
||||||
|
goto out_security_failure;
|
||||||
|
|
||||||
|
free_secdata(secdata);
|
||||||
|
|
||||||
while ((p = strsep(&raw, ",")) != NULL) {
|
while ((p = strsep(&raw, ",")) != NULL) {
|
||||||
substring_t args[MAX_OPT_ARGS];
|
substring_t args[MAX_OPT_ARGS];
|
||||||
int option, token;
|
int option, token;
|
||||||
@ -1042,7 +1057,10 @@ static int nfs_parse_mount_options(char *raw,
|
|||||||
out_nomem:
|
out_nomem:
|
||||||
printk(KERN_INFO "NFS: not enough memory to parse option\n");
|
printk(KERN_INFO "NFS: not enough memory to parse option\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
out_security_failure:
|
||||||
|
free_secdata(secdata);
|
||||||
|
printk(KERN_INFO "NFS: security options invalid: %d\n", rc);
|
||||||
|
return 0;
|
||||||
out_unrec_vers:
|
out_unrec_vers:
|
||||||
printk(KERN_INFO "NFS: unrecognized NFS version number\n");
|
printk(KERN_INFO "NFS: unrecognized NFS version number\n");
|
||||||
return 0;
|
return 0;
|
||||||
@ -1214,6 +1232,33 @@ static int nfs_validate_mount_data(void *options,
|
|||||||
args->namlen = data->namlen;
|
args->namlen = data->namlen;
|
||||||
args->bsize = data->bsize;
|
args->bsize = data->bsize;
|
||||||
args->auth_flavors[0] = data->pseudoflavor;
|
args->auth_flavors[0] = data->pseudoflavor;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The legacy version 6 binary mount data from userspace has a
|
||||||
|
* field used only to transport selinux information into the
|
||||||
|
* the kernel. To continue to support that functionality we
|
||||||
|
* have a touch of selinux knowledge here in the NFS code. The
|
||||||
|
* userspace code converted context=blah to just blah so we are
|
||||||
|
* converting back to the full string selinux understands.
|
||||||
|
*/
|
||||||
|
if (data->context[0]){
|
||||||
|
#ifdef CONFIG_SECURITY_SELINUX
|
||||||
|
int rc;
|
||||||
|
char *opts_str = kmalloc(sizeof(data->context) + 8, GFP_KERNEL);
|
||||||
|
if (!opts_str)
|
||||||
|
return -ENOMEM;
|
||||||
|
strcpy(opts_str, "context=");
|
||||||
|
data->context[NFS_MAX_CONTEXT_LEN] = '\0';
|
||||||
|
strcat(opts_str, &data->context[0]);
|
||||||
|
rc = security_sb_parse_opts_str(opts_str, &args->lsm_opts);
|
||||||
|
kfree(opts_str);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
#else
|
||||||
|
return -EINVAL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default: {
|
default: {
|
||||||
unsigned int len;
|
unsigned int len;
|
||||||
@ -1476,6 +1521,8 @@ static int nfs_get_sb(struct file_system_type *fs_type,
|
|||||||
};
|
};
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
security_init_mnt_opts(&data.lsm_opts);
|
||||||
|
|
||||||
/* Validate the mount data */
|
/* Validate the mount data */
|
||||||
error = nfs_validate_mount_data(raw_data, &data, &mntfh, dev_name);
|
error = nfs_validate_mount_data(raw_data, &data, &mntfh, dev_name);
|
||||||
if (error < 0)
|
if (error < 0)
|
||||||
@ -1515,6 +1562,10 @@ static int nfs_get_sb(struct file_system_type *fs_type,
|
|||||||
goto error_splat_super;
|
goto error_splat_super;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
error = security_sb_set_mnt_opts(s, &data.lsm_opts);
|
||||||
|
if (error)
|
||||||
|
goto error_splat_root;
|
||||||
|
|
||||||
s->s_flags |= MS_ACTIVE;
|
s->s_flags |= MS_ACTIVE;
|
||||||
mnt->mnt_sb = s;
|
mnt->mnt_sb = s;
|
||||||
mnt->mnt_root = mntroot;
|
mnt->mnt_root = mntroot;
|
||||||
@ -1523,12 +1574,15 @@ static int nfs_get_sb(struct file_system_type *fs_type,
|
|||||||
out:
|
out:
|
||||||
kfree(data.nfs_server.hostname);
|
kfree(data.nfs_server.hostname);
|
||||||
kfree(data.mount_server.hostname);
|
kfree(data.mount_server.hostname);
|
||||||
|
security_free_mnt_opts(&data.lsm_opts);
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
out_err_nosb:
|
out_err_nosb:
|
||||||
nfs_free_server(server);
|
nfs_free_server(server);
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
error_splat_root:
|
||||||
|
dput(mntroot);
|
||||||
error_splat_super:
|
error_splat_super:
|
||||||
up_write(&s->s_umount);
|
up_write(&s->s_umount);
|
||||||
deactivate_super(s);
|
deactivate_super(s);
|
||||||
@ -1608,6 +1662,9 @@ static int nfs_xdev_get_sb(struct file_system_type *fs_type, int flags,
|
|||||||
mnt->mnt_sb = s;
|
mnt->mnt_sb = s;
|
||||||
mnt->mnt_root = mntroot;
|
mnt->mnt_root = mntroot;
|
||||||
|
|
||||||
|
/* clone any lsm security options from the parent to the new sb */
|
||||||
|
security_sb_clone_mnt_opts(data->sb, s);
|
||||||
|
|
||||||
dprintk("<-- nfs_xdev_get_sb() = 0\n");
|
dprintk("<-- nfs_xdev_get_sb() = 0\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -1850,6 +1907,8 @@ static int nfs4_get_sb(struct file_system_type *fs_type,
|
|||||||
};
|
};
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
security_init_mnt_opts(&data.lsm_opts);
|
||||||
|
|
||||||
/* Validate the mount data */
|
/* Validate the mount data */
|
||||||
error = nfs4_validate_mount_data(raw_data, &data, dev_name);
|
error = nfs4_validate_mount_data(raw_data, &data, dev_name);
|
||||||
if (error < 0)
|
if (error < 0)
|
||||||
@ -1898,6 +1957,7 @@ out:
|
|||||||
kfree(data.client_address);
|
kfree(data.client_address);
|
||||||
kfree(data.nfs_server.export_path);
|
kfree(data.nfs_server.export_path);
|
||||||
kfree(data.nfs_server.hostname);
|
kfree(data.nfs_server.hostname);
|
||||||
|
security_free_mnt_opts(&data.lsm_opts);
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
out_free:
|
out_free:
|
||||||
|
@ -870,12 +870,12 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void
|
|||||||
if (!mnt)
|
if (!mnt)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (data) {
|
if (data && !(type->fs_flags & FS_BINARY_MOUNTDATA)) {
|
||||||
secdata = alloc_secdata();
|
secdata = alloc_secdata();
|
||||||
if (!secdata)
|
if (!secdata)
|
||||||
goto out_mnt;
|
goto out_mnt;
|
||||||
|
|
||||||
error = security_sb_copy_data(type, data, secdata);
|
error = security_sb_copy_data(data, secdata);
|
||||||
if (error)
|
if (error)
|
||||||
goto out_free_secdata;
|
goto out_free_secdata;
|
||||||
}
|
}
|
||||||
|
@ -34,12 +34,6 @@
|
|||||||
#include <linux/xfrm.h>
|
#include <linux/xfrm.h>
|
||||||
#include <net/flow.h>
|
#include <net/flow.h>
|
||||||
|
|
||||||
/* only a char in selinux superblock security struct flags */
|
|
||||||
#define FSCONTEXT_MNT 0x01
|
|
||||||
#define CONTEXT_MNT 0x02
|
|
||||||
#define ROOTCONTEXT_MNT 0x04
|
|
||||||
#define DEFCONTEXT_MNT 0x08
|
|
||||||
|
|
||||||
extern unsigned securebits;
|
extern unsigned securebits;
|
||||||
|
|
||||||
struct ctl_table;
|
struct ctl_table;
|
||||||
@ -114,6 +108,32 @@ struct request_sock;
|
|||||||
|
|
||||||
#ifdef CONFIG_SECURITY
|
#ifdef CONFIG_SECURITY
|
||||||
|
|
||||||
|
struct security_mnt_opts {
|
||||||
|
char **mnt_opts;
|
||||||
|
int *mnt_opts_flags;
|
||||||
|
int num_mnt_opts;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline void security_init_mnt_opts(struct security_mnt_opts *opts)
|
||||||
|
{
|
||||||
|
opts->mnt_opts = NULL;
|
||||||
|
opts->mnt_opts_flags = NULL;
|
||||||
|
opts->num_mnt_opts = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
if (opts->mnt_opts)
|
||||||
|
for(i = 0; i < opts->num_mnt_opts; i++)
|
||||||
|
kfree(opts->mnt_opts[i]);
|
||||||
|
kfree(opts->mnt_opts);
|
||||||
|
opts->mnt_opts = NULL;
|
||||||
|
kfree(opts->mnt_opts_flags);
|
||||||
|
opts->mnt_opts_flags = NULL;
|
||||||
|
opts->num_mnt_opts = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct security_operations - main security structure
|
* struct security_operations - main security structure
|
||||||
*
|
*
|
||||||
@ -262,19 +282,19 @@ struct request_sock;
|
|||||||
* @sb_get_mnt_opts:
|
* @sb_get_mnt_opts:
|
||||||
* Get the security relevant mount options used for a superblock
|
* Get the security relevant mount options used for a superblock
|
||||||
* @sb the superblock to get security mount options from
|
* @sb the superblock to get security mount options from
|
||||||
* @mount_options array for pointers to mount options
|
* @opts binary data structure containing all lsm mount data
|
||||||
* @mount_flags array of ints specifying what each mount options is
|
|
||||||
* @num_opts number of options in the arrays
|
|
||||||
* @sb_set_mnt_opts:
|
* @sb_set_mnt_opts:
|
||||||
* Set the security relevant mount options used for a superblock
|
* Set the security relevant mount options used for a superblock
|
||||||
* @sb the superblock to set security mount options for
|
* @sb the superblock to set security mount options for
|
||||||
* @mount_options array for pointers to mount options
|
* @opts binary data structure containing all lsm mount data
|
||||||
* @mount_flags array of ints specifying what each mount options is
|
|
||||||
* @num_opts number of options in the arrays
|
|
||||||
* @sb_clone_mnt_opts:
|
* @sb_clone_mnt_opts:
|
||||||
* Copy all security options from a given superblock to another
|
* Copy all security options from a given superblock to another
|
||||||
* @oldsb old superblock which contain information to clone
|
* @oldsb old superblock which contain information to clone
|
||||||
* @newsb new superblock which needs filled in
|
* @newsb new superblock which needs filled in
|
||||||
|
* @sb_parse_opts_str:
|
||||||
|
* Parse a string of security data filling in the opts structure
|
||||||
|
* @options string containing all mount options known by the LSM
|
||||||
|
* @opts binary data structure usable by the LSM
|
||||||
*
|
*
|
||||||
* Security hooks for inode operations.
|
* Security hooks for inode operations.
|
||||||
*
|
*
|
||||||
@ -1238,8 +1258,7 @@ struct security_operations {
|
|||||||
|
|
||||||
int (*sb_alloc_security) (struct super_block * sb);
|
int (*sb_alloc_security) (struct super_block * sb);
|
||||||
void (*sb_free_security) (struct super_block * sb);
|
void (*sb_free_security) (struct super_block * sb);
|
||||||
int (*sb_copy_data)(struct file_system_type *type,
|
int (*sb_copy_data)(char *orig, char *copy);
|
||||||
void *orig, void *copy);
|
|
||||||
int (*sb_kern_mount) (struct super_block *sb, void *data);
|
int (*sb_kern_mount) (struct super_block *sb, void *data);
|
||||||
int (*sb_statfs) (struct dentry *dentry);
|
int (*sb_statfs) (struct dentry *dentry);
|
||||||
int (*sb_mount) (char *dev_name, struct nameidata * nd,
|
int (*sb_mount) (char *dev_name, struct nameidata * nd,
|
||||||
@ -1257,12 +1276,12 @@ struct security_operations {
|
|||||||
void (*sb_post_pivotroot) (struct nameidata * old_nd,
|
void (*sb_post_pivotroot) (struct nameidata * old_nd,
|
||||||
struct nameidata * new_nd);
|
struct nameidata * new_nd);
|
||||||
int (*sb_get_mnt_opts) (const struct super_block *sb,
|
int (*sb_get_mnt_opts) (const struct super_block *sb,
|
||||||
char ***mount_options, int **flags,
|
struct security_mnt_opts *opts);
|
||||||
int *num_opts);
|
int (*sb_set_mnt_opts) (struct super_block *sb,
|
||||||
int (*sb_set_mnt_opts) (struct super_block *sb, char **mount_options,
|
struct security_mnt_opts *opts);
|
||||||
int *flags, int num_opts);
|
|
||||||
void (*sb_clone_mnt_opts) (const struct super_block *oldsb,
|
void (*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 (*inode_alloc_security) (struct inode *inode);
|
int (*inode_alloc_security) (struct inode *inode);
|
||||||
void (*inode_free_security) (struct inode *inode);
|
void (*inode_free_security) (struct inode *inode);
|
||||||
@ -1507,7 +1526,7 @@ int security_bprm_check(struct linux_binprm *bprm);
|
|||||||
int security_bprm_secureexec(struct linux_binprm *bprm);
|
int security_bprm_secureexec(struct linux_binprm *bprm);
|
||||||
int security_sb_alloc(struct super_block *sb);
|
int security_sb_alloc(struct super_block *sb);
|
||||||
void security_sb_free(struct super_block *sb);
|
void security_sb_free(struct super_block *sb);
|
||||||
int security_sb_copy_data(struct file_system_type *type, void *orig, void *copy);
|
int security_sb_copy_data(char *orig, char *copy);
|
||||||
int security_sb_kern_mount(struct super_block *sb, void *data);
|
int security_sb_kern_mount(struct super_block *sb, void *data);
|
||||||
int security_sb_statfs(struct dentry *dentry);
|
int security_sb_statfs(struct dentry *dentry);
|
||||||
int security_sb_mount(char *dev_name, struct nameidata *nd,
|
int security_sb_mount(char *dev_name, struct nameidata *nd,
|
||||||
@ -1520,12 +1539,12 @@ void security_sb_post_remount(struct vfsmount *mnt, unsigned long flags, void *d
|
|||||||
void security_sb_post_addmount(struct vfsmount *mnt, struct nameidata *mountpoint_nd);
|
void security_sb_post_addmount(struct vfsmount *mnt, struct nameidata *mountpoint_nd);
|
||||||
int security_sb_pivotroot(struct nameidata *old_nd, struct nameidata *new_nd);
|
int security_sb_pivotroot(struct nameidata *old_nd, struct nameidata *new_nd);
|
||||||
void security_sb_post_pivotroot(struct nameidata *old_nd, struct nameidata *new_nd);
|
void security_sb_post_pivotroot(struct nameidata *old_nd, struct nameidata *new_nd);
|
||||||
int security_sb_get_mnt_opts(const struct super_block *sb, char ***mount_options,
|
int security_sb_get_mnt_opts(const struct super_block *sb,
|
||||||
int **flags, int *num_opts);
|
struct security_mnt_opts *opts);
|
||||||
int security_sb_set_mnt_opts(struct super_block *sb, char **mount_options,
|
int security_sb_set_mnt_opts(struct super_block *sb, struct security_mnt_opts *opts);
|
||||||
int *flags, int num_opts);
|
|
||||||
void security_sb_clone_mnt_opts(const struct super_block *oldsb,
|
void 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_inode_alloc(struct inode *inode);
|
int security_inode_alloc(struct inode *inode);
|
||||||
void security_inode_free(struct inode *inode);
|
void security_inode_free(struct inode *inode);
|
||||||
@ -1635,6 +1654,16 @@ int security_secctx_to_secid(char *secdata, u32 seclen, u32 *secid);
|
|||||||
void security_release_secctx(char *secdata, u32 seclen);
|
void security_release_secctx(char *secdata, u32 seclen);
|
||||||
|
|
||||||
#else /* CONFIG_SECURITY */
|
#else /* CONFIG_SECURITY */
|
||||||
|
struct security_mnt_opts {
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline void security_init_mnt_opts(struct security_mnt_opts *opts)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is the default capabilities functionality. Most of these functions
|
* This is the default capabilities functionality. Most of these functions
|
||||||
@ -1762,8 +1791,7 @@ static inline int security_sb_alloc (struct super_block *sb)
|
|||||||
static inline void security_sb_free (struct super_block *sb)
|
static inline void security_sb_free (struct super_block *sb)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
static inline int security_sb_copy_data (struct file_system_type *type,
|
static inline int security_sb_copy_data (char *orig, char *copy)
|
||||||
void *orig, void *copy)
|
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1819,6 +1847,27 @@ static inline int security_sb_pivotroot (struct nameidata *old_nd,
|
|||||||
static inline void security_sb_post_pivotroot (struct nameidata *old_nd,
|
static inline void security_sb_post_pivotroot (struct nameidata *old_nd,
|
||||||
struct nameidata *new_nd)
|
struct nameidata *new_nd)
|
||||||
{ }
|
{ }
|
||||||
|
static inline int security_sb_get_mnt_opts(const struct super_block *sb,
|
||||||
|
struct security_mnt_opts *opts)
|
||||||
|
{
|
||||||
|
security_init_mnt_opts(opts);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int security_sb_set_mnt_opts(struct super_block *sb,
|
||||||
|
struct security_mnt_opts *opts)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void security_sb_clone_mnt_opts(const struct super_block *oldsb,
|
||||||
|
struct super_block *newsb)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
static inline int security_sb_parse_opts_str(char *options, struct security_mnt_opts *opts)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static inline int security_inode_alloc (struct inode *inode)
|
static inline int security_inode_alloc (struct inode *inode)
|
||||||
{
|
{
|
||||||
|
@ -181,8 +181,7 @@ static void dummy_sb_free_security (struct super_block *sb)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dummy_sb_copy_data (struct file_system_type *type,
|
static int dummy_sb_copy_data (char *orig, char *copy)
|
||||||
void *orig, void *copy)
|
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -245,19 +244,17 @@ static void dummy_sb_post_pivotroot (struct nameidata *old_nd, struct nameidata
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dummy_sb_get_mnt_opts(const struct super_block *sb, char ***mount_options,
|
static int dummy_sb_get_mnt_opts(const struct super_block *sb,
|
||||||
int **flags, int *num_opts)
|
struct security_mnt_opts *opts)
|
||||||
{
|
{
|
||||||
*mount_options = NULL;
|
security_init_mnt_opts(opts);
|
||||||
*flags = NULL;
|
|
||||||
*num_opts = 0;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dummy_sb_set_mnt_opts(struct super_block *sb, char **mount_options,
|
static int dummy_sb_set_mnt_opts(struct super_block *sb,
|
||||||
int *flags, int num_opts)
|
struct security_mnt_opts *opts)
|
||||||
{
|
{
|
||||||
if (unlikely(num_opts))
|
if (unlikely(opts->num_mnt_opts))
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -268,6 +265,11 @@ static void dummy_sb_clone_mnt_opts(const struct super_block *oldsb,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int dummy_sb_parse_opts_str(char *options, struct security_mnt_opts *opts)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int dummy_inode_alloc_security (struct inode *inode)
|
static int dummy_inode_alloc_security (struct inode *inode)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
@ -1028,6 +1030,7 @@ void security_fixup_ops (struct security_operations *ops)
|
|||||||
set_to_dummy_if_null(ops, sb_get_mnt_opts);
|
set_to_dummy_if_null(ops, sb_get_mnt_opts);
|
||||||
set_to_dummy_if_null(ops, sb_set_mnt_opts);
|
set_to_dummy_if_null(ops, sb_set_mnt_opts);
|
||||||
set_to_dummy_if_null(ops, sb_clone_mnt_opts);
|
set_to_dummy_if_null(ops, sb_clone_mnt_opts);
|
||||||
|
set_to_dummy_if_null(ops, sb_parse_opts_str);
|
||||||
set_to_dummy_if_null(ops, inode_alloc_security);
|
set_to_dummy_if_null(ops, inode_alloc_security);
|
||||||
set_to_dummy_if_null(ops, inode_free_security);
|
set_to_dummy_if_null(ops, inode_free_security);
|
||||||
set_to_dummy_if_null(ops, inode_init_security);
|
set_to_dummy_if_null(ops, inode_init_security);
|
||||||
|
@ -244,10 +244,11 @@ void security_sb_free(struct super_block *sb)
|
|||||||
security_ops->sb_free_security(sb);
|
security_ops->sb_free_security(sb);
|
||||||
}
|
}
|
||||||
|
|
||||||
int security_sb_copy_data(struct file_system_type *type, void *orig, void *copy)
|
int security_sb_copy_data(char *orig, char *copy)
|
||||||
{
|
{
|
||||||
return security_ops->sb_copy_data(type, orig, copy);
|
return security_ops->sb_copy_data(orig, copy);
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(security_sb_copy_data);
|
||||||
|
|
||||||
int security_sb_kern_mount(struct super_block *sb, void *data)
|
int security_sb_kern_mount(struct super_block *sb, void *data)
|
||||||
{
|
{
|
||||||
@ -306,24 +307,30 @@ void security_sb_post_pivotroot(struct nameidata *old_nd, struct nameidata *new_
|
|||||||
}
|
}
|
||||||
|
|
||||||
int security_sb_get_mnt_opts(const struct super_block *sb,
|
int security_sb_get_mnt_opts(const struct super_block *sb,
|
||||||
char ***mount_options,
|
struct security_mnt_opts *opts)
|
||||||
int **flags, int *num_opts)
|
|
||||||
{
|
{
|
||||||
return security_ops->sb_get_mnt_opts(sb, mount_options, flags, num_opts);
|
return security_ops->sb_get_mnt_opts(sb, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
int security_sb_set_mnt_opts(struct super_block *sb,
|
int security_sb_set_mnt_opts(struct super_block *sb,
|
||||||
char **mount_options,
|
struct security_mnt_opts *opts)
|
||||||
int *flags, int num_opts)
|
|
||||||
{
|
{
|
||||||
return security_ops->sb_set_mnt_opts(sb, mount_options, flags, num_opts);
|
return security_ops->sb_set_mnt_opts(sb, opts);
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(security_sb_set_mnt_opts);
|
||||||
|
|
||||||
void security_sb_clone_mnt_opts(const struct super_block *oldsb,
|
void security_sb_clone_mnt_opts(const struct super_block *oldsb,
|
||||||
struct super_block *newsb)
|
struct super_block *newsb)
|
||||||
{
|
{
|
||||||
security_ops->sb_clone_mnt_opts(oldsb, newsb);
|
security_ops->sb_clone_mnt_opts(oldsb, newsb);
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(security_sb_clone_mnt_opts);
|
||||||
|
|
||||||
|
int security_sb_parse_opts_str(char *options, struct security_mnt_opts *opts)
|
||||||
|
{
|
||||||
|
return security_ops->sb_parse_opts_str(options, opts);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(security_sb_parse_opts_str);
|
||||||
|
|
||||||
int security_inode_alloc(struct inode *inode)
|
int security_inode_alloc(struct inode *inode)
|
||||||
{
|
{
|
||||||
|
@ -443,8 +443,7 @@ out:
|
|||||||
* mount options, or whatever.
|
* mount options, or whatever.
|
||||||
*/
|
*/
|
||||||
static int selinux_get_mnt_opts(const struct super_block *sb,
|
static int selinux_get_mnt_opts(const struct super_block *sb,
|
||||||
char ***mount_options, int **mnt_opts_flags,
|
struct security_mnt_opts *opts)
|
||||||
int *num_opts)
|
|
||||||
{
|
{
|
||||||
int rc = 0, i;
|
int rc = 0, i;
|
||||||
struct superblock_security_struct *sbsec = sb->s_security;
|
struct superblock_security_struct *sbsec = sb->s_security;
|
||||||
@ -452,9 +451,7 @@ static int selinux_get_mnt_opts(const struct super_block *sb,
|
|||||||
u32 len;
|
u32 len;
|
||||||
char tmp;
|
char tmp;
|
||||||
|
|
||||||
*num_opts = 0;
|
security_init_mnt_opts(opts);
|
||||||
*mount_options = NULL;
|
|
||||||
*mnt_opts_flags = NULL;
|
|
||||||
|
|
||||||
if (!sbsec->initialized)
|
if (!sbsec->initialized)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -470,18 +467,18 @@ static int selinux_get_mnt_opts(const struct super_block *sb,
|
|||||||
/* count the number of mount options for this sb */
|
/* count the number of mount options for this sb */
|
||||||
for (i = 0; i < 8; i++) {
|
for (i = 0; i < 8; i++) {
|
||||||
if (tmp & 0x01)
|
if (tmp & 0x01)
|
||||||
(*num_opts)++;
|
opts->num_mnt_opts++;
|
||||||
tmp >>= 1;
|
tmp >>= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
*mount_options = kcalloc(*num_opts, sizeof(char *), GFP_ATOMIC);
|
opts->mnt_opts = kcalloc(opts->num_mnt_opts, sizeof(char *), GFP_ATOMIC);
|
||||||
if (!*mount_options) {
|
if (!opts->mnt_opts) {
|
||||||
rc = -ENOMEM;
|
rc = -ENOMEM;
|
||||||
goto out_free;
|
goto out_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
*mnt_opts_flags = kcalloc(*num_opts, sizeof(int), GFP_ATOMIC);
|
opts->mnt_opts_flags = kcalloc(opts->num_mnt_opts, sizeof(int), GFP_ATOMIC);
|
||||||
if (!*mnt_opts_flags) {
|
if (!opts->mnt_opts_flags) {
|
||||||
rc = -ENOMEM;
|
rc = -ENOMEM;
|
||||||
goto out_free;
|
goto out_free;
|
||||||
}
|
}
|
||||||
@ -491,22 +488,22 @@ static int selinux_get_mnt_opts(const struct super_block *sb,
|
|||||||
rc = security_sid_to_context(sbsec->sid, &context, &len);
|
rc = security_sid_to_context(sbsec->sid, &context, &len);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto out_free;
|
goto out_free;
|
||||||
(*mount_options)[i] = context;
|
opts->mnt_opts[i] = context;
|
||||||
(*mnt_opts_flags)[i++] = FSCONTEXT_MNT;
|
opts->mnt_opts_flags[i++] = FSCONTEXT_MNT;
|
||||||
}
|
}
|
||||||
if (sbsec->flags & CONTEXT_MNT) {
|
if (sbsec->flags & CONTEXT_MNT) {
|
||||||
rc = security_sid_to_context(sbsec->mntpoint_sid, &context, &len);
|
rc = security_sid_to_context(sbsec->mntpoint_sid, &context, &len);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto out_free;
|
goto out_free;
|
||||||
(*mount_options)[i] = context;
|
opts->mnt_opts[i] = context;
|
||||||
(*mnt_opts_flags)[i++] = CONTEXT_MNT;
|
opts->mnt_opts_flags[i++] = CONTEXT_MNT;
|
||||||
}
|
}
|
||||||
if (sbsec->flags & DEFCONTEXT_MNT) {
|
if (sbsec->flags & DEFCONTEXT_MNT) {
|
||||||
rc = security_sid_to_context(sbsec->def_sid, &context, &len);
|
rc = security_sid_to_context(sbsec->def_sid, &context, &len);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto out_free;
|
goto out_free;
|
||||||
(*mount_options)[i] = context;
|
opts->mnt_opts[i] = context;
|
||||||
(*mnt_opts_flags)[i++] = DEFCONTEXT_MNT;
|
opts->mnt_opts_flags[i++] = DEFCONTEXT_MNT;
|
||||||
}
|
}
|
||||||
if (sbsec->flags & ROOTCONTEXT_MNT) {
|
if (sbsec->flags & ROOTCONTEXT_MNT) {
|
||||||
struct inode *root = sbsec->sb->s_root->d_inode;
|
struct inode *root = sbsec->sb->s_root->d_inode;
|
||||||
@ -515,24 +512,16 @@ static int selinux_get_mnt_opts(const struct super_block *sb,
|
|||||||
rc = security_sid_to_context(isec->sid, &context, &len);
|
rc = security_sid_to_context(isec->sid, &context, &len);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto out_free;
|
goto out_free;
|
||||||
(*mount_options)[i] = context;
|
opts->mnt_opts[i] = context;
|
||||||
(*mnt_opts_flags)[i++] = ROOTCONTEXT_MNT;
|
opts->mnt_opts_flags[i++] = ROOTCONTEXT_MNT;
|
||||||
}
|
}
|
||||||
|
|
||||||
BUG_ON(i != *num_opts);
|
BUG_ON(i != opts->num_mnt_opts);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out_free:
|
out_free:
|
||||||
/* don't leak context string if security_sid_to_context had an error */
|
security_free_mnt_opts(opts);
|
||||||
if (*mount_options && i)
|
|
||||||
for (; i > 0; i--)
|
|
||||||
kfree((*mount_options)[i-1]);
|
|
||||||
kfree(*mount_options);
|
|
||||||
*mount_options = NULL;
|
|
||||||
kfree(*mnt_opts_flags);
|
|
||||||
*mnt_opts_flags = NULL;
|
|
||||||
*num_opts = 0;
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -553,12 +542,13 @@ static int bad_option(struct superblock_security_struct *sbsec, char flag,
|
|||||||
return 1;
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allow filesystems with binary mount data to explicitly set mount point
|
* Allow filesystems with binary mount data to explicitly set mount point
|
||||||
* labeling information.
|
* labeling information.
|
||||||
*/
|
*/
|
||||||
static int selinux_set_mnt_opts(struct super_block *sb, char **mount_options,
|
static int selinux_set_mnt_opts(struct super_block *sb,
|
||||||
int *flags, int num_opts)
|
struct security_mnt_opts *opts)
|
||||||
{
|
{
|
||||||
int rc = 0, i;
|
int rc = 0, i;
|
||||||
struct task_security_struct *tsec = current->security;
|
struct task_security_struct *tsec = current->security;
|
||||||
@ -568,6 +558,9 @@ static int selinux_set_mnt_opts(struct super_block *sb, char **mount_options,
|
|||||||
struct inode_security_struct *root_isec = inode->i_security;
|
struct inode_security_struct *root_isec = inode->i_security;
|
||||||
u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0;
|
u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0;
|
||||||
u32 defcontext_sid = 0;
|
u32 defcontext_sid = 0;
|
||||||
|
char **mount_options = opts->mnt_opts;
|
||||||
|
int *flags = opts->mnt_opts_flags;
|
||||||
|
int num_opts = opts->num_mnt_opts;
|
||||||
|
|
||||||
mutex_lock(&sbsec->lock);
|
mutex_lock(&sbsec->lock);
|
||||||
|
|
||||||
@ -588,6 +581,21 @@ static int selinux_set_mnt_opts(struct super_block *sb, char **mount_options,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Binary mount data FS will come through this function twice. Once
|
||||||
|
* from an explicit call and once from the generic calls from the vfs.
|
||||||
|
* Since the generic VFS calls will not contain any security mount data
|
||||||
|
* we need to skip the double mount verification.
|
||||||
|
*
|
||||||
|
* This does open a hole in which we will not notice if the first
|
||||||
|
* mount using this sb set explict options and a second mount using
|
||||||
|
* this sb does not set any security options. (The first options
|
||||||
|
* will be used for both mounts)
|
||||||
|
*/
|
||||||
|
if (sbsec->initialized && (sb->s_type->fs_flags & FS_BINARY_MOUNTDATA)
|
||||||
|
&& (num_opts == 0))
|
||||||
|
goto out;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* parse the mount options, check if they are valid sids.
|
* parse the mount options, check if they are valid sids.
|
||||||
* also check if someone is trying to mount the same sb more
|
* also check if someone is trying to mount the same sb more
|
||||||
@ -792,43 +800,14 @@ static void selinux_sb_clone_mnt_opts(const struct super_block *oldsb,
|
|||||||
mutex_unlock(&newsbsec->lock);
|
mutex_unlock(&newsbsec->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
int selinux_parse_opts_str(char *options, struct security_mnt_opts *opts)
|
||||||
* string mount options parsing and call set the sbsec
|
|
||||||
*/
|
|
||||||
static int superblock_doinit(struct super_block *sb, void *data)
|
|
||||||
{
|
{
|
||||||
|
char *p;
|
||||||
char *context = NULL, *defcontext = NULL;
|
char *context = NULL, *defcontext = NULL;
|
||||||
char *fscontext = NULL, *rootcontext = NULL;
|
char *fscontext = NULL, *rootcontext = NULL;
|
||||||
int rc = 0;
|
int rc, num_mnt_opts = 0;
|
||||||
char *p, *options = data;
|
|
||||||
/* selinux only know about a fixed number of mount options */
|
|
||||||
char *mnt_opts[NUM_SEL_MNT_OPTS];
|
|
||||||
int mnt_opts_flags[NUM_SEL_MNT_OPTS], num_mnt_opts = 0;
|
|
||||||
|
|
||||||
if (!data)
|
opts->num_mnt_opts = 0;
|
||||||
goto out;
|
|
||||||
|
|
||||||
/* with the nfs patch this will become a goto out; */
|
|
||||||
if (sb->s_type->fs_flags & FS_BINARY_MOUNTDATA) {
|
|
||||||
const char *name = sb->s_type->name;
|
|
||||||
/* NFS we understand. */
|
|
||||||
if (!strcmp(name, "nfs")) {
|
|
||||||
struct nfs_mount_data *d = data;
|
|
||||||
|
|
||||||
if (d->version != NFS_MOUNT_VERSION)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
if (d->context[0]) {
|
|
||||||
context = kstrdup(d->context, GFP_KERNEL);
|
|
||||||
if (!context) {
|
|
||||||
rc = -ENOMEM;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
goto build_flags;
|
|
||||||
} else
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Standard string-based options. */
|
/* Standard string-based options. */
|
||||||
while ((p = strsep(&options, "|")) != NULL) {
|
while ((p = strsep(&options, "|")) != NULL) {
|
||||||
@ -901,26 +880,37 @@ static int superblock_doinit(struct super_block *sb, void *data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
build_flags:
|
rc = -ENOMEM;
|
||||||
if (fscontext) {
|
opts->mnt_opts = kcalloc(NUM_SEL_MNT_OPTS, sizeof(char *), GFP_ATOMIC);
|
||||||
mnt_opts[num_mnt_opts] = fscontext;
|
if (!opts->mnt_opts)
|
||||||
mnt_opts_flags[num_mnt_opts++] = FSCONTEXT_MNT;
|
goto out_err;
|
||||||
}
|
|
||||||
if (context) {
|
opts->mnt_opts_flags = kcalloc(NUM_SEL_MNT_OPTS, sizeof(int), GFP_ATOMIC);
|
||||||
mnt_opts[num_mnt_opts] = context;
|
if (!opts->mnt_opts_flags) {
|
||||||
mnt_opts_flags[num_mnt_opts++] = CONTEXT_MNT;
|
kfree(opts->mnt_opts);
|
||||||
}
|
goto out_err;
|
||||||
if (rootcontext) {
|
|
||||||
mnt_opts[num_mnt_opts] = rootcontext;
|
|
||||||
mnt_opts_flags[num_mnt_opts++] = ROOTCONTEXT_MNT;
|
|
||||||
}
|
|
||||||
if (defcontext) {
|
|
||||||
mnt_opts[num_mnt_opts] = defcontext;
|
|
||||||
mnt_opts_flags[num_mnt_opts++] = DEFCONTEXT_MNT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
if (fscontext) {
|
||||||
rc = selinux_set_mnt_opts(sb, mnt_opts, mnt_opts_flags, num_mnt_opts);
|
opts->mnt_opts[num_mnt_opts] = fscontext;
|
||||||
|
opts->mnt_opts_flags[num_mnt_opts++] = FSCONTEXT_MNT;
|
||||||
|
}
|
||||||
|
if (context) {
|
||||||
|
opts->mnt_opts[num_mnt_opts] = context;
|
||||||
|
opts->mnt_opts_flags[num_mnt_opts++] = CONTEXT_MNT;
|
||||||
|
}
|
||||||
|
if (rootcontext) {
|
||||||
|
opts->mnt_opts[num_mnt_opts] = rootcontext;
|
||||||
|
opts->mnt_opts_flags[num_mnt_opts++] = ROOTCONTEXT_MNT;
|
||||||
|
}
|
||||||
|
if (defcontext) {
|
||||||
|
opts->mnt_opts[num_mnt_opts] = defcontext;
|
||||||
|
opts->mnt_opts_flags[num_mnt_opts++] = DEFCONTEXT_MNT;
|
||||||
|
}
|
||||||
|
|
||||||
|
opts->num_mnt_opts = num_mnt_opts;
|
||||||
|
return 0;
|
||||||
|
|
||||||
out_err:
|
out_err:
|
||||||
kfree(context);
|
kfree(context);
|
||||||
kfree(defcontext);
|
kfree(defcontext);
|
||||||
@ -928,6 +918,33 @@ out_err:
|
|||||||
kfree(rootcontext);
|
kfree(rootcontext);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* string mount options parsing and call set the sbsec
|
||||||
|
*/
|
||||||
|
static int superblock_doinit(struct super_block *sb, void *data)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
char *options = data;
|
||||||
|
struct security_mnt_opts opts;
|
||||||
|
|
||||||
|
security_init_mnt_opts(&opts);
|
||||||
|
|
||||||
|
if (!data)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
BUG_ON(sb->s_type->fs_flags & FS_BINARY_MOUNTDATA);
|
||||||
|
|
||||||
|
rc = selinux_parse_opts_str(options, &opts);
|
||||||
|
if (rc)
|
||||||
|
goto out_err;
|
||||||
|
|
||||||
|
out:
|
||||||
|
rc = selinux_set_mnt_opts(sb, &opts);
|
||||||
|
|
||||||
|
out_err:
|
||||||
|
security_free_mnt_opts(&opts);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
static inline u16 inode_mode_to_security_class(umode_t mode)
|
static inline u16 inode_mode_to_security_class(umode_t mode)
|
||||||
{
|
{
|
||||||
@ -2253,7 +2270,7 @@ static inline void take_selinux_option(char **to, char *from, int *first,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int selinux_sb_copy_data(struct file_system_type *type, void *orig, void *copy)
|
static int selinux_sb_copy_data(char *orig, char *copy)
|
||||||
{
|
{
|
||||||
int fnosec, fsec, rc = 0;
|
int fnosec, fsec, rc = 0;
|
||||||
char *in_save, *in_curr, *in_end;
|
char *in_save, *in_curr, *in_end;
|
||||||
@ -2263,12 +2280,6 @@ static int selinux_sb_copy_data(struct file_system_type *type, void *orig, void
|
|||||||
in_curr = orig;
|
in_curr = orig;
|
||||||
sec_curr = copy;
|
sec_curr = copy;
|
||||||
|
|
||||||
/* Binary mount data: just copy */
|
|
||||||
if (type->fs_flags & FS_BINARY_MOUNTDATA) {
|
|
||||||
copy_page(sec_curr, in_curr);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
nosec = (char *)get_zeroed_page(GFP_KERNEL);
|
nosec = (char *)get_zeroed_page(GFP_KERNEL);
|
||||||
if (!nosec) {
|
if (!nosec) {
|
||||||
rc = -ENOMEM;
|
rc = -ENOMEM;
|
||||||
@ -5251,6 +5262,8 @@ static struct security_operations selinux_ops = {
|
|||||||
.sb_get_mnt_opts = selinux_get_mnt_opts,
|
.sb_get_mnt_opts = selinux_get_mnt_opts,
|
||||||
.sb_set_mnt_opts = selinux_set_mnt_opts,
|
.sb_set_mnt_opts = selinux_set_mnt_opts,
|
||||||
.sb_clone_mnt_opts = selinux_sb_clone_mnt_opts,
|
.sb_clone_mnt_opts = selinux_sb_clone_mnt_opts,
|
||||||
|
.sb_parse_opts_str = selinux_parse_opts_str,
|
||||||
|
|
||||||
|
|
||||||
.inode_alloc_security = selinux_inode_alloc_security,
|
.inode_alloc_security = selinux_inode_alloc_security,
|
||||||
.inode_free_security = selinux_inode_free_security,
|
.inode_free_security = selinux_inode_free_security,
|
||||||
|
@ -35,6 +35,11 @@
|
|||||||
#define POLICYDB_VERSION_MAX POLICYDB_VERSION_POLCAP
|
#define POLICYDB_VERSION_MAX POLICYDB_VERSION_POLCAP
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define CONTEXT_MNT 0x01
|
||||||
|
#define FSCONTEXT_MNT 0x02
|
||||||
|
#define ROOTCONTEXT_MNT 0x04
|
||||||
|
#define DEFCONTEXT_MNT 0x08
|
||||||
|
|
||||||
struct netlbl_lsm_secattr;
|
struct netlbl_lsm_secattr;
|
||||||
|
|
||||||
extern int selinux_enabled;
|
extern int selinux_enabled;
|
||||||
|
@ -189,17 +189,10 @@ static void smack_sb_free_security(struct super_block *sb)
|
|||||||
* Copy the Smack specific mount options out of the mount
|
* Copy the Smack specific mount options out of the mount
|
||||||
* options list.
|
* options list.
|
||||||
*/
|
*/
|
||||||
static int smack_sb_copy_data(struct file_system_type *type, void *orig,
|
static int smack_sb_copy_data(char *orig, char *smackopts)
|
||||||
void *smackopts)
|
|
||||||
{
|
{
|
||||||
char *cp, *commap, *otheropts, *dp;
|
char *cp, *commap, *otheropts, *dp;
|
||||||
|
|
||||||
/* Binary mount data: just copy */
|
|
||||||
if (type->fs_flags & FS_BINARY_MOUNTDATA) {
|
|
||||||
copy_page(smackopts, orig);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
otheropts = (char *)get_zeroed_page(GFP_KERNEL);
|
otheropts = (char *)get_zeroed_page(GFP_KERNEL);
|
||||||
if (otheropts == NULL)
|
if (otheropts == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
Loading…
Reference in New Issue
Block a user