aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorJames Morris <james.l.morris@oracle.com>2014-01-06 09:45:59 -0500
committerJames Morris <james.l.morris@oracle.com>2014-01-06 09:45:59 -0500
commitd4a82a4a033d563f1dc2c944eec2358cb38432d0 (patch)
tree83f8fca138299584d47930d2509151ea38050253 /security
parent5f64822d63efa20cee9efe8766b3a62ab6a1f6c3 (diff)
parent465954cd649a7d8cd331695bd24a16bcb5c4c716 (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.c7
-rw-r--r--security/selinux/include/security.h3
-rw-r--r--security/selinux/netlabel.c31
-rw-r--r--security/selinux/ss/constraint.h1
-rw-r--r--security/selinux/ss/policydb.c96
-rw-r--r--security/selinux/ss/policydb.h11
-rw-r--r--security/selinux/ss/services.c54
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 */
112static 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
148static struct policydb_compat_info *policydb_lookup_compat(int version) 153static 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
621static 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
616static int cls_destroy(void *key, void *datum, void *p) 634static 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
1159static int read_cons_helper(struct constraint_node **nodep, int ncons, 1174static 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
1180static 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
1199static 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
2810static 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
2756static int write_cons_helper(struct policydb *p, struct constraint_node *node, 2828static 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 {
154struct cond_node; 154struct 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 */
161struct 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 */
1832int security_load_policy(void *data, size_t len) 1832int 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
1961err: 1969err:
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
1974out:
1975 kfree(oldpolicydb);
1976 return rc;
1967} 1977}
1968 1978
1969size_t security_policydb_len(void) 1979size_t security_policydb_len(void)