aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Paris <eparis@parisplace.org>2006-07-10 07:43:53 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-07-10 16:24:13 -0400
commitc312feb2931ded0582378712727b7ea017a951bd (patch)
treedd985aa4dd0b759690af9557a5170dabf589d87f
parent2ed6e34f88a0d896a6f889b00693cae0fadacfd0 (diff)
[PATCH] SELinux: decouple fscontext/context mount options
Remove the conflict between fscontext and context mount options. If context= is specified without fscontext it will operate just as before, if both are specified we will use mount point labeling and all inodes will get the label specified by context=. The superblock will be labeled with the label of fscontext=, thus affecting operations which check the superblock security context, such as associate permissions. Signed-off-by: Eric Paris <eparis@parisplace.org> Acked-by: Stephen Smalley <sds@tycho.nsa.gov> Signed-off-by: James Morris <jmorris@namei.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--security/selinux/hooks.c69
-rw-r--r--security/selinux/include/objsec.h3
2 files changed, 56 insertions, 16 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 24caaeec8894..7e101dbea4cb 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -246,6 +246,7 @@ static int superblock_alloc_security(struct super_block *sb)
246 sbsec->sb = sb; 246 sbsec->sb = sb;
247 sbsec->sid = SECINITSID_UNLABELED; 247 sbsec->sid = SECINITSID_UNLABELED;
248 sbsec->def_sid = SECINITSID_FILE; 248 sbsec->def_sid = SECINITSID_FILE;
249 sbsec->mntpoint_sid = SECINITSID_UNLABELED;
249 sb->s_security = sbsec; 250 sb->s_security = sbsec;
250 251
251 return 0; 252 return 0;
@@ -329,9 +330,26 @@ static match_table_t tokens = {
329 330
330#define SEL_MOUNT_FAIL_MSG "SELinux: duplicate or incompatible mount options\n" 331#define SEL_MOUNT_FAIL_MSG "SELinux: duplicate or incompatible mount options\n"
331 332
333static int may_context_mount_sb_relabel(u32 sid,
334 struct superblock_security_struct *sbsec,
335 struct task_security_struct *tsec)
336{
337 int rc;
338
339 rc = avc_has_perm(tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,
340 FILESYSTEM__RELABELFROM, NULL);
341 if (rc)
342 return rc;
343
344 rc = avc_has_perm(tsec->sid, sid, SECCLASS_FILESYSTEM,
345 FILESYSTEM__RELABELTO, NULL);
346 return rc;
347}
348
332static int try_context_mount(struct super_block *sb, void *data) 349static int try_context_mount(struct super_block *sb, void *data)
333{ 350{
334 char *context = NULL, *defcontext = NULL; 351 char *context = NULL, *defcontext = NULL;
352 char *fscontext = NULL;
335 const char *name; 353 const char *name;
336 u32 sid; 354 u32 sid;
337 int alloc = 0, rc = 0, seen = 0; 355 int alloc = 0, rc = 0, seen = 0;
@@ -374,7 +392,7 @@ static int try_context_mount(struct super_block *sb, void *data)
374 392
375 switch (token) { 393 switch (token) {
376 case Opt_context: 394 case Opt_context:
377 if (seen) { 395 if (seen & (Opt_context|Opt_defcontext)) {
378 rc = -EINVAL; 396 rc = -EINVAL;
379 printk(KERN_WARNING SEL_MOUNT_FAIL_MSG); 397 printk(KERN_WARNING SEL_MOUNT_FAIL_MSG);
380 goto out_free; 398 goto out_free;
@@ -390,13 +408,13 @@ static int try_context_mount(struct super_block *sb, void *data)
390 break; 408 break;
391 409
392 case Opt_fscontext: 410 case Opt_fscontext:
393 if (seen & (Opt_context|Opt_fscontext)) { 411 if (seen & Opt_fscontext) {
394 rc = -EINVAL; 412 rc = -EINVAL;
395 printk(KERN_WARNING SEL_MOUNT_FAIL_MSG); 413 printk(KERN_WARNING SEL_MOUNT_FAIL_MSG);
396 goto out_free; 414 goto out_free;
397 } 415 }
398 context = match_strdup(&args[0]); 416 fscontext = match_strdup(&args[0]);
399 if (!context) { 417 if (!fscontext) {
400 rc = -ENOMEM; 418 rc = -ENOMEM;
401 goto out_free; 419 goto out_free;
402 } 420 }
@@ -441,29 +459,46 @@ static int try_context_mount(struct super_block *sb, void *data)
441 if (!seen) 459 if (!seen)
442 goto out; 460 goto out;
443 461
444 if (context) { 462 /* sets the context of the superblock for the fs being mounted. */
445 rc = security_context_to_sid(context, strlen(context), &sid); 463 if (fscontext) {
464 rc = security_context_to_sid(fscontext, strlen(fscontext), &sid);
446 if (rc) { 465 if (rc) {
447 printk(KERN_WARNING "SELinux: security_context_to_sid" 466 printk(KERN_WARNING "SELinux: security_context_to_sid"
448 "(%s) failed for (dev %s, type %s) errno=%d\n", 467 "(%s) failed for (dev %s, type %s) errno=%d\n",
449 context, sb->s_id, name, rc); 468 fscontext, sb->s_id, name, rc);
450 goto out_free; 469 goto out_free;
451 } 470 }
452 471
453 rc = avc_has_perm(tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM, 472 rc = may_context_mount_sb_relabel(sid, sbsec, tsec);
454 FILESYSTEM__RELABELFROM, NULL);
455 if (rc) 473 if (rc)
456 goto out_free; 474 goto out_free;
457 475
458 rc = avc_has_perm(tsec->sid, sid, SECCLASS_FILESYSTEM, 476 sbsec->sid = sid;
459 FILESYSTEM__RELABELTO, NULL); 477 }
478
479 /*
480 * Switch to using mount point labeling behavior.
481 * sets the label used on all file below the mountpoint, and will set
482 * the superblock context if not already set.
483 */
484 if (context) {
485 rc = security_context_to_sid(context, strlen(context), &sid);
486 if (rc) {
487 printk(KERN_WARNING "SELinux: security_context_to_sid"
488 "(%s) failed for (dev %s, type %s) errno=%d\n",
489 context, sb->s_id, name, rc);
490 goto out_free;
491 }
492
493 rc = may_context_mount_sb_relabel(sid, sbsec, tsec);
460 if (rc) 494 if (rc)
461 goto out_free; 495 goto out_free;
462 496
463 sbsec->sid = sid; 497 if (!fscontext)
498 sbsec->sid = sid;
499 sbsec->mntpoint_sid = sid;
464 500
465 if (seen & Opt_context) 501 sbsec->behavior = SECURITY_FS_USE_MNTPOINT;
466 sbsec->behavior = SECURITY_FS_USE_MNTPOINT;
467 } 502 }
468 503
469 if (defcontext) { 504 if (defcontext) {
@@ -495,6 +530,7 @@ out_free:
495 if (alloc) { 530 if (alloc) {
496 kfree(context); 531 kfree(context);
497 kfree(defcontext); 532 kfree(defcontext);
533 kfree(fscontext);
498 } 534 }
499out: 535out:
500 return rc; 536 return rc;
@@ -876,8 +912,11 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
876 goto out; 912 goto out;
877 isec->sid = sid; 913 isec->sid = sid;
878 break; 914 break;
915 case SECURITY_FS_USE_MNTPOINT:
916 isec->sid = sbsec->mntpoint_sid;
917 break;
879 default: 918 default:
880 /* Default to the fs SID. */ 919 /* Default to the fs superblock SID. */
881 isec->sid = sbsec->sid; 920 isec->sid = sbsec->sid;
882 921
883 if (sbsec->proc) { 922 if (sbsec->proc) {
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h
index cf54a304169a..940178865fc7 100644
--- a/security/selinux/include/objsec.h
+++ b/security/selinux/include/objsec.h
@@ -57,8 +57,9 @@ struct file_security_struct {
57struct superblock_security_struct { 57struct superblock_security_struct {
58 struct super_block *sb; /* back pointer to sb object */ 58 struct super_block *sb; /* back pointer to sb object */
59 struct list_head list; /* list of superblock_security_struct */ 59 struct list_head list; /* list of superblock_security_struct */
60 u32 sid; /* SID of file system */ 60 u32 sid; /* SID of file system superblock */
61 u32 def_sid; /* default SID for labeling */ 61 u32 def_sid; /* default SID for labeling */
62 u32 mntpoint_sid; /* SECURITY_FS_USE_MNTPOINT context for files */
62 unsigned int behavior; /* labeling behavior */ 63 unsigned int behavior; /* labeling behavior */
63 unsigned char initialized; /* initialization flag */ 64 unsigned char initialized; /* initialization flag */
64 unsigned char proc; /* proc fs */ 65 unsigned char proc; /* proc fs */