aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/selinuxfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux/selinuxfs.c')
-rw-r--r--security/selinux/selinuxfs.c85
1 files changed, 78 insertions, 7 deletions
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 93b3177c758..aca099aa2ed 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -96,12 +96,18 @@ enum sel_inos {
96 SEL_COMMIT_BOOLS, /* commit new boolean values */ 96 SEL_COMMIT_BOOLS, /* commit new boolean values */
97 SEL_MLS, /* return if MLS policy is enabled */ 97 SEL_MLS, /* return if MLS policy is enabled */
98 SEL_DISABLE, /* disable SELinux until next reboot */ 98 SEL_DISABLE, /* disable SELinux until next reboot */
99 SEL_AVC, /* AVC management directory */
100 SEL_MEMBER, /* compute polyinstantiation membership decision */ 99 SEL_MEMBER, /* compute polyinstantiation membership decision */
101 SEL_CHECKREQPROT, /* check requested protection, not kernel-applied one */ 100 SEL_CHECKREQPROT, /* check requested protection, not kernel-applied one */
102 SEL_COMPAT_NET, /* whether to use old compat network packet controls */ 101 SEL_COMPAT_NET, /* whether to use old compat network packet controls */
102 SEL_INO_NEXT, /* The next inode number to use */
103}; 103};
104 104
105static unsigned long sel_last_ino = SEL_INO_NEXT - 1;
106
107#define SEL_INITCON_INO_OFFSET 0x01000000
108#define SEL_BOOL_INO_OFFSET 0x02000000
109#define SEL_INO_MASK 0x00ffffff
110
105#define TMPBUFLEN 12 111#define TMPBUFLEN 12
106static ssize_t sel_read_enforce(struct file *filp, char __user *buf, 112static ssize_t sel_read_enforce(struct file *filp, char __user *buf,
107 size_t count, loff_t *ppos) 113 size_t count, loff_t *ppos)
@@ -777,8 +783,6 @@ static struct inode *sel_make_inode(struct super_block *sb, int mode)
777 return ret; 783 return ret;
778} 784}
779 785
780#define BOOL_INO_OFFSET 30
781
782static ssize_t sel_read_bool(struct file *filep, char __user *buf, 786static ssize_t sel_read_bool(struct file *filep, char __user *buf,
783 size_t count, loff_t *ppos) 787 size_t count, loff_t *ppos)
784{ 788{
@@ -806,14 +810,14 @@ static ssize_t sel_read_bool(struct file *filep, char __user *buf,
806 } 810 }
807 811
808 inode = filep->f_path.dentry->d_inode; 812 inode = filep->f_path.dentry->d_inode;
809 cur_enforcing = security_get_bool_value(inode->i_ino - BOOL_INO_OFFSET); 813 cur_enforcing = security_get_bool_value(inode->i_ino&SEL_INO_MASK);
810 if (cur_enforcing < 0) { 814 if (cur_enforcing < 0) {
811 ret = cur_enforcing; 815 ret = cur_enforcing;
812 goto out; 816 goto out;
813 } 817 }
814 818
815 length = scnprintf(page, PAGE_SIZE, "%d %d", cur_enforcing, 819 length = scnprintf(page, PAGE_SIZE, "%d %d", cur_enforcing,
816 bool_pending_values[inode->i_ino - BOOL_INO_OFFSET]); 820 bool_pending_values[inode->i_ino&SEL_INO_MASK]);
817 ret = simple_read_from_buffer(buf, count, ppos, page, length); 821 ret = simple_read_from_buffer(buf, count, ppos, page, length);
818out: 822out:
819 mutex_unlock(&sel_mutex); 823 mutex_unlock(&sel_mutex);
@@ -865,7 +869,7 @@ static ssize_t sel_write_bool(struct file *filep, const char __user *buf,
865 new_value = 1; 869 new_value = 1;
866 870
867 inode = filep->f_path.dentry->d_inode; 871 inode = filep->f_path.dentry->d_inode;
868 bool_pending_values[inode->i_ino - BOOL_INO_OFFSET] = new_value; 872 bool_pending_values[inode->i_ino&SEL_INO_MASK] = new_value;
869 length = count; 873 length = count;
870 874
871out: 875out:
@@ -1029,7 +1033,7 @@ static int sel_make_bools(void)
1029 isec->sid = sid; 1033 isec->sid = sid;
1030 isec->initialized = 1; 1034 isec->initialized = 1;
1031 inode->i_fop = &sel_bool_ops; 1035 inode->i_fop = &sel_bool_ops;
1032 inode->i_ino = i + BOOL_INO_OFFSET; 1036 inode->i_ino = i|SEL_BOOL_INO_OFFSET;
1033 d_add(dentry, inode); 1037 d_add(dentry, inode);
1034 } 1038 }
1035 bool_num = num; 1039 bool_num = num;
@@ -1234,6 +1238,56 @@ static int sel_make_avc_files(struct dentry *dir)
1234 goto out; 1238 goto out;
1235 } 1239 }
1236 inode->i_fop = files[i].ops; 1240 inode->i_fop = files[i].ops;
1241 inode->i_ino = ++sel_last_ino;
1242 d_add(dentry, inode);
1243 }
1244out:
1245 return ret;
1246}
1247
1248static ssize_t sel_read_initcon(struct file * file, char __user *buf,
1249 size_t count, loff_t *ppos)
1250{
1251 struct inode *inode;
1252 char *con;
1253 u32 sid, len;
1254 ssize_t ret;
1255
1256 inode = file->f_path.dentry->d_inode;
1257 sid = inode->i_ino&SEL_INO_MASK;
1258 ret = security_sid_to_context(sid, &con, &len);
1259 if (ret < 0)
1260 return ret;
1261
1262 ret = simple_read_from_buffer(buf, count, ppos, con, len);
1263 kfree(con);
1264 return ret;
1265}
1266
1267static const struct file_operations sel_initcon_ops = {
1268 .read = sel_read_initcon,
1269};
1270
1271static int sel_make_initcon_files(struct dentry *dir)
1272{
1273 int i, ret = 0;
1274
1275 for (i = 1; i <= SECINITSID_NUM; i++) {
1276 struct inode *inode;
1277 struct dentry *dentry;
1278 dentry = d_alloc_name(dir, security_get_initial_sid_context(i));
1279 if (!dentry) {
1280 ret = -ENOMEM;
1281 goto out;
1282 }
1283
1284 inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO);
1285 if (!inode) {
1286 ret = -ENOMEM;
1287 goto out;
1288 }
1289 inode->i_fop = &sel_initcon_ops;
1290 inode->i_ino = i|SEL_INITCON_INO_OFFSET;
1237 d_add(dentry, inode); 1291 d_add(dentry, inode);
1238 } 1292 }
1239out: 1293out:
@@ -1252,6 +1306,7 @@ static int sel_make_dir(struct inode *dir, struct dentry *dentry)
1252 } 1306 }
1253 inode->i_op = &simple_dir_inode_operations; 1307 inode->i_op = &simple_dir_inode_operations;
1254 inode->i_fop = &simple_dir_operations; 1308 inode->i_fop = &simple_dir_operations;
1309 inode->i_ino = ++sel_last_ino;
1255 /* directory inodes start off with i_nlink == 2 (for "." entry) */ 1310 /* directory inodes start off with i_nlink == 2 (for "." entry) */
1256 inc_nlink(inode); 1311 inc_nlink(inode);
1257 d_add(dentry, inode); 1312 d_add(dentry, inode);
@@ -1314,6 +1369,7 @@ static int sel_fill_super(struct super_block * sb, void * data, int silent)
1314 ret = -ENOMEM; 1369 ret = -ENOMEM;
1315 goto err; 1370 goto err;
1316 } 1371 }
1372 inode->i_ino = ++sel_last_ino;
1317 isec = (struct inode_security_struct*)inode->i_security; 1373 isec = (struct inode_security_struct*)inode->i_security;
1318 isec->sid = SECINITSID_DEVNULL; 1374 isec->sid = SECINITSID_DEVNULL;
1319 isec->sclass = SECCLASS_CHR_FILE; 1375 isec->sclass = SECCLASS_CHR_FILE;
@@ -1336,6 +1392,21 @@ static int sel_fill_super(struct super_block * sb, void * data, int silent)
1336 ret = sel_make_avc_files(dentry); 1392 ret = sel_make_avc_files(dentry);
1337 if (ret) 1393 if (ret)
1338 goto err; 1394 goto err;
1395
1396 dentry = d_alloc_name(sb->s_root, "initial_contexts");
1397 if (!dentry) {
1398 ret = -ENOMEM;
1399 goto err;
1400 }
1401
1402 ret = sel_make_dir(root_inode, dentry);
1403 if (ret)
1404 goto err;
1405
1406 ret = sel_make_initcon_files(dentry);
1407 if (ret)
1408 goto err;
1409
1339out: 1410out:
1340 return ret; 1411 return ret;
1341err: 1412err: