浏览代码

selinux: export initial SID contexts via selinuxfs

Make the initial SID contexts accessible to userspace via selinuxfs.
An initial use of this support will be to make the unlabeled context
available to libselinux for use for invalidated userspace SIDs.

Signed-off-by: James Carter <jwcart2@tycho.nsa.gov>
Acked-by:  Stephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: James Morris <jmorris@namei.org>
James Carter 18 年之前
父节点
当前提交
f0ee2e467f
共有 3 个文件被更改,包括 76 次插入0 次删除
  1. 2 0
      security/selinux/include/security.h
  2. 67 0
      security/selinux/selinuxfs.c
  3. 7 0
      security/selinux/ss/services.c

+ 2 - 0
security/selinux/include/security.h

@@ -123,5 +123,7 @@ static inline int security_netlbl_sid_to_secattr(u32 sid,
 }
 }
 #endif /* CONFIG_NETLABEL */
 #endif /* CONFIG_NETLABEL */
 
 
+const char *security_get_initial_sid_context(u32 sid);
+
 #endif /* _SELINUX_SECURITY_H_ */
 #endif /* _SELINUX_SECURITY_H_ */
 
 

+ 67 - 0
security/selinux/selinuxfs.c

@@ -102,6 +102,9 @@ enum sel_inos {
 	SEL_COMPAT_NET,	/* whether to use old compat network packet controls */
 	SEL_COMPAT_NET,	/* whether to use old compat network packet controls */
 };
 };
 
 
+#define SEL_INITCON_INO_OFFSET 	0x01000000
+#define SEL_INO_MASK		0x00ffffff
+
 #define TMPBUFLEN	12
 #define TMPBUFLEN	12
 static ssize_t sel_read_enforce(struct file *filp, char __user *buf,
 static ssize_t sel_read_enforce(struct file *filp, char __user *buf,
 				size_t count, loff_t *ppos)
 				size_t count, loff_t *ppos)
@@ -1240,6 +1243,55 @@ out:
 	return ret;
 	return ret;
 }
 }
 
 
+static ssize_t sel_read_initcon(struct file * file, char __user *buf,
+				size_t count, loff_t *ppos)
+{
+	struct inode *inode;
+	char *con;
+	u32 sid, len;
+	ssize_t ret;
+
+	inode = file->f_path.dentry->d_inode;
+	sid = inode->i_ino&SEL_INO_MASK;
+	ret = security_sid_to_context(sid, &con, &len);
+	if (ret < 0)
+		return ret;
+
+	ret = simple_read_from_buffer(buf, count, ppos, con, len);
+	kfree(con);
+	return ret;
+}
+
+static const struct file_operations sel_initcon_ops = {
+	.read		= sel_read_initcon,
+};
+
+static int sel_make_initcon_files(struct dentry *dir)
+{
+	int i, ret = 0;
+
+	for (i = 1; i <= SECINITSID_NUM; i++) {
+		struct inode *inode;
+		struct dentry *dentry;
+		dentry = d_alloc_name(dir, security_get_initial_sid_context(i));
+		if (!dentry) {
+			ret = -ENOMEM;
+			goto out;
+		}
+
+		inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO);
+		if (!inode) {
+			ret = -ENOMEM;
+			goto out;
+		}
+		inode->i_fop = &sel_initcon_ops;
+		inode->i_ino = i|SEL_INITCON_INO_OFFSET;
+		d_add(dentry, inode);
+	}
+out:
+	return ret;
+}
+
 static int sel_make_dir(struct inode *dir, struct dentry *dentry)
 static int sel_make_dir(struct inode *dir, struct dentry *dentry)
 {
 {
 	int ret = 0;
 	int ret = 0;
@@ -1336,6 +1388,21 @@ static int sel_fill_super(struct super_block * sb, void * data, int silent)
 	ret = sel_make_avc_files(dentry);
 	ret = sel_make_avc_files(dentry);
 	if (ret)
 	if (ret)
 		goto err;
 		goto err;
+
+	dentry = d_alloc_name(sb->s_root, "initial_contexts");
+	if (!dentry) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	ret = sel_make_dir(root_inode, dentry);
+	if (ret)
+		goto err;
+
+	ret = sel_make_initcon_files(dentry);
+	if (ret)
+		goto err;
+
 out:
 out:
 	return ret;
 	return ret;
 err:
 err:

+ 7 - 0
security/selinux/ss/services.c

@@ -593,6 +593,13 @@ static int context_struct_to_string(struct context *context, char **scontext, u3
 
 
 #include "initial_sid_to_string.h"
 #include "initial_sid_to_string.h"
 
 
+const char *security_get_initial_sid_context(u32 sid)
+{
+	if (unlikely(sid > SECINITSID_NUM))
+		return NULL;
+	return initial_sid_to_string[sid];
+}
+
 /**
 /**
  * security_sid_to_context - Obtain a context for a given SID.
  * security_sid_to_context - Obtain a context for a given SID.
  * @sid: security identifier, SID
  * @sid: security identifier, SID