aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/ss/policydb.c
diff options
context:
space:
mode:
authorStephen Smalley <sds@tycho.nsa.gov>2007-11-07 10:08:00 -0500
committerJames Morris <jmorris@namei.org>2007-11-07 16:56:23 -0500
commit45e5421eb5bbcd9efa037d682dd357284e3ef982 (patch)
treeceb24143024fe335d08ac30fb4da9ca25fbeb6e6 /security/selinux/ss/policydb.c
parent6d2b685564ba417f4c6d80c3661f0dfee13fff85 (diff)
SELinux: add more validity checks on policy load
Add more validity checks at policy load time to reject malformed policies and prevent subsequent out-of-range indexing when in permissive mode. Resolves the NULL pointer dereference reported in https://bugzilla.redhat.com/show_bug.cgi?id=357541. Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov> Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/selinux/ss/policydb.c')
-rw-r--r--security/selinux/ss/policydb.c45
1 files changed, 44 insertions, 1 deletions
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index 539828b229b2..b582aae3c62c 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -713,6 +713,27 @@ out:
713 return rc; 713 return rc;
714} 714}
715 715
716int policydb_class_isvalid(struct policydb *p, unsigned int class)
717{
718 if (!class || class > p->p_classes.nprim)
719 return 0;
720 return 1;
721}
722
723int policydb_role_isvalid(struct policydb *p, unsigned int role)
724{
725 if (!role || role > p->p_roles.nprim)
726 return 0;
727 return 1;
728}
729
730int policydb_type_isvalid(struct policydb *p, unsigned int type)
731{
732 if (!type || type > p->p_types.nprim)
733 return 0;
734 return 1;
735}
736
716/* 737/*
717 * Return 1 if the fields in the security context 738 * Return 1 if the fields in the security context
718 * structure `c' are valid. Return 0 otherwise. 739 * structure `c' are valid. Return 0 otherwise.
@@ -1260,6 +1281,7 @@ static int mls_read_level(struct mls_level *lp, void *fp)
1260 "categories\n"); 1281 "categories\n");
1261 goto bad; 1282 goto bad;
1262 } 1283 }
1284
1263 return 0; 1285 return 0;
1264 1286
1265bad: 1287bad:
@@ -1563,7 +1585,7 @@ int policydb_read(struct policydb *p, void *fp)
1563 p->symtab[i].nprim = nprim; 1585 p->symtab[i].nprim = nprim;
1564 } 1586 }
1565 1587
1566 rc = avtab_read(&p->te_avtab, fp, p->policyvers); 1588 rc = avtab_read(&p->te_avtab, fp, p);
1567 if (rc) 1589 if (rc)
1568 goto bad; 1590 goto bad;
1569 1591
@@ -1595,6 +1617,12 @@ int policydb_read(struct policydb *p, void *fp)
1595 tr->role = le32_to_cpu(buf[0]); 1617 tr->role = le32_to_cpu(buf[0]);
1596 tr->type = le32_to_cpu(buf[1]); 1618 tr->type = le32_to_cpu(buf[1]);
1597 tr->new_role = le32_to_cpu(buf[2]); 1619 tr->new_role = le32_to_cpu(buf[2]);
1620 if (!policydb_role_isvalid(p, tr->role) ||
1621 !policydb_type_isvalid(p, tr->type) ||
1622 !policydb_role_isvalid(p, tr->new_role)) {
1623 rc = -EINVAL;
1624 goto bad;
1625 }
1598 ltr = tr; 1626 ltr = tr;
1599 } 1627 }
1600 1628
@@ -1619,6 +1647,11 @@ int policydb_read(struct policydb *p, void *fp)
1619 goto bad; 1647 goto bad;
1620 ra->role = le32_to_cpu(buf[0]); 1648 ra->role = le32_to_cpu(buf[0]);
1621 ra->new_role = le32_to_cpu(buf[1]); 1649 ra->new_role = le32_to_cpu(buf[1]);
1650 if (!policydb_role_isvalid(p, ra->role) ||
1651 !policydb_role_isvalid(p, ra->new_role)) {
1652 rc = -EINVAL;
1653 goto bad;
1654 }
1622 lra = ra; 1655 lra = ra;
1623 } 1656 }
1624 1657
@@ -1872,9 +1905,19 @@ int policydb_read(struct policydb *p, void *fp)
1872 rt->target_class = le32_to_cpu(buf[0]); 1905 rt->target_class = le32_to_cpu(buf[0]);
1873 } else 1906 } else
1874 rt->target_class = SECCLASS_PROCESS; 1907 rt->target_class = SECCLASS_PROCESS;
1908 if (!policydb_type_isvalid(p, rt->source_type) ||
1909 !policydb_type_isvalid(p, rt->target_type) ||
1910 !policydb_class_isvalid(p, rt->target_class)) {
1911 rc = -EINVAL;
1912 goto bad;
1913 }
1875 rc = mls_read_range_helper(&rt->target_range, fp); 1914 rc = mls_read_range_helper(&rt->target_range, fp);
1876 if (rc) 1915 if (rc)
1877 goto bad; 1916 goto bad;
1917 if (!mls_range_isvalid(p, &rt->target_range)) {
1918 printk(KERN_WARNING "security: rangetrans: invalid range\n");
1919 goto bad;
1920 }
1878 lrt = rt; 1921 lrt = rt;
1879 } 1922 }
1880 } 1923 }