diff options
| -rw-r--r-- | security/selinux/Kconfig | 2 | ||||
| -rw-r--r-- | security/selinux/include/security.h | 15 | ||||
| -rw-r--r-- | security/selinux/selinuxfs.c | 89 | ||||
| -rw-r--r-- | security/selinux/ss/policydb.c | 18 | ||||
| -rw-r--r-- | security/selinux/ss/policydb.h | 2 | ||||
| -rw-r--r-- | security/selinux/ss/services.c | 67 |
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 | |||
| 145 | config SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE | 145 | config 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 | ||
| 37 | struct netlbl_lsm_secattr; | 38 | struct netlbl_lsm_secattr; |
| @@ -39,8 +40,19 @@ struct netlbl_lsm_secattr; | |||
| 39 | extern int selinux_enabled; | 40 | extern int selinux_enabled; |
| 40 | extern int selinux_mls_enabled; | 41 | extern int selinux_mls_enabled; |
| 41 | 42 | ||
| 43 | /* Policy capabilities */ | ||
| 44 | enum { | ||
| 45 | POLICYDB_CAPABILITY_NETPEER, | ||
| 46 | __POLICYDB_CAPABILITY_MAX | ||
| 47 | }; | ||
| 48 | #define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_MAX - 1) | ||
| 49 | |||
| 50 | extern int selinux_policycap_netpeer; | ||
| 51 | |||
| 42 | int security_load_policy(void * data, size_t len); | 52 | int security_load_policy(void * data, size_t len); |
| 43 | 53 | ||
| 54 | int security_policycap_supported(unsigned int req_cap); | ||
| 55 | |||
| 44 | #define SEL_VEC_MAX 32 | 56 | #define SEL_VEC_MAX 32 |
| 45 | struct av_decision { | 57 | struct av_decision { |
| 46 | u32 allowed; | 58 | u32 allowed; |
| @@ -91,6 +103,7 @@ int security_get_classes(char ***classes, int *nclasses); | |||
| 91 | int security_get_permissions(char *class, char ***perms, int *nperms); | 103 | int security_get_permissions(char *class, char ***perms, int *nperms); |
| 92 | int security_get_reject_unknown(void); | 104 | int security_get_reject_unknown(void); |
| 93 | int security_get_allow_unknown(void); | 105 | int security_get_allow_unknown(void); |
| 106 | int 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 */ | ||
| 44 | static char *policycap_names[] = { | ||
| 45 | "network_peer_controls" | ||
| 46 | }; | ||
| 47 | |||
| 38 | unsigned int selinux_checkreqprot = CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE; | 48 | unsigned 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; | |||
| 72 | static struct dentry *class_dir = NULL; | 82 | static struct dentry *class_dir = NULL; |
| 73 | static unsigned long last_class_ino; | 83 | static unsigned long last_class_ino; |
| 74 | 84 | ||
| 85 | /* global data for policy capabilities */ | ||
| 86 | static struct dentry *policycap_dir = NULL; | ||
| 87 | |||
| 75 | extern void selnl_notify_setenforce(int val); | 88 | extern 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 | ||
| 112 | static unsigned long sel_last_ino = SEL_INO_NEXT - 1; | 125 | static 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 |
| 120 | static ssize_t sel_read_enforce(struct file *filp, char __user *buf, | 134 | static 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 */ |
| 264 | static int sel_make_bools(void); | 278 | static int sel_make_bools(void); |
| 265 | static int sel_make_classes(void); | 279 | static int sel_make_classes(void); |
| 280 | static int sel_make_policycap(void); | ||
| 266 | 281 | ||
| 267 | /* declaration for sel_make_class_dirs */ | 282 | /* declaration for sel_make_class_dirs */ |
| 268 | static int sel_make_dir(struct inode *dir, struct dentry *dentry, | 283 | static 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 | ||
| 1423 | static 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 | |||
| 1437 | static const struct file_operations sel_policycap_ops = { | ||
| 1438 | .read = sel_read_policycap, | ||
| 1439 | }; | ||
| 1440 | |||
| 1402 | static int sel_make_perm_files(char *objclass, int classvalue, | 1441 | static 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 | ||
| 1587 | static 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 | |||
| 1548 | static int sel_make_dir(struct inode *dir, struct dentry *dentry, | 1617 | static 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 | |||
| 1676 | out: | 1757 | out: |
| 1677 | return ret; | 1758 | return ret; |
| 1678 | err: | 1759 | err: |
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 | ||
| 107 | static struct policydb_compat_info *policydb_lookup_compat(int version) | 117 | static 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 | |||
| 186 | out: | 198 | out: |
| 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 @@ | |||
| 59 | extern void selnl_notify_policyload(u32 seqno); | 60 | extern void selnl_notify_policyload(u32 seqno); |
| 60 | unsigned int policydb_loaded_version; | 61 | unsigned int policydb_loaded_version; |
| 61 | 62 | ||
| 63 | int 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 | ||
| 1305 | static void security_load_policycaps(void) | ||
| 1306 | { | ||
| 1307 | selinux_policycap_netpeer = ebitmap_get_bit(&policydb.policycaps, | ||
| 1308 | POLICYDB_CAPABILITY_NETPEER); | ||
| 1309 | } | ||
| 1310 | |||
| 1302 | extern void selinux_complete_init(void); | 1311 | extern void selinux_complete_init(void); |
| 1303 | static int security_preserve_bools(struct policydb *p); | 1312 | static 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 | */ | ||
| 2176 | int 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 | |||
| 2190 | out: | ||
| 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 | */ | ||
| 2205 | int 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 | |||
| 2151 | struct selinux_audit_rule { | 2216 | struct selinux_audit_rule { |
| 2152 | u32 au_seqno; | 2217 | u32 au_seqno; |
| 2153 | struct context au_ctxt; | 2218 | struct context au_ctxt; |
