aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/ss/policydb.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux/ss/policydb.c')
-rw-r--r--security/selinux/ss/policydb.c139
1 files changed, 75 insertions, 64 deletions
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index c57802a164d5..a39d38af220b 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -1701,6 +1701,78 @@ u32 string_to_av_perm(struct policydb *p, u16 tclass, const char *name)
1701 return 1U << (perdatum->value-1); 1701 return 1U << (perdatum->value-1);
1702} 1702}
1703 1703
1704static int range_read(struct policydb *p, void *fp)
1705{
1706 struct range_trans *rt = NULL;
1707 struct mls_range *r = NULL;
1708 int i, rc;
1709 __le32 buf[2];
1710 u32 nel;
1711
1712 if (p->policyvers < POLICYDB_VERSION_MLS)
1713 return 0;
1714
1715 rc = next_entry(buf, fp, sizeof(u32));
1716 if (rc)
1717 goto out;
1718
1719 nel = le32_to_cpu(buf[0]);
1720 for (i = 0; i < nel; i++) {
1721 rc = -ENOMEM;
1722 rt = kzalloc(sizeof(*rt), GFP_KERNEL);
1723 if (!rt)
1724 goto out;
1725
1726 rc = next_entry(buf, fp, (sizeof(u32) * 2));
1727 if (rc)
1728 goto out;
1729
1730 rt->source_type = le32_to_cpu(buf[0]);
1731 rt->target_type = le32_to_cpu(buf[1]);
1732 if (p->policyvers >= POLICYDB_VERSION_RANGETRANS) {
1733 rc = next_entry(buf, fp, sizeof(u32));
1734 if (rc)
1735 goto out;
1736 rt->target_class = le32_to_cpu(buf[0]);
1737 } else
1738 rt->target_class = p->process_class;
1739
1740 rc = -EINVAL;
1741 if (!policydb_type_isvalid(p, rt->source_type) ||
1742 !policydb_type_isvalid(p, rt->target_type) ||
1743 !policydb_class_isvalid(p, rt->target_class))
1744 goto out;
1745
1746 rc = -ENOMEM;
1747 r = kzalloc(sizeof(*r), GFP_KERNEL);
1748 if (!r)
1749 goto out;
1750
1751 rc = mls_read_range_helper(r, fp);
1752 if (rc)
1753 goto out;
1754
1755 rc = -EINVAL;
1756 if (!mls_range_isvalid(p, r)) {
1757 printk(KERN_WARNING "SELinux: rangetrans: invalid range\n");
1758 goto out;
1759 }
1760
1761 rc = hashtab_insert(p->range_tr, rt, r);
1762 if (rc)
1763 goto out;
1764
1765 rt = NULL;
1766 r = NULL;
1767 }
1768 rangetr_hash_eval(p->range_tr);
1769 rc = 0;
1770out:
1771 kfree(rt);
1772 kfree(r);
1773 return rc;
1774}
1775
1704/* 1776/*
1705 * Read the configuration data from a policy database binary 1777 * Read the configuration data from a policy database binary
1706 * representation file into a policy database structure. 1778 * representation file into a policy database structure.
@@ -1717,8 +1789,6 @@ int policydb_read(struct policydb *p, void *fp)
1717 u32 len, len2, nprim, nel, nel2; 1789 u32 len, len2, nprim, nel, nel2;
1718 char *policydb_str; 1790 char *policydb_str;
1719 struct policydb_compat_info *info; 1791 struct policydb_compat_info *info;
1720 struct range_trans *rt;
1721 struct mls_range *r;
1722 1792
1723 rc = policydb_init(p); 1793 rc = policydb_init(p);
1724 if (rc) 1794 if (rc)
@@ -2131,68 +2201,9 @@ int policydb_read(struct policydb *p, void *fp)
2131 } 2201 }
2132 } 2202 }
2133 2203
2134 if (p->policyvers >= POLICYDB_VERSION_MLS) { 2204 rc = range_read(p, fp);
2135 int new_rangetr = p->policyvers >= POLICYDB_VERSION_RANGETRANS; 2205 if (rc)
2136 rc = next_entry(buf, fp, sizeof(u32)); 2206 goto bad;
2137 if (rc < 0)
2138 goto bad;
2139 nel = le32_to_cpu(buf[0]);
2140 for (i = 0; i < nel; i++) {
2141 rt = kzalloc(sizeof(*rt), GFP_KERNEL);
2142 if (!rt) {
2143 rc = -ENOMEM;
2144 goto bad;
2145 }
2146 rc = next_entry(buf, fp, (sizeof(u32) * 2));
2147 if (rc < 0) {
2148 kfree(rt);
2149 goto bad;
2150 }
2151 rt->source_type = le32_to_cpu(buf[0]);
2152 rt->target_type = le32_to_cpu(buf[1]);
2153 if (new_rangetr) {
2154 rc = next_entry(buf, fp, sizeof(u32));
2155 if (rc < 0) {
2156 kfree(rt);
2157 goto bad;
2158 }
2159 rt->target_class = le32_to_cpu(buf[0]);
2160 } else
2161 rt->target_class = p->process_class;
2162 if (!policydb_type_isvalid(p, rt->source_type) ||
2163 !policydb_type_isvalid(p, rt->target_type) ||
2164 !policydb_class_isvalid(p, rt->target_class)) {
2165 kfree(rt);
2166 rc = -EINVAL;
2167 goto bad;
2168 }
2169 r = kzalloc(sizeof(*r), GFP_KERNEL);
2170 if (!r) {
2171 kfree(rt);
2172 rc = -ENOMEM;
2173 goto bad;
2174 }
2175 rc = mls_read_range_helper(r, fp);
2176 if (rc) {
2177 kfree(rt);
2178 kfree(r);
2179 goto bad;
2180 }
2181 if (!mls_range_isvalid(p, r)) {
2182 printk(KERN_WARNING "SELinux: rangetrans: invalid range\n");
2183 kfree(rt);
2184 kfree(r);
2185 goto bad;
2186 }
2187 rc = hashtab_insert(p->range_tr, rt, r);
2188 if (rc) {
2189 kfree(rt);
2190 kfree(r);
2191 goto bad;
2192 }
2193 }
2194 rangetr_hash_eval(p->range_tr);
2195 }
2196 2207
2197 p->type_attr_map = kmalloc(p->p_types.nprim * sizeof(struct ebitmap), GFP_KERNEL); 2208 p->type_attr_map = kmalloc(p->p_types.nprim * sizeof(struct ebitmap), GFP_KERNEL);
2198 if (!p->type_attr_map) 2209 if (!p->type_attr_map)