diff options
Diffstat (limited to 'security/selinux/ss')
| -rw-r--r-- | security/selinux/ss/policydb.c | 238 |
1 files changed, 133 insertions, 105 deletions
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c index a39d38af220b..4ea073eaf8bf 100644 --- a/security/selinux/ss/policydb.c +++ b/security/selinux/ss/policydb.c | |||
| @@ -655,6 +655,9 @@ static int range_tr_destroy(void *key, void *datum, void *p) | |||
| 655 | 655 | ||
| 656 | static void ocontext_destroy(struct ocontext *c, int i) | 656 | static void ocontext_destroy(struct ocontext *c, int i) |
| 657 | { | 657 | { |
| 658 | if (!c) | ||
| 659 | return; | ||
| 660 | |||
| 658 | context_destroy(&c->context[0]); | 661 | context_destroy(&c->context[0]); |
| 659 | context_destroy(&c->context[1]); | 662 | context_destroy(&c->context[1]); |
| 660 | if (i == OCON_ISID || i == OCON_FS || | 663 | if (i == OCON_ISID || i == OCON_FS || |
| @@ -1773,6 +1776,131 @@ out: | |||
| 1773 | return rc; | 1776 | return rc; |
| 1774 | } | 1777 | } |
| 1775 | 1778 | ||
| 1779 | static int genfs_read(struct policydb *p, void *fp) | ||
| 1780 | { | ||
| 1781 | int i, j, rc; | ||
| 1782 | u32 nel, nel2, len, len2; | ||
| 1783 | __le32 buf[1]; | ||
| 1784 | struct ocontext *l, *c; | ||
| 1785 | struct ocontext *newc = NULL; | ||
| 1786 | struct genfs *genfs_p, *genfs; | ||
| 1787 | struct genfs *newgenfs = NULL; | ||
| 1788 | |||
| 1789 | rc = next_entry(buf, fp, sizeof(u32)); | ||
| 1790 | if (rc) | ||
| 1791 | goto out; | ||
| 1792 | nel = le32_to_cpu(buf[0]); | ||
| 1793 | |||
| 1794 | for (i = 0; i < nel; i++) { | ||
| 1795 | rc = next_entry(buf, fp, sizeof(u32)); | ||
| 1796 | if (rc) | ||
| 1797 | goto out; | ||
| 1798 | len = le32_to_cpu(buf[0]); | ||
| 1799 | |||
| 1800 | rc = -ENOMEM; | ||
| 1801 | newgenfs = kzalloc(sizeof(*newgenfs), GFP_KERNEL); | ||
| 1802 | if (!newgenfs) | ||
| 1803 | goto out; | ||
| 1804 | |||
| 1805 | rc = -ENOMEM; | ||
| 1806 | newgenfs->fstype = kmalloc(len + 1, GFP_KERNEL); | ||
| 1807 | if (!newgenfs->fstype) | ||
| 1808 | goto out; | ||
| 1809 | |||
| 1810 | rc = next_entry(newgenfs->fstype, fp, len); | ||
| 1811 | if (rc) | ||
| 1812 | goto out; | ||
| 1813 | |||
| 1814 | newgenfs->fstype[len] = 0; | ||
| 1815 | |||
| 1816 | for (genfs_p = NULL, genfs = p->genfs; genfs; | ||
| 1817 | genfs_p = genfs, genfs = genfs->next) { | ||
| 1818 | rc = -EINVAL; | ||
| 1819 | if (strcmp(newgenfs->fstype, genfs->fstype) == 0) { | ||
| 1820 | printk(KERN_ERR "SELinux: dup genfs fstype %s\n", | ||
| 1821 | newgenfs->fstype); | ||
| 1822 | goto out; | ||
| 1823 | } | ||
| 1824 | if (strcmp(newgenfs->fstype, genfs->fstype) < 0) | ||
| 1825 | break; | ||
| 1826 | } | ||
| 1827 | newgenfs->next = genfs; | ||
| 1828 | if (genfs_p) | ||
| 1829 | genfs_p->next = newgenfs; | ||
| 1830 | else | ||
| 1831 | p->genfs = newgenfs; | ||
| 1832 | genfs = newgenfs; | ||
| 1833 | newgenfs = NULL; | ||
| 1834 | |||
| 1835 | rc = next_entry(buf, fp, sizeof(u32)); | ||
| 1836 | if (rc) | ||
| 1837 | goto out; | ||
| 1838 | |||
| 1839 | nel2 = le32_to_cpu(buf[0]); | ||
| 1840 | for (j = 0; j < nel2; j++) { | ||
| 1841 | rc = next_entry(buf, fp, sizeof(u32)); | ||
| 1842 | if (rc) | ||
| 1843 | goto out; | ||
| 1844 | len = le32_to_cpu(buf[0]); | ||
| 1845 | |||
| 1846 | rc = -ENOMEM; | ||
| 1847 | newc = kzalloc(sizeof(*newc), GFP_KERNEL); | ||
| 1848 | if (!newc) | ||
| 1849 | goto out; | ||
| 1850 | |||
| 1851 | rc = -ENOMEM; | ||
| 1852 | newc->u.name = kmalloc(len + 1, GFP_KERNEL); | ||
| 1853 | if (!newc->u.name) | ||
| 1854 | goto out; | ||
| 1855 | |||
| 1856 | rc = next_entry(newc->u.name, fp, len); | ||
| 1857 | if (rc) | ||
| 1858 | goto out; | ||
| 1859 | newc->u.name[len] = 0; | ||
| 1860 | |||
| 1861 | rc = next_entry(buf, fp, sizeof(u32)); | ||
| 1862 | if (rc) | ||
| 1863 | goto out; | ||
| 1864 | |||
| 1865 | newc->v.sclass = le32_to_cpu(buf[0]); | ||
| 1866 | rc = context_read_and_validate(&newc->context[0], p, fp); | ||
| 1867 | if (rc) | ||
| 1868 | goto out; | ||
| 1869 | |||
| 1870 | for (l = NULL, c = genfs->head; c; | ||
| 1871 | l = c, c = c->next) { | ||
| 1872 | rc = -EINVAL; | ||
| 1873 | if (!strcmp(newc->u.name, c->u.name) && | ||
| 1874 | (!c->v.sclass || !newc->v.sclass || | ||
| 1875 | newc->v.sclass == c->v.sclass)) { | ||
| 1876 | printk(KERN_ERR "SELinux: dup genfs entry (%s,%s)\n", | ||
| 1877 | genfs->fstype, c->u.name); | ||
| 1878 | goto out; | ||
| 1879 | } | ||
| 1880 | len = strlen(newc->u.name); | ||
| 1881 | len2 = strlen(c->u.name); | ||
| 1882 | if (len > len2) | ||
| 1883 | break; | ||
| 1884 | } | ||
| 1885 | |||
| 1886 | newc->next = c; | ||
| 1887 | if (l) | ||
| 1888 | l->next = newc; | ||
| 1889 | else | ||
| 1890 | genfs->head = newc; | ||
| 1891 | newc = NULL; | ||
| 1892 | } | ||
| 1893 | } | ||
| 1894 | rc = 0; | ||
| 1895 | out: | ||
| 1896 | if (newgenfs) | ||
| 1897 | kfree(newgenfs->fstype); | ||
| 1898 | kfree(newgenfs); | ||
| 1899 | ocontext_destroy(newc, OCON_FSUSE); | ||
| 1900 | |||
| 1901 | return rc; | ||
| 1902 | } | ||
| 1903 | |||
| 1776 | /* | 1904 | /* |
| 1777 | * Read the configuration data from a policy database binary | 1905 | * Read the configuration data from a policy database binary |
| 1778 | * representation file into a policy database structure. | 1906 | * representation file into a policy database structure. |
| @@ -1781,12 +1909,12 @@ int policydb_read(struct policydb *p, void *fp) | |||
| 1781 | { | 1909 | { |
| 1782 | struct role_allow *ra, *lra; | 1910 | struct role_allow *ra, *lra; |
| 1783 | struct role_trans *tr, *ltr; | 1911 | struct role_trans *tr, *ltr; |
| 1784 | struct ocontext *l, *c, *newc; | 1912 | struct ocontext *l, *c; |
| 1785 | struct genfs *genfs_p, *genfs, *newgenfs; | ||
| 1786 | int i, j, rc; | 1913 | int i, j, rc; |
| 1787 | __le32 buf[4]; | 1914 | __le32 buf[4]; |
| 1788 | u32 nodebuf[8]; | 1915 | u32 nodebuf[8]; |
| 1789 | u32 len, len2, nprim, nel, nel2; | 1916 | u32 len, nprim, nel; |
| 1917 | |||
| 1790 | char *policydb_str; | 1918 | char *policydb_str; |
| 1791 | struct policydb_compat_info *info; | 1919 | struct policydb_compat_info *info; |
| 1792 | 1920 | ||
| @@ -2099,107 +2227,9 @@ int policydb_read(struct policydb *p, void *fp) | |||
| 2099 | } | 2227 | } |
| 2100 | } | 2228 | } |
| 2101 | 2229 | ||
| 2102 | rc = next_entry(buf, fp, sizeof(u32)); | 2230 | rc = genfs_read(p, fp); |
| 2103 | if (rc < 0) | 2231 | if (rc) |
| 2104 | goto bad; | 2232 | goto bad; |
| 2105 | nel = le32_to_cpu(buf[0]); | ||
| 2106 | genfs_p = NULL; | ||
| 2107 | rc = -EINVAL; | ||
| 2108 | for (i = 0; i < nel; i++) { | ||
| 2109 | rc = next_entry(buf, fp, sizeof(u32)); | ||
| 2110 | if (rc < 0) | ||
| 2111 | goto bad; | ||
| 2112 | len = le32_to_cpu(buf[0]); | ||
| 2113 | newgenfs = kzalloc(sizeof(*newgenfs), GFP_KERNEL); | ||
| 2114 | if (!newgenfs) { | ||
| 2115 | rc = -ENOMEM; | ||
| 2116 | goto bad; | ||
| 2117 | } | ||
| 2118 | |||
| 2119 | newgenfs->fstype = kmalloc(len + 1, GFP_KERNEL); | ||
| 2120 | if (!newgenfs->fstype) { | ||
| 2121 | rc = -ENOMEM; | ||
| 2122 | kfree(newgenfs); | ||
| 2123 | goto bad; | ||
| 2124 | } | ||
| 2125 | rc = next_entry(newgenfs->fstype, fp, len); | ||
| 2126 | if (rc < 0) { | ||
| 2127 | kfree(newgenfs->fstype); | ||
| 2128 | kfree(newgenfs); | ||
| 2129 | goto bad; | ||
| 2130 | } | ||
| 2131 | newgenfs->fstype[len] = 0; | ||
| 2132 | for (genfs_p = NULL, genfs = p->genfs; genfs; | ||
| 2133 | genfs_p = genfs, genfs = genfs->next) { | ||
| 2134 | if (strcmp(newgenfs->fstype, genfs->fstype) == 0) { | ||
| 2135 | printk(KERN_ERR "SELinux: dup genfs " | ||
| 2136 | "fstype %s\n", newgenfs->fstype); | ||
| 2137 | kfree(newgenfs->fstype); | ||
| 2138 | kfree(newgenfs); | ||
| 2139 | goto bad; | ||
| 2140 | } | ||
| 2141 | if (strcmp(newgenfs->fstype, genfs->fstype) < 0) | ||
| 2142 | break; | ||
| 2143 | } | ||
| 2144 | newgenfs->next = genfs; | ||
| 2145 | if (genfs_p) | ||
| 2146 | genfs_p->next = newgenfs; | ||
| 2147 | else | ||
| 2148 | p->genfs = newgenfs; | ||
| 2149 | rc = next_entry(buf, fp, sizeof(u32)); | ||
| 2150 | if (rc < 0) | ||
| 2151 | goto bad; | ||
| 2152 | nel2 = le32_to_cpu(buf[0]); | ||
| 2153 | for (j = 0; j < nel2; j++) { | ||
| 2154 | rc = next_entry(buf, fp, sizeof(u32)); | ||
| 2155 | if (rc < 0) | ||
| 2156 | goto bad; | ||
| 2157 | len = le32_to_cpu(buf[0]); | ||
| 2158 | |||
| 2159 | newc = kzalloc(sizeof(*newc), GFP_KERNEL); | ||
| 2160 | if (!newc) { | ||
| 2161 | rc = -ENOMEM; | ||
| 2162 | goto bad; | ||
| 2163 | } | ||
| 2164 | |||
| 2165 | newc->u.name = kmalloc(len + 1, GFP_KERNEL); | ||
| 2166 | if (!newc->u.name) { | ||
| 2167 | rc = -ENOMEM; | ||
| 2168 | goto bad_newc; | ||
| 2169 | } | ||
| 2170 | rc = next_entry(newc->u.name, fp, len); | ||
| 2171 | if (rc < 0) | ||
| 2172 | goto bad_newc; | ||
| 2173 | newc->u.name[len] = 0; | ||
| 2174 | rc = next_entry(buf, fp, sizeof(u32)); | ||
| 2175 | if (rc < 0) | ||
| 2176 | goto bad_newc; | ||
| 2177 | newc->v.sclass = le32_to_cpu(buf[0]); | ||
| 2178 | if (context_read_and_validate(&newc->context[0], p, fp)) | ||
| 2179 | goto bad_newc; | ||
| 2180 | for (l = NULL, c = newgenfs->head; c; | ||
| 2181 | l = c, c = c->next) { | ||
| 2182 | if (!strcmp(newc->u.name, c->u.name) && | ||
| 2183 | (!c->v.sclass || !newc->v.sclass || | ||
| 2184 | newc->v.sclass == c->v.sclass)) { | ||
| 2185 | printk(KERN_ERR "SELinux: dup genfs " | ||
| 2186 | "entry (%s,%s)\n", | ||
| 2187 | newgenfs->fstype, c->u.name); | ||
| 2188 | goto bad_newc; | ||
| 2189 | } | ||
| 2190 | len = strlen(newc->u.name); | ||
| 2191 | len2 = strlen(c->u.name); | ||
| 2192 | if (len > len2) | ||
| 2193 | break; | ||
| 2194 | } | ||
| 2195 | |||
| 2196 | newc->next = c; | ||
| 2197 | if (l) | ||
| 2198 | l->next = newc; | ||
| 2199 | else | ||
| 2200 | newgenfs->head = newc; | ||
| 2201 | } | ||
| 2202 | } | ||
| 2203 | 2233 | ||
| 2204 | rc = range_read(p, fp); | 2234 | rc = range_read(p, fp); |
| 2205 | if (rc) | 2235 | if (rc) |
| @@ -2227,8 +2257,6 @@ int policydb_read(struct policydb *p, void *fp) | |||
| 2227 | rc = 0; | 2257 | rc = 0; |
| 2228 | out: | 2258 | out: |
| 2229 | return rc; | 2259 | return rc; |
| 2230 | bad_newc: | ||
| 2231 | ocontext_destroy(newc, OCON_FSUSE); | ||
| 2232 | bad: | 2260 | bad: |
| 2233 | if (!rc) | 2261 | if (!rc) |
| 2234 | rc = -EINVAL; | 2262 | rc = -EINVAL; |
