From f0ee2e467ffa68c3122128b704c1540ee294b748 Mon Sep 17 00:00:00 2001 From: James Carter Date: Wed, 4 Apr 2007 10:11:29 -0400 Subject: 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 Acked-by: Stephen Smalley Signed-off-by: James Morris --- security/selinux/selinuxfs.c | 67 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) (limited to 'security/selinux/selinuxfs.c') diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index 93b3177c7585..e24235c59ddf 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c @@ -102,6 +102,9 @@ enum sel_inos { 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 static ssize_t sel_read_enforce(struct file *filp, char __user *buf, size_t count, loff_t *ppos) @@ -1240,6 +1243,55 @@ out: 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) { 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); if (ret) 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: return ret; err: -- cgit v1.2.3 From 6174eafce3a38114adc6058e2872434c53feae87 Mon Sep 17 00:00:00 2001 From: James Carter Date: Wed, 4 Apr 2007 16:18:39 -0400 Subject: selinux: explicitly number all selinuxfs inodes Explicitly number all selinuxfs inodes to prevent a conflict between inodes numbered using last_ino when created with new_inode() and those labeled explicitly. Signed-off-by: James Carter Acked-by: Eric Paris Acked-by: Stephen Smalley Signed-off-by: James Morris --- security/selinux/selinuxfs.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'security/selinux/selinuxfs.c') diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index e24235c59ddf..1a786db50bd9 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c @@ -100,8 +100,11 @@ enum sel_inos { SEL_MEMBER, /* compute polyinstantiation membership decision */ SEL_CHECKREQPROT, /* check requested protection, not kernel-applied one */ SEL_COMPAT_NET, /* whether to use old compat network packet controls */ + SEL_INO_NEXT, /* The next inode number to use */ }; +static unsigned long sel_last_ino = SEL_INO_NEXT - 1; + #define SEL_INITCON_INO_OFFSET 0x01000000 #define SEL_INO_MASK 0x00ffffff @@ -1237,6 +1240,7 @@ static int sel_make_avc_files(struct dentry *dir) goto out; } inode->i_fop = files[i].ops; + inode->i_ino = ++sel_last_ino; d_add(dentry, inode); } out: @@ -1304,6 +1308,7 @@ static int sel_make_dir(struct inode *dir, struct dentry *dentry) } inode->i_op = &simple_dir_inode_operations; inode->i_fop = &simple_dir_operations; + inode->i_ino = ++sel_last_ino; /* directory inodes start off with i_nlink == 2 (for "." entry) */ inc_nlink(inode); d_add(dentry, inode); @@ -1366,6 +1371,7 @@ static int sel_fill_super(struct super_block * sb, void * data, int silent) ret = -ENOMEM; goto err; } + inode->i_ino = ++sel_last_ino; isec = (struct inode_security_struct*)inode->i_security; isec->sid = SECINITSID_DEVNULL; isec->sclass = SECCLASS_CHR_FILE; -- cgit v1.2.3 From 68b00df9bb5f38e87c102b3179a18eba9c9937a8 Mon Sep 17 00:00:00 2001 From: James Carter Date: Wed, 4 Apr 2007 16:18:43 -0400 Subject: selinux: remove unused enumeration constant from selinuxfs Remove the unused enumeration constant, SEL_AVC, from the sel_inos enumeration in selinuxfs. Signed-off-by: James Carter Acked-by: Eric Paris Acked-by: Stephen Smalley Signed-off-by: James Morris --- security/selinux/selinuxfs.c | 1 - 1 file changed, 1 deletion(-) (limited to 'security/selinux/selinuxfs.c') diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index 1a786db50bd9..097bc0409553 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c @@ -96,7 +96,6 @@ enum sel_inos { SEL_COMMIT_BOOLS, /* commit new boolean values */ SEL_MLS, /* return if MLS policy is enabled */ SEL_DISABLE, /* disable SELinux until next reboot */ - SEL_AVC, /* AVC management directory */ SEL_MEMBER, /* compute polyinstantiation membership decision */ SEL_CHECKREQPROT, /* check requested protection, not kernel-applied one */ SEL_COMPAT_NET, /* whether to use old compat network packet controls */ -- cgit v1.2.3 From bce34bc0eef03c68b5c49a3cc5bc77c84760cfe2 Mon Sep 17 00:00:00 2001 From: James Carter Date: Wed, 4 Apr 2007 16:18:50 -0400 Subject: selinux: change numbering of boolean directory inodes in selinuxfs Change the numbering of the booleans directory inodes in selinuxfs to provide more room for new inodes without a conflict in inode numbers and to be consistent with how inode numbering is done in the initial_contexts directory. Signed-off-by: James Carter Acked-by: Eric Paris Acked-by: Stephen Smalley Signed-off-by: James Morris --- security/selinux/selinuxfs.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'security/selinux/selinuxfs.c') diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index 097bc0409553..aca099aa2ed3 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c @@ -105,6 +105,7 @@ enum sel_inos { static unsigned long sel_last_ino = SEL_INO_NEXT - 1; #define SEL_INITCON_INO_OFFSET 0x01000000 +#define SEL_BOOL_INO_OFFSET 0x02000000 #define SEL_INO_MASK 0x00ffffff #define TMPBUFLEN 12 @@ -782,8 +783,6 @@ static struct inode *sel_make_inode(struct super_block *sb, int mode) return ret; } -#define BOOL_INO_OFFSET 30 - static ssize_t sel_read_bool(struct file *filep, char __user *buf, size_t count, loff_t *ppos) { @@ -811,14 +810,14 @@ static ssize_t sel_read_bool(struct file *filep, char __user *buf, } inode = filep->f_path.dentry->d_inode; - cur_enforcing = security_get_bool_value(inode->i_ino - BOOL_INO_OFFSET); + cur_enforcing = security_get_bool_value(inode->i_ino&SEL_INO_MASK); if (cur_enforcing < 0) { ret = cur_enforcing; goto out; } length = scnprintf(page, PAGE_SIZE, "%d %d", cur_enforcing, - bool_pending_values[inode->i_ino - BOOL_INO_OFFSET]); + bool_pending_values[inode->i_ino&SEL_INO_MASK]); ret = simple_read_from_buffer(buf, count, ppos, page, length); out: mutex_unlock(&sel_mutex); @@ -870,7 +869,7 @@ static ssize_t sel_write_bool(struct file *filep, const char __user *buf, new_value = 1; inode = filep->f_path.dentry->d_inode; - bool_pending_values[inode->i_ino - BOOL_INO_OFFSET] = new_value; + bool_pending_values[inode->i_ino&SEL_INO_MASK] = new_value; length = count; out: @@ -1034,7 +1033,7 @@ static int sel_make_bools(void) isec->sid = sid; isec->initialized = 1; inode->i_fop = &sel_bool_ops; - inode->i_ino = i + BOOL_INO_OFFSET; + inode->i_ino = i|SEL_BOOL_INO_OFFSET; d_add(dentry, inode); } bool_num = num; -- cgit v1.2.3