diff options
author | James Morris <james.l.morris@oracle.com> | 2014-01-06 09:45:59 -0500 |
---|---|---|
committer | James Morris <james.l.morris@oracle.com> | 2014-01-06 09:45:59 -0500 |
commit | d4a82a4a033d563f1dc2c944eec2358cb38432d0 (patch) | |
tree | 83f8fca138299584d47930d2509151ea38050253 /security | |
parent | 5f64822d63efa20cee9efe8766b3a62ab6a1f6c3 (diff) | |
parent | 465954cd649a7d8cd331695bd24a16bcb5c4c716 (diff) |
Merge branch 'master' of git://git.infradead.org/users/pcmoore/selinux into next
Conflicts:
security/selinux/hooks.c
Resolved using request struct.
Signed-off-by: James Morris <james.l.morris@oracle.com>
Diffstat (limited to 'security')
-rw-r--r-- | security/selinux/hooks.c | 7 | ||||
-rw-r--r-- | security/selinux/include/security.h | 3 | ||||
-rw-r--r-- | security/selinux/netlabel.c | 31 | ||||
-rw-r--r-- | security/selinux/ss/constraint.h | 1 | ||||
-rw-r--r-- | security/selinux/ss/policydb.c | 96 | ||||
-rw-r--r-- | security/selinux/ss/policydb.h | 11 | ||||
-rw-r--r-- | security/selinux/ss/services.c | 54 |
7 files changed, 164 insertions, 39 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 6625699f497c..3219560f9fae 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -82,7 +82,6 @@ | |||
82 | #include <linux/syslog.h> | 82 | #include <linux/syslog.h> |
83 | #include <linux/user_namespace.h> | 83 | #include <linux/user_namespace.h> |
84 | #include <linux/export.h> | 84 | #include <linux/export.h> |
85 | #include <linux/security.h> | ||
86 | #include <linux/msg.h> | 85 | #include <linux/msg.h> |
87 | #include <linux/shm.h> | 86 | #include <linux/shm.h> |
88 | 87 | ||
@@ -4474,14 +4473,10 @@ static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb, | |||
4474 | { | 4473 | { |
4475 | struct sk_security_struct *sksec = sk->sk_security; | 4474 | struct sk_security_struct *sksec = sk->sk_security; |
4476 | int err; | 4475 | int err; |
4477 | u16 family = sk->sk_family; | 4476 | u16 family = req->rsk_ops->family; |
4478 | u32 connsid; | 4477 | u32 connsid; |
4479 | u32 peersid; | 4478 | u32 peersid; |
4480 | 4479 | ||
4481 | /* handle mapped IPv4 packets arriving via IPv6 sockets */ | ||
4482 | if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP)) | ||
4483 | family = PF_INET; | ||
4484 | |||
4485 | err = selinux_skb_peerlbl_sid(skb, family, &peersid); | 4480 | err = selinux_skb_peerlbl_sid(skb, family, &peersid); |
4486 | if (err) | 4481 | if (err) |
4487 | return err; | 4482 | return err; |
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index fe341ae37004..8ed8daf7f1ee 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h | |||
@@ -33,13 +33,14 @@ | |||
33 | #define POLICYDB_VERSION_ROLETRANS 26 | 33 | #define POLICYDB_VERSION_ROLETRANS 26 |
34 | #define POLICYDB_VERSION_NEW_OBJECT_DEFAULTS 27 | 34 | #define POLICYDB_VERSION_NEW_OBJECT_DEFAULTS 27 |
35 | #define POLICYDB_VERSION_DEFAULT_TYPE 28 | 35 | #define POLICYDB_VERSION_DEFAULT_TYPE 28 |
36 | #define POLICYDB_VERSION_CONSTRAINT_NAMES 29 | ||
36 | 37 | ||
37 | /* Range of policy versions we understand*/ | 38 | /* Range of policy versions we understand*/ |
38 | #define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE | 39 | #define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE |
39 | #ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX | 40 | #ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX |
40 | #define POLICYDB_VERSION_MAX CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE | 41 | #define POLICYDB_VERSION_MAX CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE |
41 | #else | 42 | #else |
42 | #define POLICYDB_VERSION_MAX POLICYDB_VERSION_DEFAULT_TYPE | 43 | #define POLICYDB_VERSION_MAX POLICYDB_VERSION_CONSTRAINT_NAMES |
43 | #endif | 44 | #endif |
44 | 45 | ||
45 | /* Mask for just the mount related flags */ | 46 | /* Mask for just the mount related flags */ |
diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c index 6235d052338b..0364120d1ec8 100644 --- a/security/selinux/netlabel.c +++ b/security/selinux/netlabel.c | |||
@@ -101,6 +101,32 @@ static struct netlbl_lsm_secattr *selinux_netlbl_sock_genattr(struct sock *sk) | |||
101 | } | 101 | } |
102 | 102 | ||
103 | /** | 103 | /** |
104 | * selinux_netlbl_sock_getattr - Get the cached NetLabel secattr | ||
105 | * @sk: the socket | ||
106 | * @sid: the SID | ||
107 | * | ||
108 | * Query the socket's cached secattr and if the SID matches the cached value | ||
109 | * return the cache, otherwise return NULL. | ||
110 | * | ||
111 | */ | ||
112 | static struct netlbl_lsm_secattr *selinux_netlbl_sock_getattr( | ||
113 | const struct sock *sk, | ||
114 | u32 sid) | ||
115 | { | ||
116 | struct sk_security_struct *sksec = sk->sk_security; | ||
117 | struct netlbl_lsm_secattr *secattr = sksec->nlbl_secattr; | ||
118 | |||
119 | if (secattr == NULL) | ||
120 | return NULL; | ||
121 | |||
122 | if ((secattr->flags & NETLBL_SECATTR_SECID) && | ||
123 | (secattr->attr.secid == sid)) | ||
124 | return secattr; | ||
125 | |||
126 | return NULL; | ||
127 | } | ||
128 | |||
129 | /** | ||
104 | * selinux_netlbl_cache_invalidate - Invalidate the NetLabel cache | 130 | * selinux_netlbl_cache_invalidate - Invalidate the NetLabel cache |
105 | * | 131 | * |
106 | * Description: | 132 | * Description: |
@@ -224,7 +250,7 @@ int selinux_netlbl_skbuff_setsid(struct sk_buff *skb, | |||
224 | struct sk_security_struct *sksec = sk->sk_security; | 250 | struct sk_security_struct *sksec = sk->sk_security; |
225 | if (sksec->nlbl_state != NLBL_REQSKB) | 251 | if (sksec->nlbl_state != NLBL_REQSKB) |
226 | return 0; | 252 | return 0; |
227 | secattr = sksec->nlbl_secattr; | 253 | secattr = selinux_netlbl_sock_getattr(sk, sid); |
228 | } | 254 | } |
229 | if (secattr == NULL) { | 255 | if (secattr == NULL) { |
230 | secattr = &secattr_storage; | 256 | secattr = &secattr_storage; |
@@ -410,6 +436,9 @@ int selinux_netlbl_socket_setsockopt(struct socket *sock, | |||
410 | sksec->nlbl_state == NLBL_CONNLABELED)) { | 436 | sksec->nlbl_state == NLBL_CONNLABELED)) { |
411 | netlbl_secattr_init(&secattr); | 437 | netlbl_secattr_init(&secattr); |
412 | lock_sock(sk); | 438 | lock_sock(sk); |
439 | /* call the netlabel function directly as we want to see the | ||
440 | * on-the-wire label that is assigned via the socket's options | ||
441 | * and not the cached netlabel/lsm attributes */ | ||
413 | rc = netlbl_sock_getattr(sk, &secattr); | 442 | rc = netlbl_sock_getattr(sk, &secattr); |
414 | release_sock(sk); | 443 | release_sock(sk); |
415 | if (rc == 0) | 444 | if (rc == 0) |
diff --git a/security/selinux/ss/constraint.h b/security/selinux/ss/constraint.h index 149dda731fd3..96fd947c494b 100644 --- a/security/selinux/ss/constraint.h +++ b/security/selinux/ss/constraint.h | |||
@@ -48,6 +48,7 @@ struct constraint_expr { | |||
48 | u32 op; /* operator */ | 48 | u32 op; /* operator */ |
49 | 49 | ||
50 | struct ebitmap names; /* names */ | 50 | struct ebitmap names; /* names */ |
51 | struct type_set *type_names; | ||
51 | 52 | ||
52 | struct constraint_expr *next; /* next expression */ | 53 | struct constraint_expr *next; /* next expression */ |
53 | }; | 54 | }; |
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c index f6195ebde3c9..dc4011643b55 100644 --- a/security/selinux/ss/policydb.c +++ b/security/selinux/ss/policydb.c | |||
@@ -143,6 +143,11 @@ static struct policydb_compat_info policydb_compat[] = { | |||
143 | .sym_num = SYM_NUM, | 143 | .sym_num = SYM_NUM, |
144 | .ocon_num = OCON_NUM, | 144 | .ocon_num = OCON_NUM, |
145 | }, | 145 | }, |
146 | { | ||
147 | .version = POLICYDB_VERSION_CONSTRAINT_NAMES, | ||
148 | .sym_num = SYM_NUM, | ||
149 | .ocon_num = OCON_NUM, | ||
150 | }, | ||
146 | }; | 151 | }; |
147 | 152 | ||
148 | static struct policydb_compat_info *policydb_lookup_compat(int version) | 153 | static struct policydb_compat_info *policydb_lookup_compat(int version) |
@@ -613,6 +618,19 @@ static int common_destroy(void *key, void *datum, void *p) | |||
613 | return 0; | 618 | return 0; |
614 | } | 619 | } |
615 | 620 | ||
621 | static void constraint_expr_destroy(struct constraint_expr *expr) | ||
622 | { | ||
623 | if (expr) { | ||
624 | ebitmap_destroy(&expr->names); | ||
625 | if (expr->type_names) { | ||
626 | ebitmap_destroy(&expr->type_names->types); | ||
627 | ebitmap_destroy(&expr->type_names->negset); | ||
628 | kfree(expr->type_names); | ||
629 | } | ||
630 | kfree(expr); | ||
631 | } | ||
632 | } | ||
633 | |||
616 | static int cls_destroy(void *key, void *datum, void *p) | 634 | static int cls_destroy(void *key, void *datum, void *p) |
617 | { | 635 | { |
618 | struct class_datum *cladatum; | 636 | struct class_datum *cladatum; |
@@ -628,10 +646,9 @@ static int cls_destroy(void *key, void *datum, void *p) | |||
628 | while (constraint) { | 646 | while (constraint) { |
629 | e = constraint->expr; | 647 | e = constraint->expr; |
630 | while (e) { | 648 | while (e) { |
631 | ebitmap_destroy(&e->names); | ||
632 | etmp = e; | 649 | etmp = e; |
633 | e = e->next; | 650 | e = e->next; |
634 | kfree(etmp); | 651 | constraint_expr_destroy(etmp); |
635 | } | 652 | } |
636 | ctemp = constraint; | 653 | ctemp = constraint; |
637 | constraint = constraint->next; | 654 | constraint = constraint->next; |
@@ -642,16 +659,14 @@ static int cls_destroy(void *key, void *datum, void *p) | |||
642 | while (constraint) { | 659 | while (constraint) { |
643 | e = constraint->expr; | 660 | e = constraint->expr; |
644 | while (e) { | 661 | while (e) { |
645 | ebitmap_destroy(&e->names); | ||
646 | etmp = e; | 662 | etmp = e; |
647 | e = e->next; | 663 | e = e->next; |
648 | kfree(etmp); | 664 | constraint_expr_destroy(etmp); |
649 | } | 665 | } |
650 | ctemp = constraint; | 666 | ctemp = constraint; |
651 | constraint = constraint->next; | 667 | constraint = constraint->next; |
652 | kfree(ctemp); | 668 | kfree(ctemp); |
653 | } | 669 | } |
654 | |||
655 | kfree(cladatum->comkey); | 670 | kfree(cladatum->comkey); |
656 | } | 671 | } |
657 | kfree(datum); | 672 | kfree(datum); |
@@ -1156,8 +1171,34 @@ bad: | |||
1156 | return rc; | 1171 | return rc; |
1157 | } | 1172 | } |
1158 | 1173 | ||
1159 | static int read_cons_helper(struct constraint_node **nodep, int ncons, | 1174 | static void type_set_init(struct type_set *t) |
1160 | int allowxtarget, void *fp) | 1175 | { |
1176 | ebitmap_init(&t->types); | ||
1177 | ebitmap_init(&t->negset); | ||
1178 | } | ||
1179 | |||
1180 | static int type_set_read(struct type_set *t, void *fp) | ||
1181 | { | ||
1182 | __le32 buf[1]; | ||
1183 | int rc; | ||
1184 | |||
1185 | if (ebitmap_read(&t->types, fp)) | ||
1186 | return -EINVAL; | ||
1187 | if (ebitmap_read(&t->negset, fp)) | ||
1188 | return -EINVAL; | ||
1189 | |||
1190 | rc = next_entry(buf, fp, sizeof(u32)); | ||
1191 | if (rc < 0) | ||
1192 | return -EINVAL; | ||
1193 | t->flags = le32_to_cpu(buf[0]); | ||
1194 | |||
1195 | return 0; | ||
1196 | } | ||
1197 | |||
1198 | |||
1199 | static int read_cons_helper(struct policydb *p, | ||
1200 | struct constraint_node **nodep, | ||
1201 | int ncons, int allowxtarget, void *fp) | ||
1161 | { | 1202 | { |
1162 | struct constraint_node *c, *lc; | 1203 | struct constraint_node *c, *lc; |
1163 | struct constraint_expr *e, *le; | 1204 | struct constraint_expr *e, *le; |
@@ -1225,6 +1266,18 @@ static int read_cons_helper(struct constraint_node **nodep, int ncons, | |||
1225 | rc = ebitmap_read(&e->names, fp); | 1266 | rc = ebitmap_read(&e->names, fp); |
1226 | if (rc) | 1267 | if (rc) |
1227 | return rc; | 1268 | return rc; |
1269 | if (p->policyvers >= | ||
1270 | POLICYDB_VERSION_CONSTRAINT_NAMES) { | ||
1271 | e->type_names = kzalloc(sizeof | ||
1272 | (*e->type_names), | ||
1273 | GFP_KERNEL); | ||
1274 | if (!e->type_names) | ||
1275 | return -ENOMEM; | ||
1276 | type_set_init(e->type_names); | ||
1277 | rc = type_set_read(e->type_names, fp); | ||
1278 | if (rc) | ||
1279 | return rc; | ||
1280 | } | ||
1228 | break; | 1281 | break; |
1229 | default: | 1282 | default: |
1230 | return -EINVAL; | 1283 | return -EINVAL; |
@@ -1301,7 +1354,7 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp) | |||
1301 | goto bad; | 1354 | goto bad; |
1302 | } | 1355 | } |
1303 | 1356 | ||
1304 | rc = read_cons_helper(&cladatum->constraints, ncons, 0, fp); | 1357 | rc = read_cons_helper(p, &cladatum->constraints, ncons, 0, fp); |
1305 | if (rc) | 1358 | if (rc) |
1306 | goto bad; | 1359 | goto bad; |
1307 | 1360 | ||
@@ -1311,7 +1364,8 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp) | |||
1311 | if (rc) | 1364 | if (rc) |
1312 | goto bad; | 1365 | goto bad; |
1313 | ncons = le32_to_cpu(buf[0]); | 1366 | ncons = le32_to_cpu(buf[0]); |
1314 | rc = read_cons_helper(&cladatum->validatetrans, ncons, 1, fp); | 1367 | rc = read_cons_helper(p, &cladatum->validatetrans, |
1368 | ncons, 1, fp); | ||
1315 | if (rc) | 1369 | if (rc) |
1316 | goto bad; | 1370 | goto bad; |
1317 | } | 1371 | } |
@@ -2753,6 +2807,24 @@ static int common_write(void *vkey, void *datum, void *ptr) | |||
2753 | return 0; | 2807 | return 0; |
2754 | } | 2808 | } |
2755 | 2809 | ||
2810 | static int type_set_write(struct type_set *t, void *fp) | ||
2811 | { | ||
2812 | int rc; | ||
2813 | __le32 buf[1]; | ||
2814 | |||
2815 | if (ebitmap_write(&t->types, fp)) | ||
2816 | return -EINVAL; | ||
2817 | if (ebitmap_write(&t->negset, fp)) | ||
2818 | return -EINVAL; | ||
2819 | |||
2820 | buf[0] = cpu_to_le32(t->flags); | ||
2821 | rc = put_entry(buf, sizeof(u32), 1, fp); | ||
2822 | if (rc) | ||
2823 | return -EINVAL; | ||
2824 | |||
2825 | return 0; | ||
2826 | } | ||
2827 | |||
2756 | static int write_cons_helper(struct policydb *p, struct constraint_node *node, | 2828 | static int write_cons_helper(struct policydb *p, struct constraint_node *node, |
2757 | void *fp) | 2829 | void *fp) |
2758 | { | 2830 | { |
@@ -2784,6 +2856,12 @@ static int write_cons_helper(struct policydb *p, struct constraint_node *node, | |||
2784 | rc = ebitmap_write(&e->names, fp); | 2856 | rc = ebitmap_write(&e->names, fp); |
2785 | if (rc) | 2857 | if (rc) |
2786 | return rc; | 2858 | return rc; |
2859 | if (p->policyvers >= | ||
2860 | POLICYDB_VERSION_CONSTRAINT_NAMES) { | ||
2861 | rc = type_set_write(e->type_names, fp); | ||
2862 | if (rc) | ||
2863 | return rc; | ||
2864 | } | ||
2787 | break; | 2865 | break; |
2788 | default: | 2866 | default: |
2789 | break; | 2867 | break; |
diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h index da637471d4ce..725d5945a97e 100644 --- a/security/selinux/ss/policydb.h +++ b/security/selinux/ss/policydb.h | |||
@@ -154,6 +154,17 @@ struct cond_bool_datum { | |||
154 | struct cond_node; | 154 | struct cond_node; |
155 | 155 | ||
156 | /* | 156 | /* |
157 | * type set preserves data needed to determine constraint info from | ||
158 | * policy source. This is not used by the kernel policy but allows | ||
159 | * utilities such as audit2allow to determine constraint denials. | ||
160 | */ | ||
161 | struct type_set { | ||
162 | struct ebitmap types; | ||
163 | struct ebitmap negset; | ||
164 | u32 flags; | ||
165 | }; | ||
166 | |||
167 | /* | ||
157 | * The configuration data includes security contexts for | 168 | * The configuration data includes security contexts for |
158 | * initial SIDs, unlabeled file systems, TCP and UDP port numbers, | 169 | * initial SIDs, unlabeled file systems, TCP and UDP port numbers, |
159 | * network interfaces, and nodes. This structure stores the | 170 | * network interfaces, and nodes. This structure stores the |
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index d106733ad987..fc5a63a05a1c 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c | |||
@@ -1831,7 +1831,7 @@ static int security_preserve_bools(struct policydb *p); | |||
1831 | */ | 1831 | */ |
1832 | int security_load_policy(void *data, size_t len) | 1832 | int security_load_policy(void *data, size_t len) |
1833 | { | 1833 | { |
1834 | struct policydb oldpolicydb, newpolicydb; | 1834 | struct policydb *oldpolicydb, *newpolicydb; |
1835 | struct sidtab oldsidtab, newsidtab; | 1835 | struct sidtab oldsidtab, newsidtab; |
1836 | struct selinux_mapping *oldmap, *map = NULL; | 1836 | struct selinux_mapping *oldmap, *map = NULL; |
1837 | struct convert_context_args args; | 1837 | struct convert_context_args args; |
@@ -1840,12 +1840,19 @@ int security_load_policy(void *data, size_t len) | |||
1840 | int rc = 0; | 1840 | int rc = 0; |
1841 | struct policy_file file = { data, len }, *fp = &file; | 1841 | struct policy_file file = { data, len }, *fp = &file; |
1842 | 1842 | ||
1843 | oldpolicydb = kzalloc(2 * sizeof(*oldpolicydb), GFP_KERNEL); | ||
1844 | if (!oldpolicydb) { | ||
1845 | rc = -ENOMEM; | ||
1846 | goto out; | ||
1847 | } | ||
1848 | newpolicydb = oldpolicydb + 1; | ||
1849 | |||
1843 | if (!ss_initialized) { | 1850 | if (!ss_initialized) { |
1844 | avtab_cache_init(); | 1851 | avtab_cache_init(); |
1845 | rc = policydb_read(&policydb, fp); | 1852 | rc = policydb_read(&policydb, fp); |
1846 | if (rc) { | 1853 | if (rc) { |
1847 | avtab_cache_destroy(); | 1854 | avtab_cache_destroy(); |
1848 | return rc; | 1855 | goto out; |
1849 | } | 1856 | } |
1850 | 1857 | ||
1851 | policydb.len = len; | 1858 | policydb.len = len; |
@@ -1855,14 +1862,14 @@ int security_load_policy(void *data, size_t len) | |||
1855 | if (rc) { | 1862 | if (rc) { |
1856 | policydb_destroy(&policydb); | 1863 | policydb_destroy(&policydb); |
1857 | avtab_cache_destroy(); | 1864 | avtab_cache_destroy(); |
1858 | return rc; | 1865 | goto out; |
1859 | } | 1866 | } |
1860 | 1867 | ||
1861 | rc = policydb_load_isids(&policydb, &sidtab); | 1868 | rc = policydb_load_isids(&policydb, &sidtab); |
1862 | if (rc) { | 1869 | if (rc) { |
1863 | policydb_destroy(&policydb); | 1870 | policydb_destroy(&policydb); |
1864 | avtab_cache_destroy(); | 1871 | avtab_cache_destroy(); |
1865 | return rc; | 1872 | goto out; |
1866 | } | 1873 | } |
1867 | 1874 | ||
1868 | security_load_policycaps(); | 1875 | security_load_policycaps(); |
@@ -1874,36 +1881,36 @@ int security_load_policy(void *data, size_t len) | |||
1874 | selinux_status_update_policyload(seqno); | 1881 | selinux_status_update_policyload(seqno); |
1875 | selinux_netlbl_cache_invalidate(); | 1882 | selinux_netlbl_cache_invalidate(); |
1876 | selinux_xfrm_notify_policyload(); | 1883 | selinux_xfrm_notify_policyload(); |
1877 | return 0; | 1884 | goto out; |
1878 | } | 1885 | } |
1879 | 1886 | ||
1880 | #if 0 | 1887 | #if 0 |
1881 | sidtab_hash_eval(&sidtab, "sids"); | 1888 | sidtab_hash_eval(&sidtab, "sids"); |
1882 | #endif | 1889 | #endif |
1883 | 1890 | ||
1884 | rc = policydb_read(&newpolicydb, fp); | 1891 | rc = policydb_read(newpolicydb, fp); |
1885 | if (rc) | 1892 | if (rc) |
1886 | return rc; | 1893 | goto out; |
1887 | 1894 | ||
1888 | newpolicydb.len = len; | 1895 | newpolicydb->len = len; |
1889 | /* If switching between different policy types, log MLS status */ | 1896 | /* If switching between different policy types, log MLS status */ |
1890 | if (policydb.mls_enabled && !newpolicydb.mls_enabled) | 1897 | if (policydb.mls_enabled && !newpolicydb->mls_enabled) |
1891 | printk(KERN_INFO "SELinux: Disabling MLS support...\n"); | 1898 | printk(KERN_INFO "SELinux: Disabling MLS support...\n"); |
1892 | else if (!policydb.mls_enabled && newpolicydb.mls_enabled) | 1899 | else if (!policydb.mls_enabled && newpolicydb->mls_enabled) |
1893 | printk(KERN_INFO "SELinux: Enabling MLS support...\n"); | 1900 | printk(KERN_INFO "SELinux: Enabling MLS support...\n"); |
1894 | 1901 | ||
1895 | rc = policydb_load_isids(&newpolicydb, &newsidtab); | 1902 | rc = policydb_load_isids(newpolicydb, &newsidtab); |
1896 | if (rc) { | 1903 | if (rc) { |
1897 | printk(KERN_ERR "SELinux: unable to load the initial SIDs\n"); | 1904 | printk(KERN_ERR "SELinux: unable to load the initial SIDs\n"); |
1898 | policydb_destroy(&newpolicydb); | 1905 | policydb_destroy(newpolicydb); |
1899 | return rc; | 1906 | goto out; |
1900 | } | 1907 | } |
1901 | 1908 | ||
1902 | rc = selinux_set_mapping(&newpolicydb, secclass_map, &map, &map_size); | 1909 | rc = selinux_set_mapping(newpolicydb, secclass_map, &map, &map_size); |
1903 | if (rc) | 1910 | if (rc) |
1904 | goto err; | 1911 | goto err; |
1905 | 1912 | ||
1906 | rc = security_preserve_bools(&newpolicydb); | 1913 | rc = security_preserve_bools(newpolicydb); |
1907 | if (rc) { | 1914 | if (rc) { |
1908 | printk(KERN_ERR "SELinux: unable to preserve booleans\n"); | 1915 | printk(KERN_ERR "SELinux: unable to preserve booleans\n"); |
1909 | goto err; | 1916 | goto err; |
@@ -1921,7 +1928,7 @@ int security_load_policy(void *data, size_t len) | |||
1921 | * in the new SID table. | 1928 | * in the new SID table. |
1922 | */ | 1929 | */ |
1923 | args.oldp = &policydb; | 1930 | args.oldp = &policydb; |
1924 | args.newp = &newpolicydb; | 1931 | args.newp = newpolicydb; |
1925 | rc = sidtab_map(&newsidtab, convert_context, &args); | 1932 | rc = sidtab_map(&newsidtab, convert_context, &args); |
1926 | if (rc) { | 1933 | if (rc) { |
1927 | printk(KERN_ERR "SELinux: unable to convert the internal" | 1934 | printk(KERN_ERR "SELinux: unable to convert the internal" |
@@ -1931,12 +1938,12 @@ int security_load_policy(void *data, size_t len) | |||
1931 | } | 1938 | } |
1932 | 1939 | ||
1933 | /* Save the old policydb and SID table to free later. */ | 1940 | /* Save the old policydb and SID table to free later. */ |
1934 | memcpy(&oldpolicydb, &policydb, sizeof policydb); | 1941 | memcpy(oldpolicydb, &policydb, sizeof(policydb)); |
1935 | sidtab_set(&oldsidtab, &sidtab); | 1942 | sidtab_set(&oldsidtab, &sidtab); |
1936 | 1943 | ||
1937 | /* Install the new policydb and SID table. */ | 1944 | /* Install the new policydb and SID table. */ |
1938 | write_lock_irq(&policy_rwlock); | 1945 | write_lock_irq(&policy_rwlock); |
1939 | memcpy(&policydb, &newpolicydb, sizeof policydb); | 1946 | memcpy(&policydb, newpolicydb, sizeof(policydb)); |
1940 | sidtab_set(&sidtab, &newsidtab); | 1947 | sidtab_set(&sidtab, &newsidtab); |
1941 | security_load_policycaps(); | 1948 | security_load_policycaps(); |
1942 | oldmap = current_mapping; | 1949 | oldmap = current_mapping; |
@@ -1946,7 +1953,7 @@ int security_load_policy(void *data, size_t len) | |||
1946 | write_unlock_irq(&policy_rwlock); | 1953 | write_unlock_irq(&policy_rwlock); |
1947 | 1954 | ||
1948 | /* Free the old policydb and SID table. */ | 1955 | /* Free the old policydb and SID table. */ |
1949 | policydb_destroy(&oldpolicydb); | 1956 | policydb_destroy(oldpolicydb); |
1950 | sidtab_destroy(&oldsidtab); | 1957 | sidtab_destroy(&oldsidtab); |
1951 | kfree(oldmap); | 1958 | kfree(oldmap); |
1952 | 1959 | ||
@@ -1956,14 +1963,17 @@ int security_load_policy(void *data, size_t len) | |||
1956 | selinux_netlbl_cache_invalidate(); | 1963 | selinux_netlbl_cache_invalidate(); |
1957 | selinux_xfrm_notify_policyload(); | 1964 | selinux_xfrm_notify_policyload(); |
1958 | 1965 | ||
1959 | return 0; | 1966 | rc = 0; |
1967 | goto out; | ||
1960 | 1968 | ||
1961 | err: | 1969 | err: |
1962 | kfree(map); | 1970 | kfree(map); |
1963 | sidtab_destroy(&newsidtab); | 1971 | sidtab_destroy(&newsidtab); |
1964 | policydb_destroy(&newpolicydb); | 1972 | policydb_destroy(newpolicydb); |
1965 | return rc; | ||
1966 | 1973 | ||
1974 | out: | ||
1975 | kfree(oldpolicydb); | ||
1976 | return rc; | ||
1967 | } | 1977 | } |
1968 | 1978 | ||
1969 | size_t security_policydb_len(void) | 1979 | size_t security_policydb_len(void) |