Commit c9180a57 authored by Eric Paris's avatar Eric Paris Committed by James Morris

Security: add get, set, and cloning of superblock security information

Adds security_get_sb_mnt_opts, security_set_sb_mnt_opts, and
security_clont_sb_mnt_opts to the LSM and to SELinux.  This will allow
filesystems to directly own and control all of their mount options if they
so choose.  This interface deals only with option identifiers and strings so
it should generic enough for any LSM which may come in the future.

Filesystems which pass text mount data around in the kernel (almost all of
them) need not currently make use of this interface when dealing with
SELinux since it will still parse those strings as it always has.  I assume
future LSM's would do the same.  NFS is the primary FS which does not use
text mount data and thus must make use of this interface.

An LSM would need to implement these functions only if they had mount time
options, such as selinux has context= or fscontext=.  If the LSM has no
mount time options they could simply not implement and let the dummy ops
take care of things.

An LSM other than SELinux would need to define new option numbers in
security.h and any FS which decides to own there own security options would
need to be patched to use this new interface for every possible LSM.  This
is because it was stated to me very clearly that LSM's should not attempt to
understand FS mount data and the burdon to understand security should be in
the FS which owns the options.
Signed-off-by: default avatarEric Paris <eparis@redhat.com>
Acked-by: default avatarStephen D. Smalley <sds@tycho.nsa.gov>
Signed-off-by: default avatarJames Morris <jmorris@namei.org>
parent 19c5fc19
...@@ -34,6 +34,12 @@ ...@@ -34,6 +34,12 @@
#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
/* /*
* Bounding set * Bounding set
*/ */
...@@ -261,6 +267,22 @@ struct request_sock; ...@@ -261,6 +267,22 @@ struct request_sock;
* Update module state after a successful pivot. * Update module state after a successful pivot.
* @old_nd contains the nameidata structure for the old root. * @old_nd contains the nameidata structure for the old root.
* @new_nd contains the nameidata structure for the new root. * @new_nd contains the nameidata structure for the new root.
* @sb_get_mnt_opts:
* Get the security relevant mount options used for a superblock
* @sb the superblock to get security mount options from
* @mount_options array for pointers to mount options
* @mount_flags array of ints specifying what each mount options is
* @num_opts number of options in the arrays
* @sb_set_mnt_opts:
* Set the security relevant mount options used for a superblock
* @sb the superblock to set security mount options for
* @mount_options array for pointers to mount options
* @mount_flags array of ints specifying what each mount options is
* @num_opts number of options in the arrays
* @sb_clone_mnt_opts:
* Copy all security options from a given superblock to another
* @oldsb old superblock which contain information to clone
* @newsb new superblock which needs filled in
* *
* Security hooks for inode operations. * Security hooks for inode operations.
* *
...@@ -1242,6 +1264,13 @@ struct security_operations { ...@@ -1242,6 +1264,13 @@ struct security_operations {
struct nameidata * new_nd); struct nameidata * new_nd);
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,
char ***mount_options, int **flags,
int *num_opts);
int (*sb_set_mnt_opts) (struct super_block *sb, char **mount_options,
int *flags, int num_opts);
void (*sb_clone_mnt_opts) (const struct super_block *oldsb,
struct super_block *newsb);
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);
...@@ -1499,6 +1528,13 @@ void security_sb_post_mountroot(void); ...@@ -1499,6 +1528,13 @@ void security_sb_post_mountroot(void);
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 **flags, int *num_opts);
int security_sb_set_mnt_opts(struct super_block *sb, char **mount_options,
int *flags, int num_opts);
void security_sb_clone_mnt_opts(const struct super_block *oldsb,
struct super_block *newsb);
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);
int security_inode_init_security(struct inode *inode, struct inode *dir, int security_inode_init_security(struct inode *inode, struct inode *dir,
......
...@@ -245,6 +245,29 @@ static void dummy_sb_post_pivotroot (struct nameidata *old_nd, struct nameidata ...@@ -245,6 +245,29 @@ 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,
int **flags, int *num_opts)
{
*mount_options = NULL;
*flags = NULL;
*num_opts = 0;
return 0;
}
static int dummy_sb_set_mnt_opts(struct super_block *sb, char **mount_options,
int *flags, int num_opts)
{
if (unlikely(num_opts))
return -EOPNOTSUPP;
return 0;
}
static void dummy_sb_clone_mnt_opts(const struct super_block *oldsb,
struct super_block *newsb)
{
return;
}
static int dummy_inode_alloc_security (struct inode *inode) static int dummy_inode_alloc_security (struct inode *inode)
{ {
return 0; return 0;
...@@ -998,6 +1021,9 @@ void security_fixup_ops (struct security_operations *ops) ...@@ -998,6 +1021,9 @@ void security_fixup_ops (struct security_operations *ops)
set_to_dummy_if_null(ops, sb_post_addmount); set_to_dummy_if_null(ops, sb_post_addmount);
set_to_dummy_if_null(ops, sb_pivotroot); set_to_dummy_if_null(ops, sb_pivotroot);
set_to_dummy_if_null(ops, sb_post_pivotroot); set_to_dummy_if_null(ops, sb_post_pivotroot);
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_clone_mnt_opts);
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);
......
...@@ -308,6 +308,26 @@ void security_sb_post_pivotroot(struct nameidata *old_nd, struct nameidata *new_ ...@@ -308,6 +308,26 @@ void security_sb_post_pivotroot(struct nameidata *old_nd, struct nameidata *new_
security_ops->sb_post_pivotroot(old_nd, new_nd); security_ops->sb_post_pivotroot(old_nd, new_nd);
} }
int security_sb_get_mnt_opts(const struct super_block *sb,
char ***mount_options,
int **flags, int *num_opts)
{
return security_ops->sb_get_mnt_opts(sb, mount_options, flags, num_opts);
}
int security_sb_set_mnt_opts(struct super_block *sb,
char **mount_options,
int *flags, int num_opts)
{
return security_ops->sb_set_mnt_opts(sb, mount_options, flags, num_opts);
}
void security_sb_clone_mnt_opts(const struct super_block *oldsb,
struct super_block *newsb)
{
security_ops->sb_clone_mnt_opts(oldsb, newsb);
}
int security_inode_alloc(struct inode *inode) int security_inode_alloc(struct inode *inode)
{ {
inode->i_security = NULL; inode->i_security = NULL;
......
This diff is collapsed.
...@@ -65,6 +65,7 @@ struct superblock_security_struct { ...@@ -65,6 +65,7 @@ struct superblock_security_struct {
u32 mntpoint_sid; /* SECURITY_FS_USE_MNTPOINT context for files */ u32 mntpoint_sid; /* SECURITY_FS_USE_MNTPOINT context for files */
unsigned int behavior; /* labeling behavior */ unsigned int behavior; /* labeling behavior */
unsigned char initialized; /* initialization flag */ unsigned char initialized; /* initialization flag */
unsigned char flags; /* which mount options were specified */
unsigned char proc; /* proc fs */ unsigned char proc; /* proc fs */
struct mutex lock; struct mutex lock;
struct list_head isec_head; struct list_head isec_head;
......
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