diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-12-15 14:17:45 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-12-15 14:17:45 -0500 |
commit | 29b1deb2a48a9dd02b93597aa4c055a24c0e989f (patch) | |
tree | 7e179afa1380b31646512aa5cf025e7b162c4885 /security | |
parent | 0925f2cdf9d11fb24130d00d6bbea84502610535 (diff) |
Revert "selinux: consider filesystem subtype in policies"
This reverts commit 102aefdda4d8275ce7d7100bc16c88c74272b260.
Tom London reports that it causes sync() to hang on Fedora rawhide:
https://bugzilla.redhat.com/show_bug.cgi?id=1033965
and Josh Boyer bisected it down to this commit. Reverting the commit in
the rawhide kernel fixes the problem.
Eric Paris root-caused it to incorrect subtype matching in that commit
breaking fuse, and has a tentative patch, but by now we're better off
retrying this in 3.14 rather than playing with it any more.
Reported-by: Tom London <selinux@gmail.com>
Bisected-by: Josh Boyer <jwboyer@fedoraproject.org>
Acked-by: Eric Paris <eparis@redhat.com>
Cc: James Morris <jmorris@namei.org>
Cc: Anand Avati <avati@redhat.com>
Cc: Paul Moore <paul@paul-moore.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'security')
-rw-r--r-- | security/selinux/hooks.c | 40 | ||||
-rw-r--r-- | security/selinux/ss/services.c | 42 |
2 files changed, 22 insertions, 60 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 794c3ca49eac..98b1caa1c1d3 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -95,10 +95,6 @@ | |||
95 | #include "audit.h" | 95 | #include "audit.h" |
96 | #include "avc_ss.h" | 96 | #include "avc_ss.h" |
97 | 97 | ||
98 | #define SB_TYPE_FMT "%s%s%s" | ||
99 | #define SB_SUBTYPE(sb) (sb->s_subtype && sb->s_subtype[0]) | ||
100 | #define SB_TYPE_ARGS(sb) sb->s_type->name, SB_SUBTYPE(sb) ? "." : "", SB_SUBTYPE(sb) ? sb->s_subtype : "" | ||
101 | |||
102 | extern struct security_operations *security_ops; | 98 | extern struct security_operations *security_ops; |
103 | 99 | ||
104 | /* SECMARK reference count */ | 100 | /* SECMARK reference count */ |
@@ -413,8 +409,8 @@ static int sb_finish_set_opts(struct super_block *sb) | |||
413 | the first boot of the SELinux kernel before we have | 409 | the first boot of the SELinux kernel before we have |
414 | assigned xattr values to the filesystem. */ | 410 | assigned xattr values to the filesystem. */ |
415 | if (!root_inode->i_op->getxattr) { | 411 | if (!root_inode->i_op->getxattr) { |
416 | printk(KERN_WARNING "SELinux: (dev %s, type "SB_TYPE_FMT") has no " | 412 | printk(KERN_WARNING "SELinux: (dev %s, type %s) has no " |
417 | "xattr support\n", sb->s_id, SB_TYPE_ARGS(sb)); | 413 | "xattr support\n", sb->s_id, sb->s_type->name); |
418 | rc = -EOPNOTSUPP; | 414 | rc = -EOPNOTSUPP; |
419 | goto out; | 415 | goto out; |
420 | } | 416 | } |
@@ -422,22 +418,22 @@ static int sb_finish_set_opts(struct super_block *sb) | |||
422 | if (rc < 0 && rc != -ENODATA) { | 418 | if (rc < 0 && rc != -ENODATA) { |
423 | if (rc == -EOPNOTSUPP) | 419 | if (rc == -EOPNOTSUPP) |
424 | printk(KERN_WARNING "SELinux: (dev %s, type " | 420 | printk(KERN_WARNING "SELinux: (dev %s, type " |
425 | SB_TYPE_FMT") has no security xattr handler\n", | 421 | "%s) has no security xattr handler\n", |
426 | sb->s_id, SB_TYPE_ARGS(sb)); | 422 | sb->s_id, sb->s_type->name); |
427 | else | 423 | else |
428 | printk(KERN_WARNING "SELinux: (dev %s, type " | 424 | printk(KERN_WARNING "SELinux: (dev %s, type " |
429 | SB_TYPE_FMT") getxattr errno %d\n", sb->s_id, | 425 | "%s) getxattr errno %d\n", sb->s_id, |
430 | SB_TYPE_ARGS(sb), -rc); | 426 | sb->s_type->name, -rc); |
431 | goto out; | 427 | goto out; |
432 | } | 428 | } |
433 | } | 429 | } |
434 | 430 | ||
435 | if (sbsec->behavior > ARRAY_SIZE(labeling_behaviors)) | 431 | if (sbsec->behavior > ARRAY_SIZE(labeling_behaviors)) |
436 | printk(KERN_ERR "SELinux: initialized (dev %s, type "SB_TYPE_FMT"), unknown behavior\n", | 432 | printk(KERN_ERR "SELinux: initialized (dev %s, type %s), unknown behavior\n", |
437 | sb->s_id, SB_TYPE_ARGS(sb)); | 433 | sb->s_id, sb->s_type->name); |
438 | else | 434 | else |
439 | printk(KERN_DEBUG "SELinux: initialized (dev %s, type "SB_TYPE_FMT"), %s\n", | 435 | printk(KERN_DEBUG "SELinux: initialized (dev %s, type %s), %s\n", |
440 | sb->s_id, SB_TYPE_ARGS(sb), | 436 | sb->s_id, sb->s_type->name, |
441 | labeling_behaviors[sbsec->behavior-1]); | 437 | labeling_behaviors[sbsec->behavior-1]); |
442 | 438 | ||
443 | sbsec->flags |= SE_SBINITIALIZED; | 439 | sbsec->flags |= SE_SBINITIALIZED; |
@@ -600,6 +596,7 @@ static int selinux_set_mnt_opts(struct super_block *sb, | |||
600 | const struct cred *cred = current_cred(); | 596 | const struct cred *cred = current_cred(); |
601 | int rc = 0, i; | 597 | int rc = 0, i; |
602 | struct superblock_security_struct *sbsec = sb->s_security; | 598 | struct superblock_security_struct *sbsec = sb->s_security; |
599 | const char *name = sb->s_type->name; | ||
603 | struct inode *inode = sbsec->sb->s_root->d_inode; | 600 | struct inode *inode = sbsec->sb->s_root->d_inode; |
604 | struct inode_security_struct *root_isec = inode->i_security; | 601 | struct inode_security_struct *root_isec = inode->i_security; |
605 | u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0; | 602 | u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0; |
@@ -658,8 +655,8 @@ static int selinux_set_mnt_opts(struct super_block *sb, | |||
658 | strlen(mount_options[i]), &sid); | 655 | strlen(mount_options[i]), &sid); |
659 | if (rc) { | 656 | if (rc) { |
660 | printk(KERN_WARNING "SELinux: security_context_to_sid" | 657 | printk(KERN_WARNING "SELinux: security_context_to_sid" |
661 | "(%s) failed for (dev %s, type "SB_TYPE_FMT") errno=%d\n", | 658 | "(%s) failed for (dev %s, type %s) errno=%d\n", |
662 | mount_options[i], sb->s_id, SB_TYPE_ARGS(sb), rc); | 659 | mount_options[i], sb->s_id, name, rc); |
663 | goto out; | 660 | goto out; |
664 | } | 661 | } |
665 | switch (flags[i]) { | 662 | switch (flags[i]) { |
@@ -806,8 +803,7 @@ out: | |||
806 | out_double_mount: | 803 | out_double_mount: |
807 | rc = -EINVAL; | 804 | rc = -EINVAL; |
808 | printk(KERN_WARNING "SELinux: mount invalid. Same superblock, different " | 805 | printk(KERN_WARNING "SELinux: mount invalid. Same superblock, different " |
809 | "security settings for (dev %s, type "SB_TYPE_FMT")\n", sb->s_id, | 806 | "security settings for (dev %s, type %s)\n", sb->s_id, name); |
810 | SB_TYPE_ARGS(sb)); | ||
811 | goto out; | 807 | goto out; |
812 | } | 808 | } |
813 | 809 | ||
@@ -2480,8 +2476,8 @@ static int selinux_sb_remount(struct super_block *sb, void *data) | |||
2480 | rc = security_context_to_sid(mount_options[i], len, &sid); | 2476 | rc = security_context_to_sid(mount_options[i], len, &sid); |
2481 | if (rc) { | 2477 | if (rc) { |
2482 | printk(KERN_WARNING "SELinux: security_context_to_sid" | 2478 | printk(KERN_WARNING "SELinux: security_context_to_sid" |
2483 | "(%s) failed for (dev %s, type "SB_TYPE_FMT") errno=%d\n", | 2479 | "(%s) failed for (dev %s, type %s) errno=%d\n", |
2484 | mount_options[i], sb->s_id, SB_TYPE_ARGS(sb), rc); | 2480 | mount_options[i], sb->s_id, sb->s_type->name, rc); |
2485 | goto out_free_opts; | 2481 | goto out_free_opts; |
2486 | } | 2482 | } |
2487 | rc = -EINVAL; | 2483 | rc = -EINVAL; |
@@ -2519,8 +2515,8 @@ out_free_secdata: | |||
2519 | return rc; | 2515 | return rc; |
2520 | out_bad_option: | 2516 | out_bad_option: |
2521 | printk(KERN_WARNING "SELinux: unable to change security options " | 2517 | printk(KERN_WARNING "SELinux: unable to change security options " |
2522 | "during remount (dev %s, type "SB_TYPE_FMT")\n", sb->s_id, | 2518 | "during remount (dev %s, type=%s)\n", sb->s_id, |
2523 | SB_TYPE_ARGS(sb)); | 2519 | sb->s_type->name); |
2524 | goto out_free_opts; | 2520 | goto out_free_opts; |
2525 | } | 2521 | } |
2526 | 2522 | ||
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index ee470a0b5c27..d106733ad987 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c | |||
@@ -2334,50 +2334,16 @@ int security_fs_use(struct super_block *sb) | |||
2334 | struct ocontext *c; | 2334 | struct ocontext *c; |
2335 | struct superblock_security_struct *sbsec = sb->s_security; | 2335 | struct superblock_security_struct *sbsec = sb->s_security; |
2336 | const char *fstype = sb->s_type->name; | 2336 | 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; | ||
2339 | 2337 | ||
2340 | read_lock(&policy_rwlock); | 2338 | read_lock(&policy_rwlock); |
2341 | 2339 | ||
2342 | for (c = policydb.ocontexts[OCON_FSUSE]; c; c = c->next) { | 2340 | c = policydb.ocontexts[OCON_FSUSE]; |
2343 | char *sub; | 2341 | while (c) { |
2344 | int baselen; | 2342 | if (strcmp(fstype, c->u.name) == 0) |
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)) | ||
2374 | break; | 2343 | break; |
2344 | c = c->next; | ||
2375 | } | 2345 | } |
2376 | 2346 | ||
2377 | /* in case we had found an fstype match but no subtype match */ | ||
2378 | if (!c) | ||
2379 | c = base; | ||
2380 | |||
2381 | if (c) { | 2347 | if (c) { |
2382 | sbsec->behavior = c->v.behavior; | 2348 | sbsec->behavior = c->v.behavior; |
2383 | if (!c->sid[0]) { | 2349 | if (!c->sid[0]) { |