diff options
Diffstat (limited to 'security/selinux/ss/services.c')
| -rw-r--r-- | security/selinux/ss/services.c | 63 |
1 files changed, 61 insertions, 2 deletions
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 9ea2feca3cd4..223c1ff6ef23 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c | |||
| @@ -51,6 +51,7 @@ | |||
| 51 | #include <linux/mutex.h> | 51 | #include <linux/mutex.h> |
| 52 | #include <linux/selinux.h> | 52 | #include <linux/selinux.h> |
| 53 | #include <linux/flex_array.h> | 53 | #include <linux/flex_array.h> |
| 54 | #include <linux/vmalloc.h> | ||
| 54 | #include <net/netlabel.h> | 55 | #include <net/netlabel.h> |
| 55 | 56 | ||
| 56 | #include "flask.h" | 57 | #include "flask.h" |
| @@ -991,7 +992,8 @@ static int context_struct_to_string(struct context *context, char **scontext, u3 | |||
| 991 | { | 992 | { |
| 992 | char *scontextp; | 993 | char *scontextp; |
| 993 | 994 | ||
| 994 | *scontext = NULL; | 995 | if (scontext) |
| 996 | *scontext = NULL; | ||
| 995 | *scontext_len = 0; | 997 | *scontext_len = 0; |
| 996 | 998 | ||
| 997 | if (context->len) { | 999 | if (context->len) { |
| @@ -1008,6 +1010,9 @@ static int context_struct_to_string(struct context *context, char **scontext, u3 | |||
| 1008 | *scontext_len += strlen(policydb.p_type_val_to_name[context->type - 1]) + 1; | 1010 | *scontext_len += strlen(policydb.p_type_val_to_name[context->type - 1]) + 1; |
| 1009 | *scontext_len += mls_compute_context_len(context); | 1011 | *scontext_len += mls_compute_context_len(context); |
| 1010 | 1012 | ||
| 1013 | if (!scontext) | ||
| 1014 | return 0; | ||
| 1015 | |||
| 1011 | /* Allocate space for the context; caller must free this space. */ | 1016 | /* Allocate space for the context; caller must free this space. */ |
| 1012 | scontextp = kmalloc(*scontext_len, GFP_ATOMIC); | 1017 | scontextp = kmalloc(*scontext_len, GFP_ATOMIC); |
| 1013 | if (!scontextp) | 1018 | if (!scontextp) |
| @@ -1047,7 +1052,8 @@ static int security_sid_to_context_core(u32 sid, char **scontext, | |||
| 1047 | struct context *context; | 1052 | struct context *context; |
| 1048 | int rc = 0; | 1053 | int rc = 0; |
| 1049 | 1054 | ||
| 1050 | *scontext = NULL; | 1055 | if (scontext) |
| 1056 | *scontext = NULL; | ||
| 1051 | *scontext_len = 0; | 1057 | *scontext_len = 0; |
| 1052 | 1058 | ||
| 1053 | if (!ss_initialized) { | 1059 | if (!ss_initialized) { |
| @@ -1055,6 +1061,8 @@ static int security_sid_to_context_core(u32 sid, char **scontext, | |||
| 1055 | char *scontextp; | 1061 | char *scontextp; |
| 1056 | 1062 | ||
| 1057 | *scontext_len = strlen(initial_sid_to_string[sid]) + 1; | 1063 | *scontext_len = strlen(initial_sid_to_string[sid]) + 1; |
| 1064 | if (!scontext) | ||
| 1065 | goto out; | ||
| 1058 | scontextp = kmalloc(*scontext_len, GFP_ATOMIC); | 1066 | scontextp = kmalloc(*scontext_len, GFP_ATOMIC); |
| 1059 | if (!scontextp) { | 1067 | if (!scontextp) { |
| 1060 | rc = -ENOMEM; | 1068 | rc = -ENOMEM; |
| @@ -1769,6 +1777,7 @@ int security_load_policy(void *data, size_t len) | |||
| 1769 | return rc; | 1777 | return rc; |
| 1770 | } | 1778 | } |
| 1771 | 1779 | ||
| 1780 | policydb.len = len; | ||
| 1772 | rc = selinux_set_mapping(&policydb, secclass_map, | 1781 | rc = selinux_set_mapping(&policydb, secclass_map, |
| 1773 | ¤t_mapping, | 1782 | ¤t_mapping, |
| 1774 | ¤t_mapping_size); | 1783 | ¤t_mapping_size); |
| @@ -1791,6 +1800,7 @@ int security_load_policy(void *data, size_t len) | |||
| 1791 | selinux_complete_init(); | 1800 | selinux_complete_init(); |
| 1792 | avc_ss_reset(seqno); | 1801 | avc_ss_reset(seqno); |
| 1793 | selnl_notify_policyload(seqno); | 1802 | selnl_notify_policyload(seqno); |
| 1803 | selinux_status_update_policyload(seqno); | ||
| 1794 | selinux_netlbl_cache_invalidate(); | 1804 | selinux_netlbl_cache_invalidate(); |
| 1795 | selinux_xfrm_notify_policyload(); | 1805 | selinux_xfrm_notify_policyload(); |
| 1796 | return 0; | 1806 | return 0; |
| @@ -1804,6 +1814,7 @@ int security_load_policy(void *data, size_t len) | |||
| 1804 | if (rc) | 1814 | if (rc) |
| 1805 | return rc; | 1815 | return rc; |
| 1806 | 1816 | ||
| 1817 | newpolicydb.len = len; | ||
| 1807 | /* If switching between different policy types, log MLS status */ | 1818 | /* If switching between different policy types, log MLS status */ |
| 1808 | if (policydb.mls_enabled && !newpolicydb.mls_enabled) | 1819 | if (policydb.mls_enabled && !newpolicydb.mls_enabled) |
| 1809 | printk(KERN_INFO "SELinux: Disabling MLS support...\n"); | 1820 | printk(KERN_INFO "SELinux: Disabling MLS support...\n"); |
| @@ -1870,6 +1881,7 @@ int security_load_policy(void *data, size_t len) | |||
| 1870 | 1881 | ||
| 1871 | avc_ss_reset(seqno); | 1882 | avc_ss_reset(seqno); |
| 1872 | selnl_notify_policyload(seqno); | 1883 | selnl_notify_policyload(seqno); |
| 1884 | selinux_status_update_policyload(seqno); | ||
| 1873 | selinux_netlbl_cache_invalidate(); | 1885 | selinux_netlbl_cache_invalidate(); |
| 1874 | selinux_xfrm_notify_policyload(); | 1886 | selinux_xfrm_notify_policyload(); |
| 1875 | 1887 | ||
| @@ -1883,6 +1895,17 @@ err: | |||
| 1883 | 1895 | ||
| 1884 | } | 1896 | } |
| 1885 | 1897 | ||
| 1898 | size_t security_policydb_len(void) | ||
| 1899 | { | ||
| 1900 | size_t len; | ||
| 1901 | |||
| 1902 | read_lock(&policy_rwlock); | ||
| 1903 | len = policydb.len; | ||
| 1904 | read_unlock(&policy_rwlock); | ||
| 1905 | |||
| 1906 | return len; | ||
| 1907 | } | ||
| 1908 | |||
| 1886 | /** | 1909 | /** |
| 1887 | * security_port_sid - Obtain the SID for a port. | 1910 | * security_port_sid - Obtain the SID for a port. |
| 1888 | * @protocol: protocol number | 1911 | * @protocol: protocol number |
| @@ -2374,6 +2397,7 @@ out: | |||
| 2374 | if (!rc) { | 2397 | if (!rc) { |
| 2375 | avc_ss_reset(seqno); | 2398 | avc_ss_reset(seqno); |
| 2376 | selnl_notify_policyload(seqno); | 2399 | selnl_notify_policyload(seqno); |
| 2400 | selinux_status_update_policyload(seqno); | ||
| 2377 | selinux_xfrm_notify_policyload(); | 2401 | selinux_xfrm_notify_policyload(); |
| 2378 | } | 2402 | } |
| 2379 | return rc; | 2403 | return rc; |
| @@ -3129,3 +3153,38 @@ netlbl_sid_to_secattr_failure: | |||
| 3129 | return rc; | 3153 | return rc; |
| 3130 | } | 3154 | } |
| 3131 | #endif /* CONFIG_NETLABEL */ | 3155 | #endif /* CONFIG_NETLABEL */ |
| 3156 | |||
| 3157 | /** | ||
| 3158 | * security_read_policy - read the policy. | ||
| 3159 | * @data: binary policy data | ||
| 3160 | * @len: length of data in bytes | ||
| 3161 | * | ||
| 3162 | */ | ||
| 3163 | int security_read_policy(void **data, ssize_t *len) | ||
| 3164 | { | ||
| 3165 | int rc; | ||
| 3166 | struct policy_file fp; | ||
| 3167 | |||
| 3168 | if (!ss_initialized) | ||
| 3169 | return -EINVAL; | ||
| 3170 | |||
| 3171 | *len = security_policydb_len(); | ||
| 3172 | |||
| 3173 | *data = vmalloc_user(*len); | ||
| 3174 | if (!*data) | ||
| 3175 | return -ENOMEM; | ||
| 3176 | |||
| 3177 | fp.data = *data; | ||
| 3178 | fp.len = *len; | ||
| 3179 | |||
| 3180 | read_lock(&policy_rwlock); | ||
| 3181 | rc = policydb_write(&policydb, &fp); | ||
| 3182 | read_unlock(&policy_rwlock); | ||
| 3183 | |||
| 3184 | if (rc) | ||
| 3185 | return rc; | ||
| 3186 | |||
| 3187 | *len = (unsigned long)fp.data - (unsigned long)*data; | ||
| 3188 | return 0; | ||
| 3189 | |||
| 3190 | } | ||
