Skip to content

Commit 102aefd

Browse files
avatieparis
authored andcommitted
selinux: consider filesystem subtype in policies
Not considering sub filesystem has the following limitation. Support for SELinux in FUSE is dependent on the particular userspace filesystem, which is identified by the subtype. For e.g, GlusterFS, a FUSE based filesystem supports SELinux (by mounting and processing FUSE requests in different threads, avoiding the mount time deadlock), whereas other FUSE based filesystems (identified by a different subtype) have the mount time deadlock. By considering the subtype of the filesytem in the SELinux policies, allows us to specify a filesystem subtype, in the following way: fs_use_xattr fuse.glusterfs gen_context(system_u:object_r:fs_t,s0); This way not all FUSE filesystems are put in the same bucket and subjected to the limitations of the other subtypes. Signed-off-by: Anand Avati <[email protected]> Signed-off-by: Eric Paris <[email protected]>
1 parent 2be4d74 commit 102aefd

File tree

2 files changed

+60
-22
lines changed

2 files changed

+60
-22
lines changed

security/selinux/hooks.c

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,10 @@
9494
#include "audit.h"
9595
#include "avc_ss.h"
9696

97+
#define SB_TYPE_FMT "%s%s%s"
98+
#define SB_SUBTYPE(sb) (sb->s_subtype && sb->s_subtype[0])
99+
#define SB_TYPE_ARGS(sb) sb->s_type->name, SB_SUBTYPE(sb) ? "." : "", SB_SUBTYPE(sb) ? sb->s_subtype : ""
100+
97101
extern struct security_operations *security_ops;
98102

99103
/* SECMARK reference count */
@@ -407,31 +411,31 @@ static int sb_finish_set_opts(struct super_block *sb)
407411
the first boot of the SELinux kernel before we have
408412
assigned xattr values to the filesystem. */
409413
if (!root_inode->i_op->getxattr) {
410-
printk(KERN_WARNING "SELinux: (dev %s, type %s) has no "
411-
"xattr support\n", sb->s_id, sb->s_type->name);
414+
printk(KERN_WARNING "SELinux: (dev %s, type "SB_TYPE_FMT") has no "
415+
"xattr support\n", sb->s_id, SB_TYPE_ARGS(sb));
412416
rc = -EOPNOTSUPP;
413417
goto out;
414418
}
415419
rc = root_inode->i_op->getxattr(root, XATTR_NAME_SELINUX, NULL, 0);
416420
if (rc < 0 && rc != -ENODATA) {
417421
if (rc == -EOPNOTSUPP)
418422
printk(KERN_WARNING "SELinux: (dev %s, type "
419-
"%s) has no security xattr handler\n",
420-
sb->s_id, sb->s_type->name);
423+
SB_TYPE_FMT") has no security xattr handler\n",
424+
sb->s_id, SB_TYPE_ARGS(sb));
421425
else
422426
printk(KERN_WARNING "SELinux: (dev %s, type "
423-
"%s) getxattr errno %d\n", sb->s_id,
424-
sb->s_type->name, -rc);
427+
SB_TYPE_FMT") getxattr errno %d\n", sb->s_id,
428+
SB_TYPE_ARGS(sb), -rc);
425429
goto out;
426430
}
427431
}
428432

429433
if (sbsec->behavior > ARRAY_SIZE(labeling_behaviors))
430-
printk(KERN_ERR "SELinux: initialized (dev %s, type %s), unknown behavior\n",
431-
sb->s_id, sb->s_type->name);
434+
printk(KERN_ERR "SELinux: initialized (dev %s, type "SB_TYPE_FMT"), unknown behavior\n",
435+
sb->s_id, SB_TYPE_ARGS(sb));
432436
else
433-
printk(KERN_DEBUG "SELinux: initialized (dev %s, type %s), %s\n",
434-
sb->s_id, sb->s_type->name,
437+
printk(KERN_DEBUG "SELinux: initialized (dev %s, type "SB_TYPE_FMT"), %s\n",
438+
sb->s_id, SB_TYPE_ARGS(sb),
435439
labeling_behaviors[sbsec->behavior-1]);
436440

437441
sbsec->flags |= SE_SBINITIALIZED;
@@ -589,7 +593,6 @@ static int selinux_set_mnt_opts(struct super_block *sb,
589593
const struct cred *cred = current_cred();
590594
int rc = 0, i;
591595
struct superblock_security_struct *sbsec = sb->s_security;
592-
const char *name = sb->s_type->name;
593596
struct inode *inode = sbsec->sb->s_root->d_inode;
594597
struct inode_security_struct *root_isec = inode->i_security;
595598
u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0;
@@ -642,8 +645,8 @@ static int selinux_set_mnt_opts(struct super_block *sb,
642645
strlen(mount_options[i]), &sid);
643646
if (rc) {
644647
printk(KERN_WARNING "SELinux: security_context_to_sid"
645-
"(%s) failed for (dev %s, type %s) errno=%d\n",
646-
mount_options[i], sb->s_id, name, rc);
648+
"(%s) failed for (dev %s, type "SB_TYPE_FMT") errno=%d\n",
649+
mount_options[i], sb->s_id, SB_TYPE_ARGS(sb), rc);
647650
goto out;
648651
}
649652
switch (flags[i]) {
@@ -779,7 +782,8 @@ static int selinux_set_mnt_opts(struct super_block *sb,
779782
out_double_mount:
780783
rc = -EINVAL;
781784
printk(KERN_WARNING "SELinux: mount invalid. Same superblock, different "
782-
"security settings for (dev %s, type %s)\n", sb->s_id, name);
785+
"security settings for (dev %s, type "SB_TYPE_FMT")\n", sb->s_id,
786+
SB_TYPE_ARGS(sb));
783787
goto out;
784788
}
785789

@@ -2439,8 +2443,8 @@ static int selinux_sb_remount(struct super_block *sb, void *data)
24392443
rc = security_context_to_sid(mount_options[i], len, &sid);
24402444
if (rc) {
24412445
printk(KERN_WARNING "SELinux: security_context_to_sid"
2442-
"(%s) failed for (dev %s, type %s) errno=%d\n",
2443-
mount_options[i], sb->s_id, sb->s_type->name, rc);
2446+
"(%s) failed for (dev %s, type "SB_TYPE_FMT") errno=%d\n",
2447+
mount_options[i], sb->s_id, SB_TYPE_ARGS(sb), rc);
24442448
goto out_free_opts;
24452449
}
24462450
rc = -EINVAL;
@@ -2478,8 +2482,8 @@ static int selinux_sb_remount(struct super_block *sb, void *data)
24782482
return rc;
24792483
out_bad_option:
24802484
printk(KERN_WARNING "SELinux: unable to change security options "
2481-
"during remount (dev %s, type=%s)\n", sb->s_id,
2482-
sb->s_type->name);
2485+
"during remount (dev %s, type "SB_TYPE_FMT")\n", sb->s_id,
2486+
SB_TYPE_ARGS(sb));
24832487
goto out_free_opts;
24842488
}
24852489

security/selinux/ss/services.c

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2334,16 +2334,50 @@ int security_fs_use(struct super_block *sb)
23342334
struct ocontext *c;
23352335
struct superblock_security_struct *sbsec = sb->s_security;
23362336
const char *fstype = sb->s_type->name;
2337+
const char *subtype = (sb->s_subtype && sb->s_subtype[0]) ? sb->s_subtype : NULL;
2338+
struct ocontext *base = NULL;
23372339

23382340
read_lock(&policy_rwlock);
23392341

2340-
c = policydb.ocontexts[OCON_FSUSE];
2341-
while (c) {
2342-
if (strcmp(fstype, c->u.name) == 0)
2342+
for (c = policydb.ocontexts[OCON_FSUSE]; c; c = c->next) {
2343+
char *sub;
2344+
int baselen;
2345+
2346+
baselen = strlen(fstype);
2347+
2348+
/* if base does not match, this is not the one */
2349+
if (strncmp(fstype, c->u.name, baselen))
2350+
continue;
2351+
2352+
/* if there is no subtype, this is the one! */
2353+
if (!subtype)
2354+
break;
2355+
2356+
/* skip past the base in this entry */
2357+
sub = c->u.name + baselen;
2358+
2359+
/* entry is only a base. save it. keep looking for subtype */
2360+
if (sub[0] == '\0') {
2361+
base = c;
2362+
continue;
2363+
}
2364+
2365+
/* entry is not followed by a subtype, so it is not a match */
2366+
if (sub[0] != '.')
2367+
continue;
2368+
2369+
/* whew, we found a subtype of this fstype */
2370+
sub++; /* move past '.' */
2371+
2372+
/* exact match of fstype AND subtype */
2373+
if (!strcmp(subtype, sub))
23432374
break;
2344-
c = c->next;
23452375
}
23462376

2377+
/* in case we had found an fstype match but no subtype match */
2378+
if (!c)
2379+
c = base;
2380+
23472381
if (c) {
23482382
sbsec->behavior = c->v.behavior;
23492383
if (!c->sid[0]) {

0 commit comments

Comments
 (0)