diff options
Diffstat (limited to 'security/selinux/ss/policydb.c')
| -rw-r--r-- | security/selinux/ss/policydb.c | 45 |
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 | ||
| 716 | int 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 | |||
| 723 | int 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 | |||
| 730 | int 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 | ||
| 1265 | bad: | 1287 | bad: |
| @@ -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 | } |
