Skip to contentSkip to conversation

2/2 rootcontext= option to label root inode when mounting

PATCH In review Eric Paris 2 participants 2 messages Jul 5, 2006 SELinux security module

lore
Share & tools
lore

Eric Paris

author
#0 lore raw

PATCH 1/1 2/2 rootcontext= option to label root inode when mounting

The second patch will introduce a new rootcontext= option to FS mounting. This option will allow you to explicitly label the root inode of a FS being mounted before that FS or inode because visable to userspace. This was found to be useful for things like stateless linux, see https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=190001

This should address all of the concerns with the original patch.

 security/selinux/hooks.c |   67 ++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 58 insertions(+), 9 deletions(-)
security/selinux/hooks.c renamed from security/selinux/hooks.c.withdecouple +58 -9
@@ -320,12 +320,14 @@ enum {
 	Opt_context = 1,
 	Opt_fscontext = 2,
 	Opt_defcontext = 4,
+	Opt_rootcontext = 8,
 };
 
 static match_table_t tokens = {
 	{Opt_context, "context=%s"},
 	{Opt_fscontext, "fscontext=%s"},
 	{Opt_defcontext, "defcontext=%s"},
+	{Opt_rootcontext, "rootcontext=%s"},
 };
 
 #define SEL_MOUNT_FAIL_MSG "SELinux:  duplicate or incompatible mount options\n"
@@ -345,10 +347,24 @@ static int may_context_mount_sb_relabel(
 	return rc;
 }
 
+static int may_context_mount_inode_relabel(u32 sid, struct superblock_security_struct *sbsec,
+			struct task_security_struct *tsec)
+{
+	int rc;
+	rc = avc_has_perm(tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,
+			  FILESYSTEM__RELABELFROM, NULL);
+	if (rc)
+		return rc;
+
+	rc = avc_has_perm(sid, sbsec->sid, SECCLASS_FILESYSTEM,
+			  FILESYSTEM__ASSOCIATE, NULL);
+	return rc;
+}
+
 static int try_context_mount(struct super_block *sb, void *data)
 {
 	char *context = NULL, *defcontext = NULL;
-	char *fscontext = NULL;
+	char *fscontext = NULL, *rootcontext = NULL;
 	const char *name;
 	u32 sid;
 	int alloc = 0, rc = 0, seen = 0;
@@ -422,6 +438,22 @@ static int try_context_mount(struct supe
 				seen |= Opt_fscontext;
 				break;
 
+			case Opt_rootcontext:
+				if (seen & Opt_rootcontext) {
+					rc = -EINVAL;
+					printk(KERN_WARNING SEL_MOUNT_FAIL_MSG);
+					goto out_free;
+				}
+				rootcontext = match_strdup(&args[0]);
+				if (!rootcontext) {
+					rc = -ENOMEM;
+					goto out_free;
+				}
+				if (!alloc)
+					alloc = 1;
+				seen |= Opt_rootcontext;
+				break;
+
 			case Opt_defcontext:
 				if (sbsec->behavior != SECURITY_FS_USE_XATTR) {
 					rc = -EINVAL;
@@ -500,6 +532,27 @@ static int try_context_mount(struct supe
 		sbsec->behavior = SECURITY_FS_USE_MNTPOINT;
 	}
 
+	if (rootcontext) {
+		struct inode *inode = sb->s_root->d_inode;
+		struct inode_security_struct *isec = inode->i_security;
+		rc = security_context_to_sid(rootcontext, strlen(rootcontext), &sid);
+		if (rc) {
+			printk(KERN_WARNING "SELinux: security_context_to_sid"
+			       "(%s) failed for (dev %s, type %s) errno=%d\n",
+			       rootcontext, sb->s_id, name, rc);
+			goto out_free;
+		}
+
+		rc = may_context_mount_inode_relabel(sid, sbsec, tsec);
+		if (rc)
+			goto out_free;
+
+		down(&isec->sem);
+		isec->sid = sid;
+		isec->initialized = 1;
+		up(&isec->sem);
+	}
+
 	if (defcontext) {
 		rc = security_context_to_sid(defcontext, strlen(defcontext), &sid);
 		if (rc) {
@@ -512,13 +565,7 @@ static int try_context_mount(struct supe
 		if (sid == sbsec->def_sid)
 			goto out_free;
 
-		rc = avc_has_perm(tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,
-				  FILESYSTEM__RELABELFROM, NULL);
-		if (rc)
-			goto out_free;
-
-		rc = avc_has_perm(sid, sbsec->sid, SECCLASS_FILESYSTEM,
-				  FILESYSTEM__ASSOCIATE, NULL);
+		rc = may_context_mount_inode_relabel(sid, sbsec, tsec);
 		if (rc)
 			goto out_free;
 
@@ -530,6 +577,7 @@ out_free:
 		kfree(context);
 		kfree(defcontext);
 		kfree(fscontext);
+		kfree(rootcontext);
 	}
 out:
 	return rc;
@@ -1881,7 +1929,8 @@ static inline int selinux_option(char *o
 {
 	return (match_prefix("context=", sizeof("context=")-1, option, len) ||
 	        match_prefix("fscontext=", sizeof("fscontext=")-1, option, len) ||
-	        match_prefix("defcontext=", sizeof("defcontext=")-1, option, len));
+	        match_prefix("defcontext=", sizeof("defcontext=")-1, option, len) ||
+		match_prefix("rootcontext=", sizeof("rootcontext=")-1, option, len));
 }
 
 static inline void take_option(char **to, char *from, int *first, int len)

--
This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to [email protected] with the words "unsubscribe selinux" without quotes as the message.

#1 lore raw
Quoted 35 lines · Eric Paris

The second patch will introduce a new rootcontext= option to FS mounting. This option will allow you to explicitly label the root inode of a FS being mounted before that FS or inode because visable to userspace. This was found to be useful for things like stateless linux, see https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=190001

This should address all of the concerns with the original patch.

 security/selinux/hooks.c |   67 ++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 58 insertions(+), 9 deletions(-)
security/selinux/hooks.c renamed from security/selinux/hooks.c.withdecouple +5 -0
@@ -320,12 +320,14 @@ enum {
 	Opt_context = 1,
 	Opt_fscontext = 2,
 	Opt_defcontext = 4,
+	Opt_rootcontext = 8,
 };
 
 static match_table_t tokens = {
 	{Opt_context, "context=%s"},
 	{Opt_fscontext, "fscontext=%s"},
 	{Opt_defcontext, "defcontext=%s"},
+	{Opt_rootcontext, "rootcontext=%s"},
 };
 
 #define SEL_MOUNT_FAIL_MSG "SELinux:  duplicate or incompatible mount options\n"
@@ -345,10 +347,24 @@ static int may_context_mount_sb_relabel(
 	return rc;
 }
 
+static int may_context_mount_inode_relabel(u32 sid, struct superblock_security_struct *sbsec,
+			struct task_security_struct *tsec)
+{

security/selinux/hooks.c static int may_context_mount_sb_relabel( · line 362

Quoted 10 lines
security/selinux/hooks.c renamed from security/selinux/hooks.c.withdecouple +10 -0
+	int rc;
+	rc = avc_has_perm(tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,
+			  FILESYSTEM__RELABELFROM, NULL);
+	if (rc)
+		return rc;
+
+	rc = avc_has_perm(sid, sbsec->sid, SECCLASS_FILESYSTEM,
+			  FILESYSTEM__ASSOCIATE, NULL);
+	return rc;
+}

Ok, now I see why you have the suffix on the other function name. Line is still too long though.

security/selinux/hooks.c static int try_context_mount(struct supe · line 553

Quoted 4 lines
security/selinux/hooks.c renamed from security/selinux/hooks.c.withdecouple +4 -0
+		down(&isec->sem);
+		isec->sid = sid;
+		isec->initialized = 1;
+		up(&isec->sem);

I don't think that taking the isec sem serves any purpose here (nor does it in inode_security_set_sid, but that can be removed by separate patch later).

Signature · 8 lines
Stephen Smalley
National Security Agency


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to [email protected] with
the words "unsubscribe selinux" without quotes as the message.