aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/ss/services.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux/ss/services.c')
-rw-r--r--security/selinux/ss/services.c76
1 files changed, 44 insertions, 32 deletions
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index d106733ad987..4bca49414a40 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -1232,6 +1232,10 @@ static int security_context_to_sid_core(const char *scontext, u32 scontext_len,
1232 struct context context; 1232 struct context context;
1233 int rc = 0; 1233 int rc = 0;
1234 1234
1235 /* An empty security context is never valid. */
1236 if (!scontext_len)
1237 return -EINVAL;
1238
1235 if (!ss_initialized) { 1239 if (!ss_initialized) {
1236 int i; 1240 int i;
1237 1241
@@ -1285,16 +1289,18 @@ out:
1285 * @scontext: security context 1289 * @scontext: security context
1286 * @scontext_len: length in bytes 1290 * @scontext_len: length in bytes
1287 * @sid: security identifier, SID 1291 * @sid: security identifier, SID
1292 * @gfp: context for the allocation
1288 * 1293 *
1289 * Obtains a SID associated with the security context that 1294 * Obtains a SID associated with the security context that
1290 * has the string representation specified by @scontext. 1295 * has the string representation specified by @scontext.
1291 * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient 1296 * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient
1292 * memory is available, or 0 on success. 1297 * memory is available, or 0 on success.
1293 */ 1298 */
1294int security_context_to_sid(const char *scontext, u32 scontext_len, u32 *sid) 1299int security_context_to_sid(const char *scontext, u32 scontext_len, u32 *sid,
1300 gfp_t gfp)
1295{ 1301{
1296 return security_context_to_sid_core(scontext, scontext_len, 1302 return security_context_to_sid_core(scontext, scontext_len,
1297 sid, SECSID_NULL, GFP_KERNEL, 0); 1303 sid, SECSID_NULL, gfp, 0);
1298} 1304}
1299 1305
1300/** 1306/**
@@ -1831,7 +1837,7 @@ static int security_preserve_bools(struct policydb *p);
1831 */ 1837 */
1832int security_load_policy(void *data, size_t len) 1838int security_load_policy(void *data, size_t len)
1833{ 1839{
1834 struct policydb oldpolicydb, newpolicydb; 1840 struct policydb *oldpolicydb, *newpolicydb;
1835 struct sidtab oldsidtab, newsidtab; 1841 struct sidtab oldsidtab, newsidtab;
1836 struct selinux_mapping *oldmap, *map = NULL; 1842 struct selinux_mapping *oldmap, *map = NULL;
1837 struct convert_context_args args; 1843 struct convert_context_args args;
@@ -1840,12 +1846,19 @@ int security_load_policy(void *data, size_t len)
1840 int rc = 0; 1846 int rc = 0;
1841 struct policy_file file = { data, len }, *fp = &file; 1847 struct policy_file file = { data, len }, *fp = &file;
1842 1848
1849 oldpolicydb = kzalloc(2 * sizeof(*oldpolicydb), GFP_KERNEL);
1850 if (!oldpolicydb) {
1851 rc = -ENOMEM;
1852 goto out;
1853 }
1854 newpolicydb = oldpolicydb + 1;
1855
1843 if (!ss_initialized) { 1856 if (!ss_initialized) {
1844 avtab_cache_init(); 1857 avtab_cache_init();
1845 rc = policydb_read(&policydb, fp); 1858 rc = policydb_read(&policydb, fp);
1846 if (rc) { 1859 if (rc) {
1847 avtab_cache_destroy(); 1860 avtab_cache_destroy();
1848 return rc; 1861 goto out;
1849 } 1862 }
1850 1863
1851 policydb.len = len; 1864 policydb.len = len;
@@ -1855,14 +1868,14 @@ int security_load_policy(void *data, size_t len)
1855 if (rc) { 1868 if (rc) {
1856 policydb_destroy(&policydb); 1869 policydb_destroy(&policydb);
1857 avtab_cache_destroy(); 1870 avtab_cache_destroy();
1858 return rc; 1871 goto out;
1859 } 1872 }
1860 1873
1861 rc = policydb_load_isids(&policydb, &sidtab); 1874 rc = policydb_load_isids(&policydb, &sidtab);
1862 if (rc) { 1875 if (rc) {
1863 policydb_destroy(&policydb); 1876 policydb_destroy(&policydb);
1864 avtab_cache_destroy(); 1877 avtab_cache_destroy();
1865 return rc; 1878 goto out;
1866 } 1879 }
1867 1880
1868 security_load_policycaps(); 1881 security_load_policycaps();
@@ -1874,36 +1887,36 @@ int security_load_policy(void *data, size_t len)
1874 selinux_status_update_policyload(seqno); 1887 selinux_status_update_policyload(seqno);
1875 selinux_netlbl_cache_invalidate(); 1888 selinux_netlbl_cache_invalidate();
1876 selinux_xfrm_notify_policyload(); 1889 selinux_xfrm_notify_policyload();
1877 return 0; 1890 goto out;
1878 } 1891 }
1879 1892
1880#if 0 1893#if 0
1881 sidtab_hash_eval(&sidtab, "sids"); 1894 sidtab_hash_eval(&sidtab, "sids");
1882#endif 1895#endif
1883 1896
1884 rc = policydb_read(&newpolicydb, fp); 1897 rc = policydb_read(newpolicydb, fp);
1885 if (rc) 1898 if (rc)
1886 return rc; 1899 goto out;
1887 1900
1888 newpolicydb.len = len; 1901 newpolicydb->len = len;
1889 /* If switching between different policy types, log MLS status */ 1902 /* If switching between different policy types, log MLS status */
1890 if (policydb.mls_enabled && !newpolicydb.mls_enabled) 1903 if (policydb.mls_enabled && !newpolicydb->mls_enabled)
1891 printk(KERN_INFO "SELinux: Disabling MLS support...\n"); 1904 printk(KERN_INFO "SELinux: Disabling MLS support...\n");
1892 else if (!policydb.mls_enabled && newpolicydb.mls_enabled) 1905 else if (!policydb.mls_enabled && newpolicydb->mls_enabled)
1893 printk(KERN_INFO "SELinux: Enabling MLS support...\n"); 1906 printk(KERN_INFO "SELinux: Enabling MLS support...\n");
1894 1907
1895 rc = policydb_load_isids(&newpolicydb, &newsidtab); 1908 rc = policydb_load_isids(newpolicydb, &newsidtab);
1896 if (rc) { 1909 if (rc) {
1897 printk(KERN_ERR "SELinux: unable to load the initial SIDs\n"); 1910 printk(KERN_ERR "SELinux: unable to load the initial SIDs\n");
1898 policydb_destroy(&newpolicydb); 1911 policydb_destroy(newpolicydb);
1899 return rc; 1912 goto out;
1900 } 1913 }
1901 1914
1902 rc = selinux_set_mapping(&newpolicydb, secclass_map, &map, &map_size); 1915 rc = selinux_set_mapping(newpolicydb, secclass_map, &map, &map_size);
1903 if (rc) 1916 if (rc)
1904 goto err; 1917 goto err;
1905 1918
1906 rc = security_preserve_bools(&newpolicydb); 1919 rc = security_preserve_bools(newpolicydb);
1907 if (rc) { 1920 if (rc) {
1908 printk(KERN_ERR "SELinux: unable to preserve booleans\n"); 1921 printk(KERN_ERR "SELinux: unable to preserve booleans\n");
1909 goto err; 1922 goto err;
@@ -1921,7 +1934,7 @@ int security_load_policy(void *data, size_t len)
1921 * in the new SID table. 1934 * in the new SID table.
1922 */ 1935 */
1923 args.oldp = &policydb; 1936 args.oldp = &policydb;
1924 args.newp = &newpolicydb; 1937 args.newp = newpolicydb;
1925 rc = sidtab_map(&newsidtab, convert_context, &args); 1938 rc = sidtab_map(&newsidtab, convert_context, &args);
1926 if (rc) { 1939 if (rc) {
1927 printk(KERN_ERR "SELinux: unable to convert the internal" 1940 printk(KERN_ERR "SELinux: unable to convert the internal"
@@ -1931,12 +1944,12 @@ int security_load_policy(void *data, size_t len)
1931 } 1944 }
1932 1945
1933 /* Save the old policydb and SID table to free later. */ 1946 /* Save the old policydb and SID table to free later. */
1934 memcpy(&oldpolicydb, &policydb, sizeof policydb); 1947 memcpy(oldpolicydb, &policydb, sizeof(policydb));
1935 sidtab_set(&oldsidtab, &sidtab); 1948 sidtab_set(&oldsidtab, &sidtab);
1936 1949
1937 /* Install the new policydb and SID table. */ 1950 /* Install the new policydb and SID table. */
1938 write_lock_irq(&policy_rwlock); 1951 write_lock_irq(&policy_rwlock);
1939 memcpy(&policydb, &newpolicydb, sizeof policydb); 1952 memcpy(&policydb, newpolicydb, sizeof(policydb));
1940 sidtab_set(&sidtab, &newsidtab); 1953 sidtab_set(&sidtab, &newsidtab);
1941 security_load_policycaps(); 1954 security_load_policycaps();
1942 oldmap = current_mapping; 1955 oldmap = current_mapping;
@@ -1946,7 +1959,7 @@ int security_load_policy(void *data, size_t len)
1946 write_unlock_irq(&policy_rwlock); 1959 write_unlock_irq(&policy_rwlock);
1947 1960
1948 /* Free the old policydb and SID table. */ 1961 /* Free the old policydb and SID table. */
1949 policydb_destroy(&oldpolicydb); 1962 policydb_destroy(oldpolicydb);
1950 sidtab_destroy(&oldsidtab); 1963 sidtab_destroy(&oldsidtab);
1951 kfree(oldmap); 1964 kfree(oldmap);
1952 1965
@@ -1956,14 +1969,17 @@ int security_load_policy(void *data, size_t len)
1956 selinux_netlbl_cache_invalidate(); 1969 selinux_netlbl_cache_invalidate();
1957 selinux_xfrm_notify_policyload(); 1970 selinux_xfrm_notify_policyload();
1958 1971
1959 return 0; 1972 rc = 0;
1973 goto out;
1960 1974
1961err: 1975err:
1962 kfree(map); 1976 kfree(map);
1963 sidtab_destroy(&newsidtab); 1977 sidtab_destroy(&newsidtab);
1964 policydb_destroy(&newpolicydb); 1978 policydb_destroy(newpolicydb);
1965 return rc;
1966 1979
1980out:
1981 kfree(oldpolicydb);
1982 return rc;
1967} 1983}
1968 1984
1969size_t security_policydb_len(void) 1985size_t security_policydb_len(void)
@@ -2938,25 +2954,21 @@ int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule,
2938 struct selinux_audit_rule *rule = vrule; 2954 struct selinux_audit_rule *rule = vrule;
2939 int match = 0; 2955 int match = 0;
2940 2956
2941 if (!rule) { 2957 if (unlikely(!rule)) {
2942 audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR, 2958 WARN_ONCE(1, "selinux_audit_rule_match: missing rule\n");
2943 "selinux_audit_rule_match: missing rule\n");
2944 return -ENOENT; 2959 return -ENOENT;
2945 } 2960 }
2946 2961
2947 read_lock(&policy_rwlock); 2962 read_lock(&policy_rwlock);
2948 2963
2949 if (rule->au_seqno < latest_granting) { 2964 if (rule->au_seqno < latest_granting) {
2950 audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR,
2951 "selinux_audit_rule_match: stale rule\n");
2952 match = -ESTALE; 2965 match = -ESTALE;
2953 goto out; 2966 goto out;
2954 } 2967 }
2955 2968
2956 ctxt = sidtab_search(&sidtab, sid); 2969 ctxt = sidtab_search(&sidtab, sid);
2957 if (!ctxt) { 2970 if (unlikely(!ctxt)) {
2958 audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR, 2971 WARN_ONCE(1, "selinux_audit_rule_match: unrecognized SID %d\n",
2959 "selinux_audit_rule_match: unrecognized SID %d\n",
2960 sid); 2972 sid);
2961 match = -ENOENT; 2973 match = -ENOENT;
2962 goto out; 2974 goto out;