summaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-rw-r--r--security/Kconfig16
-rw-r--r--security/apparmor/crypto.c2
-rw-r--r--security/integrity/Kconfig15
-rw-r--r--security/integrity/Makefile5
-rw-r--r--security/integrity/digsig.c111
-rw-r--r--security/integrity/digsig_asymmetric.c1
-rw-r--r--security/integrity/evm/evm_crypto.c3
-rw-r--r--security/integrity/ima/Kconfig10
-rw-r--r--security/integrity/ima/ima_api.c2
-rw-r--r--security/integrity/ima/ima_appraise.c14
-rw-r--r--security/integrity/ima/ima_kexec.c2
-rw-r--r--security/integrity/ima/ima_main.c23
-rw-r--r--security/integrity/ima/ima_policy.c181
-rw-r--r--security/integrity/integrity.h22
-rw-r--r--security/integrity/platform_certs/efi_parser.c108
-rw-r--r--security/integrity/platform_certs/load_uefi.c194
-rw-r--r--security/integrity/platform_certs/platform_keyring.c58
-rw-r--r--security/keys/encrypted-keys/encrypted.c33
-rw-r--r--security/keys/internal.h2
-rw-r--r--security/keys/keyctl_pkey.c4
-rw-r--r--security/keys/process_keys.c1
-rw-r--r--security/keys/trusted.c6
-rw-r--r--security/selinux/hooks.c5
-rw-r--r--security/selinux/include/security.h2
-rw-r--r--security/selinux/nlmsgtab.c13
-rw-r--r--security/selinux/ss/mls.c34
-rw-r--r--security/selinux/ss/mls.h3
-rw-r--r--security/selinux/ss/policydb.c61
-rw-r--r--security/selinux/ss/services.c222
-rw-r--r--security/selinux/ss/services.h2
-rw-r--r--security/selinux/ss/sidtab.c609
-rw-r--r--security/selinux/ss/sidtab.h96
-rw-r--r--security/selinux/xfrm.c4
33 files changed, 1332 insertions, 532 deletions
diff --git a/security/Kconfig b/security/Kconfig
index d9aa521b5206..e4fe2f3c2c65 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -4,7 +4,7 @@
4 4
5menu "Security options" 5menu "Security options"
6 6
7source security/keys/Kconfig 7source "security/keys/Kconfig"
8 8
9config SECURITY_DMESG_RESTRICT 9config SECURITY_DMESG_RESTRICT
10 bool "Restrict unprivileged access to the kernel syslog" 10 bool "Restrict unprivileged access to the kernel syslog"
@@ -230,14 +230,14 @@ config STATIC_USERMODEHELPER_PATH
230 If you wish for all usermode helper programs to be disabled, 230 If you wish for all usermode helper programs to be disabled,
231 specify an empty string here (i.e. ""). 231 specify an empty string here (i.e. "").
232 232
233source security/selinux/Kconfig 233source "security/selinux/Kconfig"
234source security/smack/Kconfig 234source "security/smack/Kconfig"
235source security/tomoyo/Kconfig 235source "security/tomoyo/Kconfig"
236source security/apparmor/Kconfig 236source "security/apparmor/Kconfig"
237source security/loadpin/Kconfig 237source "security/loadpin/Kconfig"
238source security/yama/Kconfig 238source "security/yama/Kconfig"
239 239
240source security/integrity/Kconfig 240source "security/integrity/Kconfig"
241 241
242choice 242choice
243 prompt "Default security module" 243 prompt "Default security module"
diff --git a/security/apparmor/crypto.c b/security/apparmor/crypto.c
index 136f2a047836..af03d98c7552 100644
--- a/security/apparmor/crypto.c
+++ b/security/apparmor/crypto.c
@@ -112,7 +112,7 @@ static int __init init_profile_hash(void)
112 if (!apparmor_initialized) 112 if (!apparmor_initialized)
113 return 0; 113 return 0;
114 114
115 tfm = crypto_alloc_shash("sha1", 0, CRYPTO_ALG_ASYNC); 115 tfm = crypto_alloc_shash("sha1", 0, 0);
116 if (IS_ERR(tfm)) { 116 if (IS_ERR(tfm)) {
117 int error = PTR_ERR(tfm); 117 int error = PTR_ERR(tfm);
118 AA_ERROR("failed to setup profile sha1 hashing: %d\n", error); 118 AA_ERROR("failed to setup profile sha1 hashing: %d\n", error);
diff --git a/security/integrity/Kconfig b/security/integrity/Kconfig
index da9565891738..2ea4ec9991d5 100644
--- a/security/integrity/Kconfig
+++ b/security/integrity/Kconfig
@@ -51,6 +51,17 @@ config INTEGRITY_TRUSTED_KEYRING
51 .evm keyrings be signed by a key on the system trusted 51 .evm keyrings be signed by a key on the system trusted
52 keyring. 52 keyring.
53 53
54config INTEGRITY_PLATFORM_KEYRING
55 bool "Provide keyring for platform/firmware trusted keys"
56 depends on INTEGRITY_ASYMMETRIC_KEYS
57 depends on SYSTEM_BLACKLIST_KEYRING
58 depends on EFI
59 help
60 Provide a separate, distinct keyring for platform trusted keys, which
61 the kernel automatically populates during initialization from values
62 provided by the platform for verifying the kexec'ed kerned image
63 and, possibly, the initramfs signature.
64
54config INTEGRITY_AUDIT 65config INTEGRITY_AUDIT
55 bool "Enables integrity auditing support " 66 bool "Enables integrity auditing support "
56 depends on AUDIT 67 depends on AUDIT
@@ -66,7 +77,7 @@ config INTEGRITY_AUDIT
66 be enabled by specifying 'integrity_audit=1' on the kernel 77 be enabled by specifying 'integrity_audit=1' on the kernel
67 command line. 78 command line.
68 79
69source security/integrity/ima/Kconfig 80source "security/integrity/ima/Kconfig"
70source security/integrity/evm/Kconfig 81source "security/integrity/evm/Kconfig"
71 82
72endif # if INTEGRITY 83endif # if INTEGRITY
diff --git a/security/integrity/Makefile b/security/integrity/Makefile
index 04d6e462b079..86df9aba8c0f 100644
--- a/security/integrity/Makefile
+++ b/security/integrity/Makefile
@@ -9,6 +9,11 @@ integrity-y := iint.o
9integrity-$(CONFIG_INTEGRITY_AUDIT) += integrity_audit.o 9integrity-$(CONFIG_INTEGRITY_AUDIT) += integrity_audit.o
10integrity-$(CONFIG_INTEGRITY_SIGNATURE) += digsig.o 10integrity-$(CONFIG_INTEGRITY_SIGNATURE) += digsig.o
11integrity-$(CONFIG_INTEGRITY_ASYMMETRIC_KEYS) += digsig_asymmetric.o 11integrity-$(CONFIG_INTEGRITY_ASYMMETRIC_KEYS) += digsig_asymmetric.o
12integrity-$(CONFIG_INTEGRITY_PLATFORM_KEYRING) += platform_certs/platform_keyring.o \
13 platform_certs/efi_parser.o \
14 platform_certs/load_uefi.o
15obj-$(CONFIG_LOAD_UEFI_KEYS) += platform_certs/load_uefi.o
16$(obj)/load_uefi.o: KBUILD_CFLAGS += -fshort-wchar
12 17
13subdir-$(CONFIG_IMA) += ima 18subdir-$(CONFIG_IMA) += ima
14obj-$(CONFIG_IMA) += ima/ 19obj-$(CONFIG_IMA) += ima/
diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c
index 5eacba858e4b..f45d6edecf99 100644
--- a/security/integrity/digsig.c
+++ b/security/integrity/digsig.c
@@ -34,7 +34,7 @@ static const char * const keyring_name[INTEGRITY_KEYRING_MAX] = {
34 ".evm", 34 ".evm",
35 ".ima", 35 ".ima",
36#endif 36#endif
37 "_module", 37 ".platform",
38}; 38};
39 39
40#ifdef CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY 40#ifdef CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY
@@ -73,12 +73,38 @@ int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
73 return -EOPNOTSUPP; 73 return -EOPNOTSUPP;
74} 74}
75 75
76int __init integrity_init_keyring(const unsigned int id) 76static int __integrity_init_keyring(const unsigned int id, key_perm_t perm,
77 struct key_restriction *restriction)
77{ 78{
78 const struct cred *cred = current_cred(); 79 const struct cred *cred = current_cred();
79 struct key_restriction *restriction;
80 int err = 0; 80 int err = 0;
81 81
82 keyring[id] = keyring_alloc(keyring_name[id], KUIDT_INIT(0),
83 KGIDT_INIT(0), cred, perm,
84 KEY_ALLOC_NOT_IN_QUOTA, restriction, NULL);
85 if (IS_ERR(keyring[id])) {
86 err = PTR_ERR(keyring[id]);
87 pr_info("Can't allocate %s keyring (%d)\n",
88 keyring_name[id], err);
89 keyring[id] = NULL;
90 }
91
92 return err;
93}
94
95int __init integrity_init_keyring(const unsigned int id)
96{
97 struct key_restriction *restriction;
98 key_perm_t perm;
99
100 perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW
101 | KEY_USR_READ | KEY_USR_SEARCH;
102
103 if (id == INTEGRITY_KEYRING_PLATFORM) {
104 restriction = NULL;
105 goto out;
106 }
107
82 if (!IS_ENABLED(CONFIG_INTEGRITY_TRUSTED_KEYRING)) 108 if (!IS_ENABLED(CONFIG_INTEGRITY_TRUSTED_KEYRING))
83 return 0; 109 return 0;
84 110
@@ -87,32 +113,43 @@ int __init integrity_init_keyring(const unsigned int id)
87 return -ENOMEM; 113 return -ENOMEM;
88 114
89 restriction->check = restrict_link_to_ima; 115 restriction->check = restrict_link_to_ima;
116 perm |= KEY_USR_WRITE;
90 117
91 keyring[id] = keyring_alloc(keyring_name[id], KUIDT_INIT(0), 118out:
92 KGIDT_INIT(0), cred, 119 return __integrity_init_keyring(id, perm, restriction);
93 ((KEY_POS_ALL & ~KEY_POS_SETATTR) | 120}
94 KEY_USR_VIEW | KEY_USR_READ | 121
95 KEY_USR_WRITE | KEY_USR_SEARCH), 122int __init integrity_add_key(const unsigned int id, const void *data,
96 KEY_ALLOC_NOT_IN_QUOTA, 123 off_t size, key_perm_t perm)
97 restriction, NULL); 124{
98 if (IS_ERR(keyring[id])) { 125 key_ref_t key;
99 err = PTR_ERR(keyring[id]); 126 int rc = 0;
100 pr_info("Can't allocate %s keyring (%d)\n", 127
101 keyring_name[id], err); 128 if (!keyring[id])
102 keyring[id] = NULL; 129 return -EINVAL;
130
131 key = key_create_or_update(make_key_ref(keyring[id], 1), "asymmetric",
132 NULL, data, size, perm,
133 KEY_ALLOC_NOT_IN_QUOTA);
134 if (IS_ERR(key)) {
135 rc = PTR_ERR(key);
136 pr_err("Problem loading X.509 certificate %d\n", rc);
137 } else {
138 pr_notice("Loaded X.509 cert '%s'\n",
139 key_ref_to_ptr(key)->description);
140 key_ref_put(key);
103 } 141 }
104 return err; 142
143 return rc;
144
105} 145}
106 146
107int __init integrity_load_x509(const unsigned int id, const char *path) 147int __init integrity_load_x509(const unsigned int id, const char *path)
108{ 148{
109 key_ref_t key;
110 void *data; 149 void *data;
111 loff_t size; 150 loff_t size;
112 int rc; 151 int rc;
113 152 key_perm_t perm;
114 if (!keyring[id])
115 return -EINVAL;
116 153
117 rc = kernel_read_file_from_path(path, &data, &size, 0, 154 rc = kernel_read_file_from_path(path, &data, &size, 0,
118 READING_X509_CERTIFICATE); 155 READING_X509_CERTIFICATE);
@@ -121,23 +158,21 @@ int __init integrity_load_x509(const unsigned int id, const char *path)
121 return rc; 158 return rc;
122 } 159 }
123 160
124 key = key_create_or_update(make_key_ref(keyring[id], 1), 161 perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW | KEY_USR_READ;
125 "asymmetric", 162
126 NULL, 163 pr_info("Loading X.509 certificate: %s\n", path);
127 data, 164 rc = integrity_add_key(id, (const void *)data, size, perm);
128 size, 165
129 ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
130 KEY_USR_VIEW | KEY_USR_READ),
131 KEY_ALLOC_NOT_IN_QUOTA);
132 if (IS_ERR(key)) {
133 rc = PTR_ERR(key);
134 pr_err("Problem loading X.509 certificate (%d): %s\n",
135 rc, path);
136 } else {
137 pr_notice("Loaded X.509 cert '%s': %s\n",
138 key_ref_to_ptr(key)->description, path);
139 key_ref_put(key);
140 }
141 vfree(data); 166 vfree(data);
142 return 0; 167 return rc;
168}
169
170int __init integrity_load_cert(const unsigned int id, const char *source,
171 const void *data, size_t len, key_perm_t perm)
172{
173 if (!data)
174 return -EINVAL;
175
176 pr_info("Loading X.509 certificate: %s\n", source);
177 return integrity_add_key(id, data, len, perm);
143} 178}
diff --git a/security/integrity/digsig_asymmetric.c b/security/integrity/digsig_asymmetric.c
index 6dc075144508..d775e03fbbcc 100644
--- a/security/integrity/digsig_asymmetric.c
+++ b/security/integrity/digsig_asymmetric.c
@@ -106,6 +106,7 @@ int asymmetric_verify(struct key *keyring, const char *sig,
106 106
107 pks.pkey_algo = "rsa"; 107 pks.pkey_algo = "rsa";
108 pks.hash_algo = hash_algo_name[hdr->hash_algo]; 108 pks.hash_algo = hash_algo_name[hdr->hash_algo];
109 pks.encoding = "pkcs1";
109 pks.digest = (u8 *)data; 110 pks.digest = (u8 *)data;
110 pks.digest_size = datalen; 111 pks.digest_size = datalen;
111 pks.s = hdr->sig; 112 pks.s = hdr->sig;
diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c
index 77ef210a8a6b..43e2dc3a60d0 100644
--- a/security/integrity/evm/evm_crypto.c
+++ b/security/integrity/evm/evm_crypto.c
@@ -97,8 +97,7 @@ static struct shash_desc *init_desc(char type, uint8_t hash_algo)
97 mutex_lock(&mutex); 97 mutex_lock(&mutex);
98 if (*tfm) 98 if (*tfm)
99 goto out; 99 goto out;
100 *tfm = crypto_alloc_shash(algo, 0, 100 *tfm = crypto_alloc_shash(algo, 0, CRYPTO_NOLOAD);
101 CRYPTO_ALG_ASYNC | CRYPTO_NOLOAD);
102 if (IS_ERR(*tfm)) { 101 if (IS_ERR(*tfm)) {
103 rc = PTR_ERR(*tfm); 102 rc = PTR_ERR(*tfm);
104 pr_err("Can not allocate %s (reason: %ld)\n", algo, rc); 103 pr_err("Can not allocate %s (reason: %ld)\n", algo, rc);
diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
index 13b446328dda..a18f8c6d13b5 100644
--- a/security/integrity/ima/Kconfig
+++ b/security/integrity/ima/Kconfig
@@ -157,6 +157,14 @@ config IMA_APPRAISE
157 <http://linux-ima.sourceforge.net> 157 <http://linux-ima.sourceforge.net>
158 If unsure, say N. 158 If unsure, say N.
159 159
160config IMA_ARCH_POLICY
161 bool "Enable loading an IMA architecture specific policy"
162 depends on KEXEC_VERIFY_SIG || IMA_APPRAISE && INTEGRITY_ASYMMETRIC_KEYS
163 default n
164 help
165 This option enables loading an IMA architecture specific policy
166 based on run time secure boot flags.
167
160config IMA_APPRAISE_BUILD_POLICY 168config IMA_APPRAISE_BUILD_POLICY
161 bool "IMA build time configured policy rules" 169 bool "IMA build time configured policy rules"
162 depends on IMA_APPRAISE && INTEGRITY_ASYMMETRIC_KEYS 170 depends on IMA_APPRAISE && INTEGRITY_ASYMMETRIC_KEYS
@@ -217,7 +225,7 @@ config IMA_APPRAISE_REQUIRE_POLICY_SIGS
217 225
218config IMA_APPRAISE_BOOTPARAM 226config IMA_APPRAISE_BOOTPARAM
219 bool "ima_appraise boot parameter" 227 bool "ima_appraise boot parameter"
220 depends on IMA_APPRAISE 228 depends on IMA_APPRAISE && !IMA_ARCH_POLICY
221 default y 229 default y
222 help 230 help
223 This option enables the different "ima_appraise=" modes 231 This option enables the different "ima_appraise=" modes
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index 67dfbd1af3ca..c7505fb122d4 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -335,7 +335,7 @@ void ima_audit_measurement(struct integrity_iint_cache *iint,
335 audit_log_untrustedstring(ab, filename); 335 audit_log_untrustedstring(ab, filename);
336 audit_log_format(ab, " hash=\"%s:%s\"", algo_name, hash); 336 audit_log_format(ab, " hash=\"%s:%s\"", algo_name, hash);
337 337
338 audit_log_task_info(ab, current); 338 audit_log_task_info(ab);
339 audit_log_end(ab); 339 audit_log_end(ab);
340 340
341 iint->flags |= IMA_AUDITED; 341 iint->flags |= IMA_AUDITED;
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
index 2e11e750a067..a2baa85ea2f5 100644
--- a/security/integrity/ima/ima_appraise.c
+++ b/security/integrity/ima/ima_appraise.c
@@ -289,12 +289,22 @@ int ima_appraise_measurement(enum ima_hooks func,
289 case EVM_IMA_XATTR_DIGSIG: 289 case EVM_IMA_XATTR_DIGSIG:
290 set_bit(IMA_DIGSIG, &iint->atomic_flags); 290 set_bit(IMA_DIGSIG, &iint->atomic_flags);
291 rc = integrity_digsig_verify(INTEGRITY_KEYRING_IMA, 291 rc = integrity_digsig_verify(INTEGRITY_KEYRING_IMA,
292 (const char *)xattr_value, rc, 292 (const char *)xattr_value,
293 xattr_len,
293 iint->ima_hash->digest, 294 iint->ima_hash->digest,
294 iint->ima_hash->length); 295 iint->ima_hash->length);
295 if (rc == -EOPNOTSUPP) { 296 if (rc == -EOPNOTSUPP) {
296 status = INTEGRITY_UNKNOWN; 297 status = INTEGRITY_UNKNOWN;
297 } else if (rc) { 298 break;
299 }
300 if (IS_ENABLED(CONFIG_INTEGRITY_PLATFORM_KEYRING) && rc &&
301 func == KEXEC_KERNEL_CHECK)
302 rc = integrity_digsig_verify(INTEGRITY_KEYRING_PLATFORM,
303 (const char *)xattr_value,
304 xattr_len,
305 iint->ima_hash->digest,
306 iint->ima_hash->length);
307 if (rc) {
298 cause = "invalid-signature"; 308 cause = "invalid-signature";
299 status = INTEGRITY_FAIL; 309 status = INTEGRITY_FAIL;
300 } else { 310 } else {
diff --git a/security/integrity/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c
index 16bd18747cfa..d6f32807b347 100644
--- a/security/integrity/ima/ima_kexec.c
+++ b/security/integrity/ima/ima_kexec.c
@@ -106,7 +106,7 @@ void ima_add_kexec_buffer(struct kimage *image)
106 kexec_segment_size = ALIGN(ima_get_binary_runtime_size() + 106 kexec_segment_size = ALIGN(ima_get_binary_runtime_size() +
107 PAGE_SIZE / 2, PAGE_SIZE); 107 PAGE_SIZE / 2, PAGE_SIZE);
108 if ((kexec_segment_size == ULONG_MAX) || 108 if ((kexec_segment_size == ULONG_MAX) ||
109 ((kexec_segment_size >> PAGE_SHIFT) > totalram_pages / 2)) { 109 ((kexec_segment_size >> PAGE_SHIFT) > totalram_pages() / 2)) {
110 pr_err("Binary measurement list too large.\n"); 110 pr_err("Binary measurement list too large.\n");
111 return; 111 return;
112 } 112 }
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index adaf96932237..4ffac4f5c647 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -21,7 +21,7 @@
21 21
22#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 22#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
23 23
24#include <linux/init.h> 24#include <linux/module.h>
25#include <linux/file.h> 25#include <linux/file.h>
26#include <linux/binfmts.h> 26#include <linux/binfmts.h>
27#include <linux/mount.h> 27#include <linux/mount.h>
@@ -105,7 +105,7 @@ static void ima_rdwr_violation_check(struct file *file,
105 } else { 105 } else {
106 if (must_measure) 106 if (must_measure)
107 set_bit(IMA_MUST_MEASURE, &iint->atomic_flags); 107 set_bit(IMA_MUST_MEASURE, &iint->atomic_flags);
108 if ((atomic_read(&inode->i_writecount) > 0) && must_measure) 108 if (inode_is_open_for_write(inode) && must_measure)
109 send_writers = true; 109 send_writers = true;
110 } 110 }
111 111
@@ -507,20 +507,26 @@ int ima_post_read_file(struct file *file, void *buf, loff_t size,
507 */ 507 */
508int ima_load_data(enum kernel_load_data_id id) 508int ima_load_data(enum kernel_load_data_id id)
509{ 509{
510 bool sig_enforce; 510 bool ima_enforce, sig_enforce;
511 511
512 if ((ima_appraise & IMA_APPRAISE_ENFORCE) != IMA_APPRAISE_ENFORCE) 512 ima_enforce =
513 return 0; 513 (ima_appraise & IMA_APPRAISE_ENFORCE) == IMA_APPRAISE_ENFORCE;
514 514
515 switch (id) { 515 switch (id) {
516 case LOADING_KEXEC_IMAGE: 516 case LOADING_KEXEC_IMAGE:
517 if (ima_appraise & IMA_APPRAISE_KEXEC) { 517 if (IS_ENABLED(CONFIG_KEXEC_VERIFY_SIG)
518 && arch_ima_get_secureboot()) {
519 pr_err("impossible to appraise a kernel image without a file descriptor; try using kexec_file_load syscall.\n");
520 return -EACCES;
521 }
522
523 if (ima_enforce && (ima_appraise & IMA_APPRAISE_KEXEC)) {
518 pr_err("impossible to appraise a kernel image without a file descriptor; try using kexec_file_load syscall.\n"); 524 pr_err("impossible to appraise a kernel image without a file descriptor; try using kexec_file_load syscall.\n");
519 return -EACCES; /* INTEGRITY_UNKNOWN */ 525 return -EACCES; /* INTEGRITY_UNKNOWN */
520 } 526 }
521 break; 527 break;
522 case LOADING_FIRMWARE: 528 case LOADING_FIRMWARE:
523 if (ima_appraise & IMA_APPRAISE_FIRMWARE) { 529 if (ima_enforce && (ima_appraise & IMA_APPRAISE_FIRMWARE)) {
524 pr_err("Prevent firmware sysfs fallback loading.\n"); 530 pr_err("Prevent firmware sysfs fallback loading.\n");
525 return -EACCES; /* INTEGRITY_UNKNOWN */ 531 return -EACCES; /* INTEGRITY_UNKNOWN */
526 } 532 }
@@ -528,7 +534,8 @@ int ima_load_data(enum kernel_load_data_id id)
528 case LOADING_MODULE: 534 case LOADING_MODULE:
529 sig_enforce = is_module_sig_enforced(); 535 sig_enforce = is_module_sig_enforced();
530 536
531 if (!sig_enforce && (ima_appraise & IMA_APPRAISE_MODULES)) { 537 if (ima_enforce && (!sig_enforce
538 && (ima_appraise & IMA_APPRAISE_MODULES))) {
532 pr_err("impossible to appraise a module without a file descriptor. sig_enforce kernel parameter might help\n"); 539 pr_err("impossible to appraise a module without a file descriptor. sig_enforce kernel parameter might help\n");
533 return -EACCES; /* INTEGRITY_UNKNOWN */ 540 return -EACCES; /* INTEGRITY_UNKNOWN */
534 } 541 }
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index 3778dc396193..8bc8a1c8cb3f 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -20,6 +20,7 @@
20#include <linux/rculist.h> 20#include <linux/rculist.h>
21#include <linux/genhd.h> 21#include <linux/genhd.h>
22#include <linux/seq_file.h> 22#include <linux/seq_file.h>
23#include <linux/ima.h>
23 24
24#include "ima.h" 25#include "ima.h"
25 26
@@ -58,6 +59,8 @@ enum lsm_rule_types { LSM_OBJ_USER, LSM_OBJ_ROLE, LSM_OBJ_TYPE,
58 59
59enum policy_types { ORIGINAL_TCB = 1, DEFAULT_TCB }; 60enum policy_types { ORIGINAL_TCB = 1, DEFAULT_TCB };
60 61
62enum policy_rule_list { IMA_DEFAULT_POLICY = 1, IMA_CUSTOM_POLICY };
63
61struct ima_rule_entry { 64struct ima_rule_entry {
62 struct list_head list; 65 struct list_head list;
63 int action; 66 int action;
@@ -104,7 +107,8 @@ static struct ima_rule_entry dont_measure_rules[] __ro_after_init = {
104 .flags = IMA_FSMAGIC}, 107 .flags = IMA_FSMAGIC},
105 {.action = DONT_MEASURE, .fsmagic = CGROUP2_SUPER_MAGIC, 108 {.action = DONT_MEASURE, .fsmagic = CGROUP2_SUPER_MAGIC,
106 .flags = IMA_FSMAGIC}, 109 .flags = IMA_FSMAGIC},
107 {.action = DONT_MEASURE, .fsmagic = NSFS_MAGIC, .flags = IMA_FSMAGIC} 110 {.action = DONT_MEASURE, .fsmagic = NSFS_MAGIC, .flags = IMA_FSMAGIC},
111 {.action = DONT_MEASURE, .fsmagic = EFIVARFS_MAGIC, .flags = IMA_FSMAGIC}
108}; 112};
109 113
110static struct ima_rule_entry original_measurement_rules[] __ro_after_init = { 114static struct ima_rule_entry original_measurement_rules[] __ro_after_init = {
@@ -147,6 +151,7 @@ static struct ima_rule_entry default_appraise_rules[] __ro_after_init = {
147 {.action = DONT_APPRAISE, .fsmagic = SELINUX_MAGIC, .flags = IMA_FSMAGIC}, 151 {.action = DONT_APPRAISE, .fsmagic = SELINUX_MAGIC, .flags = IMA_FSMAGIC},
148 {.action = DONT_APPRAISE, .fsmagic = SMACK_MAGIC, .flags = IMA_FSMAGIC}, 152 {.action = DONT_APPRAISE, .fsmagic = SMACK_MAGIC, .flags = IMA_FSMAGIC},
149 {.action = DONT_APPRAISE, .fsmagic = NSFS_MAGIC, .flags = IMA_FSMAGIC}, 153 {.action = DONT_APPRAISE, .fsmagic = NSFS_MAGIC, .flags = IMA_FSMAGIC},
154 {.action = DONT_APPRAISE, .fsmagic = EFIVARFS_MAGIC, .flags = IMA_FSMAGIC},
150 {.action = DONT_APPRAISE, .fsmagic = CGROUP_SUPER_MAGIC, .flags = IMA_FSMAGIC}, 155 {.action = DONT_APPRAISE, .fsmagic = CGROUP_SUPER_MAGIC, .flags = IMA_FSMAGIC},
151 {.action = DONT_APPRAISE, .fsmagic = CGROUP2_SUPER_MAGIC, .flags = IMA_FSMAGIC}, 156 {.action = DONT_APPRAISE, .fsmagic = CGROUP2_SUPER_MAGIC, .flags = IMA_FSMAGIC},
152#ifdef CONFIG_IMA_WRITE_POLICY 157#ifdef CONFIG_IMA_WRITE_POLICY
@@ -193,6 +198,9 @@ static struct ima_rule_entry secure_boot_rules[] __ro_after_init = {
193 .flags = IMA_FUNC | IMA_DIGSIG_REQUIRED}, 198 .flags = IMA_FUNC | IMA_DIGSIG_REQUIRED},
194}; 199};
195 200
201/* An array of architecture specific rules */
202struct ima_rule_entry *arch_policy_entry __ro_after_init;
203
196static LIST_HEAD(ima_default_rules); 204static LIST_HEAD(ima_default_rules);
197static LIST_HEAD(ima_policy_rules); 205static LIST_HEAD(ima_policy_rules);
198static LIST_HEAD(ima_temp_rules); 206static LIST_HEAD(ima_temp_rules);
@@ -473,6 +481,75 @@ static int ima_appraise_flag(enum ima_hooks func)
473 return 0; 481 return 0;
474} 482}
475 483
484static void add_rules(struct ima_rule_entry *entries, int count,
485 enum policy_rule_list policy_rule)
486{
487 int i = 0;
488
489 for (i = 0; i < count; i++) {
490 struct ima_rule_entry *entry;
491
492 if (policy_rule & IMA_DEFAULT_POLICY)
493 list_add_tail(&entries[i].list, &ima_default_rules);
494
495 if (policy_rule & IMA_CUSTOM_POLICY) {
496 entry = kmemdup(&entries[i], sizeof(*entry),
497 GFP_KERNEL);
498 if (!entry)
499 continue;
500
501 list_add_tail(&entry->list, &ima_policy_rules);
502 }
503 if (entries[i].action == APPRAISE)
504 temp_ima_appraise |= ima_appraise_flag(entries[i].func);
505 if (entries[i].func == POLICY_CHECK)
506 temp_ima_appraise |= IMA_APPRAISE_POLICY;
507 }
508}
509
510static int ima_parse_rule(char *rule, struct ima_rule_entry *entry);
511
512static int __init ima_init_arch_policy(void)
513{
514 const char * const *arch_rules;
515 const char * const *rules;
516 int arch_entries = 0;
517 int i = 0;
518
519 arch_rules = arch_get_ima_policy();
520 if (!arch_rules)
521 return arch_entries;
522
523 /* Get number of rules */
524 for (rules = arch_rules; *rules != NULL; rules++)
525 arch_entries++;
526
527 arch_policy_entry = kcalloc(arch_entries + 1,
528 sizeof(*arch_policy_entry), GFP_KERNEL);
529 if (!arch_policy_entry)
530 return 0;
531
532 /* Convert each policy string rules to struct ima_rule_entry format */
533 for (rules = arch_rules, i = 0; *rules != NULL; rules++) {
534 char rule[255];
535 int result;
536
537 result = strlcpy(rule, *rules, sizeof(rule));
538
539 INIT_LIST_HEAD(&arch_policy_entry[i].list);
540 result = ima_parse_rule(rule, &arch_policy_entry[i]);
541 if (result) {
542 pr_warn("Skipping unknown architecture policy rule: %s\n",
543 rule);
544 memset(&arch_policy_entry[i], 0,
545 sizeof(*arch_policy_entry));
546 continue;
547 }
548 i++;
549 }
550 return i;
551}
552
476/** 553/**
477 * ima_init_policy - initialize the default measure rules. 554 * ima_init_policy - initialize the default measure rules.
478 * 555 *
@@ -481,68 +558,68 @@ static int ima_appraise_flag(enum ima_hooks func)
481 */ 558 */
482void __init ima_init_policy(void) 559void __init ima_init_policy(void)
483{ 560{
484 int i, measure_entries, appraise_entries, secure_boot_entries; 561 int build_appraise_entries, arch_entries;
485 562
486 /* if !ima_policy set entries = 0 so we load NO default rules */ 563 /* if !ima_policy, we load NO default rules */
487 measure_entries = ima_policy ? ARRAY_SIZE(dont_measure_rules) : 0; 564 if (ima_policy)
488 appraise_entries = ima_use_appraise_tcb ? 565 add_rules(dont_measure_rules, ARRAY_SIZE(dont_measure_rules),
489 ARRAY_SIZE(default_appraise_rules) : 0; 566 IMA_DEFAULT_POLICY);
490 secure_boot_entries = ima_use_secure_boot ?
491 ARRAY_SIZE(secure_boot_rules) : 0;
492
493 for (i = 0; i < measure_entries; i++)
494 list_add_tail(&dont_measure_rules[i].list, &ima_default_rules);
495 567
496 switch (ima_policy) { 568 switch (ima_policy) {
497 case ORIGINAL_TCB: 569 case ORIGINAL_TCB:
498 for (i = 0; i < ARRAY_SIZE(original_measurement_rules); i++) 570 add_rules(original_measurement_rules,
499 list_add_tail(&original_measurement_rules[i].list, 571 ARRAY_SIZE(original_measurement_rules),
500 &ima_default_rules); 572 IMA_DEFAULT_POLICY);
501 break; 573 break;
502 case DEFAULT_TCB: 574 case DEFAULT_TCB:
503 for (i = 0; i < ARRAY_SIZE(default_measurement_rules); i++) 575 add_rules(default_measurement_rules,
504 list_add_tail(&default_measurement_rules[i].list, 576 ARRAY_SIZE(default_measurement_rules),
505 &ima_default_rules); 577 IMA_DEFAULT_POLICY);
506 default: 578 default:
507 break; 579 break;
508 } 580 }
509 581
510 /* 582 /*
583 * Based on runtime secure boot flags, insert arch specific measurement
584 * and appraise rules requiring file signatures for both the initial
585 * and custom policies, prior to other appraise rules.
586 * (Highest priority)
587 */
588 arch_entries = ima_init_arch_policy();
589 if (!arch_entries)
590 pr_info("No architecture policies found\n");
591 else
592 add_rules(arch_policy_entry, arch_entries,
593 IMA_DEFAULT_POLICY | IMA_CUSTOM_POLICY);
594
595 /*
511 * Insert the builtin "secure_boot" policy rules requiring file 596 * Insert the builtin "secure_boot" policy rules requiring file
512 * signatures, prior to any other appraise rules. 597 * signatures, prior to other appraise rules.
513 */ 598 */
514 for (i = 0; i < secure_boot_entries; i++) { 599 if (ima_use_secure_boot)
515 list_add_tail(&secure_boot_rules[i].list, &ima_default_rules); 600 add_rules(secure_boot_rules, ARRAY_SIZE(secure_boot_rules),
516 temp_ima_appraise |= 601 IMA_DEFAULT_POLICY);
517 ima_appraise_flag(secure_boot_rules[i].func);
518 }
519 602
520 /* 603 /*
521 * Insert the build time appraise rules requiring file signatures 604 * Insert the build time appraise rules requiring file signatures
522 * for both the initial and custom policies, prior to other appraise 605 * for both the initial and custom policies, prior to other appraise
523 * rules. 606 * rules. As the secure boot rules includes all of the build time
607 * rules, include either one or the other set of rules, but not both.
524 */ 608 */
525 for (i = 0; i < ARRAY_SIZE(build_appraise_rules); i++) { 609 build_appraise_entries = ARRAY_SIZE(build_appraise_rules);
526 struct ima_rule_entry *entry; 610 if (build_appraise_entries) {
527 611 if (ima_use_secure_boot)
528 if (!secure_boot_entries) 612 add_rules(build_appraise_rules, build_appraise_entries,
529 list_add_tail(&build_appraise_rules[i].list, 613 IMA_CUSTOM_POLICY);
530 &ima_default_rules); 614 else
531 615 add_rules(build_appraise_rules, build_appraise_entries,
532 entry = kmemdup(&build_appraise_rules[i], sizeof(*entry), 616 IMA_DEFAULT_POLICY | IMA_CUSTOM_POLICY);
533 GFP_KERNEL);
534 if (entry)
535 list_add_tail(&entry->list, &ima_policy_rules);
536 build_ima_appraise |=
537 ima_appraise_flag(build_appraise_rules[i].func);
538 } 617 }
539 618
540 for (i = 0; i < appraise_entries; i++) { 619 if (ima_use_appraise_tcb)
541 list_add_tail(&default_appraise_rules[i].list, 620 add_rules(default_appraise_rules,
542 &ima_default_rules); 621 ARRAY_SIZE(default_appraise_rules),
543 if (default_appraise_rules[i].func == POLICY_CHECK) 622 IMA_DEFAULT_POLICY);
544 temp_ima_appraise |= IMA_APPRAISE_POLICY;
545 }
546 623
547 ima_rules = &ima_default_rules; 624 ima_rules = &ima_default_rules;
548 ima_update_policy_flag(); 625 ima_update_policy_flag();
@@ -576,13 +653,21 @@ void ima_update_policy(void)
576 if (ima_rules != policy) { 653 if (ima_rules != policy) {
577 ima_policy_flag = 0; 654 ima_policy_flag = 0;
578 ima_rules = policy; 655 ima_rules = policy;
656
657 /*
658 * IMA architecture specific policy rules are specified
659 * as strings and converted to an array of ima_entry_rules
660 * on boot. After loading a custom policy, free the
661 * architecture specific rules stored as an array.
662 */
663 kfree(arch_policy_entry);
579 } 664 }
580 ima_update_policy_flag(); 665 ima_update_policy_flag();
581} 666}
582 667
668/* Keep the enumeration in sync with the policy_tokens! */
583enum { 669enum {
584 Opt_err = -1, 670 Opt_measure, Opt_dont_measure,
585 Opt_measure = 1, Opt_dont_measure,
586 Opt_appraise, Opt_dont_appraise, 671 Opt_appraise, Opt_dont_appraise,
587 Opt_audit, Opt_hash, Opt_dont_hash, 672 Opt_audit, Opt_hash, Opt_dont_hash,
588 Opt_obj_user, Opt_obj_role, Opt_obj_type, 673 Opt_obj_user, Opt_obj_role, Opt_obj_type,
@@ -592,10 +677,10 @@ enum {
592 Opt_uid_gt, Opt_euid_gt, Opt_fowner_gt, 677 Opt_uid_gt, Opt_euid_gt, Opt_fowner_gt,
593 Opt_uid_lt, Opt_euid_lt, Opt_fowner_lt, 678 Opt_uid_lt, Opt_euid_lt, Opt_fowner_lt,
594 Opt_appraise_type, Opt_permit_directio, 679 Opt_appraise_type, Opt_permit_directio,
595 Opt_pcr 680 Opt_pcr, Opt_err
596}; 681};
597 682
598static match_table_t policy_tokens = { 683static const match_table_t policy_tokens = {
599 {Opt_measure, "measure"}, 684 {Opt_measure, "measure"},
600 {Opt_dont_measure, "dont_measure"}, 685 {Opt_dont_measure, "dont_measure"},
601 {Opt_appraise, "appraise"}, 686 {Opt_appraise, "appraise"},
@@ -1103,7 +1188,7 @@ void ima_policy_stop(struct seq_file *m, void *v)
1103{ 1188{
1104} 1189}
1105 1190
1106#define pt(token) policy_tokens[token + Opt_err].pattern 1191#define pt(token) policy_tokens[token].pattern
1107#define mt(token) mask_tokens[token] 1192#define mt(token) mask_tokens[token]
1108 1193
1109/* 1194/*
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
index e60473b13a8d..7de59f44cba3 100644
--- a/security/integrity/integrity.h
+++ b/security/integrity/integrity.h
@@ -141,7 +141,7 @@ int integrity_kernel_read(struct file *file, loff_t offset,
141 141
142#define INTEGRITY_KEYRING_EVM 0 142#define INTEGRITY_KEYRING_EVM 0
143#define INTEGRITY_KEYRING_IMA 1 143#define INTEGRITY_KEYRING_IMA 1
144#define INTEGRITY_KEYRING_MODULE 2 144#define INTEGRITY_KEYRING_PLATFORM 2
145#define INTEGRITY_KEYRING_MAX 3 145#define INTEGRITY_KEYRING_MAX 3
146 146
147extern struct dentry *integrity_dir; 147extern struct dentry *integrity_dir;
@@ -153,6 +153,8 @@ int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
153 153
154int __init integrity_init_keyring(const unsigned int id); 154int __init integrity_init_keyring(const unsigned int id);
155int __init integrity_load_x509(const unsigned int id, const char *path); 155int __init integrity_load_x509(const unsigned int id, const char *path);
156int __init integrity_load_cert(const unsigned int id, const char *source,
157 const void *data, size_t len, key_perm_t perm);
156#else 158#else
157 159
158static inline int integrity_digsig_verify(const unsigned int id, 160static inline int integrity_digsig_verify(const unsigned int id,
@@ -166,6 +168,14 @@ static inline int integrity_init_keyring(const unsigned int id)
166{ 168{
167 return 0; 169 return 0;
168} 170}
171
172static inline int __init integrity_load_cert(const unsigned int id,
173 const char *source,
174 const void *data, size_t len,
175 key_perm_t perm)
176{
177 return 0;
178}
169#endif /* CONFIG_INTEGRITY_SIGNATURE */ 179#endif /* CONFIG_INTEGRITY_SIGNATURE */
170 180
171#ifdef CONFIG_INTEGRITY_ASYMMETRIC_KEYS 181#ifdef CONFIG_INTEGRITY_ASYMMETRIC_KEYS
@@ -222,3 +232,13 @@ integrity_audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, int type)
222} 232}
223 233
224#endif 234#endif
235
236#ifdef CONFIG_INTEGRITY_PLATFORM_KEYRING
237void __init add_to_platform_keyring(const char *source, const void *data,
238 size_t len);
239#else
240static inline void __init add_to_platform_keyring(const char *source,
241 const void *data, size_t len)
242{
243}
244#endif
diff --git a/security/integrity/platform_certs/efi_parser.c b/security/integrity/platform_certs/efi_parser.c
new file mode 100644
index 000000000000..18f01f36fe6a
--- /dev/null
+++ b/security/integrity/platform_certs/efi_parser.c
@@ -0,0 +1,108 @@
1// SPDX-License-Identifier: GPL-2.0+
2/* EFI signature/key/certificate list parser
3 *
4 * Copyright (C) 2012, 2016 Red Hat, Inc. All Rights Reserved.
5 * Written by David Howells (dhowells@redhat.com)
6 */
7
8#define pr_fmt(fmt) "EFI: "fmt
9#include <linux/module.h>
10#include <linux/printk.h>
11#include <linux/err.h>
12#include <linux/efi.h>
13
14/**
15 * parse_efi_signature_list - Parse an EFI signature list for certificates
16 * @source: The source of the key
17 * @data: The data blob to parse
18 * @size: The size of the data blob
19 * @get_handler_for_guid: Get the handler func for the sig type (or NULL)
20 *
21 * Parse an EFI signature list looking for elements of interest. A list is
22 * made up of a series of sublists, where all the elements in a sublist are of
23 * the same type, but sublists can be of different types.
24 *
25 * For each sublist encountered, the @get_handler_for_guid function is called
26 * with the type specifier GUID and returns either a pointer to a function to
27 * handle elements of that type or NULL if the type is not of interest.
28 *
29 * If the sublist is of interest, each element is passed to the handler
30 * function in turn.
31 *
32 * Error EBADMSG is returned if the list doesn't parse correctly and 0 is
33 * returned if the list was parsed correctly. No error can be returned from
34 * the @get_handler_for_guid function or the element handler function it
35 * returns.
36 */
37int __init parse_efi_signature_list(
38 const char *source,
39 const void *data, size_t size,
40 efi_element_handler_t (*get_handler_for_guid)(const efi_guid_t *))
41{
42 efi_element_handler_t handler;
43 unsigned int offs = 0;
44
45 pr_devel("-->%s(,%zu)\n", __func__, size);
46
47 while (size > 0) {
48 const efi_signature_data_t *elem;
49 efi_signature_list_t list;
50 size_t lsize, esize, hsize, elsize;
51
52 if (size < sizeof(list))
53 return -EBADMSG;
54
55 memcpy(&list, data, sizeof(list));
56 pr_devel("LIST[%04x] guid=%pUl ls=%x hs=%x ss=%x\n",
57 offs,
58 list.signature_type.b, list.signature_list_size,
59 list.signature_header_size, list.signature_size);
60
61 lsize = list.signature_list_size;
62 hsize = list.signature_header_size;
63 esize = list.signature_size;
64 elsize = lsize - sizeof(list) - hsize;
65
66 if (lsize > size) {
67 pr_devel("<--%s() = -EBADMSG [overrun @%x]\n",
68 __func__, offs);
69 return -EBADMSG;
70 }
71
72 if (lsize < sizeof(list) ||
73 lsize - sizeof(list) < hsize ||
74 esize < sizeof(*elem) ||
75 elsize < esize ||
76 elsize % esize != 0) {
77 pr_devel("- bad size combo @%x\n", offs);
78 return -EBADMSG;
79 }
80
81 handler = get_handler_for_guid(&list.signature_type);
82 if (!handler) {
83 data += lsize;
84 size -= lsize;
85 offs += lsize;
86 continue;
87 }
88
89 data += sizeof(list) + hsize;
90 size -= sizeof(list) + hsize;
91 offs += sizeof(list) + hsize;
92
93 for (; elsize > 0; elsize -= esize) {
94 elem = data;
95
96 pr_devel("ELEM[%04x]\n", offs);
97 handler(source,
98 &elem->signature_data,
99 esize - sizeof(*elem));
100
101 data += esize;
102 size -= esize;
103 offs += esize;
104 }
105 }
106
107 return 0;
108}
diff --git a/security/integrity/platform_certs/load_uefi.c b/security/integrity/platform_certs/load_uefi.c
new file mode 100644
index 000000000000..81b19c52832b
--- /dev/null
+++ b/security/integrity/platform_certs/load_uefi.c
@@ -0,0 +1,194 @@
1// SPDX-License-Identifier: GPL-2.0
2
3#include <linux/kernel.h>
4#include <linux/sched.h>
5#include <linux/cred.h>
6#include <linux/err.h>
7#include <linux/efi.h>
8#include <linux/slab.h>
9#include <keys/asymmetric-type.h>
10#include <keys/system_keyring.h>
11#include "../integrity.h"
12
13static efi_guid_t efi_cert_x509_guid __initdata = EFI_CERT_X509_GUID;
14static efi_guid_t efi_cert_x509_sha256_guid __initdata =
15 EFI_CERT_X509_SHA256_GUID;
16static efi_guid_t efi_cert_sha256_guid __initdata = EFI_CERT_SHA256_GUID;
17
18/*
19 * Look to see if a UEFI variable called MokIgnoreDB exists and return true if
20 * it does.
21 *
22 * This UEFI variable is set by the shim if a user tells the shim to not use
23 * the certs/hashes in the UEFI db variable for verification purposes. If it
24 * is set, we should ignore the db variable also and the true return indicates
25 * this.
26 */
27static __init bool uefi_check_ignore_db(void)
28{
29 efi_status_t status;
30 unsigned int db = 0;
31 unsigned long size = sizeof(db);
32 efi_guid_t guid = EFI_SHIM_LOCK_GUID;
33
34 status = efi.get_variable(L"MokIgnoreDB", &guid, NULL, &size, &db);
35 return status == EFI_SUCCESS;
36}
37
38/*
39 * Get a certificate list blob from the named EFI variable.
40 */
41static __init void *get_cert_list(efi_char16_t *name, efi_guid_t *guid,
42 unsigned long *size)
43{
44 efi_status_t status;
45 unsigned long lsize = 4;
46 unsigned long tmpdb[4];
47 void *db;
48
49 status = efi.get_variable(name, guid, NULL, &lsize, &tmpdb);
50 if (status != EFI_BUFFER_TOO_SMALL) {
51 pr_err("Couldn't get size: 0x%lx\n", status);
52 return NULL;
53 }
54
55 db = kmalloc(lsize, GFP_KERNEL);
56 if (!db)
57 return NULL;
58
59 status = efi.get_variable(name, guid, NULL, &lsize, db);
60 if (status != EFI_SUCCESS) {
61 kfree(db);
62 pr_err("Error reading db var: 0x%lx\n", status);
63 return NULL;
64 }
65
66 *size = lsize;
67 return db;
68}
69
70/*
71 * Blacklist a hash.
72 */
73static __init void uefi_blacklist_hash(const char *source, const void *data,
74 size_t len, const char *type,
75 size_t type_len)
76{
77 char *hash, *p;
78
79 hash = kmalloc(type_len + len * 2 + 1, GFP_KERNEL);
80 if (!hash)
81 return;
82 p = memcpy(hash, type, type_len);
83 p += type_len;
84 bin2hex(p, data, len);
85 p += len * 2;
86 *p = 0;
87
88 mark_hash_blacklisted(hash);
89 kfree(hash);
90}
91
92/*
93 * Blacklist an X509 TBS hash.
94 */
95static __init void uefi_blacklist_x509_tbs(const char *source,
96 const void *data, size_t len)
97{
98 uefi_blacklist_hash(source, data, len, "tbs:", 4);
99}
100
101/*
102 * Blacklist the hash of an executable.
103 */
104static __init void uefi_blacklist_binary(const char *source,
105 const void *data, size_t len)
106{
107 uefi_blacklist_hash(source, data, len, "bin:", 4);
108}
109
110/*
111 * Return the appropriate handler for particular signature list types found in
112 * the UEFI db and MokListRT tables.
113 */
114static __init efi_element_handler_t get_handler_for_db(const efi_guid_t *
115 sig_type)
116{
117 if (efi_guidcmp(*sig_type, efi_cert_x509_guid) == 0)
118 return add_to_platform_keyring;
119 return 0;
120}
121
122/*
123 * Return the appropriate handler for particular signature list types found in
124 * the UEFI dbx and MokListXRT tables.
125 */
126static __init efi_element_handler_t get_handler_for_dbx(const efi_guid_t *
127 sig_type)
128{
129 if (efi_guidcmp(*sig_type, efi_cert_x509_sha256_guid) == 0)
130 return uefi_blacklist_x509_tbs;
131 if (efi_guidcmp(*sig_type, efi_cert_sha256_guid) == 0)
132 return uefi_blacklist_binary;
133 return 0;
134}
135
136/*
137 * Load the certs contained in the UEFI databases into the platform trusted
138 * keyring and the UEFI blacklisted X.509 cert SHA256 hashes into the blacklist
139 * keyring.
140 */
141static int __init load_uefi_certs(void)
142{
143 efi_guid_t secure_var = EFI_IMAGE_SECURITY_DATABASE_GUID;
144 efi_guid_t mok_var = EFI_SHIM_LOCK_GUID;
145 void *db = NULL, *dbx = NULL, *mok = NULL;
146 unsigned long dbsize = 0, dbxsize = 0, moksize = 0;
147 int rc = 0;
148
149 if (!efi.get_variable)
150 return false;
151
152 /* Get db, MokListRT, and dbx. They might not exist, so it isn't
153 * an error if we can't get them.
154 */
155 if (!uefi_check_ignore_db()) {
156 db = get_cert_list(L"db", &secure_var, &dbsize);
157 if (!db) {
158 pr_err("MODSIGN: Couldn't get UEFI db list\n");
159 } else {
160 rc = parse_efi_signature_list("UEFI:db",
161 db, dbsize, get_handler_for_db);
162 if (rc)
163 pr_err("Couldn't parse db signatures: %d\n",
164 rc);
165 kfree(db);
166 }
167 }
168
169 mok = get_cert_list(L"MokListRT", &mok_var, &moksize);
170 if (!mok) {
171 pr_info("Couldn't get UEFI MokListRT\n");
172 } else {
173 rc = parse_efi_signature_list("UEFI:MokListRT",
174 mok, moksize, get_handler_for_db);
175 if (rc)
176 pr_err("Couldn't parse MokListRT signatures: %d\n", rc);
177 kfree(mok);
178 }
179
180 dbx = get_cert_list(L"dbx", &secure_var, &dbxsize);
181 if (!dbx) {
182 pr_info("Couldn't get UEFI dbx list\n");
183 } else {
184 rc = parse_efi_signature_list("UEFI:dbx",
185 dbx, dbxsize,
186 get_handler_for_dbx);
187 if (rc)
188 pr_err("Couldn't parse dbx signatures: %d\n", rc);
189 kfree(dbx);
190 }
191
192 return rc;
193}
194late_initcall(load_uefi_certs);
diff --git a/security/integrity/platform_certs/platform_keyring.c b/security/integrity/platform_certs/platform_keyring.c
new file mode 100644
index 000000000000..bcafd7387729
--- /dev/null
+++ b/security/integrity/platform_certs/platform_keyring.c
@@ -0,0 +1,58 @@
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Platform keyring for firmware/platform keys
4 *
5 * Copyright IBM Corporation, 2018
6 * Author(s): Nayna Jain <nayna@linux.ibm.com>
7 */
8
9#include <linux/export.h>
10#include <linux/kernel.h>
11#include <linux/sched.h>
12#include <linux/cred.h>
13#include <linux/err.h>
14#include <linux/slab.h>
15#include "../integrity.h"
16
17/**
18 * add_to_platform_keyring - Add to platform keyring without validation.
19 * @source: Source of key
20 * @data: The blob holding the key
21 * @len: The length of the data blob
22 *
23 * Add a key to the platform keyring without checking its trust chain. This
24 * is available only during kernel initialisation.
25 */
26void __init add_to_platform_keyring(const char *source, const void *data,
27 size_t len)
28{
29 key_perm_t perm;
30 int rc;
31
32 perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW;
33
34 rc = integrity_load_cert(INTEGRITY_KEYRING_PLATFORM, source, data, len,
35 perm);
36 if (rc)
37 pr_info("Error adding keys to platform keyring %s\n", source);
38}
39
40/*
41 * Create the trusted keyrings.
42 */
43static __init int platform_keyring_init(void)
44{
45 int rc;
46
47 rc = integrity_init_keyring(INTEGRITY_KEYRING_PLATFORM);
48 if (rc)
49 return rc;
50
51 pr_notice("Platform Keyring initialized\n");
52 return 0;
53}
54
55/*
56 * Must be initialised before we try and load the keys into the keyring.
57 */
58device_initcall(platform_keyring_init);
diff --git a/security/keys/encrypted-keys/encrypted.c b/security/keys/encrypted-keys/encrypted.c
index d92cbf9687c3..389a298274d3 100644
--- a/security/keys/encrypted-keys/encrypted.c
+++ b/security/keys/encrypted-keys/encrypted.c
@@ -45,6 +45,7 @@ static const char hmac_alg[] = "hmac(sha256)";
45static const char blkcipher_alg[] = "cbc(aes)"; 45static const char blkcipher_alg[] = "cbc(aes)";
46static const char key_format_default[] = "default"; 46static const char key_format_default[] = "default";
47static const char key_format_ecryptfs[] = "ecryptfs"; 47static const char key_format_ecryptfs[] = "ecryptfs";
48static const char key_format_enc32[] = "enc32";
48static unsigned int ivsize; 49static unsigned int ivsize;
49static int blksize; 50static int blksize;
50 51
@@ -54,6 +55,7 @@ static int blksize;
54#define HASH_SIZE SHA256_DIGEST_SIZE 55#define HASH_SIZE SHA256_DIGEST_SIZE
55#define MAX_DATA_SIZE 4096 56#define MAX_DATA_SIZE 4096
56#define MIN_DATA_SIZE 20 57#define MIN_DATA_SIZE 20
58#define KEY_ENC32_PAYLOAD_LEN 32
57 59
58static struct crypto_shash *hash_tfm; 60static struct crypto_shash *hash_tfm;
59 61
@@ -62,12 +64,13 @@ enum {
62}; 64};
63 65
64enum { 66enum {
65 Opt_error = -1, Opt_default, Opt_ecryptfs 67 Opt_error = -1, Opt_default, Opt_ecryptfs, Opt_enc32
66}; 68};
67 69
68static const match_table_t key_format_tokens = { 70static const match_table_t key_format_tokens = {
69 {Opt_default, "default"}, 71 {Opt_default, "default"},
70 {Opt_ecryptfs, "ecryptfs"}, 72 {Opt_ecryptfs, "ecryptfs"},
73 {Opt_enc32, "enc32"},
71 {Opt_error, NULL} 74 {Opt_error, NULL}
72}; 75};
73 76
@@ -195,6 +198,7 @@ static int datablob_parse(char *datablob, const char **format,
195 key_format = match_token(p, key_format_tokens, args); 198 key_format = match_token(p, key_format_tokens, args);
196 switch (key_format) { 199 switch (key_format) {
197 case Opt_ecryptfs: 200 case Opt_ecryptfs:
201 case Opt_enc32:
198 case Opt_default: 202 case Opt_default:
199 *format = p; 203 *format = p;
200 *master_desc = strsep(&datablob, " \t"); 204 *master_desc = strsep(&datablob, " \t");
@@ -342,7 +346,7 @@ static int calc_hmac(u8 *digest, const u8 *key, unsigned int keylen,
342 struct crypto_shash *tfm; 346 struct crypto_shash *tfm;
343 int err; 347 int err;
344 348
345 tfm = crypto_alloc_shash(hmac_alg, 0, CRYPTO_ALG_ASYNC); 349 tfm = crypto_alloc_shash(hmac_alg, 0, 0);
346 if (IS_ERR(tfm)) { 350 if (IS_ERR(tfm)) {
347 pr_err("encrypted_key: can't alloc %s transform: %ld\n", 351 pr_err("encrypted_key: can't alloc %s transform: %ld\n",
348 hmac_alg, PTR_ERR(tfm)); 352 hmac_alg, PTR_ERR(tfm));
@@ -625,15 +629,22 @@ static struct encrypted_key_payload *encrypted_key_alloc(struct key *key,
625 format_len = (!format) ? strlen(key_format_default) : strlen(format); 629 format_len = (!format) ? strlen(key_format_default) : strlen(format);
626 decrypted_datalen = dlen; 630 decrypted_datalen = dlen;
627 payload_datalen = decrypted_datalen; 631 payload_datalen = decrypted_datalen;
628 if (format && !strcmp(format, key_format_ecryptfs)) { 632 if (format) {
629 if (dlen != ECRYPTFS_MAX_KEY_BYTES) { 633 if (!strcmp(format, key_format_ecryptfs)) {
630 pr_err("encrypted_key: keylen for the ecryptfs format " 634 if (dlen != ECRYPTFS_MAX_KEY_BYTES) {
631 "must be equal to %d bytes\n", 635 pr_err("encrypted_key: keylen for the ecryptfs format must be equal to %d bytes\n",
632 ECRYPTFS_MAX_KEY_BYTES); 636 ECRYPTFS_MAX_KEY_BYTES);
633 return ERR_PTR(-EINVAL); 637 return ERR_PTR(-EINVAL);
638 }
639 decrypted_datalen = ECRYPTFS_MAX_KEY_BYTES;
640 payload_datalen = sizeof(struct ecryptfs_auth_tok);
641 } else if (!strcmp(format, key_format_enc32)) {
642 if (decrypted_datalen != KEY_ENC32_PAYLOAD_LEN) {
643 pr_err("encrypted_key: enc32 key payload incorrect length: %d\n",
644 decrypted_datalen);
645 return ERR_PTR(-EINVAL);
646 }
634 } 647 }
635 decrypted_datalen = ECRYPTFS_MAX_KEY_BYTES;
636 payload_datalen = sizeof(struct ecryptfs_auth_tok);
637 } 648 }
638 649
639 encrypted_datalen = roundup(decrypted_datalen, blksize); 650 encrypted_datalen = roundup(decrypted_datalen, blksize);
@@ -984,7 +995,7 @@ static int __init init_encrypted(void)
984{ 995{
985 int ret; 996 int ret;
986 997
987 hash_tfm = crypto_alloc_shash(hash_alg, 0, CRYPTO_ALG_ASYNC); 998 hash_tfm = crypto_alloc_shash(hash_alg, 0, 0);
988 if (IS_ERR(hash_tfm)) { 999 if (IS_ERR(hash_tfm)) {
989 pr_err("encrypted_key: can't allocate %s transform: %ld\n", 1000 pr_err("encrypted_key: can't allocate %s transform: %ld\n",
990 hash_alg, PTR_ERR(hash_tfm)); 1001 hash_alg, PTR_ERR(hash_tfm));
diff --git a/security/keys/internal.h b/security/keys/internal.h
index 74cb0ff42fed..479909b858c7 100644
--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -158,8 +158,6 @@ extern struct key *request_key_and_link(struct key_type *type,
158 158
159extern bool lookup_user_key_possessed(const struct key *key, 159extern bool lookup_user_key_possessed(const struct key *key,
160 const struct key_match_data *match_data); 160 const struct key_match_data *match_data);
161extern key_ref_t lookup_user_key(key_serial_t id, unsigned long flags,
162 key_perm_t perm);
163#define KEY_LOOKUP_CREATE 0x01 161#define KEY_LOOKUP_CREATE 0x01
164#define KEY_LOOKUP_PARTIAL 0x02 162#define KEY_LOOKUP_PARTIAL 0x02
165#define KEY_LOOKUP_FOR_UNLINK 0x04 163#define KEY_LOOKUP_FOR_UNLINK 0x04
diff --git a/security/keys/keyctl_pkey.c b/security/keys/keyctl_pkey.c
index 783978842f13..8bdea5abad11 100644
--- a/security/keys/keyctl_pkey.c
+++ b/security/keys/keyctl_pkey.c
@@ -25,7 +25,7 @@ static void keyctl_pkey_params_free(struct kernel_pkey_params *params)
25} 25}
26 26
27enum { 27enum {
28 Opt_err = -1, 28 Opt_err,
29 Opt_enc, /* "enc=<encoding>" eg. "enc=oaep" */ 29 Opt_enc, /* "enc=<encoding>" eg. "enc=oaep" */
30 Opt_hash, /* "hash=<digest-name>" eg. "hash=sha1" */ 30 Opt_hash, /* "hash=<digest-name>" eg. "hash=sha1" */
31}; 31};
@@ -50,6 +50,8 @@ static int keyctl_pkey_params_parse(struct kernel_pkey_params *params)
50 if (*p == '\0' || *p == ' ' || *p == '\t') 50 if (*p == '\0' || *p == ' ' || *p == '\t')
51 continue; 51 continue;
52 token = match_token(p, param_keys, args); 52 token = match_token(p, param_keys, args);
53 if (token == Opt_err)
54 return -EINVAL;
53 if (__test_and_set_bit(token, &token_mask)) 55 if (__test_and_set_bit(token, &token_mask))
54 return -EINVAL; 56 return -EINVAL;
55 q = args[0].from; 57 q = args[0].from;
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index 8b8994920620..02c77e928f68 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -754,6 +754,7 @@ reget_creds:
754 put_cred(ctx.cred); 754 put_cred(ctx.cred);
755 goto try_again; 755 goto try_again;
756} 756}
757EXPORT_SYMBOL(lookup_user_key);
757 758
758/* 759/*
759 * Join the named keyring as the session keyring if possible else attempt to 760 * Join the named keyring as the session keyring if possible else attempt to
diff --git a/security/keys/trusted.c b/security/keys/trusted.c
index ff6789365a12..4d98f4f87236 100644
--- a/security/keys/trusted.c
+++ b/security/keys/trusted.c
@@ -711,7 +711,7 @@ static int key_unseal(struct trusted_key_payload *p,
711} 711}
712 712
713enum { 713enum {
714 Opt_err = -1, 714 Opt_err,
715 Opt_new, Opt_load, Opt_update, 715 Opt_new, Opt_load, Opt_update,
716 Opt_keyhandle, Opt_keyauth, Opt_blobauth, 716 Opt_keyhandle, Opt_keyauth, Opt_blobauth,
717 Opt_pcrinfo, Opt_pcrlock, Opt_migratable, 717 Opt_pcrinfo, Opt_pcrlock, Opt_migratable,
@@ -1199,14 +1199,14 @@ static int __init trusted_shash_alloc(void)
1199{ 1199{
1200 int ret; 1200 int ret;
1201 1201
1202 hmacalg = crypto_alloc_shash(hmac_alg, 0, CRYPTO_ALG_ASYNC); 1202 hmacalg = crypto_alloc_shash(hmac_alg, 0, 0);
1203 if (IS_ERR(hmacalg)) { 1203 if (IS_ERR(hmacalg)) {
1204 pr_info("trusted_key: could not allocate crypto %s\n", 1204 pr_info("trusted_key: could not allocate crypto %s\n",
1205 hmac_alg); 1205 hmac_alg);
1206 return PTR_ERR(hmacalg); 1206 return PTR_ERR(hmacalg);
1207 } 1207 }
1208 1208
1209 hashalg = crypto_alloc_shash(hash_alg, 0, CRYPTO_ALG_ASYNC); 1209 hashalg = crypto_alloc_shash(hash_alg, 0, 0);
1210 if (IS_ERR(hashalg)) { 1210 if (IS_ERR(hashalg)) {
1211 pr_info("trusted_key: could not allocate crypto %s\n", 1211 pr_info("trusted_key: could not allocate crypto %s\n",
1212 hash_alg); 1212 hash_alg);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 7ce683259357..0f27db6d94a9 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2934,7 +2934,7 @@ static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data)
2934 return rc; 2934 return rc;
2935 2935
2936 /* Allow all mounts performed by the kernel */ 2936 /* Allow all mounts performed by the kernel */
2937 if (flags & MS_KERNMOUNT) 2937 if (flags & (MS_KERNMOUNT | MS_SUBMOUNT))
2938 return 0; 2938 return 0;
2939 2939
2940 ad.type = LSM_AUDIT_DATA_DENTRY; 2940 ad.type = LSM_AUDIT_DATA_DENTRY;
@@ -5318,6 +5318,9 @@ static int selinux_sctp_bind_connect(struct sock *sk, int optname,
5318 addr_buf = address; 5318 addr_buf = address;
5319 5319
5320 while (walk_size < addrlen) { 5320 while (walk_size < addrlen) {
5321 if (walk_size + sizeof(sa_family_t) > addrlen)
5322 return -EINVAL;
5323
5321 addr = addr_buf; 5324 addr = addr_buf;
5322 switch (addr->sa_family) { 5325 switch (addr->sa_family) {
5323 case AF_UNSPEC: 5326 case AF_UNSPEC:
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index 23e762d529fa..ba8eedf42b90 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -81,7 +81,7 @@ enum {
81}; 81};
82#define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_MAX - 1) 82#define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_MAX - 1)
83 83
84extern char *selinux_policycap_names[__POLICYDB_CAPABILITY_MAX]; 84extern const char *selinux_policycap_names[__POLICYDB_CAPABILITY_MAX];
85 85
86/* 86/*
87 * type_datum properties 87 * type_datum properties
diff --git a/security/selinux/nlmsgtab.c b/security/selinux/nlmsgtab.c
index 74b951f55608..9cec81209617 100644
--- a/security/selinux/nlmsgtab.c
+++ b/security/selinux/nlmsgtab.c
@@ -80,6 +80,9 @@ static const struct nlmsg_perm nlmsg_route_perms[] =
80 { RTM_NEWSTATS, NETLINK_ROUTE_SOCKET__NLMSG_READ }, 80 { RTM_NEWSTATS, NETLINK_ROUTE_SOCKET__NLMSG_READ },
81 { RTM_GETSTATS, NETLINK_ROUTE_SOCKET__NLMSG_READ }, 81 { RTM_GETSTATS, NETLINK_ROUTE_SOCKET__NLMSG_READ },
82 { RTM_NEWCACHEREPORT, NETLINK_ROUTE_SOCKET__NLMSG_READ }, 82 { RTM_NEWCACHEREPORT, NETLINK_ROUTE_SOCKET__NLMSG_READ },
83 { RTM_NEWCHAIN, NETLINK_ROUTE_SOCKET__NLMSG_WRITE },
84 { RTM_DELCHAIN, NETLINK_ROUTE_SOCKET__NLMSG_WRITE },
85 { RTM_GETCHAIN, NETLINK_ROUTE_SOCKET__NLMSG_READ },
83}; 86};
84 87
85static const struct nlmsg_perm nlmsg_tcpdiag_perms[] = 88static const struct nlmsg_perm nlmsg_tcpdiag_perms[] =
@@ -158,7 +161,11 @@ int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm)
158 161
159 switch (sclass) { 162 switch (sclass) {
160 case SECCLASS_NETLINK_ROUTE_SOCKET: 163 case SECCLASS_NETLINK_ROUTE_SOCKET:
161 /* RTM_MAX always point to RTM_SETxxxx, ie RTM_NEWxxx + 3 */ 164 /* RTM_MAX always points to RTM_SETxxxx, ie RTM_NEWxxx + 3.
165 * If the BUILD_BUG_ON() below fails you must update the
166 * structures at the top of this file with the new mappings
167 * before updating the BUILD_BUG_ON() macro!
168 */
162 BUILD_BUG_ON(RTM_MAX != (RTM_NEWCHAIN + 3)); 169 BUILD_BUG_ON(RTM_MAX != (RTM_NEWCHAIN + 3));
163 err = nlmsg_perm(nlmsg_type, perm, nlmsg_route_perms, 170 err = nlmsg_perm(nlmsg_type, perm, nlmsg_route_perms,
164 sizeof(nlmsg_route_perms)); 171 sizeof(nlmsg_route_perms));
@@ -170,6 +177,10 @@ int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm)
170 break; 177 break;
171 178
172 case SECCLASS_NETLINK_XFRM_SOCKET: 179 case SECCLASS_NETLINK_XFRM_SOCKET:
180 /* If the BUILD_BUG_ON() below fails you must update the
181 * structures at the top of this file with the new mappings
182 * before updating the BUILD_BUG_ON() macro!
183 */
173 BUILD_BUG_ON(XFRM_MSG_MAX != XFRM_MSG_MAPPING); 184 BUILD_BUG_ON(XFRM_MSG_MAX != XFRM_MSG_MAPPING);
174 err = nlmsg_perm(nlmsg_type, perm, nlmsg_xfrm_perms, 185 err = nlmsg_perm(nlmsg_type, perm, nlmsg_xfrm_perms,
175 sizeof(nlmsg_xfrm_perms)); 186 sizeof(nlmsg_xfrm_perms));
diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c
index 2fe459df3c85..5e05f5b902d7 100644
--- a/security/selinux/ss/mls.c
+++ b/security/selinux/ss/mls.c
@@ -245,9 +245,13 @@ int mls_context_to_sid(struct policydb *pol,
245 char *rangep[2]; 245 char *rangep[2];
246 246
247 if (!pol->mls_enabled) { 247 if (!pol->mls_enabled) {
248 if ((def_sid != SECSID_NULL && oldc) || (*scontext) == '\0') 248 /*
249 return 0; 249 * With no MLS, only return -EINVAL if there is a MLS field
250 return -EINVAL; 250 * and it did not come from an xattr.
251 */
252 if (oldc && def_sid == SECSID_NULL)
253 return -EINVAL;
254 return 0;
251 } 255 }
252 256
253 /* 257 /*
@@ -436,16 +440,17 @@ int mls_setup_user_range(struct policydb *p,
436 440
437/* 441/*
438 * Convert the MLS fields in the security context 442 * Convert the MLS fields in the security context
439 * structure `c' from the values specified in the 443 * structure `oldc' from the values specified in the
440 * policy `oldp' to the values specified in the policy `newp'. 444 * policy `oldp' to the values specified in the policy `newp',
445 * storing the resulting context in `newc'.
441 */ 446 */
442int mls_convert_context(struct policydb *oldp, 447int mls_convert_context(struct policydb *oldp,
443 struct policydb *newp, 448 struct policydb *newp,
444 struct context *c) 449 struct context *oldc,
450 struct context *newc)
445{ 451{
446 struct level_datum *levdatum; 452 struct level_datum *levdatum;
447 struct cat_datum *catdatum; 453 struct cat_datum *catdatum;
448 struct ebitmap bitmap;
449 struct ebitmap_node *node; 454 struct ebitmap_node *node;
450 int l, i; 455 int l, i;
451 456
@@ -455,28 +460,25 @@ int mls_convert_context(struct policydb *oldp,
455 for (l = 0; l < 2; l++) { 460 for (l = 0; l < 2; l++) {
456 levdatum = hashtab_search(newp->p_levels.table, 461 levdatum = hashtab_search(newp->p_levels.table,
457 sym_name(oldp, SYM_LEVELS, 462 sym_name(oldp, SYM_LEVELS,
458 c->range.level[l].sens - 1)); 463 oldc->range.level[l].sens - 1));
459 464
460 if (!levdatum) 465 if (!levdatum)
461 return -EINVAL; 466 return -EINVAL;
462 c->range.level[l].sens = levdatum->level->sens; 467 newc->range.level[l].sens = levdatum->level->sens;
463 468
464 ebitmap_init(&bitmap); 469 ebitmap_for_each_positive_bit(&oldc->range.level[l].cat,
465 ebitmap_for_each_positive_bit(&c->range.level[l].cat, node, i) { 470 node, i) {
466 int rc; 471 int rc;
467 472
468 catdatum = hashtab_search(newp->p_cats.table, 473 catdatum = hashtab_search(newp->p_cats.table,
469 sym_name(oldp, SYM_CATS, i)); 474 sym_name(oldp, SYM_CATS, i));
470 if (!catdatum) 475 if (!catdatum)
471 return -EINVAL; 476 return -EINVAL;
472 rc = ebitmap_set_bit(&bitmap, catdatum->value - 1, 1); 477 rc = ebitmap_set_bit(&newc->range.level[l].cat,
478 catdatum->value - 1, 1);
473 if (rc) 479 if (rc)
474 return rc; 480 return rc;
475
476 cond_resched();
477 } 481 }
478 ebitmap_destroy(&c->range.level[l].cat);
479 c->range.level[l].cat = bitmap;
480 } 482 }
481 483
482 return 0; 484 return 0;
diff --git a/security/selinux/ss/mls.h b/security/selinux/ss/mls.h
index 67093647576d..7954b1e60b64 100644
--- a/security/selinux/ss/mls.h
+++ b/security/selinux/ss/mls.h
@@ -46,7 +46,8 @@ int mls_range_set(struct context *context, struct mls_range *range);
46 46
47int mls_convert_context(struct policydb *oldp, 47int mls_convert_context(struct policydb *oldp,
48 struct policydb *newp, 48 struct policydb *newp,
49 struct context *context); 49 struct context *oldc,
50 struct context *newc);
50 51
51int mls_compute_sid(struct policydb *p, 52int mls_compute_sid(struct policydb *p,
52 struct context *scontext, 53 struct context *scontext,
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index f4eadd3f7350..a50d625e7946 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -909,13 +909,21 @@ int policydb_load_isids(struct policydb *p, struct sidtab *s)
909 if (!c->context[0].user) { 909 if (!c->context[0].user) {
910 pr_err("SELinux: SID %s was never defined.\n", 910 pr_err("SELinux: SID %s was never defined.\n",
911 c->u.name); 911 c->u.name);
912 sidtab_destroy(s);
913 goto out;
914 }
915 if (c->sid[0] == SECSID_NULL || c->sid[0] > SECINITSID_NUM) {
916 pr_err("SELinux: Initial SID %s out of range.\n",
917 c->u.name);
918 sidtab_destroy(s);
912 goto out; 919 goto out;
913 } 920 }
914 921
915 rc = sidtab_insert(s, c->sid[0], &c->context[0]); 922 rc = sidtab_set_initial(s, c->sid[0], &c->context[0]);
916 if (rc) { 923 if (rc) {
917 pr_err("SELinux: unable to load initial SID %s.\n", 924 pr_err("SELinux: unable to load initial SID %s.\n",
918 c->u.name); 925 c->u.name);
926 sidtab_destroy(s);
919 goto out; 927 goto out;
920 } 928 }
921 } 929 }
@@ -2108,6 +2116,7 @@ static int ocontext_read(struct policydb *p, struct policydb_compat_info *info,
2108{ 2116{
2109 int i, j, rc; 2117 int i, j, rc;
2110 u32 nel, len; 2118 u32 nel, len;
2119 __be64 prefixbuf[1];
2111 __le32 buf[3]; 2120 __le32 buf[3];
2112 struct ocontext *l, *c; 2121 struct ocontext *l, *c;
2113 u32 nodebuf[8]; 2122 u32 nodebuf[8];
@@ -2217,21 +2226,30 @@ static int ocontext_read(struct policydb *p, struct policydb_compat_info *info,
2217 goto out; 2226 goto out;
2218 break; 2227 break;
2219 } 2228 }
2220 case OCON_IBPKEY: 2229 case OCON_IBPKEY: {
2221 rc = next_entry(nodebuf, fp, sizeof(u32) * 4); 2230 u32 pkey_lo, pkey_hi;
2231
2232 rc = next_entry(prefixbuf, fp, sizeof(u64));
2233 if (rc)
2234 goto out;
2235
2236 /* we need to have subnet_prefix in CPU order */
2237 c->u.ibpkey.subnet_prefix = be64_to_cpu(prefixbuf[0]);
2238
2239 rc = next_entry(buf, fp, sizeof(u32) * 2);
2222 if (rc) 2240 if (rc)
2223 goto out; 2241 goto out;
2224 2242
2225 c->u.ibpkey.subnet_prefix = be64_to_cpu(*((__be64 *)nodebuf)); 2243 pkey_lo = le32_to_cpu(buf[0]);
2244 pkey_hi = le32_to_cpu(buf[1]);
2226 2245
2227 if (nodebuf[2] > 0xffff || 2246 if (pkey_lo > U16_MAX || pkey_hi > U16_MAX) {
2228 nodebuf[3] > 0xffff) {
2229 rc = -EINVAL; 2247 rc = -EINVAL;
2230 goto out; 2248 goto out;
2231 } 2249 }
2232 2250
2233 c->u.ibpkey.low_pkey = le32_to_cpu(nodebuf[2]); 2251 c->u.ibpkey.low_pkey = pkey_lo;
2234 c->u.ibpkey.high_pkey = le32_to_cpu(nodebuf[3]); 2252 c->u.ibpkey.high_pkey = pkey_hi;
2235 2253
2236 rc = context_read_and_validate(&c->context[0], 2254 rc = context_read_and_validate(&c->context[0],
2237 p, 2255 p,
@@ -2239,7 +2257,10 @@ static int ocontext_read(struct policydb *p, struct policydb_compat_info *info,
2239 if (rc) 2257 if (rc)
2240 goto out; 2258 goto out;
2241 break; 2259 break;
2242 case OCON_IBENDPORT: 2260 }
2261 case OCON_IBENDPORT: {
2262 u32 port;
2263
2243 rc = next_entry(buf, fp, sizeof(u32) * 2); 2264 rc = next_entry(buf, fp, sizeof(u32) * 2);
2244 if (rc) 2265 if (rc)
2245 goto out; 2266 goto out;
@@ -2249,12 +2270,13 @@ static int ocontext_read(struct policydb *p, struct policydb_compat_info *info,
2249 if (rc) 2270 if (rc)
2250 goto out; 2271 goto out;
2251 2272
2252 if (buf[1] > 0xff || buf[1] == 0) { 2273 port = le32_to_cpu(buf[1]);
2274 if (port > U8_MAX || port == 0) {
2253 rc = -EINVAL; 2275 rc = -EINVAL;
2254 goto out; 2276 goto out;
2255 } 2277 }
2256 2278
2257 c->u.ibendport.port = le32_to_cpu(buf[1]); 2279 c->u.ibendport.port = port;
2258 2280
2259 rc = context_read_and_validate(&c->context[0], 2281 rc = context_read_and_validate(&c->context[0],
2260 p, 2282 p,
@@ -2262,7 +2284,8 @@ static int ocontext_read(struct policydb *p, struct policydb_compat_info *info,
2262 if (rc) 2284 if (rc)
2263 goto out; 2285 goto out;
2264 break; 2286 break;
2265 } 2287 } /* end case */
2288 } /* end switch */
2266 } 2289 }
2267 } 2290 }
2268 rc = 0; 2291 rc = 0;
@@ -3105,6 +3128,7 @@ static int ocontext_write(struct policydb *p, struct policydb_compat_info *info,
3105{ 3128{
3106 unsigned int i, j, rc; 3129 unsigned int i, j, rc;
3107 size_t nel, len; 3130 size_t nel, len;
3131 __be64 prefixbuf[1];
3108 __le32 buf[3]; 3132 __le32 buf[3];
3109 u32 nodebuf[8]; 3133 u32 nodebuf[8];
3110 struct ocontext *c; 3134 struct ocontext *c;
@@ -3192,12 +3216,17 @@ static int ocontext_write(struct policydb *p, struct policydb_compat_info *info,
3192 return rc; 3216 return rc;
3193 break; 3217 break;
3194 case OCON_IBPKEY: 3218 case OCON_IBPKEY:
3195 *((__be64 *)nodebuf) = cpu_to_be64(c->u.ibpkey.subnet_prefix); 3219 /* subnet_prefix is in CPU order */
3220 prefixbuf[0] = cpu_to_be64(c->u.ibpkey.subnet_prefix);
3196 3221
3197 nodebuf[2] = cpu_to_le32(c->u.ibpkey.low_pkey); 3222 rc = put_entry(prefixbuf, sizeof(u64), 1, fp);
3198 nodebuf[3] = cpu_to_le32(c->u.ibpkey.high_pkey); 3223 if (rc)
3224 return rc;
3199 3225
3200 rc = put_entry(nodebuf, sizeof(u32), 4, fp); 3226 buf[0] = cpu_to_le32(c->u.ibpkey.low_pkey);
3227 buf[1] = cpu_to_le32(c->u.ibpkey.high_pkey);
3228
3229 rc = put_entry(buf, sizeof(u32), 2, fp);
3201 if (rc) 3230 if (rc)
3202 return rc; 3231 return rc;
3203 rc = context_write(p, &c->context[0], fp); 3232 rc = context_write(p, &c->context[0], fp);
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 12e414394530..dd44126c8d14 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -71,7 +71,7 @@
71#include "audit.h" 71#include "audit.h"
72 72
73/* Policy capability names */ 73/* Policy capability names */
74char *selinux_policycap_names[__POLICYDB_CAPABILITY_MAX] = { 74const char *selinux_policycap_names[__POLICYDB_CAPABILITY_MAX] = {
75 "network_peer_controls", 75 "network_peer_controls",
76 "open_perms", 76 "open_perms",
77 "extended_socket_class", 77 "extended_socket_class",
@@ -776,7 +776,7 @@ static int security_compute_validatetrans(struct selinux_state *state,
776 read_lock(&state->ss->policy_rwlock); 776 read_lock(&state->ss->policy_rwlock);
777 777
778 policydb = &state->ss->policydb; 778 policydb = &state->ss->policydb;
779 sidtab = &state->ss->sidtab; 779 sidtab = state->ss->sidtab;
780 780
781 if (!user) 781 if (!user)
782 tclass = unmap_class(&state->ss->map, orig_tclass); 782 tclass = unmap_class(&state->ss->map, orig_tclass);
@@ -876,7 +876,7 @@ int security_bounded_transition(struct selinux_state *state,
876 read_lock(&state->ss->policy_rwlock); 876 read_lock(&state->ss->policy_rwlock);
877 877
878 policydb = &state->ss->policydb; 878 policydb = &state->ss->policydb;
879 sidtab = &state->ss->sidtab; 879 sidtab = state->ss->sidtab;
880 880
881 rc = -EINVAL; 881 rc = -EINVAL;
882 old_context = sidtab_search(sidtab, old_sid); 882 old_context = sidtab_search(sidtab, old_sid);
@@ -1034,7 +1034,7 @@ void security_compute_xperms_decision(struct selinux_state *state,
1034 goto allow; 1034 goto allow;
1035 1035
1036 policydb = &state->ss->policydb; 1036 policydb = &state->ss->policydb;
1037 sidtab = &state->ss->sidtab; 1037 sidtab = state->ss->sidtab;
1038 1038
1039 scontext = sidtab_search(sidtab, ssid); 1039 scontext = sidtab_search(sidtab, ssid);
1040 if (!scontext) { 1040 if (!scontext) {
@@ -1123,7 +1123,7 @@ void security_compute_av(struct selinux_state *state,
1123 goto allow; 1123 goto allow;
1124 1124
1125 policydb = &state->ss->policydb; 1125 policydb = &state->ss->policydb;
1126 sidtab = &state->ss->sidtab; 1126 sidtab = state->ss->sidtab;
1127 1127
1128 scontext = sidtab_search(sidtab, ssid); 1128 scontext = sidtab_search(sidtab, ssid);
1129 if (!scontext) { 1129 if (!scontext) {
@@ -1177,7 +1177,7 @@ void security_compute_av_user(struct selinux_state *state,
1177 goto allow; 1177 goto allow;
1178 1178
1179 policydb = &state->ss->policydb; 1179 policydb = &state->ss->policydb;
1180 sidtab = &state->ss->sidtab; 1180 sidtab = state->ss->sidtab;
1181 1181
1182 scontext = sidtab_search(sidtab, ssid); 1182 scontext = sidtab_search(sidtab, ssid);
1183 if (!scontext) { 1183 if (!scontext) {
@@ -1315,7 +1315,7 @@ static int security_sid_to_context_core(struct selinux_state *state,
1315 } 1315 }
1316 read_lock(&state->ss->policy_rwlock); 1316 read_lock(&state->ss->policy_rwlock);
1317 policydb = &state->ss->policydb; 1317 policydb = &state->ss->policydb;
1318 sidtab = &state->ss->sidtab; 1318 sidtab = state->ss->sidtab;
1319 if (force) 1319 if (force)
1320 context = sidtab_search_force(sidtab, sid); 1320 context = sidtab_search_force(sidtab, sid);
1321 else 1321 else
@@ -1483,7 +1483,7 @@ static int security_context_to_sid_core(struct selinux_state *state,
1483 } 1483 }
1484 read_lock(&state->ss->policy_rwlock); 1484 read_lock(&state->ss->policy_rwlock);
1485 policydb = &state->ss->policydb; 1485 policydb = &state->ss->policydb;
1486 sidtab = &state->ss->sidtab; 1486 sidtab = state->ss->sidtab;
1487 rc = string_to_context_struct(policydb, sidtab, scontext2, 1487 rc = string_to_context_struct(policydb, sidtab, scontext2,
1488 &context, def_sid); 1488 &context, def_sid);
1489 if (rc == -EINVAL && force) { 1489 if (rc == -EINVAL && force) {
@@ -1668,7 +1668,7 @@ static int security_compute_sid(struct selinux_state *state,
1668 } 1668 }
1669 1669
1670 policydb = &state->ss->policydb; 1670 policydb = &state->ss->policydb;
1671 sidtab = &state->ss->sidtab; 1671 sidtab = state->ss->sidtab;
1672 1672
1673 scontext = sidtab_search(sidtab, ssid); 1673 scontext = sidtab_search(sidtab, ssid);
1674 if (!scontext) { 1674 if (!scontext) {
@@ -1880,19 +1880,6 @@ int security_change_sid(struct selinux_state *state,
1880 out_sid, false); 1880 out_sid, false);
1881} 1881}
1882 1882
1883/* Clone the SID into the new SID table. */
1884static int clone_sid(u32 sid,
1885 struct context *context,
1886 void *arg)
1887{
1888 struct sidtab *s = arg;
1889
1890 if (sid > SECINITSID_NUM)
1891 return sidtab_insert(s, sid, context);
1892 else
1893 return 0;
1894}
1895
1896static inline int convert_context_handle_invalid_context( 1883static inline int convert_context_handle_invalid_context(
1897 struct selinux_state *state, 1884 struct selinux_state *state,
1898 struct context *context) 1885 struct context *context)
@@ -1920,101 +1907,84 @@ struct convert_context_args {
1920 1907
1921/* 1908/*
1922 * Convert the values in the security context 1909 * Convert the values in the security context
1923 * structure `c' from the values specified 1910 * structure `oldc' from the values specified
1924 * in the policy `p->oldp' to the values specified 1911 * in the policy `p->oldp' to the values specified
1925 * in the policy `p->newp'. Verify that the 1912 * in the policy `p->newp', storing the new context
1926 * context is valid under the new policy. 1913 * in `newc'. Verify that the context is valid
1914 * under the new policy.
1927 */ 1915 */
1928static int convert_context(u32 key, 1916static int convert_context(struct context *oldc, struct context *newc, void *p)
1929 struct context *c,
1930 void *p)
1931{ 1917{
1932 struct convert_context_args *args; 1918 struct convert_context_args *args;
1933 struct context oldc;
1934 struct ocontext *oc; 1919 struct ocontext *oc;
1935 struct mls_range *range;
1936 struct role_datum *role; 1920 struct role_datum *role;
1937 struct type_datum *typdatum; 1921 struct type_datum *typdatum;
1938 struct user_datum *usrdatum; 1922 struct user_datum *usrdatum;
1939 char *s; 1923 char *s;
1940 u32 len; 1924 u32 len;
1941 int rc = 0; 1925 int rc;
1942
1943 if (key <= SECINITSID_NUM)
1944 goto out;
1945 1926
1946 args = p; 1927 args = p;
1947 1928
1948 if (c->str) { 1929 if (oldc->str) {
1949 struct context ctx; 1930 s = kstrdup(oldc->str, GFP_KERNEL);
1950
1951 rc = -ENOMEM;
1952 s = kstrdup(c->str, GFP_KERNEL);
1953 if (!s) 1931 if (!s)
1954 goto out; 1932 return -ENOMEM;
1955 1933
1956 rc = string_to_context_struct(args->newp, NULL, s, 1934 rc = string_to_context_struct(args->newp, NULL, s,
1957 &ctx, SECSID_NULL); 1935 newc, SECSID_NULL);
1958 kfree(s); 1936 if (rc == -EINVAL) {
1959 if (!rc) {
1960 pr_info("SELinux: Context %s became valid (mapped).\n",
1961 c->str);
1962 /* Replace string with mapped representation. */
1963 kfree(c->str);
1964 memcpy(c, &ctx, sizeof(*c));
1965 goto out;
1966 } else if (rc == -EINVAL) {
1967 /* Retain string representation for later mapping. */ 1937 /* Retain string representation for later mapping. */
1968 rc = 0; 1938 context_init(newc);
1969 goto out; 1939 newc->str = s;
1970 } else { 1940 newc->len = oldc->len;
1941 return 0;
1942 }
1943 kfree(s);
1944 if (rc) {
1971 /* Other error condition, e.g. ENOMEM. */ 1945 /* Other error condition, e.g. ENOMEM. */
1972 pr_err("SELinux: Unable to map context %s, rc = %d.\n", 1946 pr_err("SELinux: Unable to map context %s, rc = %d.\n",
1973 c->str, -rc); 1947 oldc->str, -rc);
1974 goto out; 1948 return rc;
1975 } 1949 }
1950 pr_info("SELinux: Context %s became valid (mapped).\n",
1951 oldc->str);
1952 return 0;
1976 } 1953 }
1977 1954
1978 rc = context_cpy(&oldc, c); 1955 context_init(newc);
1979 if (rc)
1980 goto out;
1981 1956
1982 /* Convert the user. */ 1957 /* Convert the user. */
1983 rc = -EINVAL; 1958 rc = -EINVAL;
1984 usrdatum = hashtab_search(args->newp->p_users.table, 1959 usrdatum = hashtab_search(args->newp->p_users.table,
1985 sym_name(args->oldp, SYM_USERS, c->user - 1)); 1960 sym_name(args->oldp,
1961 SYM_USERS, oldc->user - 1));
1986 if (!usrdatum) 1962 if (!usrdatum)
1987 goto bad; 1963 goto bad;
1988 c->user = usrdatum->value; 1964 newc->user = usrdatum->value;
1989 1965
1990 /* Convert the role. */ 1966 /* Convert the role. */
1991 rc = -EINVAL; 1967 rc = -EINVAL;
1992 role = hashtab_search(args->newp->p_roles.table, 1968 role = hashtab_search(args->newp->p_roles.table,
1993 sym_name(args->oldp, SYM_ROLES, c->role - 1)); 1969 sym_name(args->oldp, SYM_ROLES, oldc->role - 1));
1994 if (!role) 1970 if (!role)
1995 goto bad; 1971 goto bad;
1996 c->role = role->value; 1972 newc->role = role->value;
1997 1973
1998 /* Convert the type. */ 1974 /* Convert the type. */
1999 rc = -EINVAL; 1975 rc = -EINVAL;
2000 typdatum = hashtab_search(args->newp->p_types.table, 1976 typdatum = hashtab_search(args->newp->p_types.table,
2001 sym_name(args->oldp, SYM_TYPES, c->type - 1)); 1977 sym_name(args->oldp,
1978 SYM_TYPES, oldc->type - 1));
2002 if (!typdatum) 1979 if (!typdatum)
2003 goto bad; 1980 goto bad;
2004 c->type = typdatum->value; 1981 newc->type = typdatum->value;
2005 1982
2006 /* Convert the MLS fields if dealing with MLS policies */ 1983 /* Convert the MLS fields if dealing with MLS policies */
2007 if (args->oldp->mls_enabled && args->newp->mls_enabled) { 1984 if (args->oldp->mls_enabled && args->newp->mls_enabled) {
2008 rc = mls_convert_context(args->oldp, args->newp, c); 1985 rc = mls_convert_context(args->oldp, args->newp, oldc, newc);
2009 if (rc) 1986 if (rc)
2010 goto bad; 1987 goto bad;
2011 } else if (args->oldp->mls_enabled && !args->newp->mls_enabled) {
2012 /*
2013 * Switching between MLS and non-MLS policy:
2014 * free any storage used by the MLS fields in the
2015 * context for all existing entries in the sidtab.
2016 */
2017 mls_context_destroy(c);
2018 } else if (!args->oldp->mls_enabled && args->newp->mls_enabled) { 1988 } else if (!args->oldp->mls_enabled && args->newp->mls_enabled) {
2019 /* 1989 /*
2020 * Switching between non-MLS and MLS policy: 1990 * Switching between non-MLS and MLS policy:
@@ -2032,38 +2002,30 @@ static int convert_context(u32 key,
2032 " the initial SIDs list\n"); 2002 " the initial SIDs list\n");
2033 goto bad; 2003 goto bad;
2034 } 2004 }
2035 range = &oc->context[0].range; 2005 rc = mls_range_set(newc, &oc->context[0].range);
2036 rc = mls_range_set(c, range);
2037 if (rc) 2006 if (rc)
2038 goto bad; 2007 goto bad;
2039 } 2008 }
2040 2009
2041 /* Check the validity of the new context. */ 2010 /* Check the validity of the new context. */
2042 if (!policydb_context_isvalid(args->newp, c)) { 2011 if (!policydb_context_isvalid(args->newp, newc)) {
2043 rc = convert_context_handle_invalid_context(args->state, 2012 rc = convert_context_handle_invalid_context(args->state, oldc);
2044 &oldc);
2045 if (rc) 2013 if (rc)
2046 goto bad; 2014 goto bad;
2047 } 2015 }
2048 2016
2049 context_destroy(&oldc); 2017 return 0;
2050
2051 rc = 0;
2052out:
2053 return rc;
2054bad: 2018bad:
2055 /* Map old representation to string and save it. */ 2019 /* Map old representation to string and save it. */
2056 rc = context_struct_to_string(args->oldp, &oldc, &s, &len); 2020 rc = context_struct_to_string(args->oldp, oldc, &s, &len);
2057 if (rc) 2021 if (rc)
2058 return rc; 2022 return rc;
2059 context_destroy(&oldc); 2023 context_destroy(newc);
2060 context_destroy(c); 2024 newc->str = s;
2061 c->str = s; 2025 newc->len = len;
2062 c->len = len;
2063 pr_info("SELinux: Context %s became invalid (unmapped).\n", 2026 pr_info("SELinux: Context %s became invalid (unmapped).\n",
2064 c->str); 2027 newc->str);
2065 rc = 0; 2028 return 0;
2066 goto out;
2067} 2029}
2068 2030
2069static void security_load_policycaps(struct selinux_state *state) 2031static void security_load_policycaps(struct selinux_state *state)
@@ -2103,11 +2065,11 @@ static int security_preserve_bools(struct selinux_state *state,
2103int security_load_policy(struct selinux_state *state, void *data, size_t len) 2065int security_load_policy(struct selinux_state *state, void *data, size_t len)
2104{ 2066{
2105 struct policydb *policydb; 2067 struct policydb *policydb;
2106 struct sidtab *sidtab; 2068 struct sidtab *oldsidtab, *newsidtab;
2107 struct policydb *oldpolicydb, *newpolicydb; 2069 struct policydb *oldpolicydb, *newpolicydb;
2108 struct sidtab oldsidtab, newsidtab;
2109 struct selinux_mapping *oldmapping; 2070 struct selinux_mapping *oldmapping;
2110 struct selinux_map newmap; 2071 struct selinux_map newmap;
2072 struct sidtab_convert_params convert_params;
2111 struct convert_context_args args; 2073 struct convert_context_args args;
2112 u32 seqno; 2074 u32 seqno;
2113 int rc = 0; 2075 int rc = 0;
@@ -2121,27 +2083,37 @@ int security_load_policy(struct selinux_state *state, void *data, size_t len)
2121 newpolicydb = oldpolicydb + 1; 2083 newpolicydb = oldpolicydb + 1;
2122 2084
2123 policydb = &state->ss->policydb; 2085 policydb = &state->ss->policydb;
2124 sidtab = &state->ss->sidtab; 2086
2087 newsidtab = kmalloc(sizeof(*newsidtab), GFP_KERNEL);
2088 if (!newsidtab) {
2089 rc = -ENOMEM;
2090 goto out;
2091 }
2125 2092
2126 if (!state->initialized) { 2093 if (!state->initialized) {
2127 rc = policydb_read(policydb, fp); 2094 rc = policydb_read(policydb, fp);
2128 if (rc) 2095 if (rc) {
2096 kfree(newsidtab);
2129 goto out; 2097 goto out;
2098 }
2130 2099
2131 policydb->len = len; 2100 policydb->len = len;
2132 rc = selinux_set_mapping(policydb, secclass_map, 2101 rc = selinux_set_mapping(policydb, secclass_map,
2133 &state->ss->map); 2102 &state->ss->map);
2134 if (rc) { 2103 if (rc) {
2104 kfree(newsidtab);
2135 policydb_destroy(policydb); 2105 policydb_destroy(policydb);
2136 goto out; 2106 goto out;
2137 } 2107 }
2138 2108
2139 rc = policydb_load_isids(policydb, sidtab); 2109 rc = policydb_load_isids(policydb, newsidtab);
2140 if (rc) { 2110 if (rc) {
2111 kfree(newsidtab);
2141 policydb_destroy(policydb); 2112 policydb_destroy(policydb);
2142 goto out; 2113 goto out;
2143 } 2114 }
2144 2115
2116 state->ss->sidtab = newsidtab;
2145 security_load_policycaps(state); 2117 security_load_policycaps(state);
2146 state->initialized = 1; 2118 state->initialized = 1;
2147 seqno = ++state->ss->latest_granting; 2119 seqno = ++state->ss->latest_granting;
@@ -2154,13 +2126,11 @@ int security_load_policy(struct selinux_state *state, void *data, size_t len)
2154 goto out; 2126 goto out;
2155 } 2127 }
2156 2128
2157#if 0
2158 sidtab_hash_eval(sidtab, "sids");
2159#endif
2160
2161 rc = policydb_read(newpolicydb, fp); 2129 rc = policydb_read(newpolicydb, fp);
2162 if (rc) 2130 if (rc) {
2131 kfree(newsidtab);
2163 goto out; 2132 goto out;
2133 }
2164 2134
2165 newpolicydb->len = len; 2135 newpolicydb->len = len;
2166 /* If switching between different policy types, log MLS status */ 2136 /* If switching between different policy types, log MLS status */
@@ -2169,10 +2139,11 @@ int security_load_policy(struct selinux_state *state, void *data, size_t len)
2169 else if (!policydb->mls_enabled && newpolicydb->mls_enabled) 2139 else if (!policydb->mls_enabled && newpolicydb->mls_enabled)
2170 pr_info("SELinux: Enabling MLS support...\n"); 2140 pr_info("SELinux: Enabling MLS support...\n");
2171 2141
2172 rc = policydb_load_isids(newpolicydb, &newsidtab); 2142 rc = policydb_load_isids(newpolicydb, newsidtab);
2173 if (rc) { 2143 if (rc) {
2174 pr_err("SELinux: unable to load the initial SIDs\n"); 2144 pr_err("SELinux: unable to load the initial SIDs\n");
2175 policydb_destroy(newpolicydb); 2145 policydb_destroy(newpolicydb);
2146 kfree(newsidtab);
2176 goto out; 2147 goto out;
2177 } 2148 }
2178 2149
@@ -2186,12 +2157,7 @@ int security_load_policy(struct selinux_state *state, void *data, size_t len)
2186 goto err; 2157 goto err;
2187 } 2158 }
2188 2159
2189 /* Clone the SID table. */ 2160 oldsidtab = state->ss->sidtab;
2190 sidtab_shutdown(sidtab);
2191
2192 rc = sidtab_map(sidtab, clone_sid, &newsidtab);
2193 if (rc)
2194 goto err;
2195 2161
2196 /* 2162 /*
2197 * Convert the internal representations of contexts 2163 * Convert the internal representations of contexts
@@ -2200,7 +2166,12 @@ int security_load_policy(struct selinux_state *state, void *data, size_t len)
2200 args.state = state; 2166 args.state = state;
2201 args.oldp = policydb; 2167 args.oldp = policydb;
2202 args.newp = newpolicydb; 2168 args.newp = newpolicydb;
2203 rc = sidtab_map(&newsidtab, convert_context, &args); 2169
2170 convert_params.func = convert_context;
2171 convert_params.args = &args;
2172 convert_params.target = newsidtab;
2173
2174 rc = sidtab_convert(oldsidtab, &convert_params);
2204 if (rc) { 2175 if (rc) {
2205 pr_err("SELinux: unable to convert the internal" 2176 pr_err("SELinux: unable to convert the internal"
2206 " representation of contexts in the new SID" 2177 " representation of contexts in the new SID"
@@ -2210,12 +2181,11 @@ int security_load_policy(struct selinux_state *state, void *data, size_t len)
2210 2181
2211 /* Save the old policydb and SID table to free later. */ 2182 /* Save the old policydb and SID table to free later. */
2212 memcpy(oldpolicydb, policydb, sizeof(*policydb)); 2183 memcpy(oldpolicydb, policydb, sizeof(*policydb));
2213 sidtab_set(&oldsidtab, sidtab);
2214 2184
2215 /* Install the new policydb and SID table. */ 2185 /* Install the new policydb and SID table. */
2216 write_lock_irq(&state->ss->policy_rwlock); 2186 write_lock_irq(&state->ss->policy_rwlock);
2217 memcpy(policydb, newpolicydb, sizeof(*policydb)); 2187 memcpy(policydb, newpolicydb, sizeof(*policydb));
2218 sidtab_set(sidtab, &newsidtab); 2188 state->ss->sidtab = newsidtab;
2219 security_load_policycaps(state); 2189 security_load_policycaps(state);
2220 oldmapping = state->ss->map.mapping; 2190 oldmapping = state->ss->map.mapping;
2221 state->ss->map.mapping = newmap.mapping; 2191 state->ss->map.mapping = newmap.mapping;
@@ -2225,7 +2195,8 @@ int security_load_policy(struct selinux_state *state, void *data, size_t len)
2225 2195
2226 /* Free the old policydb and SID table. */ 2196 /* Free the old policydb and SID table. */
2227 policydb_destroy(oldpolicydb); 2197 policydb_destroy(oldpolicydb);
2228 sidtab_destroy(&oldsidtab); 2198 sidtab_destroy(oldsidtab);
2199 kfree(oldsidtab);
2229 kfree(oldmapping); 2200 kfree(oldmapping);
2230 2201
2231 avc_ss_reset(state->avc, seqno); 2202 avc_ss_reset(state->avc, seqno);
@@ -2239,7 +2210,8 @@ int security_load_policy(struct selinux_state *state, void *data, size_t len)
2239 2210
2240err: 2211err:
2241 kfree(newmap.mapping); 2212 kfree(newmap.mapping);
2242 sidtab_destroy(&newsidtab); 2213 sidtab_destroy(newsidtab);
2214 kfree(newsidtab);
2243 policydb_destroy(newpolicydb); 2215 policydb_destroy(newpolicydb);
2244 2216
2245out: 2217out:
@@ -2276,7 +2248,7 @@ int security_port_sid(struct selinux_state *state,
2276 read_lock(&state->ss->policy_rwlock); 2248 read_lock(&state->ss->policy_rwlock);
2277 2249
2278 policydb = &state->ss->policydb; 2250 policydb = &state->ss->policydb;
2279 sidtab = &state->ss->sidtab; 2251 sidtab = state->ss->sidtab;
2280 2252
2281 c = policydb->ocontexts[OCON_PORT]; 2253 c = policydb->ocontexts[OCON_PORT];
2282 while (c) { 2254 while (c) {
@@ -2322,7 +2294,7 @@ int security_ib_pkey_sid(struct selinux_state *state,
2322 read_lock(&state->ss->policy_rwlock); 2294 read_lock(&state->ss->policy_rwlock);
2323 2295
2324 policydb = &state->ss->policydb; 2296 policydb = &state->ss->policydb;
2325 sidtab = &state->ss->sidtab; 2297 sidtab = state->ss->sidtab;
2326 2298
2327 c = policydb->ocontexts[OCON_IBPKEY]; 2299 c = policydb->ocontexts[OCON_IBPKEY];
2328 while (c) { 2300 while (c) {
@@ -2368,7 +2340,7 @@ int security_ib_endport_sid(struct selinux_state *state,
2368 read_lock(&state->ss->policy_rwlock); 2340 read_lock(&state->ss->policy_rwlock);
2369 2341
2370 policydb = &state->ss->policydb; 2342 policydb = &state->ss->policydb;
2371 sidtab = &state->ss->sidtab; 2343 sidtab = state->ss->sidtab;
2372 2344
2373 c = policydb->ocontexts[OCON_IBENDPORT]; 2345 c = policydb->ocontexts[OCON_IBENDPORT];
2374 while (c) { 2346 while (c) {
@@ -2414,7 +2386,7 @@ int security_netif_sid(struct selinux_state *state,
2414 read_lock(&state->ss->policy_rwlock); 2386 read_lock(&state->ss->policy_rwlock);
2415 2387
2416 policydb = &state->ss->policydb; 2388 policydb = &state->ss->policydb;
2417 sidtab = &state->ss->sidtab; 2389 sidtab = state->ss->sidtab;
2418 2390
2419 c = policydb->ocontexts[OCON_NETIF]; 2391 c = policydb->ocontexts[OCON_NETIF];
2420 while (c) { 2392 while (c) {
@@ -2479,7 +2451,7 @@ int security_node_sid(struct selinux_state *state,
2479 read_lock(&state->ss->policy_rwlock); 2451 read_lock(&state->ss->policy_rwlock);
2480 2452
2481 policydb = &state->ss->policydb; 2453 policydb = &state->ss->policydb;
2482 sidtab = &state->ss->sidtab; 2454 sidtab = state->ss->sidtab;
2483 2455
2484 switch (domain) { 2456 switch (domain) {
2485 case AF_INET: { 2457 case AF_INET: {
@@ -2579,7 +2551,7 @@ int security_get_user_sids(struct selinux_state *state,
2579 read_lock(&state->ss->policy_rwlock); 2551 read_lock(&state->ss->policy_rwlock);
2580 2552
2581 policydb = &state->ss->policydb; 2553 policydb = &state->ss->policydb;
2582 sidtab = &state->ss->sidtab; 2554 sidtab = state->ss->sidtab;
2583 2555
2584 context_init(&usercon); 2556 context_init(&usercon);
2585 2557
@@ -2681,7 +2653,7 @@ static inline int __security_genfs_sid(struct selinux_state *state,
2681 u32 *sid) 2653 u32 *sid)
2682{ 2654{
2683 struct policydb *policydb = &state->ss->policydb; 2655 struct policydb *policydb = &state->ss->policydb;
2684 struct sidtab *sidtab = &state->ss->sidtab; 2656 struct sidtab *sidtab = state->ss->sidtab;
2685 int len; 2657 int len;
2686 u16 sclass; 2658 u16 sclass;
2687 struct genfs *genfs; 2659 struct genfs *genfs;
@@ -2767,7 +2739,7 @@ int security_fs_use(struct selinux_state *state, struct super_block *sb)
2767 read_lock(&state->ss->policy_rwlock); 2739 read_lock(&state->ss->policy_rwlock);
2768 2740
2769 policydb = &state->ss->policydb; 2741 policydb = &state->ss->policydb;
2770 sidtab = &state->ss->sidtab; 2742 sidtab = state->ss->sidtab;
2771 2743
2772 c = policydb->ocontexts[OCON_FSUSE]; 2744 c = policydb->ocontexts[OCON_FSUSE];
2773 while (c) { 2745 while (c) {
@@ -2973,7 +2945,7 @@ int security_sid_mls_copy(struct selinux_state *state,
2973 u32 sid, u32 mls_sid, u32 *new_sid) 2945 u32 sid, u32 mls_sid, u32 *new_sid)
2974{ 2946{
2975 struct policydb *policydb = &state->ss->policydb; 2947 struct policydb *policydb = &state->ss->policydb;
2976 struct sidtab *sidtab = &state->ss->sidtab; 2948 struct sidtab *sidtab = state->ss->sidtab;
2977 struct context *context1; 2949 struct context *context1;
2978 struct context *context2; 2950 struct context *context2;
2979 struct context newcon; 2951 struct context newcon;
@@ -3064,7 +3036,7 @@ int security_net_peersid_resolve(struct selinux_state *state,
3064 u32 *peer_sid) 3036 u32 *peer_sid)
3065{ 3037{
3066 struct policydb *policydb = &state->ss->policydb; 3038 struct policydb *policydb = &state->ss->policydb;
3067 struct sidtab *sidtab = &state->ss->sidtab; 3039 struct sidtab *sidtab = state->ss->sidtab;
3068 int rc; 3040 int rc;
3069 struct context *nlbl_ctx; 3041 struct context *nlbl_ctx;
3070 struct context *xfrm_ctx; 3042 struct context *xfrm_ctx;
@@ -3425,7 +3397,7 @@ int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule,
3425 goto out; 3397 goto out;
3426 } 3398 }
3427 3399
3428 ctxt = sidtab_search(&state->ss->sidtab, sid); 3400 ctxt = sidtab_search(state->ss->sidtab, sid);
3429 if (unlikely(!ctxt)) { 3401 if (unlikely(!ctxt)) {
3430 WARN_ONCE(1, "selinux_audit_rule_match: unrecognized SID %d\n", 3402 WARN_ONCE(1, "selinux_audit_rule_match: unrecognized SID %d\n",
3431 sid); 3403 sid);
@@ -3588,7 +3560,7 @@ int security_netlbl_secattr_to_sid(struct selinux_state *state,
3588 u32 *sid) 3560 u32 *sid)
3589{ 3561{
3590 struct policydb *policydb = &state->ss->policydb; 3562 struct policydb *policydb = &state->ss->policydb;
3591 struct sidtab *sidtab = &state->ss->sidtab; 3563 struct sidtab *sidtab = state->ss->sidtab;
3592 int rc; 3564 int rc;
3593 struct context *ctx; 3565 struct context *ctx;
3594 struct context ctx_new; 3566 struct context ctx_new;
@@ -3666,7 +3638,7 @@ int security_netlbl_sid_to_secattr(struct selinux_state *state,
3666 read_lock(&state->ss->policy_rwlock); 3638 read_lock(&state->ss->policy_rwlock);
3667 3639
3668 rc = -ENOENT; 3640 rc = -ENOENT;
3669 ctx = sidtab_search(&state->ss->sidtab, sid); 3641 ctx = sidtab_search(state->ss->sidtab, sid);
3670 if (ctx == NULL) 3642 if (ctx == NULL)
3671 goto out; 3643 goto out;
3672 3644
diff --git a/security/selinux/ss/services.h b/security/selinux/ss/services.h
index 24c7bdcc8075..9a36de860368 100644
--- a/security/selinux/ss/services.h
+++ b/security/selinux/ss/services.h
@@ -24,7 +24,7 @@ struct selinux_map {
24}; 24};
25 25
26struct selinux_ss { 26struct selinux_ss {
27 struct sidtab sidtab; 27 struct sidtab *sidtab;
28 struct policydb policydb; 28 struct policydb policydb;
29 rwlock_t policy_rwlock; 29 rwlock_t policy_rwlock;
30 u32 latest_granting; 30 u32 latest_granting;
diff --git a/security/selinux/ss/sidtab.c b/security/selinux/ss/sidtab.c
index fd75a12fa8fc..e63a90ff2728 100644
--- a/security/selinux/ss/sidtab.c
+++ b/security/selinux/ss/sidtab.c
@@ -2,108 +2,164 @@
2/* 2/*
3 * Implementation of the SID table type. 3 * Implementation of the SID table type.
4 * 4 *
5 * Author : Stephen Smalley, <sds@tycho.nsa.gov> 5 * Original author: Stephen Smalley, <sds@tycho.nsa.gov>
6 * Author: Ondrej Mosnacek, <omosnacek@gmail.com>
7 *
8 * Copyright (C) 2018 Red Hat, Inc.
6 */ 9 */
10#include <linux/errno.h>
7#include <linux/kernel.h> 11#include <linux/kernel.h>
8#include <linux/slab.h> 12#include <linux/slab.h>
13#include <linux/sched.h>
9#include <linux/spinlock.h> 14#include <linux/spinlock.h>
10#include <linux/errno.h> 15#include <linux/atomic.h>
11#include "flask.h" 16#include "flask.h"
12#include "security.h" 17#include "security.h"
13#include "sidtab.h" 18#include "sidtab.h"
14 19
15#define SIDTAB_HASH(sid) \
16(sid & SIDTAB_HASH_MASK)
17
18int sidtab_init(struct sidtab *s) 20int sidtab_init(struct sidtab *s)
19{ 21{
20 int i; 22 u32 i;
21 23
22 s->htable = kmalloc_array(SIDTAB_SIZE, sizeof(*s->htable), GFP_ATOMIC); 24 memset(s->roots, 0, sizeof(s->roots));
23 if (!s->htable) 25
24 return -ENOMEM; 26 for (i = 0; i < SIDTAB_RCACHE_SIZE; i++)
25 for (i = 0; i < SIDTAB_SIZE; i++) 27 atomic_set(&s->rcache[i], -1);
26 s->htable[i] = NULL; 28
27 s->nel = 0; 29 for (i = 0; i < SECINITSID_NUM; i++)
28 s->next_sid = 1; 30 s->isids[i].set = 0;
29 s->shutdown = 0; 31
32 atomic_set(&s->count, 0);
33
34 s->convert = NULL;
35
30 spin_lock_init(&s->lock); 36 spin_lock_init(&s->lock);
31 return 0; 37 return 0;
32} 38}
33 39
34int sidtab_insert(struct sidtab *s, u32 sid, struct context *context) 40int sidtab_set_initial(struct sidtab *s, u32 sid, struct context *context)
35{ 41{
36 int hvalue; 42 struct sidtab_isid_entry *entry;
37 struct sidtab_node *prev, *cur, *newnode; 43 int rc;
38
39 if (!s)
40 return -ENOMEM;
41
42 hvalue = SIDTAB_HASH(sid);
43 prev = NULL;
44 cur = s->htable[hvalue];
45 while (cur && sid > cur->sid) {
46 prev = cur;
47 cur = cur->next;
48 }
49 44
50 if (cur && sid == cur->sid) 45 if (sid == 0 || sid > SECINITSID_NUM)
51 return -EEXIST; 46 return -EINVAL;
52 47
53 newnode = kmalloc(sizeof(*newnode), GFP_ATOMIC); 48 entry = &s->isids[sid - 1];
54 if (!newnode)
55 return -ENOMEM;
56 49
57 newnode->sid = sid; 50 rc = context_cpy(&entry->context, context);
58 if (context_cpy(&newnode->context, context)) { 51 if (rc)
59 kfree(newnode); 52 return rc;
60 return -ENOMEM;
61 }
62 53
63 if (prev) { 54 entry->set = 1;
64 newnode->next = prev->next; 55 return 0;
65 wmb(); 56}
66 prev->next = newnode; 57
67 } else { 58static u32 sidtab_level_from_count(u32 count)
68 newnode->next = s->htable[hvalue]; 59{
69 wmb(); 60 u32 capacity = SIDTAB_LEAF_ENTRIES;
70 s->htable[hvalue] = newnode; 61 u32 level = 0;
62
63 while (count > capacity) {
64 capacity <<= SIDTAB_INNER_SHIFT;
65 ++level;
71 } 66 }
67 return level;
68}
72 69
73 s->nel++; 70static int sidtab_alloc_roots(struct sidtab *s, u32 level)
74 if (sid >= s->next_sid) 71{
75 s->next_sid = sid + 1; 72 u32 l;
73
74 if (!s->roots[0].ptr_leaf) {
75 s->roots[0].ptr_leaf = kzalloc(SIDTAB_NODE_ALLOC_SIZE,
76 GFP_ATOMIC);
77 if (!s->roots[0].ptr_leaf)
78 return -ENOMEM;
79 }
80 for (l = 1; l <= level; ++l)
81 if (!s->roots[l].ptr_inner) {
82 s->roots[l].ptr_inner = kzalloc(SIDTAB_NODE_ALLOC_SIZE,
83 GFP_ATOMIC);
84 if (!s->roots[l].ptr_inner)
85 return -ENOMEM;
86 s->roots[l].ptr_inner->entries[0] = s->roots[l - 1];
87 }
76 return 0; 88 return 0;
77} 89}
78 90
79static struct context *sidtab_search_core(struct sidtab *s, u32 sid, int force) 91static struct context *sidtab_do_lookup(struct sidtab *s, u32 index, int alloc)
80{ 92{
81 int hvalue; 93 union sidtab_entry_inner *entry;
82 struct sidtab_node *cur; 94 u32 level, capacity_shift, leaf_index = index / SIDTAB_LEAF_ENTRIES;
95
96 /* find the level of the subtree we need */
97 level = sidtab_level_from_count(index + 1);
98 capacity_shift = level * SIDTAB_INNER_SHIFT;
83 99
84 if (!s) 100 /* allocate roots if needed */
101 if (alloc && sidtab_alloc_roots(s, level) != 0)
85 return NULL; 102 return NULL;
86 103
87 hvalue = SIDTAB_HASH(sid); 104 /* lookup inside the subtree */
88 cur = s->htable[hvalue]; 105 entry = &s->roots[level];
89 while (cur && sid > cur->sid) 106 while (level != 0) {
90 cur = cur->next; 107 capacity_shift -= SIDTAB_INNER_SHIFT;
91 108 --level;
92 if (force && cur && sid == cur->sid && cur->context.len) 109
93 return &cur->context; 110 entry = &entry->ptr_inner->entries[leaf_index >> capacity_shift];
94 111 leaf_index &= ((u32)1 << capacity_shift) - 1;
95 if (!cur || sid != cur->sid || cur->context.len) { 112
96 /* Remap invalid SIDs to the unlabeled SID. */ 113 if (!entry->ptr_inner) {
97 sid = SECINITSID_UNLABELED; 114 if (alloc)
98 hvalue = SIDTAB_HASH(sid); 115 entry->ptr_inner = kzalloc(SIDTAB_NODE_ALLOC_SIZE,
99 cur = s->htable[hvalue]; 116 GFP_ATOMIC);
100 while (cur && sid > cur->sid) 117 if (!entry->ptr_inner)
101 cur = cur->next; 118 return NULL;
102 if (!cur || sid != cur->sid) 119 }
120 }
121 if (!entry->ptr_leaf) {
122 if (alloc)
123 entry->ptr_leaf = kzalloc(SIDTAB_NODE_ALLOC_SIZE,
124 GFP_ATOMIC);
125 if (!entry->ptr_leaf)
103 return NULL; 126 return NULL;
104 } 127 }
128 return &entry->ptr_leaf->entries[index % SIDTAB_LEAF_ENTRIES].context;
129}
130
131static struct context *sidtab_lookup(struct sidtab *s, u32 index)
132{
133 u32 count = (u32)atomic_read(&s->count);
134
135 if (index >= count)
136 return NULL;
137
138 /* read entries after reading count */
139 smp_rmb();
140
141 return sidtab_do_lookup(s, index, 0);
142}
143
144static struct context *sidtab_lookup_initial(struct sidtab *s, u32 sid)
145{
146 return s->isids[sid - 1].set ? &s->isids[sid - 1].context : NULL;
147}
148
149static struct context *sidtab_search_core(struct sidtab *s, u32 sid, int force)
150{
151 struct context *context;
152
153 if (sid != 0) {
154 if (sid > SECINITSID_NUM)
155 context = sidtab_lookup(s, sid - (SECINITSID_NUM + 1));
156 else
157 context = sidtab_lookup_initial(s, sid);
158 if (context && (!context->len || force))
159 return context;
160 }
105 161
106 return &cur->context; 162 return sidtab_lookup_initial(s, SECINITSID_UNLABELED);
107} 163}
108 164
109struct context *sidtab_search(struct sidtab *s, u32 sid) 165struct context *sidtab_search(struct sidtab *s, u32 sid)
@@ -116,191 +172,324 @@ struct context *sidtab_search_force(struct sidtab *s, u32 sid)
116 return sidtab_search_core(s, sid, 1); 172 return sidtab_search_core(s, sid, 1);
117} 173}
118 174
119int sidtab_map(struct sidtab *s, 175static int sidtab_find_context(union sidtab_entry_inner entry,
120 int (*apply) (u32 sid, 176 u32 *pos, u32 count, u32 level,
121 struct context *context, 177 struct context *context, u32 *index)
122 void *args),
123 void *args)
124{ 178{
125 int i, rc = 0; 179 int rc;
126 struct sidtab_node *cur; 180 u32 i;
127 181
128 if (!s) 182 if (level != 0) {
129 goto out; 183 struct sidtab_node_inner *node = entry.ptr_inner;
184
185 i = 0;
186 while (i < SIDTAB_INNER_ENTRIES && *pos < count) {
187 rc = sidtab_find_context(node->entries[i],
188 pos, count, level - 1,
189 context, index);
190 if (rc == 0)
191 return 0;
192 i++;
193 }
194 } else {
195 struct sidtab_node_leaf *node = entry.ptr_leaf;
130 196
131 for (i = 0; i < SIDTAB_SIZE; i++) { 197 i = 0;
132 cur = s->htable[i]; 198 while (i < SIDTAB_LEAF_ENTRIES && *pos < count) {
133 while (cur) { 199 if (context_cmp(&node->entries[i].context, context)) {
134 rc = apply(cur->sid, &cur->context, args); 200 *index = *pos;
135 if (rc) 201 return 0;
136 goto out; 202 }
137 cur = cur->next; 203 (*pos)++;
204 i++;
138 } 205 }
139 } 206 }
140out: 207 return -ENOENT;
141 return rc;
142} 208}
143 209
144static void sidtab_update_cache(struct sidtab *s, struct sidtab_node *n, int loc) 210static void sidtab_rcache_update(struct sidtab *s, u32 index, u32 pos)
145{ 211{
146 BUG_ON(loc >= SIDTAB_CACHE_LEN); 212 while (pos > 0) {
147 213 atomic_set(&s->rcache[pos], atomic_read(&s->rcache[pos - 1]));
148 while (loc > 0) { 214 --pos;
149 s->cache[loc] = s->cache[loc - 1];
150 loc--;
151 } 215 }
152 s->cache[0] = n; 216 atomic_set(&s->rcache[0], (int)index);
153} 217}
154 218
155static inline u32 sidtab_search_context(struct sidtab *s, 219static void sidtab_rcache_push(struct sidtab *s, u32 index)
156 struct context *context)
157{ 220{
158 int i; 221 sidtab_rcache_update(s, index, SIDTAB_RCACHE_SIZE - 1);
159 struct sidtab_node *cur;
160
161 for (i = 0; i < SIDTAB_SIZE; i++) {
162 cur = s->htable[i];
163 while (cur) {
164 if (context_cmp(&cur->context, context)) {
165 sidtab_update_cache(s, cur, SIDTAB_CACHE_LEN - 1);
166 return cur->sid;
167 }
168 cur = cur->next;
169 }
170 }
171 return 0;
172} 222}
173 223
174static inline u32 sidtab_search_cache(struct sidtab *s, struct context *context) 224static int sidtab_rcache_search(struct sidtab *s, struct context *context,
225 u32 *index)
175{ 226{
176 int i; 227 u32 i;
177 struct sidtab_node *node;
178 228
179 for (i = 0; i < SIDTAB_CACHE_LEN; i++) { 229 for (i = 0; i < SIDTAB_RCACHE_SIZE; i++) {
180 node = s->cache[i]; 230 int v = atomic_read(&s->rcache[i]);
181 if (unlikely(!node)) 231
232 if (v < 0)
233 continue;
234
235 if (context_cmp(sidtab_do_lookup(s, (u32)v, 0), context)) {
236 sidtab_rcache_update(s, (u32)v, i);
237 *index = (u32)v;
182 return 0; 238 return 0;
183 if (context_cmp(&node->context, context)) {
184 sidtab_update_cache(s, node, i);
185 return node->sid;
186 } 239 }
187 } 240 }
188 return 0; 241 return -ENOENT;
189} 242}
190 243
191int sidtab_context_to_sid(struct sidtab *s, 244static int sidtab_reverse_lookup(struct sidtab *s, struct context *context,
192 struct context *context, 245 u32 *index)
193 u32 *out_sid)
194{ 246{
195 u32 sid;
196 int ret = 0;
197 unsigned long flags; 247 unsigned long flags;
248 u32 count = (u32)atomic_read(&s->count);
249 u32 count_locked, level, pos;
250 struct sidtab_convert_params *convert;
251 struct context *dst, *dst_convert;
252 int rc;
253
254 rc = sidtab_rcache_search(s, context, index);
255 if (rc == 0)
256 return 0;
257
258 level = sidtab_level_from_count(count);
259
260 /* read entries after reading count */
261 smp_rmb();
262
263 pos = 0;
264 rc = sidtab_find_context(s->roots[level], &pos, count, level,
265 context, index);
266 if (rc == 0) {
267 sidtab_rcache_push(s, *index);
268 return 0;
269 }
198 270
199 *out_sid = SECSID_NULL; 271 /* lock-free search failed: lock, re-search, and insert if not found */
272 spin_lock_irqsave(&s->lock, flags);
200 273
201 sid = sidtab_search_cache(s, context); 274 convert = s->convert;
202 if (!sid) 275 count_locked = (u32)atomic_read(&s->count);
203 sid = sidtab_search_context(s, context); 276 level = sidtab_level_from_count(count_locked);
204 if (!sid) { 277
205 spin_lock_irqsave(&s->lock, flags); 278 /* if count has changed before we acquired the lock, then catch up */
206 /* Rescan now that we hold the lock. */ 279 while (count < count_locked) {
207 sid = sidtab_search_context(s, context); 280 if (context_cmp(sidtab_do_lookup(s, count, 0), context)) {
208 if (sid) 281 sidtab_rcache_push(s, count);
209 goto unlock_out; 282 *index = count;
210 /* No SID exists for the context. Allocate a new one. */ 283 rc = 0;
211 if (s->next_sid == UINT_MAX || s->shutdown) { 284 goto out_unlock;
212 ret = -ENOMEM;
213 goto unlock_out;
214 } 285 }
215 sid = s->next_sid++; 286 ++count;
216 if (context->len)
217 pr_info("SELinux: Context %s is not valid (left unmapped).\n",
218 context->str);
219 ret = sidtab_insert(s, sid, context);
220 if (ret)
221 s->next_sid--;
222unlock_out:
223 spin_unlock_irqrestore(&s->lock, flags);
224 } 287 }
225 288
226 if (ret) 289 /* insert context into new entry */
227 return ret; 290 rc = -ENOMEM;
291 dst = sidtab_do_lookup(s, count, 1);
292 if (!dst)
293 goto out_unlock;
294
295 rc = context_cpy(dst, context);
296 if (rc)
297 goto out_unlock;
298
299 /*
300 * if we are building a new sidtab, we need to convert the context
301 * and insert it there as well
302 */
303 if (convert) {
304 rc = -ENOMEM;
305 dst_convert = sidtab_do_lookup(convert->target, count, 1);
306 if (!dst_convert) {
307 context_destroy(dst);
308 goto out_unlock;
309 }
228 310
229 *out_sid = sid; 311 rc = convert->func(context, dst_convert, convert->args);
230 return 0; 312 if (rc) {
313 context_destroy(dst);
314 goto out_unlock;
315 }
316
317 /* at this point we know the insert won't fail */
318 atomic_set(&convert->target->count, count + 1);
319 }
320
321 if (context->len)
322 pr_info("SELinux: Context %s is not valid (left unmapped).\n",
323 context->str);
324
325 sidtab_rcache_push(s, count);
326 *index = count;
327
328 /* write entries before writing new count */
329 smp_wmb();
330
331 atomic_set(&s->count, count + 1);
332
333 rc = 0;
334out_unlock:
335 spin_unlock_irqrestore(&s->lock, flags);
336 return rc;
231} 337}
232 338
233void sidtab_hash_eval(struct sidtab *h, char *tag) 339int sidtab_context_to_sid(struct sidtab *s, struct context *context, u32 *sid)
234{ 340{
235 int i, chain_len, slots_used, max_chain_len; 341 int rc;
236 struct sidtab_node *cur; 342 u32 i;
237 343
238 slots_used = 0; 344 for (i = 0; i < SECINITSID_NUM; i++) {
239 max_chain_len = 0; 345 struct sidtab_isid_entry *entry = &s->isids[i];
240 for (i = 0; i < SIDTAB_SIZE; i++) {
241 cur = h->htable[i];
242 if (cur) {
243 slots_used++;
244 chain_len = 0;
245 while (cur) {
246 chain_len++;
247 cur = cur->next;
248 }
249 346
250 if (chain_len > max_chain_len) 347 if (entry->set && context_cmp(context, &entry->context)) {
251 max_chain_len = chain_len; 348 *sid = i + 1;
349 return 0;
252 } 350 }
253 } 351 }
254 352
255 pr_debug("%s: %d entries and %d/%d buckets used, longest " 353 rc = sidtab_reverse_lookup(s, context, sid);
256 "chain length %d\n", tag, h->nel, slots_used, SIDTAB_SIZE, 354 if (rc)
257 max_chain_len); 355 return rc;
356 *sid += SECINITSID_NUM + 1;
357 return 0;
258} 358}
259 359
260void sidtab_destroy(struct sidtab *s) 360static int sidtab_convert_tree(union sidtab_entry_inner *edst,
361 union sidtab_entry_inner *esrc,
362 u32 *pos, u32 count, u32 level,
363 struct sidtab_convert_params *convert)
261{ 364{
262 int i; 365 int rc;
263 struct sidtab_node *cur, *temp; 366 u32 i;
264 367
265 if (!s) 368 if (level != 0) {
266 return; 369 if (!edst->ptr_inner) {
267 370 edst->ptr_inner = kzalloc(SIDTAB_NODE_ALLOC_SIZE,
268 for (i = 0; i < SIDTAB_SIZE; i++) { 371 GFP_KERNEL);
269 cur = s->htable[i]; 372 if (!edst->ptr_inner)
270 while (cur) { 373 return -ENOMEM;
271 temp = cur; 374 }
272 cur = cur->next; 375 i = 0;
273 context_destroy(&temp->context); 376 while (i < SIDTAB_INNER_ENTRIES && *pos < count) {
274 kfree(temp); 377 rc = sidtab_convert_tree(&edst->ptr_inner->entries[i],
378 &esrc->ptr_inner->entries[i],
379 pos, count, level - 1,
380 convert);
381 if (rc)
382 return rc;
383 i++;
384 }
385 } else {
386 if (!edst->ptr_leaf) {
387 edst->ptr_leaf = kzalloc(SIDTAB_NODE_ALLOC_SIZE,
388 GFP_KERNEL);
389 if (!edst->ptr_leaf)
390 return -ENOMEM;
391 }
392 i = 0;
393 while (i < SIDTAB_LEAF_ENTRIES && *pos < count) {
394 rc = convert->func(&esrc->ptr_leaf->entries[i].context,
395 &edst->ptr_leaf->entries[i].context,
396 convert->args);
397 if (rc)
398 return rc;
399 (*pos)++;
400 i++;
275 } 401 }
276 s->htable[i] = NULL; 402 cond_resched();
277 } 403 }
278 kfree(s->htable); 404 return 0;
279 s->htable = NULL;
280 s->nel = 0;
281 s->next_sid = 1;
282} 405}
283 406
284void sidtab_set(struct sidtab *dst, struct sidtab *src) 407int sidtab_convert(struct sidtab *s, struct sidtab_convert_params *params)
285{ 408{
286 unsigned long flags; 409 unsigned long flags;
287 int i; 410 u32 count, level, pos;
288 411 int rc;
289 spin_lock_irqsave(&src->lock, flags); 412
290 dst->htable = src->htable; 413 spin_lock_irqsave(&s->lock, flags);
291 dst->nel = src->nel; 414
292 dst->next_sid = src->next_sid; 415 /* concurrent policy loads are not allowed */
293 dst->shutdown = 0; 416 if (s->convert) {
294 for (i = 0; i < SIDTAB_CACHE_LEN; i++) 417 spin_unlock_irqrestore(&s->lock, flags);
295 dst->cache[i] = NULL; 418 return -EBUSY;
296 spin_unlock_irqrestore(&src->lock, flags); 419 }
420
421 count = (u32)atomic_read(&s->count);
422 level = sidtab_level_from_count(count);
423
424 /* allocate last leaf in the new sidtab (to avoid race with
425 * live convert)
426 */
427 rc = sidtab_do_lookup(params->target, count - 1, 1) ? 0 : -ENOMEM;
428 if (rc) {
429 spin_unlock_irqrestore(&s->lock, flags);
430 return rc;
431 }
432
433 /* set count in case no new entries are added during conversion */
434 atomic_set(&params->target->count, count);
435
436 /* enable live convert of new entries */
437 s->convert = params;
438
439 /* we can safely do the rest of the conversion outside the lock */
440 spin_unlock_irqrestore(&s->lock, flags);
441
442 pr_info("SELinux: Converting %u SID table entries...\n", count);
443
444 /* convert all entries not covered by live convert */
445 pos = 0;
446 rc = sidtab_convert_tree(&params->target->roots[level],
447 &s->roots[level], &pos, count, level, params);
448 if (rc) {
449 /* we need to keep the old table - disable live convert */
450 spin_lock_irqsave(&s->lock, flags);
451 s->convert = NULL;
452 spin_unlock_irqrestore(&s->lock, flags);
453 }
454 return rc;
297} 455}
298 456
299void sidtab_shutdown(struct sidtab *s) 457static void sidtab_destroy_tree(union sidtab_entry_inner entry, u32 level)
300{ 458{
301 unsigned long flags; 459 u32 i;
302 460
303 spin_lock_irqsave(&s->lock, flags); 461 if (level != 0) {
304 s->shutdown = 1; 462 struct sidtab_node_inner *node = entry.ptr_inner;
305 spin_unlock_irqrestore(&s->lock, flags); 463
464 if (!node)
465 return;
466
467 for (i = 0; i < SIDTAB_INNER_ENTRIES; i++)
468 sidtab_destroy_tree(node->entries[i], level - 1);
469 kfree(node);
470 } else {
471 struct sidtab_node_leaf *node = entry.ptr_leaf;
472
473 if (!node)
474 return;
475
476 for (i = 0; i < SIDTAB_LEAF_ENTRIES; i++)
477 context_destroy(&node->entries[i].context);
478 kfree(node);
479 }
480}
481
482void sidtab_destroy(struct sidtab *s)
483{
484 u32 i, level;
485
486 for (i = 0; i < SECINITSID_NUM; i++)
487 if (s->isids[i].set)
488 context_destroy(&s->isids[i].context);
489
490 level = SIDTAB_MAX_LEVEL;
491 while (level && !s->roots[level].ptr_inner)
492 --level;
493
494 sidtab_destroy_tree(s->roots[level], level);
306} 495}
diff --git a/security/selinux/ss/sidtab.h b/security/selinux/ss/sidtab.h
index a1a1d2617b6f..bbd5c0d1f3bd 100644
--- a/security/selinux/ss/sidtab.h
+++ b/security/selinux/ss/sidtab.h
@@ -1,56 +1,96 @@
1/* SPDX-License-Identifier: GPL-2.0 */ 1/* SPDX-License-Identifier: GPL-2.0 */
2/* 2/*
3 * A security identifier table (sidtab) is a hash table 3 * A security identifier table (sidtab) is a lookup table
4 * of security context structures indexed by SID value. 4 * of security context structures indexed by SID value.
5 * 5 *
6 * Author : Stephen Smalley, <sds@tycho.nsa.gov> 6 * Original author: Stephen Smalley, <sds@tycho.nsa.gov>
7 * Author: Ondrej Mosnacek, <omosnacek@gmail.com>
8 *
9 * Copyright (C) 2018 Red Hat, Inc.
7 */ 10 */
8#ifndef _SS_SIDTAB_H_ 11#ifndef _SS_SIDTAB_H_
9#define _SS_SIDTAB_H_ 12#define _SS_SIDTAB_H_
10 13
14#include <linux/spinlock_types.h>
15#include <linux/log2.h>
16
11#include "context.h" 17#include "context.h"
12 18
13struct sidtab_node { 19struct sidtab_entry_leaf {
14 u32 sid; /* security identifier */ 20 struct context context;
15 struct context context; /* security context structure */ 21};
16 struct sidtab_node *next; 22
23struct sidtab_node_inner;
24struct sidtab_node_leaf;
25
26union sidtab_entry_inner {
27 struct sidtab_node_inner *ptr_inner;
28 struct sidtab_node_leaf *ptr_leaf;
29};
30
31/* align node size to page boundary */
32#define SIDTAB_NODE_ALLOC_SHIFT PAGE_SHIFT
33#define SIDTAB_NODE_ALLOC_SIZE PAGE_SIZE
34
35#define size_to_shift(size) ((size) == 1 ? 1 : (const_ilog2((size) - 1) + 1))
36
37#define SIDTAB_INNER_SHIFT \
38 (SIDTAB_NODE_ALLOC_SHIFT - size_to_shift(sizeof(union sidtab_entry_inner)))
39#define SIDTAB_INNER_ENTRIES ((size_t)1 << SIDTAB_INNER_SHIFT)
40#define SIDTAB_LEAF_ENTRIES \
41 (SIDTAB_NODE_ALLOC_SIZE / sizeof(struct sidtab_entry_leaf))
42
43#define SIDTAB_MAX_BITS 31 /* limited to INT_MAX due to atomic_t range */
44#define SIDTAB_MAX (((u32)1 << SIDTAB_MAX_BITS) - 1)
45/* ensure enough tree levels for SIDTAB_MAX entries */
46#define SIDTAB_MAX_LEVEL \
47 DIV_ROUND_UP(SIDTAB_MAX_BITS - size_to_shift(SIDTAB_LEAF_ENTRIES), \
48 SIDTAB_INNER_SHIFT)
49
50struct sidtab_node_leaf {
51 struct sidtab_entry_leaf entries[SIDTAB_LEAF_ENTRIES];
17}; 52};
18 53
19#define SIDTAB_HASH_BITS 7 54struct sidtab_node_inner {
20#define SIDTAB_HASH_BUCKETS (1 << SIDTAB_HASH_BITS) 55 union sidtab_entry_inner entries[SIDTAB_INNER_ENTRIES];
21#define SIDTAB_HASH_MASK (SIDTAB_HASH_BUCKETS-1) 56};
22 57
23#define SIDTAB_SIZE SIDTAB_HASH_BUCKETS 58struct sidtab_isid_entry {
59 int set;
60 struct context context;
61};
62
63struct sidtab_convert_params {
64 int (*func)(struct context *oldc, struct context *newc, void *args);
65 void *args;
66 struct sidtab *target;
67};
68
69#define SIDTAB_RCACHE_SIZE 3
24 70
25struct sidtab { 71struct sidtab {
26 struct sidtab_node **htable; 72 union sidtab_entry_inner roots[SIDTAB_MAX_LEVEL + 1];
27 unsigned int nel; /* number of elements */ 73 atomic_t count;
28 unsigned int next_sid; /* next SID to allocate */ 74 struct sidtab_convert_params *convert;
29 unsigned char shutdown;
30#define SIDTAB_CACHE_LEN 3
31 struct sidtab_node *cache[SIDTAB_CACHE_LEN];
32 spinlock_t lock; 75 spinlock_t lock;
76
77 /* reverse lookup cache */
78 atomic_t rcache[SIDTAB_RCACHE_SIZE];
79
80 /* index == SID - 1 (no entry for SECSID_NULL) */
81 struct sidtab_isid_entry isids[SECINITSID_NUM];
33}; 82};
34 83
35int sidtab_init(struct sidtab *s); 84int sidtab_init(struct sidtab *s);
36int sidtab_insert(struct sidtab *s, u32 sid, struct context *context); 85int sidtab_set_initial(struct sidtab *s, u32 sid, struct context *context);
37struct context *sidtab_search(struct sidtab *s, u32 sid); 86struct context *sidtab_search(struct sidtab *s, u32 sid);
38struct context *sidtab_search_force(struct sidtab *s, u32 sid); 87struct context *sidtab_search_force(struct sidtab *s, u32 sid);
39 88
40int sidtab_map(struct sidtab *s, 89int sidtab_convert(struct sidtab *s, struct sidtab_convert_params *params);
41 int (*apply) (u32 sid,
42 struct context *context,
43 void *args),
44 void *args);
45 90
46int sidtab_context_to_sid(struct sidtab *s, 91int sidtab_context_to_sid(struct sidtab *s, struct context *context, u32 *sid);
47 struct context *context,
48 u32 *sid);
49 92
50void sidtab_hash_eval(struct sidtab *h, char *tag);
51void sidtab_destroy(struct sidtab *s); 93void sidtab_destroy(struct sidtab *s);
52void sidtab_set(struct sidtab *dst, struct sidtab *src);
53void sidtab_shutdown(struct sidtab *s);
54 94
55#endif /* _SS_SIDTAB_H_ */ 95#endif /* _SS_SIDTAB_H_ */
56 96
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c
index 91dc3783ed94..bd7d18bdb147 100644
--- a/security/selinux/xfrm.c
+++ b/security/selinux/xfrm.c
@@ -230,7 +230,7 @@ static int selinux_xfrm_skb_sid_ingress(struct sk_buff *skb,
230 u32 *sid, int ckall) 230 u32 *sid, int ckall)
231{ 231{
232 u32 sid_session = SECSID_NULL; 232 u32 sid_session = SECSID_NULL;
233 struct sec_path *sp = skb->sp; 233 struct sec_path *sp = skb_sec_path(skb);
234 234
235 if (sp) { 235 if (sp) {
236 int i; 236 int i;
@@ -408,7 +408,7 @@ int selinux_xfrm_sock_rcv_skb(u32 sk_sid, struct sk_buff *skb,
408 struct common_audit_data *ad) 408 struct common_audit_data *ad)
409{ 409{
410 int i; 410 int i;
411 struct sec_path *sp = skb->sp; 411 struct sec_path *sp = skb_sec_path(skb);
412 u32 peer_sid = SECINITSID_UNLABELED; 412 u32 peer_sid = SECINITSID_UNLABELED;
413 413
414 if (sp) { 414 if (sp) {