Skip to content

Commit c9180a5

Browse files
eparisJames Morris
authored andcommitted
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: Eric Paris <[email protected]> Acked-by: Stephen D. Smalley <[email protected]> Signed-off-by: James Morris <[email protected]>
1 parent 19c5fc1 commit c9180a5

File tree

5 files changed

+577
-254
lines changed

5 files changed

+577
-254
lines changed

include/linux/security.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@
3434
#include <linux/xfrm.h>
3535
#include <net/flow.h>
3636

37+
/* only a char in selinux superblock security struct flags */
38+
#define FSCONTEXT_MNT 0x01
39+
#define CONTEXT_MNT 0x02
40+
#define ROOTCONTEXT_MNT 0x04
41+
#define DEFCONTEXT_MNT 0x08
42+
3743
/*
3844
* Bounding set
3945
*/
@@ -261,6 +267,22 @@ struct request_sock;
261267
* Update module state after a successful pivot.
262268
* @old_nd contains the nameidata structure for the old root.
263269
* @new_nd contains the nameidata structure for the new root.
270+
* @sb_get_mnt_opts:
271+
* Get the security relevant mount options used for a superblock
272+
* @sb the superblock to get security mount options from
273+
* @mount_options array for pointers to mount options
274+
* @mount_flags array of ints specifying what each mount options is
275+
* @num_opts number of options in the arrays
276+
* @sb_set_mnt_opts:
277+
* Set the security relevant mount options used for a superblock
278+
* @sb the superblock to set security mount options for
279+
* @mount_options array for pointers to mount options
280+
* @mount_flags array of ints specifying what each mount options is
281+
* @num_opts number of options in the arrays
282+
* @sb_clone_mnt_opts:
283+
* Copy all security options from a given superblock to another
284+
* @oldsb old superblock which contain information to clone
285+
* @newsb new superblock which needs filled in
264286
*
265287
* Security hooks for inode operations.
266288
*
@@ -1242,6 +1264,13 @@ struct security_operations {
12421264
struct nameidata * new_nd);
12431265
void (*sb_post_pivotroot) (struct nameidata * old_nd,
12441266
struct nameidata * new_nd);
1267+
int (*sb_get_mnt_opts) (const struct super_block *sb,
1268+
char ***mount_options, int **flags,
1269+
int *num_opts);
1270+
int (*sb_set_mnt_opts) (struct super_block *sb, char **mount_options,
1271+
int *flags, int num_opts);
1272+
void (*sb_clone_mnt_opts) (const struct super_block *oldsb,
1273+
struct super_block *newsb);
12451274

12461275
int (*inode_alloc_security) (struct inode *inode);
12471276
void (*inode_free_security) (struct inode *inode);
@@ -1499,6 +1528,13 @@ void security_sb_post_mountroot(void);
14991528
void security_sb_post_addmount(struct vfsmount *mnt, struct nameidata *mountpoint_nd);
15001529
int security_sb_pivotroot(struct nameidata *old_nd, struct nameidata *new_nd);
15011530
void security_sb_post_pivotroot(struct nameidata *old_nd, struct nameidata *new_nd);
1531+
int security_sb_get_mnt_opts(const struct super_block *sb, char ***mount_options,
1532+
int **flags, int *num_opts);
1533+
int security_sb_set_mnt_opts(struct super_block *sb, char **mount_options,
1534+
int *flags, int num_opts);
1535+
void security_sb_clone_mnt_opts(const struct super_block *oldsb,
1536+
struct super_block *newsb);
1537+
15021538
int security_inode_alloc(struct inode *inode);
15031539
void security_inode_free(struct inode *inode);
15041540
int security_inode_init_security(struct inode *inode, struct inode *dir,

security/dummy.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,29 @@ static void dummy_sb_post_pivotroot (struct nameidata *old_nd, struct nameidata
245245
return;
246246
}
247247

248+
static int dummy_sb_get_mnt_opts(const struct super_block *sb, char ***mount_options,
249+
int **flags, int *num_opts)
250+
{
251+
*mount_options = NULL;
252+
*flags = NULL;
253+
*num_opts = 0;
254+
return 0;
255+
}
256+
257+
static int dummy_sb_set_mnt_opts(struct super_block *sb, char **mount_options,
258+
int *flags, int num_opts)
259+
{
260+
if (unlikely(num_opts))
261+
return -EOPNOTSUPP;
262+
return 0;
263+
}
264+
265+
static void dummy_sb_clone_mnt_opts(const struct super_block *oldsb,
266+
struct super_block *newsb)
267+
{
268+
return;
269+
}
270+
248271
static int dummy_inode_alloc_security (struct inode *inode)
249272
{
250273
return 0;
@@ -998,6 +1021,9 @@ void security_fixup_ops (struct security_operations *ops)
9981021
set_to_dummy_if_null(ops, sb_post_addmount);
9991022
set_to_dummy_if_null(ops, sb_pivotroot);
10001023
set_to_dummy_if_null(ops, sb_post_pivotroot);
1024+
set_to_dummy_if_null(ops, sb_get_mnt_opts);
1025+
set_to_dummy_if_null(ops, sb_set_mnt_opts);
1026+
set_to_dummy_if_null(ops, sb_clone_mnt_opts);
10011027
set_to_dummy_if_null(ops, inode_alloc_security);
10021028
set_to_dummy_if_null(ops, inode_free_security);
10031029
set_to_dummy_if_null(ops, inode_init_security);

security/security.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,26 @@ void security_sb_post_pivotroot(struct nameidata *old_nd, struct nameidata *new_
308308
security_ops->sb_post_pivotroot(old_nd, new_nd);
309309
}
310310

311+
int security_sb_get_mnt_opts(const struct super_block *sb,
312+
char ***mount_options,
313+
int **flags, int *num_opts)
314+
{
315+
return security_ops->sb_get_mnt_opts(sb, mount_options, flags, num_opts);
316+
}
317+
318+
int security_sb_set_mnt_opts(struct super_block *sb,
319+
char **mount_options,
320+
int *flags, int num_opts)
321+
{
322+
return security_ops->sb_set_mnt_opts(sb, mount_options, flags, num_opts);
323+
}
324+
325+
void security_sb_clone_mnt_opts(const struct super_block *oldsb,
326+
struct super_block *newsb)
327+
{
328+
security_ops->sb_clone_mnt_opts(oldsb, newsb);
329+
}
330+
311331
int security_inode_alloc(struct inode *inode)
312332
{
313333
inode->i_security = NULL;

0 commit comments

Comments
 (0)