diff options
-rw-r--r-- | security/selinux/include/security.h | 2 | ||||
-rw-r--r-- | security/selinux/selinuxfs.c | 67 | ||||
-rw-r--r-- | security/selinux/ss/services.c | 7 |
3 files changed, 76 insertions, 0 deletions
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index bfe562c36469..b94378afea25 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h | |||
@@ -123,5 +123,7 @@ static inline int security_netlbl_sid_to_secattr(u32 sid, | |||
123 | } | 123 | } |
124 | #endif /* CONFIG_NETLABEL */ | 124 | #endif /* CONFIG_NETLABEL */ |
125 | 125 | ||
126 | const char *security_get_initial_sid_context(u32 sid); | ||
127 | |||
126 | #endif /* _SELINUX_SECURITY_H_ */ | 128 | #endif /* _SELINUX_SECURITY_H_ */ |
127 | 129 | ||
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 { | |||
102 | SEL_COMPAT_NET, /* whether to use old compat network packet controls */ | 102 | SEL_COMPAT_NET, /* whether to use old compat network packet controls */ |
103 | }; | 103 | }; |
104 | 104 | ||
105 | #define SEL_INITCON_INO_OFFSET 0x01000000 | ||
106 | #define SEL_INO_MASK 0x00ffffff | ||
107 | |||
105 | #define TMPBUFLEN 12 | 108 | #define TMPBUFLEN 12 |
106 | static ssize_t sel_read_enforce(struct file *filp, char __user *buf, | 109 | static ssize_t sel_read_enforce(struct file *filp, char __user *buf, |
107 | size_t count, loff_t *ppos) | 110 | size_t count, loff_t *ppos) |
@@ -1240,6 +1243,55 @@ out: | |||
1240 | return ret; | 1243 | return ret; |
1241 | } | 1244 | } |
1242 | 1245 | ||
1246 | static ssize_t sel_read_initcon(struct file * file, char __user *buf, | ||
1247 | size_t count, loff_t *ppos) | ||
1248 | { | ||
1249 | struct inode *inode; | ||
1250 | char *con; | ||
1251 | u32 sid, len; | ||
1252 | ssize_t ret; | ||
1253 | |||
1254 | inode = file->f_path.dentry->d_inode; | ||
1255 | sid = inode->i_ino&SEL_INO_MASK; | ||
1256 | ret = security_sid_to_context(sid, &con, &len); | ||
1257 | if (ret < 0) | ||
1258 | return ret; | ||
1259 | |||
1260 | ret = simple_read_from_buffer(buf, count, ppos, con, len); | ||
1261 | kfree(con); | ||
1262 | return ret; | ||
1263 | } | ||
1264 | |||
1265 | static const struct file_operations sel_initcon_ops = { | ||
1266 | .read = sel_read_initcon, | ||
1267 | }; | ||
1268 | |||
1269 | static int sel_make_initcon_files(struct dentry *dir) | ||
1270 | { | ||
1271 | int i, ret = 0; | ||
1272 | |||
1273 | for (i = 1; i <= SECINITSID_NUM; i++) { | ||
1274 | struct inode *inode; | ||
1275 | struct dentry *dentry; | ||
1276 | dentry = d_alloc_name(dir, security_get_initial_sid_context(i)); | ||
1277 | if (!dentry) { | ||
1278 | ret = -ENOMEM; | ||
1279 | goto out; | ||
1280 | } | ||
1281 | |||
1282 | inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO); | ||
1283 | if (!inode) { | ||
1284 | ret = -ENOMEM; | ||
1285 | goto out; | ||
1286 | } | ||
1287 | inode->i_fop = &sel_initcon_ops; | ||
1288 | inode->i_ino = i|SEL_INITCON_INO_OFFSET; | ||
1289 | d_add(dentry, inode); | ||
1290 | } | ||
1291 | out: | ||
1292 | return ret; | ||
1293 | } | ||
1294 | |||
1243 | static int sel_make_dir(struct inode *dir, struct dentry *dentry) | 1295 | static int sel_make_dir(struct inode *dir, struct dentry *dentry) |
1244 | { | 1296 | { |
1245 | int ret = 0; | 1297 | int ret = 0; |
@@ -1336,6 +1388,21 @@ static int sel_fill_super(struct super_block * sb, void * data, int silent) | |||
1336 | ret = sel_make_avc_files(dentry); | 1388 | ret = sel_make_avc_files(dentry); |
1337 | if (ret) | 1389 | if (ret) |
1338 | goto err; | 1390 | goto err; |
1391 | |||
1392 | dentry = d_alloc_name(sb->s_root, "initial_contexts"); | ||
1393 | if (!dentry) { | ||
1394 | ret = -ENOMEM; | ||
1395 | goto err; | ||
1396 | } | ||
1397 | |||
1398 | ret = sel_make_dir(root_inode, dentry); | ||
1399 | if (ret) | ||
1400 | goto err; | ||
1401 | |||
1402 | ret = sel_make_initcon_files(dentry); | ||
1403 | if (ret) | ||
1404 | goto err; | ||
1405 | |||
1339 | out: | 1406 | out: |
1340 | return ret; | 1407 | return ret; |
1341 | err: | 1408 | err: |
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index d3698568a213..21b8318979e3 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c | |||
@@ -593,6 +593,13 @@ static int context_struct_to_string(struct context *context, char **scontext, u3 | |||
593 | 593 | ||
594 | #include "initial_sid_to_string.h" | 594 | #include "initial_sid_to_string.h" |
595 | 595 | ||
596 | const char *security_get_initial_sid_context(u32 sid) | ||
597 | { | ||
598 | if (unlikely(sid > SECINITSID_NUM)) | ||
599 | return NULL; | ||
600 | return initial_sid_to_string[sid]; | ||
601 | } | ||
602 | |||
596 | /** | 603 | /** |
597 | * security_sid_to_context - Obtain a context for a given SID. | 604 | * security_sid_to_context - Obtain a context for a given SID. |
598 | * @sid: security identifier, SID | 605 | * @sid: security identifier, SID |