aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux
diff options
context:
space:
mode:
authorPaul Moore <paul.moore@hp.com>2008-01-29 08:38:19 -0500
committerJames Morris <jmorris@namei.org>2008-01-29 16:17:23 -0500
commit3bb56b25dbe0a4b44bd2ebceab6736d068e85068 (patch)
tree2285d831352b8580d401730eee98820ed54a81a0 /security/selinux
parent224dfbd81e1ff672eb46e7695469c395bd531083 (diff)
SELinux: Add a capabilities bitmap to SELinux policy version 22
Add a new policy capabilities bitmap to SELinux policy version 22. This bitmap will enable the security server to query the policy to determine which features it supports. Signed-off-by: Paul Moore <paul.moore@hp.com> Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/selinux')
-rw-r--r--security/selinux/Kconfig2
-rw-r--r--security/selinux/include/security.h15
-rw-r--r--security/selinux/selinuxfs.c89
-rw-r--r--security/selinux/ss/policydb.c18
-rw-r--r--security/selinux/ss/policydb.h2
-rw-r--r--security/selinux/ss/services.c67
6 files changed, 185 insertions, 8 deletions
diff --git a/security/selinux/Kconfig b/security/selinux/Kconfig
index b32a459c0683..2b517d618672 100644
--- a/security/selinux/Kconfig
+++ b/security/selinux/Kconfig
@@ -145,7 +145,7 @@ config SECURITY_SELINUX_POLICYDB_VERSION_MAX
145config SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE 145config SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE
146 int "NSA SELinux maximum supported policy format version value" 146 int "NSA SELinux maximum supported policy format version value"
147 depends on SECURITY_SELINUX_POLICYDB_VERSION_MAX 147 depends on SECURITY_SELINUX_POLICYDB_VERSION_MAX
148 range 15 21 148 range 15 22
149 default 19 149 default 19
150 help 150 help
151 This option sets the value for the maximum policy format version 151 This option sets the value for the maximum policy format version
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index a33437bba932..a22de9771806 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -25,13 +25,14 @@
25#define POLICYDB_VERSION_MLS 19 25#define POLICYDB_VERSION_MLS 19
26#define POLICYDB_VERSION_AVTAB 20 26#define POLICYDB_VERSION_AVTAB 20
27#define POLICYDB_VERSION_RANGETRANS 21 27#define POLICYDB_VERSION_RANGETRANS 21
28#define POLICYDB_VERSION_POLCAP 22
28 29
29/* Range of policy versions we understand*/ 30/* Range of policy versions we understand*/
30#define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE 31#define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE
31#ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX 32#ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX
32#define POLICYDB_VERSION_MAX CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE 33#define POLICYDB_VERSION_MAX CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE
33#else 34#else
34#define POLICYDB_VERSION_MAX POLICYDB_VERSION_RANGETRANS 35#define POLICYDB_VERSION_MAX POLICYDB_VERSION_POLCAP
35#endif 36#endif
36 37
37struct netlbl_lsm_secattr; 38struct netlbl_lsm_secattr;
@@ -39,8 +40,19 @@ struct netlbl_lsm_secattr;
39extern int selinux_enabled; 40extern int selinux_enabled;
40extern int selinux_mls_enabled; 41extern int selinux_mls_enabled;
41 42
43/* Policy capabilities */
44enum {
45 POLICYDB_CAPABILITY_NETPEER,
46 __POLICYDB_CAPABILITY_MAX
47};
48#define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_MAX - 1)
49
50extern int selinux_policycap_netpeer;
51
42int security_load_policy(void * data, size_t len); 52int security_load_policy(void * data, size_t len);
43 53
54int security_policycap_supported(unsigned int req_cap);
55
44#define SEL_VEC_MAX 32 56#define SEL_VEC_MAX 32
45struct av_decision { 57struct av_decision {
46 u32 allowed; 58 u32 allowed;
@@ -91,6 +103,7 @@ int security_get_classes(char ***classes, int *nclasses);
91int security_get_permissions(char *class, char ***perms, int *nperms); 103int security_get_permissions(char *class, char ***perms, int *nperms);
92int security_get_reject_unknown(void); 104int security_get_reject_unknown(void);
93int security_get_allow_unknown(void); 105int security_get_allow_unknown(void);
106int security_get_policycaps(int *len, int **values);
94 107
95#define SECURITY_FS_USE_XATTR 1 /* use xattr */ 108#define SECURITY_FS_USE_XATTR 1 /* use xattr */
96#define SECURITY_FS_USE_TRANS 2 /* use transition SIDs, e.g. devpts/tmpfs */ 109#define SECURITY_FS_USE_TRANS 2 /* use transition SIDs, e.g. devpts/tmpfs */
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 397fd4955fe1..a85740530afc 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -2,6 +2,11 @@
2 * 2 *
3 * Added conditional policy language extensions 3 * Added conditional policy language extensions
4 * 4 *
5 * Updated: Hewlett-Packard <paul.moore@hp.com>
6 *
7 * Added support for the policy capability bitmap
8 *
9 * Copyright (C) 2007 Hewlett-Packard Development Company, L.P.
5 * Copyright (C) 2003 - 2004 Tresys Technology, LLC 10 * Copyright (C) 2003 - 2004 Tresys Technology, LLC
6 * Copyright (C) 2004 Red Hat, Inc., James Morris <jmorris@redhat.com> 11 * Copyright (C) 2004 Red Hat, Inc., James Morris <jmorris@redhat.com>
7 * This program is free software; you can redistribute it and/or modify 12 * This program is free software; you can redistribute it and/or modify
@@ -35,6 +40,11 @@
35#include "objsec.h" 40#include "objsec.h"
36#include "conditional.h" 41#include "conditional.h"
37 42
43/* Policy capability filenames */
44static char *policycap_names[] = {
45 "network_peer_controls"
46};
47
38unsigned int selinux_checkreqprot = CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE; 48unsigned int selinux_checkreqprot = CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE;
39 49
40#ifdef CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT 50#ifdef CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT
@@ -72,6 +82,9 @@ static int *bool_pending_values = NULL;
72static struct dentry *class_dir = NULL; 82static struct dentry *class_dir = NULL;
73static unsigned long last_class_ino; 83static unsigned long last_class_ino;
74 84
85/* global data for policy capabilities */
86static struct dentry *policycap_dir = NULL;
87
75extern void selnl_notify_setenforce(int val); 88extern void selnl_notify_setenforce(int val);
76 89
77/* Check whether a task is allowed to use a security operation. */ 90/* Check whether a task is allowed to use a security operation. */
@@ -111,10 +124,11 @@ enum sel_inos {
111 124
112static unsigned long sel_last_ino = SEL_INO_NEXT - 1; 125static unsigned long sel_last_ino = SEL_INO_NEXT - 1;
113 126
114#define SEL_INITCON_INO_OFFSET 0x01000000 127#define SEL_INITCON_INO_OFFSET 0x01000000
115#define SEL_BOOL_INO_OFFSET 0x02000000 128#define SEL_BOOL_INO_OFFSET 0x02000000
116#define SEL_CLASS_INO_OFFSET 0x04000000 129#define SEL_CLASS_INO_OFFSET 0x04000000
117#define SEL_INO_MASK 0x00ffffff 130#define SEL_POLICYCAP_INO_OFFSET 0x08000000
131#define SEL_INO_MASK 0x00ffffff
118 132
119#define TMPBUFLEN 12 133#define TMPBUFLEN 12
120static ssize_t sel_read_enforce(struct file *filp, char __user *buf, 134static ssize_t sel_read_enforce(struct file *filp, char __user *buf,
@@ -263,6 +277,7 @@ static const struct file_operations sel_policyvers_ops = {
263/* declaration for sel_write_load */ 277/* declaration for sel_write_load */
264static int sel_make_bools(void); 278static int sel_make_bools(void);
265static int sel_make_classes(void); 279static int sel_make_classes(void);
280static int sel_make_policycap(void);
266 281
267/* declaration for sel_make_class_dirs */ 282/* declaration for sel_make_class_dirs */
268static int sel_make_dir(struct inode *dir, struct dentry *dentry, 283static int sel_make_dir(struct inode *dir, struct dentry *dentry,
@@ -323,6 +338,12 @@ static ssize_t sel_write_load(struct file * file, const char __user * buf,
323 } 338 }
324 339
325 ret = sel_make_classes(); 340 ret = sel_make_classes();
341 if (ret) {
342 length = ret;
343 goto out1;
344 }
345
346 ret = sel_make_policycap();
326 if (ret) 347 if (ret)
327 length = ret; 348 length = ret;
328 else 349 else
@@ -1399,6 +1420,24 @@ static const struct file_operations sel_perm_ops = {
1399 .read = sel_read_perm, 1420 .read = sel_read_perm,
1400}; 1421};
1401 1422
1423static ssize_t sel_read_policycap(struct file *file, char __user *buf,
1424 size_t count, loff_t *ppos)
1425{
1426 int value;
1427 char tmpbuf[TMPBUFLEN];
1428 ssize_t length;
1429 unsigned long i_ino = file->f_path.dentry->d_inode->i_ino;
1430
1431 value = security_policycap_supported(i_ino & SEL_INO_MASK);
1432 length = scnprintf(tmpbuf, TMPBUFLEN, "%d", value);
1433
1434 return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
1435}
1436
1437static const struct file_operations sel_policycap_ops = {
1438 .read = sel_read_policycap,
1439};
1440
1402static int sel_make_perm_files(char *objclass, int classvalue, 1441static int sel_make_perm_files(char *objclass, int classvalue,
1403 struct dentry *dir) 1442 struct dentry *dir)
1404{ 1443{
@@ -1545,6 +1584,36 @@ out:
1545 return rc; 1584 return rc;
1546} 1585}
1547 1586
1587static int sel_make_policycap(void)
1588{
1589 unsigned int iter;
1590 struct dentry *dentry = NULL;
1591 struct inode *inode = NULL;
1592
1593 sel_remove_entries(policycap_dir);
1594
1595 for (iter = 0; iter <= POLICYDB_CAPABILITY_MAX; iter++) {
1596 if (iter < ARRAY_SIZE(policycap_names))
1597 dentry = d_alloc_name(policycap_dir,
1598 policycap_names[iter]);
1599 else
1600 dentry = d_alloc_name(policycap_dir, "unknown");
1601
1602 if (dentry == NULL)
1603 return -ENOMEM;
1604
1605 inode = sel_make_inode(policycap_dir->d_sb, S_IFREG | S_IRUGO);
1606 if (inode == NULL)
1607 return -ENOMEM;
1608
1609 inode->i_fop = &sel_policycap_ops;
1610 inode->i_ino = iter | SEL_POLICYCAP_INO_OFFSET;
1611 d_add(dentry, inode);
1612 }
1613
1614 return 0;
1615}
1616
1548static int sel_make_dir(struct inode *dir, struct dentry *dentry, 1617static int sel_make_dir(struct inode *dir, struct dentry *dentry,
1549 unsigned long *ino) 1618 unsigned long *ino)
1550{ 1619{
@@ -1673,6 +1742,18 @@ static int sel_fill_super(struct super_block * sb, void * data, int silent)
1673 1742
1674 class_dir = dentry; 1743 class_dir = dentry;
1675 1744
1745 dentry = d_alloc_name(sb->s_root, "policy_capabilities");
1746 if (!dentry) {
1747 ret = -ENOMEM;
1748 goto err;
1749 }
1750
1751 ret = sel_make_dir(root_inode, dentry, &sel_last_ino);
1752 if (ret)
1753 goto err;
1754
1755 policycap_dir = dentry;
1756
1676out: 1757out:
1677 return ret; 1758 return ret;
1678err: 1759err:
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index b582aae3c62c..bd7d6a00342d 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -13,6 +13,11 @@
13 * 13 *
14 * Added conditional policy language extensions 14 * Added conditional policy language extensions
15 * 15 *
16 * Updated: Hewlett-Packard <paul.moore@hp.com>
17 *
18 * Added support for the policy capability bitmap
19 *
20 * Copyright (C) 2007 Hewlett-Packard Development Company, L.P.
16 * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. 21 * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
17 * Copyright (C) 2003 - 2004 Tresys Technology, LLC 22 * Copyright (C) 2003 - 2004 Tresys Technology, LLC
18 * This program is free software; you can redistribute it and/or modify 23 * This program is free software; you can redistribute it and/or modify
@@ -102,6 +107,11 @@ static struct policydb_compat_info policydb_compat[] = {
102 .sym_num = SYM_NUM, 107 .sym_num = SYM_NUM,
103 .ocon_num = OCON_NUM, 108 .ocon_num = OCON_NUM,
104 }, 109 },
110 {
111 .version = POLICYDB_VERSION_POLCAP,
112 .sym_num = SYM_NUM,
113 .ocon_num = OCON_NUM,
114 }
105}; 115};
106 116
107static struct policydb_compat_info *policydb_lookup_compat(int version) 117static struct policydb_compat_info *policydb_lookup_compat(int version)
@@ -183,6 +193,8 @@ static int policydb_init(struct policydb *p)
183 if (rc) 193 if (rc)
184 goto out_free_symtab; 194 goto out_free_symtab;
185 195
196 ebitmap_init(&p->policycaps);
197
186out: 198out:
187 return rc; 199 return rc;
188 200
@@ -673,8 +685,8 @@ void policydb_destroy(struct policydb *p)
673 ebitmap_destroy(&p->type_attr_map[i]); 685 ebitmap_destroy(&p->type_attr_map[i]);
674 } 686 }
675 kfree(p->type_attr_map); 687 kfree(p->type_attr_map);
676
677 kfree(p->undefined_perms); 688 kfree(p->undefined_perms);
689 ebitmap_destroy(&p->policycaps);
678 690
679 return; 691 return;
680} 692}
@@ -1554,6 +1566,10 @@ int policydb_read(struct policydb *p, void *fp)
1554 p->reject_unknown = !!(le32_to_cpu(buf[1]) & REJECT_UNKNOWN); 1566 p->reject_unknown = !!(le32_to_cpu(buf[1]) & REJECT_UNKNOWN);
1555 p->allow_unknown = !!(le32_to_cpu(buf[1]) & ALLOW_UNKNOWN); 1567 p->allow_unknown = !!(le32_to_cpu(buf[1]) & ALLOW_UNKNOWN);
1556 1568
1569 if (p->policyvers >= POLICYDB_VERSION_POLCAP &&
1570 ebitmap_read(&p->policycaps, fp) != 0)
1571 goto bad;
1572
1557 info = policydb_lookup_compat(p->policyvers); 1573 info = policydb_lookup_compat(p->policyvers);
1558 if (!info) { 1574 if (!info) {
1559 printk(KERN_ERR "security: unable to find policy compat info " 1575 printk(KERN_ERR "security: unable to find policy compat info "
diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h
index ed6fc687c66f..c4ce996e202c 100644
--- a/security/selinux/ss/policydb.h
+++ b/security/selinux/ss/policydb.h
@@ -241,6 +241,8 @@ struct policydb {
241 /* type -> attribute reverse mapping */ 241 /* type -> attribute reverse mapping */
242 struct ebitmap *type_attr_map; 242 struct ebitmap *type_attr_map;
243 243
244 struct ebitmap policycaps;
245
244 unsigned int policyvers; 246 unsigned int policyvers;
245 247
246 unsigned int reject_unknown : 1; 248 unsigned int reject_unknown : 1;
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 8dfaa3e7c26d..8ee04a424df7 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -16,12 +16,13 @@
16 * Updated: Hewlett-Packard <paul.moore@hp.com> 16 * Updated: Hewlett-Packard <paul.moore@hp.com>
17 * 17 *
18 * Added support for NetLabel 18 * Added support for NetLabel
19 * Added support for the policy capability bitmap
19 * 20 *
20 * Updated: Chad Sellers <csellers@tresys.com> 21 * Updated: Chad Sellers <csellers@tresys.com>
21 * 22 *
22 * Added validation of kernel classes and permissions 23 * Added validation of kernel classes and permissions
23 * 24 *
24 * Copyright (C) 2006 Hewlett-Packard Development Company, L.P. 25 * Copyright (C) 2006, 2007 Hewlett-Packard Development Company, L.P.
25 * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc. 26 * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc.
26 * Copyright (C) 2003 - 2004, 2006 Tresys Technology, LLC 27 * Copyright (C) 2003 - 2004, 2006 Tresys Technology, LLC
27 * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com> 28 * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com>
@@ -59,6 +60,8 @@
59extern void selnl_notify_policyload(u32 seqno); 60extern void selnl_notify_policyload(u32 seqno);
60unsigned int policydb_loaded_version; 61unsigned int policydb_loaded_version;
61 62
63int selinux_policycap_netpeer;
64
62/* 65/*
63 * This is declared in avc.c 66 * This is declared in avc.c
64 */ 67 */
@@ -1299,6 +1302,12 @@ bad:
1299 goto out; 1302 goto out;
1300} 1303}
1301 1304
1305static void security_load_policycaps(void)
1306{
1307 selinux_policycap_netpeer = ebitmap_get_bit(&policydb.policycaps,
1308 POLICYDB_CAPABILITY_NETPEER);
1309}
1310
1302extern void selinux_complete_init(void); 1311extern void selinux_complete_init(void);
1303static int security_preserve_bools(struct policydb *p); 1312static int security_preserve_bools(struct policydb *p);
1304 1313
@@ -1346,6 +1355,7 @@ int security_load_policy(void *data, size_t len)
1346 avtab_cache_destroy(); 1355 avtab_cache_destroy();
1347 return -EINVAL; 1356 return -EINVAL;
1348 } 1357 }
1358 security_load_policycaps();
1349 policydb_loaded_version = policydb.policyvers; 1359 policydb_loaded_version = policydb.policyvers;
1350 ss_initialized = 1; 1360 ss_initialized = 1;
1351 seqno = ++latest_granting; 1361 seqno = ++latest_granting;
@@ -1404,6 +1414,7 @@ int security_load_policy(void *data, size_t len)
1404 POLICY_WRLOCK; 1414 POLICY_WRLOCK;
1405 memcpy(&policydb, &newpolicydb, sizeof policydb); 1415 memcpy(&policydb, &newpolicydb, sizeof policydb);
1406 sidtab_set(&sidtab, &newsidtab); 1416 sidtab_set(&sidtab, &newsidtab);
1417 security_load_policycaps();
1407 seqno = ++latest_granting; 1418 seqno = ++latest_granting;
1408 policydb_loaded_version = policydb.policyvers; 1419 policydb_loaded_version = policydb.policyvers;
1409 POLICY_WRUNLOCK; 1420 POLICY_WRUNLOCK;
@@ -2148,6 +2159,60 @@ int security_get_allow_unknown(void)
2148 return policydb.allow_unknown; 2159 return policydb.allow_unknown;
2149} 2160}
2150 2161
2162/**
2163 * security_get_policycaps - Query the loaded policy for its capabilities
2164 * @len: the number of capability bits
2165 * @values: the capability bit array
2166 *
2167 * Description:
2168 * Get an array of the policy capabilities in @values where each entry in
2169 * @values is either true (1) or false (0) depending the policy's support of
2170 * that feature. The policy capabilities are defined by the
2171 * POLICYDB_CAPABILITY_* enums. The size of the array is stored in @len and it
2172 * is up to the caller to free the array in @values. Returns zero on success,
2173 * negative values on failure.
2174 *
2175 */
2176int security_get_policycaps(int *len, int **values)
2177{
2178 int rc = -ENOMEM;
2179 unsigned int iter;
2180
2181 POLICY_RDLOCK;
2182
2183 *values = kcalloc(POLICYDB_CAPABILITY_MAX, sizeof(int), GFP_ATOMIC);
2184 if (*values == NULL)
2185 goto out;
2186 for (iter = 0; iter < POLICYDB_CAPABILITY_MAX; iter++)
2187 (*values)[iter] = ebitmap_get_bit(&policydb.policycaps, iter);
2188 *len = POLICYDB_CAPABILITY_MAX;
2189
2190out:
2191 POLICY_RDUNLOCK;
2192 return rc;
2193}
2194
2195/**
2196 * security_policycap_supported - Check for a specific policy capability
2197 * @req_cap: capability
2198 *
2199 * Description:
2200 * This function queries the currently loaded policy to see if it supports the
2201 * capability specified by @req_cap. Returns true (1) if the capability is
2202 * supported, false (0) if it isn't supported.
2203 *
2204 */
2205int security_policycap_supported(unsigned int req_cap)
2206{
2207 int rc;
2208
2209 POLICY_RDLOCK;
2210 rc = ebitmap_get_bit(&policydb.policycaps, req_cap);
2211 POLICY_RDUNLOCK;
2212
2213 return rc;
2214}
2215
2151struct selinux_audit_rule { 2216struct selinux_audit_rule {
2152 u32 au_seqno; 2217 u32 au_seqno;
2153 struct context au_ctxt; 2218 struct context au_ctxt;