diff options
| -rw-r--r-- | security/selinux/hooks.c | 40 | ||||
| -rw-r--r-- | security/selinux/ss/services.c | 42 |
2 files changed, 60 insertions, 22 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 4fbf2c5f26ce..0d4408debb45 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
| @@ -94,6 +94,10 @@ | |||
| 94 | #include "audit.h" | 94 | #include "audit.h" |
| 95 | #include "avc_ss.h" | 95 | #include "avc_ss.h" |
| 96 | 96 | ||
| 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 | |||
| 97 | extern struct security_operations *security_ops; | 101 | extern struct security_operations *security_ops; |
| 98 | 102 | ||
| 99 | /* SECMARK reference count */ | 103 | /* SECMARK reference count */ |
| @@ -407,8 +411,8 @@ static int sb_finish_set_opts(struct super_block *sb) | |||
| 407 | the first boot of the SELinux kernel before we have | 411 | the first boot of the SELinux kernel before we have |
| 408 | assigned xattr values to the filesystem. */ | 412 | assigned xattr values to the filesystem. */ |
| 409 | if (!root_inode->i_op->getxattr) { | 413 | if (!root_inode->i_op->getxattr) { |
| 410 | printk(KERN_WARNING "SELinux: (dev %s, type %s) has no " | 414 | printk(KERN_WARNING "SELinux: (dev %s, type "SB_TYPE_FMT") has no " |
| 411 | "xattr support\n", sb->s_id, sb->s_type->name); | 415 | "xattr support\n", sb->s_id, SB_TYPE_ARGS(sb)); |
| 412 | rc = -EOPNOTSUPP; | 416 | rc = -EOPNOTSUPP; |
| 413 | goto out; | 417 | goto out; |
| 414 | } | 418 | } |
| @@ -416,22 +420,22 @@ static int sb_finish_set_opts(struct super_block *sb) | |||
| 416 | if (rc < 0 && rc != -ENODATA) { | 420 | if (rc < 0 && rc != -ENODATA) { |
| 417 | if (rc == -EOPNOTSUPP) | 421 | if (rc == -EOPNOTSUPP) |
| 418 | printk(KERN_WARNING "SELinux: (dev %s, type " | 422 | printk(KERN_WARNING "SELinux: (dev %s, type " |
| 419 | "%s) has no security xattr handler\n", | 423 | SB_TYPE_FMT") has no security xattr handler\n", |
| 420 | sb->s_id, sb->s_type->name); | 424 | sb->s_id, SB_TYPE_ARGS(sb)); |
| 421 | else | 425 | else |
| 422 | printk(KERN_WARNING "SELinux: (dev %s, type " | 426 | printk(KERN_WARNING "SELinux: (dev %s, type " |
| 423 | "%s) getxattr errno %d\n", sb->s_id, | 427 | SB_TYPE_FMT") getxattr errno %d\n", sb->s_id, |
| 424 | sb->s_type->name, -rc); | 428 | SB_TYPE_ARGS(sb), -rc); |
| 425 | goto out; | 429 | goto out; |
| 426 | } | 430 | } |
| 427 | } | 431 | } |
| 428 | 432 | ||
| 429 | if (sbsec->behavior > ARRAY_SIZE(labeling_behaviors)) | 433 | if (sbsec->behavior > ARRAY_SIZE(labeling_behaviors)) |
| 430 | printk(KERN_ERR "SELinux: initialized (dev %s, type %s), unknown behavior\n", | 434 | printk(KERN_ERR "SELinux: initialized (dev %s, type "SB_TYPE_FMT"), unknown behavior\n", |
| 431 | sb->s_id, sb->s_type->name); | 435 | sb->s_id, SB_TYPE_ARGS(sb)); |
| 432 | else | 436 | else |
| 433 | printk(KERN_DEBUG "SELinux: initialized (dev %s, type %s), %s\n", | 437 | printk(KERN_DEBUG "SELinux: initialized (dev %s, type "SB_TYPE_FMT"), %s\n", |
| 434 | sb->s_id, sb->s_type->name, | 438 | sb->s_id, SB_TYPE_ARGS(sb), |
| 435 | labeling_behaviors[sbsec->behavior-1]); | 439 | labeling_behaviors[sbsec->behavior-1]); |
| 436 | 440 | ||
| 437 | sbsec->flags |= SE_SBINITIALIZED; | 441 | sbsec->flags |= SE_SBINITIALIZED; |
| @@ -589,7 +593,6 @@ static int selinux_set_mnt_opts(struct super_block *sb, | |||
| 589 | const struct cred *cred = current_cred(); | 593 | const struct cred *cred = current_cred(); |
| 590 | int rc = 0, i; | 594 | int rc = 0, i; |
| 591 | struct superblock_security_struct *sbsec = sb->s_security; | 595 | struct superblock_security_struct *sbsec = sb->s_security; |
| 592 | const char *name = sb->s_type->name; | ||
| 593 | struct inode *inode = sbsec->sb->s_root->d_inode; | 596 | struct inode *inode = sbsec->sb->s_root->d_inode; |
| 594 | struct inode_security_struct *root_isec = inode->i_security; | 597 | struct inode_security_struct *root_isec = inode->i_security; |
| 595 | u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0; | 598 | u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0; |
| @@ -642,8 +645,8 @@ static int selinux_set_mnt_opts(struct super_block *sb, | |||
| 642 | strlen(mount_options[i]), &sid); | 645 | strlen(mount_options[i]), &sid); |
| 643 | if (rc) { | 646 | if (rc) { |
| 644 | printk(KERN_WARNING "SELinux: security_context_to_sid" | 647 | printk(KERN_WARNING "SELinux: security_context_to_sid" |
| 645 | "(%s) failed for (dev %s, type %s) errno=%d\n", | 648 | "(%s) failed for (dev %s, type "SB_TYPE_FMT") errno=%d\n", |
| 646 | mount_options[i], sb->s_id, name, rc); | 649 | mount_options[i], sb->s_id, SB_TYPE_ARGS(sb), rc); |
| 647 | goto out; | 650 | goto out; |
| 648 | } | 651 | } |
| 649 | switch (flags[i]) { | 652 | switch (flags[i]) { |
| @@ -779,7 +782,8 @@ out: | |||
| 779 | out_double_mount: | 782 | out_double_mount: |
| 780 | rc = -EINVAL; | 783 | rc = -EINVAL; |
| 781 | printk(KERN_WARNING "SELinux: mount invalid. Same superblock, different " | 784 | 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)); | ||
| 783 | goto out; | 787 | goto out; |
| 784 | } | 788 | } |
| 785 | 789 | ||
| @@ -2439,8 +2443,8 @@ static int selinux_sb_remount(struct super_block *sb, void *data) | |||
| 2439 | rc = security_context_to_sid(mount_options[i], len, &sid); | 2443 | rc = security_context_to_sid(mount_options[i], len, &sid); |
| 2440 | if (rc) { | 2444 | if (rc) { |
| 2441 | printk(KERN_WARNING "SELinux: security_context_to_sid" | 2445 | printk(KERN_WARNING "SELinux: security_context_to_sid" |
| 2442 | "(%s) failed for (dev %s, type %s) errno=%d\n", | 2446 | "(%s) failed for (dev %s, type "SB_TYPE_FMT") errno=%d\n", |
| 2443 | mount_options[i], sb->s_id, sb->s_type->name, rc); | 2447 | mount_options[i], sb->s_id, SB_TYPE_ARGS(sb), rc); |
| 2444 | goto out_free_opts; | 2448 | goto out_free_opts; |
| 2445 | } | 2449 | } |
| 2446 | rc = -EINVAL; | 2450 | rc = -EINVAL; |
| @@ -2478,8 +2482,8 @@ out_free_secdata: | |||
| 2478 | return rc; | 2482 | return rc; |
| 2479 | out_bad_option: | 2483 | out_bad_option: |
| 2480 | printk(KERN_WARNING "SELinux: unable to change security options " | 2484 | printk(KERN_WARNING "SELinux: unable to change security options " |
| 2481 | "during remount (dev %s, type=%s)\n", sb->s_id, | 2485 | "during remount (dev %s, type "SB_TYPE_FMT")\n", sb->s_id, |
| 2482 | sb->s_type->name); | 2486 | SB_TYPE_ARGS(sb)); |
| 2483 | goto out_free_opts; | 2487 | goto out_free_opts; |
| 2484 | } | 2488 | } |
| 2485 | 2489 | ||
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index d106733ad987..ee470a0b5c27 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c | |||
| @@ -2334,16 +2334,50 @@ 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; | ||
| 2337 | 2339 | ||
| 2338 | read_lock(&policy_rwlock); | 2340 | read_lock(&policy_rwlock); |
| 2339 | 2341 | ||
| 2340 | c = policydb.ocontexts[OCON_FSUSE]; | 2342 | for (c = policydb.ocontexts[OCON_FSUSE]; c; c = c->next) { |
| 2341 | while (c) { | 2343 | char *sub; |
| 2342 | if (strcmp(fstype, c->u.name) == 0) | 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)) | ||
| 2343 | break; | 2374 | break; |
| 2344 | c = c->next; | ||
| 2345 | } | 2375 | } |
| 2346 | 2376 | ||
| 2377 | /* in case we had found an fstype match but no subtype match */ | ||
| 2378 | if (!c) | ||
| 2379 | c = base; | ||
| 2380 | |||
| 2347 | if (c) { | 2381 | if (c) { |
| 2348 | sbsec->behavior = c->v.behavior; | 2382 | sbsec->behavior = c->v.behavior; |
| 2349 | if (!c->sid[0]) { | 2383 | if (!c->sid[0]) { |
