aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/security/LoadPin.txt17
-rw-r--r--Documentation/security/keys.txt52
-rw-r--r--MAINTAINERS6
-rw-r--r--arch/x86/kernel/kexec-bzimage64.c18
-rw-r--r--certs/Kconfig9
-rw-r--r--certs/system_keyring.c139
-rw-r--r--crypto/asymmetric_keys/Kconfig6
-rw-r--r--crypto/asymmetric_keys/Makefile5
-rw-r--r--crypto/asymmetric_keys/asymmetric_keys.h2
-rw-r--r--crypto/asymmetric_keys/asymmetric_type.c96
-rw-r--r--crypto/asymmetric_keys/mscode_parser.c21
-rw-r--r--crypto/asymmetric_keys/pkcs7_key_type.c72
-rw-r--r--crypto/asymmetric_keys/pkcs7_parser.c58
-rw-r--r--crypto/asymmetric_keys/pkcs7_parser.h11
-rw-r--r--crypto/asymmetric_keys/pkcs7_trust.c43
-rw-r--r--crypto/asymmetric_keys/pkcs7_verify.c107
-rw-r--r--crypto/asymmetric_keys/public_key.c20
-rw-r--r--crypto/asymmetric_keys/restrict.c108
-rw-r--r--crypto/asymmetric_keys/signature.c18
-rw-r--r--crypto/asymmetric_keys/verify_pefile.c40
-rw-r--r--crypto/asymmetric_keys/verify_pefile.h5
-rw-r--r--crypto/asymmetric_keys/x509_cert_parser.c52
-rw-r--r--crypto/asymmetric_keys/x509_parser.h12
-rw-r--r--crypto/asymmetric_keys/x509_public_key.c297
-rw-r--r--fs/cifs/cifsacl.c2
-rw-r--r--fs/exec.c29
-rw-r--r--fs/namei.c2
-rw-r--r--fs/nfs/nfs4idmap.c2
-rw-r--r--include/crypto/pkcs7.h6
-rw-r--r--include/crypto/public_key.h33
-rw-r--r--include/keys/asymmetric-subtype.h2
-rw-r--r--include/keys/asymmetric-type.h13
-rw-r--r--include/keys/system_keyring.h41
-rw-r--r--include/linux/fs.h31
-rw-r--r--include/linux/ima.h6
-rw-r--r--include/linux/key-type.h1
-rw-r--r--include/linux/key.h44
-rw-r--r--include/linux/lsm_hooks.h6
-rw-r--r--include/linux/string_helpers.h6
-rw-r--r--include/linux/verification.h49
-rw-r--r--include/linux/verify_pefile.h22
-rw-r--r--include/uapi/linux/keyctl.h10
-rw-r--r--kernel/module_signing.c7
-rw-r--r--kernel/seccomp.c2
-rw-r--r--lib/string_helpers.c92
-rw-r--r--net/dns_resolver/dns_key.c2
-rw-r--r--net/netlabel/netlabel_kapi.c2
-rw-r--r--net/rxrpc/ar-key.c4
-rw-r--r--security/Kconfig1
-rw-r--r--security/Makefile2
-rw-r--r--security/integrity/Kconfig1
-rw-r--r--security/integrity/digsig.c15
-rw-r--r--security/integrity/ima/Kconfig36
-rw-r--r--security/integrity/ima/Makefile2
-rw-r--r--security/integrity/ima/ima_appraise.c7
-rw-r--r--security/integrity/ima/ima_main.c25
-rw-r--r--security/integrity/ima/ima_mok.c23
-rw-r--r--security/integrity/integrity.h1
-rw-r--r--security/keys/Kconfig15
-rw-r--r--security/keys/Makefile1
-rw-r--r--security/keys/big_key.c198
-rw-r--r--security/keys/compat.c4
-rw-r--r--security/keys/dh.c160
-rw-r--r--security/keys/internal.h12
-rw-r--r--security/keys/key.c42
-rw-r--r--security/keys/keyctl.c5
-rw-r--r--security/keys/keyring.c46
-rw-r--r--security/keys/persistent.c4
-rw-r--r--security/keys/process_keys.c16
-rw-r--r--security/keys/request_key.c4
-rw-r--r--security/keys/request_key_auth.c2
-rw-r--r--security/keys/user_defined.c42
-rw-r--r--security/loadpin/Kconfig19
-rw-r--r--security/loadpin/Makefile1
-rw-r--r--security/loadpin/loadpin.c190
-rw-r--r--security/security.c2
-rw-r--r--security/selinux/hooks.c144
-rw-r--r--security/selinux/include/classmap.h30
-rw-r--r--security/selinux/include/conditional.h2
-rw-r--r--security/selinux/include/objsec.h5
-rw-r--r--security/selinux/ss/services.c6
-rw-r--r--security/yama/yama_lsm.c31
82 files changed, 1915 insertions, 807 deletions
diff --git a/Documentation/security/LoadPin.txt b/Documentation/security/LoadPin.txt
new file mode 100644
index 000000000000..e11877f5d3d4
--- /dev/null
+++ b/Documentation/security/LoadPin.txt
@@ -0,0 +1,17 @@
1LoadPin is a Linux Security Module that ensures all kernel-loaded files
2(modules, firmware, etc) all originate from the same filesystem, with
3the expectation that such a filesystem is backed by a read-only device
4such as dm-verity or CDROM. This allows systems that have a verified
5and/or unchangeable filesystem to enforce module and firmware loading
6restrictions without needing to sign the files individually.
7
8The LSM is selectable at build-time with CONFIG_SECURITY_LOADPIN, and
9can be controlled at boot-time with the kernel command line option
10"loadpin.enabled". By default, it is enabled, but can be disabled at
11boot ("loadpin.enabled=0").
12
13LoadPin starts pinning when it sees the first file loaded. If the
14block device backing the filesystem is not read-only, a sysctl is
15created to toggle pinning: /proc/sys/kernel/loadpin/enabled. (Having
16a mutable filesystem means pinning is mutable too, but having the
17sysctl allows for easy testing on systems with a mutable filesystem.)
diff --git a/Documentation/security/keys.txt b/Documentation/security/keys.txt
index 8c183873b2b7..20d05719bceb 100644
--- a/Documentation/security/keys.txt
+++ b/Documentation/security/keys.txt
@@ -823,6 +823,36 @@ The keyctl syscall functions are:
823 A process must have search permission on the key for this function to be 823 A process must have search permission on the key for this function to be
824 successful. 824 successful.
825 825
826 (*) Compute a Diffie-Hellman shared secret or public key
827
828 long keyctl(KEYCTL_DH_COMPUTE, struct keyctl_dh_params *params,
829 char *buffer, size_t buflen);
830
831 The params struct contains serial numbers for three keys:
832
833 - The prime, p, known to both parties
834 - The local private key
835 - The base integer, which is either a shared generator or the
836 remote public key
837
838 The value computed is:
839
840 result = base ^ private (mod prime)
841
842 If the base is the shared generator, the result is the local
843 public key. If the base is the remote public key, the result is
844 the shared secret.
845
846 The buffer length must be at least the length of the prime, or zero.
847
848 If the buffer length is nonzero, the length of the result is
849 returned when it is successfully calculated and copied in to the
850 buffer. When the buffer length is zero, the minimum required
851 buffer length is returned.
852
853 This function will return error EOPNOTSUPP if the key type is not
854 supported, error ENOKEY if the key could not be found, or error
855 EACCES if the key is not readable by the caller.
826 856
827=============== 857===============
828KERNEL SERVICES 858KERNEL SERVICES
@@ -999,6 +1029,10 @@ payload contents" for more information.
999 struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid, 1029 struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid,
1000 const struct cred *cred, 1030 const struct cred *cred,
1001 key_perm_t perm, 1031 key_perm_t perm,
1032 int (*restrict_link)(struct key *,
1033 const struct key_type *,
1034 unsigned long,
1035 const union key_payload *),
1002 unsigned long flags, 1036 unsigned long flags,
1003 struct key *dest); 1037 struct key *dest);
1004 1038
@@ -1010,6 +1044,24 @@ payload contents" for more information.
1010 KEY_ALLOC_NOT_IN_QUOTA in flags if the keyring shouldn't be accounted 1044 KEY_ALLOC_NOT_IN_QUOTA in flags if the keyring shouldn't be accounted
1011 towards the user's quota). Error ENOMEM can also be returned. 1045 towards the user's quota). Error ENOMEM can also be returned.
1012 1046
1047 If restrict_link not NULL, it should point to a function that will be
1048 called each time an attempt is made to link a key into the new keyring.
1049 This function is called to check whether a key may be added into the keying
1050 or not. Callers of key_create_or_update() within the kernel can pass
1051 KEY_ALLOC_BYPASS_RESTRICTION to suppress the check. An example of using
1052 this is to manage rings of cryptographic keys that are set up when the
1053 kernel boots where userspace is also permitted to add keys - provided they
1054 can be verified by a key the kernel already has.
1055
1056 When called, the restriction function will be passed the keyring being
1057 added to, the key flags value and the type and payload of the key being
1058 added. Note that when a new key is being created, this is called between
1059 payload preparsing and actual key creation. The function should return 0
1060 to allow the link or an error to reject it.
1061
1062 A convenience function, restrict_link_reject, exists to always return
1063 -EPERM to in this case.
1064
1013 1065
1014(*) To check the validity of a key, this function can be called: 1066(*) To check the validity of a key, this function can be called:
1015 1067
diff --git a/MAINTAINERS b/MAINTAINERS
index add406a46231..71bcef4a161c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10025,6 +10025,12 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/jj/apparmor-dev.git
10025S: Supported 10025S: Supported
10026F: security/apparmor/ 10026F: security/apparmor/
10027 10027
10028LOADPIN SECURITY MODULE
10029M: Kees Cook <keescook@chromium.org>
10030T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git lsm/loadpin
10031S: Supported
10032F: security/loadpin/
10033
10028YAMA SECURITY MODULE 10034YAMA SECURITY MODULE
10029M: Kees Cook <keescook@chromium.org> 10035M: Kees Cook <keescook@chromium.org>
10030T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git yama/tip 10036T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git yama/tip
diff --git a/arch/x86/kernel/kexec-bzimage64.c b/arch/x86/kernel/kexec-bzimage64.c
index 2af478e3fd4e..f2356bda2b05 100644
--- a/arch/x86/kernel/kexec-bzimage64.c
+++ b/arch/x86/kernel/kexec-bzimage64.c
@@ -19,8 +19,7 @@
19#include <linux/kernel.h> 19#include <linux/kernel.h>
20#include <linux/mm.h> 20#include <linux/mm.h>
21#include <linux/efi.h> 21#include <linux/efi.h>
22#include <linux/verify_pefile.h> 22#include <linux/verification.h>
23#include <keys/system_keyring.h>
24 23
25#include <asm/bootparam.h> 24#include <asm/bootparam.h>
26#include <asm/setup.h> 25#include <asm/setup.h>
@@ -529,18 +528,9 @@ static int bzImage64_cleanup(void *loader_data)
529#ifdef CONFIG_KEXEC_BZIMAGE_VERIFY_SIG 528#ifdef CONFIG_KEXEC_BZIMAGE_VERIFY_SIG
530static int bzImage64_verify_sig(const char *kernel, unsigned long kernel_len) 529static int bzImage64_verify_sig(const char *kernel, unsigned long kernel_len)
531{ 530{
532 bool trusted; 531 return verify_pefile_signature(kernel, kernel_len,
533 int ret; 532 NULL,
534 533 VERIFYING_KEXEC_PE_SIGNATURE);
535 ret = verify_pefile_signature(kernel, kernel_len,
536 system_trusted_keyring,
537 VERIFYING_KEXEC_PE_SIGNATURE,
538 &trusted);
539 if (ret < 0)
540 return ret;
541 if (!trusted)
542 return -EKEYREJECTED;
543 return 0;
544} 534}
545#endif 535#endif
546 536
diff --git a/certs/Kconfig b/certs/Kconfig
index f0f8a4433685..fc5955f5fc8a 100644
--- a/certs/Kconfig
+++ b/certs/Kconfig
@@ -17,6 +17,7 @@ config MODULE_SIG_KEY
17config SYSTEM_TRUSTED_KEYRING 17config SYSTEM_TRUSTED_KEYRING
18 bool "Provide system-wide ring of trusted keys" 18 bool "Provide system-wide ring of trusted keys"
19 depends on KEYS 19 depends on KEYS
20 depends on ASYMMETRIC_KEY_TYPE
20 help 21 help
21 Provide a system keyring to which trusted keys can be added. Keys in 22 Provide a system keyring to which trusted keys can be added. Keys in
22 the keyring are considered to be trusted. Keys may be added at will 23 the keyring are considered to be trusted. Keys may be added at will
@@ -55,4 +56,12 @@ config SYSTEM_EXTRA_CERTIFICATE_SIZE
55 This is the number of bytes reserved in the kernel image for a 56 This is the number of bytes reserved in the kernel image for a
56 certificate to be inserted. 57 certificate to be inserted.
57 58
59config SECONDARY_TRUSTED_KEYRING
60 bool "Provide a keyring to which extra trustable keys may be added"
61 depends on SYSTEM_TRUSTED_KEYRING
62 help
63 If set, provide a keyring to which extra keys may be added, provided
64 those keys are not blacklisted and are vouched for by a key built
65 into the kernel or already in the secondary trusted keyring.
66
58endmenu 67endmenu
diff --git a/certs/system_keyring.c b/certs/system_keyring.c
index f4180326c2e1..50979d6dcecd 100644
--- a/certs/system_keyring.c
+++ b/certs/system_keyring.c
@@ -18,29 +18,88 @@
18#include <keys/system_keyring.h> 18#include <keys/system_keyring.h>
19#include <crypto/pkcs7.h> 19#include <crypto/pkcs7.h>
20 20
21struct key *system_trusted_keyring; 21static struct key *builtin_trusted_keys;
22EXPORT_SYMBOL_GPL(system_trusted_keyring); 22#ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
23static struct key *secondary_trusted_keys;
24#endif
23 25
24extern __initconst const u8 system_certificate_list[]; 26extern __initconst const u8 system_certificate_list[];
25extern __initconst const unsigned long system_certificate_list_size; 27extern __initconst const unsigned long system_certificate_list_size;
26 28
29/**
30 * restrict_link_to_builtin_trusted - Restrict keyring addition by built in CA
31 *
32 * Restrict the addition of keys into a keyring based on the key-to-be-added
33 * being vouched for by a key in the built in system keyring.
34 */
35int restrict_link_by_builtin_trusted(struct key *keyring,
36 const struct key_type *type,
37 const union key_payload *payload)
38{
39 return restrict_link_by_signature(builtin_trusted_keys, type, payload);
40}
41
42#ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
43/**
44 * restrict_link_by_builtin_and_secondary_trusted - Restrict keyring
45 * addition by both builtin and secondary keyrings
46 *
47 * Restrict the addition of keys into a keyring based on the key-to-be-added
48 * being vouched for by a key in either the built-in or the secondary system
49 * keyrings.
50 */
51int restrict_link_by_builtin_and_secondary_trusted(
52 struct key *keyring,
53 const struct key_type *type,
54 const union key_payload *payload)
55{
56 /* If we have a secondary trusted keyring, then that contains a link
57 * through to the builtin keyring and the search will follow that link.
58 */
59 if (type == &key_type_keyring &&
60 keyring == secondary_trusted_keys &&
61 payload == &builtin_trusted_keys->payload)
62 /* Allow the builtin keyring to be added to the secondary */
63 return 0;
64
65 return restrict_link_by_signature(secondary_trusted_keys, type, payload);
66}
67#endif
68
27/* 69/*
28 * Load the compiled-in keys 70 * Create the trusted keyrings
29 */ 71 */
30static __init int system_trusted_keyring_init(void) 72static __init int system_trusted_keyring_init(void)
31{ 73{
32 pr_notice("Initialise system trusted keyring\n"); 74 pr_notice("Initialise system trusted keyrings\n");
33 75
34 system_trusted_keyring = 76 builtin_trusted_keys =
35 keyring_alloc(".system_keyring", 77 keyring_alloc(".builtin_trusted_keys",
36 KUIDT_INIT(0), KGIDT_INIT(0), current_cred(), 78 KUIDT_INIT(0), KGIDT_INIT(0), current_cred(),
37 ((KEY_POS_ALL & ~KEY_POS_SETATTR) | 79 ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
38 KEY_USR_VIEW | KEY_USR_READ | KEY_USR_SEARCH), 80 KEY_USR_VIEW | KEY_USR_READ | KEY_USR_SEARCH),
39 KEY_ALLOC_NOT_IN_QUOTA, NULL); 81 KEY_ALLOC_NOT_IN_QUOTA,
40 if (IS_ERR(system_trusted_keyring)) 82 NULL, NULL);
41 panic("Can't allocate system trusted keyring\n"); 83 if (IS_ERR(builtin_trusted_keys))
84 panic("Can't allocate builtin trusted keyring\n");
85
86#ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
87 secondary_trusted_keys =
88 keyring_alloc(".secondary_trusted_keys",
89 KUIDT_INIT(0), KGIDT_INIT(0), current_cred(),
90 ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
91 KEY_USR_VIEW | KEY_USR_READ | KEY_USR_SEARCH |
92 KEY_USR_WRITE),
93 KEY_ALLOC_NOT_IN_QUOTA,
94 restrict_link_by_builtin_and_secondary_trusted,
95 NULL);
96 if (IS_ERR(secondary_trusted_keys))
97 panic("Can't allocate secondary trusted keyring\n");
98
99 if (key_link(secondary_trusted_keys, builtin_trusted_keys) < 0)
100 panic("Can't link trusted keyrings\n");
101#endif
42 102
43 set_bit(KEY_FLAG_TRUSTED_ONLY, &system_trusted_keyring->flags);
44 return 0; 103 return 0;
45} 104}
46 105
@@ -76,7 +135,7 @@ static __init int load_system_certificate_list(void)
76 if (plen > end - p) 135 if (plen > end - p)
77 goto dodgy_cert; 136 goto dodgy_cert;
78 137
79 key = key_create_or_update(make_key_ref(system_trusted_keyring, 1), 138 key = key_create_or_update(make_key_ref(builtin_trusted_keys, 1),
80 "asymmetric", 139 "asymmetric",
81 NULL, 140 NULL,
82 p, 141 p,
@@ -84,8 +143,8 @@ static __init int load_system_certificate_list(void)
84 ((KEY_POS_ALL & ~KEY_POS_SETATTR) | 143 ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
85 KEY_USR_VIEW | KEY_USR_READ), 144 KEY_USR_VIEW | KEY_USR_READ),
86 KEY_ALLOC_NOT_IN_QUOTA | 145 KEY_ALLOC_NOT_IN_QUOTA |
87 KEY_ALLOC_TRUSTED | 146 KEY_ALLOC_BUILT_IN |
88 KEY_ALLOC_BUILT_IN); 147 KEY_ALLOC_BYPASS_RESTRICTION);
89 if (IS_ERR(key)) { 148 if (IS_ERR(key)) {
90 pr_err("Problem loading in-kernel X.509 certificate (%ld)\n", 149 pr_err("Problem loading in-kernel X.509 certificate (%ld)\n",
91 PTR_ERR(key)); 150 PTR_ERR(key));
@@ -108,19 +167,27 @@ late_initcall(load_system_certificate_list);
108#ifdef CONFIG_SYSTEM_DATA_VERIFICATION 167#ifdef CONFIG_SYSTEM_DATA_VERIFICATION
109 168
110/** 169/**
111 * Verify a PKCS#7-based signature on system data. 170 * verify_pkcs7_signature - Verify a PKCS#7-based signature on system data.
112 * @data: The data to be verified. 171 * @data: The data to be verified (NULL if expecting internal data).
113 * @len: Size of @data. 172 * @len: Size of @data.
114 * @raw_pkcs7: The PKCS#7 message that is the signature. 173 * @raw_pkcs7: The PKCS#7 message that is the signature.
115 * @pkcs7_len: The size of @raw_pkcs7. 174 * @pkcs7_len: The size of @raw_pkcs7.
175 * @trusted_keys: Trusted keys to use (NULL for builtin trusted keys only,
176 * (void *)1UL for all trusted keys).
116 * @usage: The use to which the key is being put. 177 * @usage: The use to which the key is being put.
178 * @view_content: Callback to gain access to content.
179 * @ctx: Context for callback.
117 */ 180 */
118int system_verify_data(const void *data, unsigned long len, 181int verify_pkcs7_signature(const void *data, size_t len,
119 const void *raw_pkcs7, size_t pkcs7_len, 182 const void *raw_pkcs7, size_t pkcs7_len,
120 enum key_being_used_for usage) 183 struct key *trusted_keys,
184 enum key_being_used_for usage,
185 int (*view_content)(void *ctx,
186 const void *data, size_t len,
187 size_t asn1hdrlen),
188 void *ctx)
121{ 189{
122 struct pkcs7_message *pkcs7; 190 struct pkcs7_message *pkcs7;
123 bool trusted;
124 int ret; 191 int ret;
125 192
126 pkcs7 = pkcs7_parse_message(raw_pkcs7, pkcs7_len); 193 pkcs7 = pkcs7_parse_message(raw_pkcs7, pkcs7_len);
@@ -128,7 +195,7 @@ int system_verify_data(const void *data, unsigned long len,
128 return PTR_ERR(pkcs7); 195 return PTR_ERR(pkcs7);
129 196
130 /* The data should be detached - so we need to supply it. */ 197 /* The data should be detached - so we need to supply it. */
131 if (pkcs7_supply_detached_data(pkcs7, data, len) < 0) { 198 if (data && pkcs7_supply_detached_data(pkcs7, data, len) < 0) {
132 pr_err("PKCS#7 signature with non-detached data\n"); 199 pr_err("PKCS#7 signature with non-detached data\n");
133 ret = -EBADMSG; 200 ret = -EBADMSG;
134 goto error; 201 goto error;
@@ -138,13 +205,33 @@ int system_verify_data(const void *data, unsigned long len,
138 if (ret < 0) 205 if (ret < 0)
139 goto error; 206 goto error;
140 207
141 ret = pkcs7_validate_trust(pkcs7, system_trusted_keyring, &trusted); 208 if (!trusted_keys) {
142 if (ret < 0) 209 trusted_keys = builtin_trusted_keys;
210 } else if (trusted_keys == (void *)1UL) {
211#ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
212 trusted_keys = secondary_trusted_keys;
213#else
214 trusted_keys = builtin_trusted_keys;
215#endif
216 }
217 ret = pkcs7_validate_trust(pkcs7, trusted_keys);
218 if (ret < 0) {
219 if (ret == -ENOKEY)
220 pr_err("PKCS#7 signature not signed with a trusted key\n");
143 goto error; 221 goto error;
222 }
223
224 if (view_content) {
225 size_t asn1hdrlen;
226
227 ret = pkcs7_get_content_data(pkcs7, &data, &len, &asn1hdrlen);
228 if (ret < 0) {
229 if (ret == -ENODATA)
230 pr_devel("PKCS#7 message does not contain data\n");
231 goto error;
232 }
144 233
145 if (!trusted) { 234 ret = view_content(ctx, data, len, asn1hdrlen);
146 pr_err("PKCS#7 signature not signed with a trusted key\n");
147 ret = -ENOKEY;
148 } 235 }
149 236
150error: 237error:
@@ -152,6 +239,6 @@ error:
152 pr_devel("<==%s() = %d\n", __func__, ret); 239 pr_devel("<==%s() = %d\n", __func__, ret);
153 return ret; 240 return ret;
154} 241}
155EXPORT_SYMBOL_GPL(system_verify_data); 242EXPORT_SYMBOL_GPL(verify_pkcs7_signature);
156 243
157#endif /* CONFIG_SYSTEM_DATA_VERIFICATION */ 244#endif /* CONFIG_SYSTEM_DATA_VERIFICATION */
diff --git a/crypto/asymmetric_keys/Kconfig b/crypto/asymmetric_keys/Kconfig
index 91a7e047a765..e28e912000a7 100644
--- a/crypto/asymmetric_keys/Kconfig
+++ b/crypto/asymmetric_keys/Kconfig
@@ -1,5 +1,5 @@
1menuconfig ASYMMETRIC_KEY_TYPE 1menuconfig ASYMMETRIC_KEY_TYPE
2 tristate "Asymmetric (public-key cryptographic) key type" 2 bool "Asymmetric (public-key cryptographic) key type"
3 depends on KEYS 3 depends on KEYS
4 help 4 help
5 This option provides support for a key type that holds the data for 5 This option provides support for a key type that holds the data for
@@ -40,8 +40,7 @@ config PKCS7_MESSAGE_PARSER
40 40
41config PKCS7_TEST_KEY 41config PKCS7_TEST_KEY
42 tristate "PKCS#7 testing key type" 42 tristate "PKCS#7 testing key type"
43 depends on PKCS7_MESSAGE_PARSER 43 depends on SYSTEM_DATA_VERIFICATION
44 select SYSTEM_TRUSTED_KEYRING
45 help 44 help
46 This option provides a type of key that can be loaded up from a 45 This option provides a type of key that can be loaded up from a
47 PKCS#7 message - provided the message is signed by a trusted key. If 46 PKCS#7 message - provided the message is signed by a trusted key. If
@@ -54,6 +53,7 @@ config PKCS7_TEST_KEY
54config SIGNED_PE_FILE_VERIFICATION 53config SIGNED_PE_FILE_VERIFICATION
55 bool "Support for PE file signature verification" 54 bool "Support for PE file signature verification"
56 depends on PKCS7_MESSAGE_PARSER=y 55 depends on PKCS7_MESSAGE_PARSER=y
56 depends on SYSTEM_DATA_VERIFICATION
57 select ASN1 57 select ASN1
58 select OID_REGISTRY 58 select OID_REGISTRY
59 help 59 help
diff --git a/crypto/asymmetric_keys/Makefile b/crypto/asymmetric_keys/Makefile
index f90486256f01..6516855bec18 100644
--- a/crypto/asymmetric_keys/Makefile
+++ b/crypto/asymmetric_keys/Makefile
@@ -4,7 +4,10 @@
4 4
5obj-$(CONFIG_ASYMMETRIC_KEY_TYPE) += asymmetric_keys.o 5obj-$(CONFIG_ASYMMETRIC_KEY_TYPE) += asymmetric_keys.o
6 6
7asymmetric_keys-y := asymmetric_type.o signature.o 7asymmetric_keys-y := \
8 asymmetric_type.o \
9 restrict.o \
10 signature.o
8 11
9obj-$(CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE) += public_key.o 12obj-$(CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE) += public_key.o
10 13
diff --git a/crypto/asymmetric_keys/asymmetric_keys.h b/crypto/asymmetric_keys/asymmetric_keys.h
index 1d450b580245..ca8e9ac34ce6 100644
--- a/crypto/asymmetric_keys/asymmetric_keys.h
+++ b/crypto/asymmetric_keys/asymmetric_keys.h
@@ -9,6 +9,8 @@
9 * 2 of the Licence, or (at your option) any later version. 9 * 2 of the Licence, or (at your option) any later version.
10 */ 10 */
11 11
12#include <keys/asymmetric-type.h>
13
12extern struct asymmetric_key_id *asymmetric_key_hex_to_key_id(const char *id); 14extern struct asymmetric_key_id *asymmetric_key_hex_to_key_id(const char *id);
13 15
14extern int __asymmetric_key_hex_to_key_id(const char *id, 16extern int __asymmetric_key_hex_to_key_id(const char *id,
diff --git a/crypto/asymmetric_keys/asymmetric_type.c b/crypto/asymmetric_keys/asymmetric_type.c
index 9f2165b27d52..6600181d5d01 100644
--- a/crypto/asymmetric_keys/asymmetric_type.c
+++ b/crypto/asymmetric_keys/asymmetric_type.c
@@ -35,6 +35,95 @@ static LIST_HEAD(asymmetric_key_parsers);
35static DECLARE_RWSEM(asymmetric_key_parsers_sem); 35static DECLARE_RWSEM(asymmetric_key_parsers_sem);
36 36
37/** 37/**
38 * find_asymmetric_key - Find a key by ID.
39 * @keyring: The keys to search.
40 * @id_0: The first ID to look for or NULL.
41 * @id_1: The second ID to look for or NULL.
42 * @partial: Use partial match if true, exact if false.
43 *
44 * Find a key in the given keyring by identifier. The preferred identifier is
45 * the id_0 and the fallback identifier is the id_1. If both are given, the
46 * lookup is by the former, but the latter must also match.
47 */
48struct key *find_asymmetric_key(struct key *keyring,
49 const struct asymmetric_key_id *id_0,
50 const struct asymmetric_key_id *id_1,
51 bool partial)
52{
53 struct key *key;
54 key_ref_t ref;
55 const char *lookup;
56 char *req, *p;
57 int len;
58
59 if (id_0) {
60 lookup = id_0->data;
61 len = id_0->len;
62 } else {
63 lookup = id_1->data;
64 len = id_1->len;
65 }
66
67 /* Construct an identifier "id:<keyid>". */
68 p = req = kmalloc(2 + 1 + len * 2 + 1, GFP_KERNEL);
69 if (!req)
70 return ERR_PTR(-ENOMEM);
71
72 if (partial) {
73 *p++ = 'i';
74 *p++ = 'd';
75 } else {
76 *p++ = 'e';
77 *p++ = 'x';
78 }
79 *p++ = ':';
80 p = bin2hex(p, lookup, len);
81 *p = 0;
82
83 pr_debug("Look up: \"%s\"\n", req);
84
85 ref = keyring_search(make_key_ref(keyring, 1),
86 &key_type_asymmetric, req);
87 if (IS_ERR(ref))
88 pr_debug("Request for key '%s' err %ld\n", req, PTR_ERR(ref));
89 kfree(req);
90
91 if (IS_ERR(ref)) {
92 switch (PTR_ERR(ref)) {
93 /* Hide some search errors */
94 case -EACCES:
95 case -ENOTDIR:
96 case -EAGAIN:
97 return ERR_PTR(-ENOKEY);
98 default:
99 return ERR_CAST(ref);
100 }
101 }
102
103 key = key_ref_to_ptr(ref);
104 if (id_0 && id_1) {
105 const struct asymmetric_key_ids *kids = asymmetric_key_ids(key);
106
107 if (!kids->id[0]) {
108 pr_debug("First ID matches, but second is missing\n");
109 goto reject;
110 }
111 if (!asymmetric_key_id_same(id_1, kids->id[1])) {
112 pr_debug("First ID matches, but second does not\n");
113 goto reject;
114 }
115 }
116
117 pr_devel("<==%s() = 0 [%x]\n", __func__, key_serial(key));
118 return key;
119
120reject:
121 key_put(key);
122 return ERR_PTR(-EKEYREJECTED);
123}
124EXPORT_SYMBOL_GPL(find_asymmetric_key);
125
126/**
38 * asymmetric_key_generate_id: Construct an asymmetric key ID 127 * asymmetric_key_generate_id: Construct an asymmetric key ID
39 * @val_1: First binary blob 128 * @val_1: First binary blob
40 * @len_1: Length of first binary blob 129 * @len_1: Length of first binary blob
@@ -331,7 +420,8 @@ static void asymmetric_key_free_preparse(struct key_preparsed_payload *prep)
331 pr_devel("==>%s()\n", __func__); 420 pr_devel("==>%s()\n", __func__);
332 421
333 if (subtype) { 422 if (subtype) {
334 subtype->destroy(prep->payload.data[asym_crypto]); 423 subtype->destroy(prep->payload.data[asym_crypto],
424 prep->payload.data[asym_auth]);
335 module_put(subtype->owner); 425 module_put(subtype->owner);
336 } 426 }
337 asymmetric_key_free_kids(kids); 427 asymmetric_key_free_kids(kids);
@@ -346,13 +436,15 @@ static void asymmetric_key_destroy(struct key *key)
346 struct asymmetric_key_subtype *subtype = asymmetric_key_subtype(key); 436 struct asymmetric_key_subtype *subtype = asymmetric_key_subtype(key);
347 struct asymmetric_key_ids *kids = key->payload.data[asym_key_ids]; 437 struct asymmetric_key_ids *kids = key->payload.data[asym_key_ids];
348 void *data = key->payload.data[asym_crypto]; 438 void *data = key->payload.data[asym_crypto];
439 void *auth = key->payload.data[asym_auth];
349 440
350 key->payload.data[asym_crypto] = NULL; 441 key->payload.data[asym_crypto] = NULL;
351 key->payload.data[asym_subtype] = NULL; 442 key->payload.data[asym_subtype] = NULL;
352 key->payload.data[asym_key_ids] = NULL; 443 key->payload.data[asym_key_ids] = NULL;
444 key->payload.data[asym_auth] = NULL;
353 445
354 if (subtype) { 446 if (subtype) {
355 subtype->destroy(data); 447 subtype->destroy(data, auth);
356 module_put(subtype->owner); 448 module_put(subtype->owner);
357 } 449 }
358 450
diff --git a/crypto/asymmetric_keys/mscode_parser.c b/crypto/asymmetric_keys/mscode_parser.c
index 3242cbfaeaa2..6a76d5c70ef6 100644
--- a/crypto/asymmetric_keys/mscode_parser.c
+++ b/crypto/asymmetric_keys/mscode_parser.c
@@ -21,19 +21,13 @@
21/* 21/*
22 * Parse a Microsoft Individual Code Signing blob 22 * Parse a Microsoft Individual Code Signing blob
23 */ 23 */
24int mscode_parse(struct pefile_context *ctx) 24int mscode_parse(void *_ctx, const void *content_data, size_t data_len,
25 size_t asn1hdrlen)
25{ 26{
26 const void *content_data; 27 struct pefile_context *ctx = _ctx;
27 size_t data_len;
28 int ret;
29
30 ret = pkcs7_get_content_data(ctx->pkcs7, &content_data, &data_len, 1);
31
32 if (ret) {
33 pr_debug("PKCS#7 message does not contain data\n");
34 return ret;
35 }
36 28
29 content_data -= asn1hdrlen;
30 data_len += asn1hdrlen;
37 pr_devel("Data: %zu [%*ph]\n", data_len, (unsigned)(data_len), 31 pr_devel("Data: %zu [%*ph]\n", data_len, (unsigned)(data_len),
38 content_data); 32 content_data);
39 33
@@ -129,7 +123,6 @@ int mscode_note_digest(void *context, size_t hdrlen,
129{ 123{
130 struct pefile_context *ctx = context; 124 struct pefile_context *ctx = context;
131 125
132 ctx->digest = value; 126 ctx->digest = kmemdup(value, vlen, GFP_KERNEL);
133 ctx->digest_len = vlen; 127 return ctx->digest ? 0 : -ENOMEM;
134 return 0;
135} 128}
diff --git a/crypto/asymmetric_keys/pkcs7_key_type.c b/crypto/asymmetric_keys/pkcs7_key_type.c
index e2d0edbbc71a..3b92523882e5 100644
--- a/crypto/asymmetric_keys/pkcs7_key_type.c
+++ b/crypto/asymmetric_keys/pkcs7_key_type.c
@@ -13,12 +13,9 @@
13#include <linux/key.h> 13#include <linux/key.h>
14#include <linux/err.h> 14#include <linux/err.h>
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/verification.h>
16#include <linux/key-type.h> 17#include <linux/key-type.h>
17#include <keys/asymmetric-type.h>
18#include <crypto/pkcs7.h>
19#include <keys/user-type.h> 18#include <keys/user-type.h>
20#include <keys/system_keyring.h>
21#include "pkcs7_parser.h"
22 19
23MODULE_LICENSE("GPL"); 20MODULE_LICENSE("GPL");
24MODULE_DESCRIPTION("PKCS#7 testing key type"); 21MODULE_DESCRIPTION("PKCS#7 testing key type");
@@ -29,60 +26,47 @@ MODULE_PARM_DESC(pkcs7_usage,
29 "Usage to specify when verifying the PKCS#7 message"); 26 "Usage to specify when verifying the PKCS#7 message");
30 27
31/* 28/*
32 * Preparse a PKCS#7 wrapped and validated data blob. 29 * Retrieve the PKCS#7 message content.
33 */ 30 */
34static int pkcs7_preparse(struct key_preparsed_payload *prep) 31static int pkcs7_view_content(void *ctx, const void *data, size_t len,
32 size_t asn1hdrlen)
35{ 33{
36 enum key_being_used_for usage = pkcs7_usage; 34 struct key_preparsed_payload *prep = ctx;
37 struct pkcs7_message *pkcs7; 35 const void *saved_prep_data;
38 const void *data, *saved_prep_data; 36 size_t saved_prep_datalen;
39 size_t datalen, saved_prep_datalen;
40 bool trusted;
41 int ret; 37 int ret;
42 38
43 kenter("");
44
45 if (usage >= NR__KEY_BEING_USED_FOR) {
46 pr_err("Invalid usage type %d\n", usage);
47 return -EINVAL;
48 }
49
50 saved_prep_data = prep->data; 39 saved_prep_data = prep->data;
51 saved_prep_datalen = prep->datalen; 40 saved_prep_datalen = prep->datalen;
52 pkcs7 = pkcs7_parse_message(saved_prep_data, saved_prep_datalen);
53 if (IS_ERR(pkcs7)) {
54 ret = PTR_ERR(pkcs7);
55 goto error;
56 }
57
58 ret = pkcs7_verify(pkcs7, usage);
59 if (ret < 0)
60 goto error_free;
61
62 ret = pkcs7_validate_trust(pkcs7, system_trusted_keyring, &trusted);
63 if (ret < 0)
64 goto error_free;
65 if (!trusted)
66 pr_warn("PKCS#7 message doesn't chain back to a trusted key\n");
67
68 ret = pkcs7_get_content_data(pkcs7, &data, &datalen, false);
69 if (ret < 0)
70 goto error_free;
71
72 prep->data = data; 41 prep->data = data;
73 prep->datalen = datalen; 42 prep->datalen = len;
43
74 ret = user_preparse(prep); 44 ret = user_preparse(prep);
45
75 prep->data = saved_prep_data; 46 prep->data = saved_prep_data;
76 prep->datalen = saved_prep_datalen; 47 prep->datalen = saved_prep_datalen;
77
78error_free:
79 pkcs7_free_message(pkcs7);
80error:
81 kleave(" = %d", ret);
82 return ret; 48 return ret;
83} 49}
84 50
85/* 51/*
52 * Preparse a PKCS#7 wrapped and validated data blob.
53 */
54static int pkcs7_preparse(struct key_preparsed_payload *prep)
55{
56 enum key_being_used_for usage = pkcs7_usage;
57
58 if (usage >= NR__KEY_BEING_USED_FOR) {
59 pr_err("Invalid usage type %d\n", usage);
60 return -EINVAL;
61 }
62
63 return verify_pkcs7_signature(NULL, 0,
64 prep->data, prep->datalen,
65 NULL, usage,
66 pkcs7_view_content, prep);
67}
68
69/*
86 * user defined keys take an arbitrary string as the description and an 70 * user defined keys take an arbitrary string as the description and an
87 * arbitrary blob of data as the payload 71 * arbitrary blob of data as the payload
88 */ 72 */
diff --git a/crypto/asymmetric_keys/pkcs7_parser.c b/crypto/asymmetric_keys/pkcs7_parser.c
index bdd0d753ce5d..af4cd8649117 100644
--- a/crypto/asymmetric_keys/pkcs7_parser.c
+++ b/crypto/asymmetric_keys/pkcs7_parser.c
@@ -44,9 +44,7 @@ struct pkcs7_parse_context {
44static void pkcs7_free_signed_info(struct pkcs7_signed_info *sinfo) 44static void pkcs7_free_signed_info(struct pkcs7_signed_info *sinfo)
45{ 45{
46 if (sinfo) { 46 if (sinfo) {
47 kfree(sinfo->sig.s); 47 public_key_signature_free(sinfo->sig);
48 kfree(sinfo->sig.digest);
49 kfree(sinfo->signing_cert_id);
50 kfree(sinfo); 48 kfree(sinfo);
51 } 49 }
52} 50}
@@ -125,6 +123,10 @@ struct pkcs7_message *pkcs7_parse_message(const void *data, size_t datalen)
125 ctx->sinfo = kzalloc(sizeof(struct pkcs7_signed_info), GFP_KERNEL); 123 ctx->sinfo = kzalloc(sizeof(struct pkcs7_signed_info), GFP_KERNEL);
126 if (!ctx->sinfo) 124 if (!ctx->sinfo)
127 goto out_no_sinfo; 125 goto out_no_sinfo;
126 ctx->sinfo->sig = kzalloc(sizeof(struct public_key_signature),
127 GFP_KERNEL);
128 if (!ctx->sinfo->sig)
129 goto out_no_sig;
128 130
129 ctx->data = (unsigned long)data; 131 ctx->data = (unsigned long)data;
130 ctx->ppcerts = &ctx->certs; 132 ctx->ppcerts = &ctx->certs;
@@ -150,6 +152,7 @@ out:
150 ctx->certs = cert->next; 152 ctx->certs = cert->next;
151 x509_free_certificate(cert); 153 x509_free_certificate(cert);
152 } 154 }
155out_no_sig:
153 pkcs7_free_signed_info(ctx->sinfo); 156 pkcs7_free_signed_info(ctx->sinfo);
154out_no_sinfo: 157out_no_sinfo:
155 pkcs7_free_message(ctx->msg); 158 pkcs7_free_message(ctx->msg);
@@ -165,24 +168,25 @@ EXPORT_SYMBOL_GPL(pkcs7_parse_message);
165 * @pkcs7: The preparsed PKCS#7 message to access 168 * @pkcs7: The preparsed PKCS#7 message to access
166 * @_data: Place to return a pointer to the data 169 * @_data: Place to return a pointer to the data
167 * @_data_len: Place to return the data length 170 * @_data_len: Place to return the data length
168 * @want_wrapper: True if the ASN.1 object header should be included in the data 171 * @_headerlen: Size of ASN.1 header not included in _data
169 * 172 *
170 * Get access to the data content of the PKCS#7 message, including, optionally, 173 * Get access to the data content of the PKCS#7 message. The size of the
171 * the header of the ASN.1 object that contains it. Returns -ENODATA if the 174 * header of the ASN.1 object that contains it is also provided and can be used
172 * data object was missing from the message. 175 * to adjust *_data and *_data_len to get the entire object.
176 *
177 * Returns -ENODATA if the data object was missing from the message.
173 */ 178 */
174int pkcs7_get_content_data(const struct pkcs7_message *pkcs7, 179int pkcs7_get_content_data(const struct pkcs7_message *pkcs7,
175 const void **_data, size_t *_data_len, 180 const void **_data, size_t *_data_len,
176 bool want_wrapper) 181 size_t *_headerlen)
177{ 182{
178 size_t wrapper;
179
180 if (!pkcs7->data) 183 if (!pkcs7->data)
181 return -ENODATA; 184 return -ENODATA;
182 185
183 wrapper = want_wrapper ? pkcs7->data_hdrlen : 0; 186 *_data = pkcs7->data;
184 *_data = pkcs7->data - wrapper; 187 *_data_len = pkcs7->data_len;
185 *_data_len = pkcs7->data_len + wrapper; 188 if (_headerlen)
189 *_headerlen = pkcs7->data_hdrlen;
186 return 0; 190 return 0;
187} 191}
188EXPORT_SYMBOL_GPL(pkcs7_get_content_data); 192EXPORT_SYMBOL_GPL(pkcs7_get_content_data);
@@ -218,25 +222,25 @@ int pkcs7_sig_note_digest_algo(void *context, size_t hdrlen,
218 222
219 switch (ctx->last_oid) { 223 switch (ctx->last_oid) {
220 case OID_md4: 224 case OID_md4:
221 ctx->sinfo->sig.hash_algo = "md4"; 225 ctx->sinfo->sig->hash_algo = "md4";
222 break; 226 break;
223 case OID_md5: 227 case OID_md5:
224 ctx->sinfo->sig.hash_algo = "md5"; 228 ctx->sinfo->sig->hash_algo = "md5";
225 break; 229 break;
226 case OID_sha1: 230 case OID_sha1:
227 ctx->sinfo->sig.hash_algo = "sha1"; 231 ctx->sinfo->sig->hash_algo = "sha1";
228 break; 232 break;
229 case OID_sha256: 233 case OID_sha256:
230 ctx->sinfo->sig.hash_algo = "sha256"; 234 ctx->sinfo->sig->hash_algo = "sha256";
231 break; 235 break;
232 case OID_sha384: 236 case OID_sha384:
233 ctx->sinfo->sig.hash_algo = "sha384"; 237 ctx->sinfo->sig->hash_algo = "sha384";
234 break; 238 break;
235 case OID_sha512: 239 case OID_sha512:
236 ctx->sinfo->sig.hash_algo = "sha512"; 240 ctx->sinfo->sig->hash_algo = "sha512";
237 break; 241 break;
238 case OID_sha224: 242 case OID_sha224:
239 ctx->sinfo->sig.hash_algo = "sha224"; 243 ctx->sinfo->sig->hash_algo = "sha224";
240 break; 244 break;
241 default: 245 default:
242 printk("Unsupported digest algo: %u\n", ctx->last_oid); 246 printk("Unsupported digest algo: %u\n", ctx->last_oid);
@@ -256,7 +260,7 @@ int pkcs7_sig_note_pkey_algo(void *context, size_t hdrlen,
256 260
257 switch (ctx->last_oid) { 261 switch (ctx->last_oid) {
258 case OID_rsaEncryption: 262 case OID_rsaEncryption:
259 ctx->sinfo->sig.pkey_algo = "rsa"; 263 ctx->sinfo->sig->pkey_algo = "rsa";
260 break; 264 break;
261 default: 265 default:
262 printk("Unsupported pkey algo: %u\n", ctx->last_oid); 266 printk("Unsupported pkey algo: %u\n", ctx->last_oid);
@@ -616,11 +620,11 @@ int pkcs7_sig_note_signature(void *context, size_t hdrlen,
616{ 620{
617 struct pkcs7_parse_context *ctx = context; 621 struct pkcs7_parse_context *ctx = context;
618 622
619 ctx->sinfo->sig.s = kmemdup(value, vlen, GFP_KERNEL); 623 ctx->sinfo->sig->s = kmemdup(value, vlen, GFP_KERNEL);
620 if (!ctx->sinfo->sig.s) 624 if (!ctx->sinfo->sig->s)
621 return -ENOMEM; 625 return -ENOMEM;
622 626
623 ctx->sinfo->sig.s_size = vlen; 627 ctx->sinfo->sig->s_size = vlen;
624 return 0; 628 return 0;
625} 629}
626 630
@@ -656,12 +660,16 @@ int pkcs7_note_signed_info(void *context, size_t hdrlen,
656 660
657 pr_devel("SINFO KID: %u [%*phN]\n", kid->len, kid->len, kid->data); 661 pr_devel("SINFO KID: %u [%*phN]\n", kid->len, kid->len, kid->data);
658 662
659 sinfo->signing_cert_id = kid; 663 sinfo->sig->auth_ids[0] = kid;
660 sinfo->index = ++ctx->sinfo_index; 664 sinfo->index = ++ctx->sinfo_index;
661 *ctx->ppsinfo = sinfo; 665 *ctx->ppsinfo = sinfo;
662 ctx->ppsinfo = &sinfo->next; 666 ctx->ppsinfo = &sinfo->next;
663 ctx->sinfo = kzalloc(sizeof(struct pkcs7_signed_info), GFP_KERNEL); 667 ctx->sinfo = kzalloc(sizeof(struct pkcs7_signed_info), GFP_KERNEL);
664 if (!ctx->sinfo) 668 if (!ctx->sinfo)
665 return -ENOMEM; 669 return -ENOMEM;
670 ctx->sinfo->sig = kzalloc(sizeof(struct public_key_signature),
671 GFP_KERNEL);
672 if (!ctx->sinfo->sig)
673 return -ENOMEM;
666 return 0; 674 return 0;
667} 675}
diff --git a/crypto/asymmetric_keys/pkcs7_parser.h b/crypto/asymmetric_keys/pkcs7_parser.h
index a66b19ebcf47..f4e81074f5e0 100644
--- a/crypto/asymmetric_keys/pkcs7_parser.h
+++ b/crypto/asymmetric_keys/pkcs7_parser.h
@@ -22,7 +22,6 @@ struct pkcs7_signed_info {
22 struct pkcs7_signed_info *next; 22 struct pkcs7_signed_info *next;
23 struct x509_certificate *signer; /* Signing certificate (in msg->certs) */ 23 struct x509_certificate *signer; /* Signing certificate (in msg->certs) */
24 unsigned index; 24 unsigned index;
25 bool trusted;
26 bool unsupported_crypto; /* T if not usable due to missing crypto */ 25 bool unsupported_crypto; /* T if not usable due to missing crypto */
27 26
28 /* Message digest - the digest of the Content Data (or NULL) */ 27 /* Message digest - the digest of the Content Data (or NULL) */
@@ -41,19 +40,17 @@ struct pkcs7_signed_info {
41#define sinfo_has_ms_statement_type 5 40#define sinfo_has_ms_statement_type 5
42 time64_t signing_time; 41 time64_t signing_time;
43 42
44 /* Issuing cert serial number and issuer's name [PKCS#7 or CMS ver 1]
45 * or issuing cert's SKID [CMS ver 3].
46 */
47 struct asymmetric_key_id *signing_cert_id;
48
49 /* Message signature. 43 /* Message signature.
50 * 44 *
51 * This contains the generated digest of _either_ the Content Data or 45 * This contains the generated digest of _either_ the Content Data or
52 * the Authenticated Attributes [RFC2315 9.3]. If the latter, one of 46 * the Authenticated Attributes [RFC2315 9.3]. If the latter, one of
53 * the attributes contains the digest of the the Content Data within 47 * the attributes contains the digest of the the Content Data within
54 * it. 48 * it.
49 *
50 * THis also contains the issuing cert serial number and issuer's name
51 * [PKCS#7 or CMS ver 1] or issuing cert's SKID [CMS ver 3].
55 */ 52 */
56 struct public_key_signature sig; 53 struct public_key_signature *sig;
57}; 54};
58 55
59struct pkcs7_message { 56struct pkcs7_message {
diff --git a/crypto/asymmetric_keys/pkcs7_trust.c b/crypto/asymmetric_keys/pkcs7_trust.c
index 7d7a39b47c62..f6a009d88a33 100644
--- a/crypto/asymmetric_keys/pkcs7_trust.c
+++ b/crypto/asymmetric_keys/pkcs7_trust.c
@@ -27,10 +27,9 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7,
27 struct pkcs7_signed_info *sinfo, 27 struct pkcs7_signed_info *sinfo,
28 struct key *trust_keyring) 28 struct key *trust_keyring)
29{ 29{
30 struct public_key_signature *sig = &sinfo->sig; 30 struct public_key_signature *sig = sinfo->sig;
31 struct x509_certificate *x509, *last = NULL, *p; 31 struct x509_certificate *x509, *last = NULL, *p;
32 struct key *key; 32 struct key *key;
33 bool trusted;
34 int ret; 33 int ret;
35 34
36 kenter(",%u,", sinfo->index); 35 kenter(",%u,", sinfo->index);
@@ -42,10 +41,8 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7,
42 41
43 for (x509 = sinfo->signer; x509; x509 = x509->signer) { 42 for (x509 = sinfo->signer; x509; x509 = x509->signer) {
44 if (x509->seen) { 43 if (x509->seen) {
45 if (x509->verified) { 44 if (x509->verified)
46 trusted = x509->trusted;
47 goto verified; 45 goto verified;
48 }
49 kleave(" = -ENOKEY [cached]"); 46 kleave(" = -ENOKEY [cached]");
50 return -ENOKEY; 47 return -ENOKEY;
51 } 48 }
@@ -54,9 +51,8 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7,
54 /* Look to see if this certificate is present in the trusted 51 /* Look to see if this certificate is present in the trusted
55 * keys. 52 * keys.
56 */ 53 */
57 key = x509_request_asymmetric_key(trust_keyring, 54 key = find_asymmetric_key(trust_keyring,
58 x509->id, x509->skid, 55 x509->id, x509->skid, false);
59 false);
60 if (!IS_ERR(key)) { 56 if (!IS_ERR(key)) {
61 /* One of the X.509 certificates in the PKCS#7 message 57 /* One of the X.509 certificates in the PKCS#7 message
62 * is apparently the same as one we already trust. 58 * is apparently the same as one we already trust.
@@ -80,17 +76,17 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7,
80 76
81 might_sleep(); 77 might_sleep();
82 last = x509; 78 last = x509;
83 sig = &last->sig; 79 sig = last->sig;
84 } 80 }
85 81
86 /* No match - see if the root certificate has a signer amongst the 82 /* No match - see if the root certificate has a signer amongst the
87 * trusted keys. 83 * trusted keys.
88 */ 84 */
89 if (last && (last->akid_id || last->akid_skid)) { 85 if (last && (last->sig->auth_ids[0] || last->sig->auth_ids[1])) {
90 key = x509_request_asymmetric_key(trust_keyring, 86 key = find_asymmetric_key(trust_keyring,
91 last->akid_id, 87 last->sig->auth_ids[0],
92 last->akid_skid, 88 last->sig->auth_ids[1],
93 false); 89 false);
94 if (!IS_ERR(key)) { 90 if (!IS_ERR(key)) {
95 x509 = last; 91 x509 = last;
96 pr_devel("sinfo %u: Root cert %u signer is key %x\n", 92 pr_devel("sinfo %u: Root cert %u signer is key %x\n",
@@ -104,10 +100,8 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7,
104 /* As a last resort, see if we have a trusted public key that matches 100 /* As a last resort, see if we have a trusted public key that matches
105 * the signed info directly. 101 * the signed info directly.
106 */ 102 */
107 key = x509_request_asymmetric_key(trust_keyring, 103 key = find_asymmetric_key(trust_keyring,
108 sinfo->signing_cert_id, 104 sinfo->sig->auth_ids[0], NULL, false);
109 NULL,
110 false);
111 if (!IS_ERR(key)) { 105 if (!IS_ERR(key)) {
112 pr_devel("sinfo %u: Direct signer is key %x\n", 106 pr_devel("sinfo %u: Direct signer is key %x\n",
113 sinfo->index, key_serial(key)); 107 sinfo->index, key_serial(key));
@@ -122,7 +116,6 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7,
122 116
123matched: 117matched:
124 ret = verify_signature(key, sig); 118 ret = verify_signature(key, sig);
125 trusted = test_bit(KEY_FLAG_TRUSTED, &key->flags);
126 key_put(key); 119 key_put(key);
127 if (ret < 0) { 120 if (ret < 0) {
128 if (ret == -ENOMEM) 121 if (ret == -ENOMEM)
@@ -134,12 +127,9 @@ matched:
134verified: 127verified:
135 if (x509) { 128 if (x509) {
136 x509->verified = true; 129 x509->verified = true;
137 for (p = sinfo->signer; p != x509; p = p->signer) { 130 for (p = sinfo->signer; p != x509; p = p->signer)
138 p->verified = true; 131 p->verified = true;
139 p->trusted = trusted;
140 }
141 } 132 }
142 sinfo->trusted = trusted;
143 kleave(" = 0"); 133 kleave(" = 0");
144 return 0; 134 return 0;
145} 135}
@@ -148,7 +138,6 @@ verified:
148 * pkcs7_validate_trust - Validate PKCS#7 trust chain 138 * pkcs7_validate_trust - Validate PKCS#7 trust chain
149 * @pkcs7: The PKCS#7 certificate to validate 139 * @pkcs7: The PKCS#7 certificate to validate
150 * @trust_keyring: Signing certificates to use as starting points 140 * @trust_keyring: Signing certificates to use as starting points
151 * @_trusted: Set to true if trustworth, false otherwise
152 * 141 *
153 * Validate that the certificate chain inside the PKCS#7 message intersects 142 * Validate that the certificate chain inside the PKCS#7 message intersects
154 * keys we already know and trust. 143 * keys we already know and trust.
@@ -170,16 +159,13 @@ verified:
170 * May also return -ENOMEM. 159 * May also return -ENOMEM.
171 */ 160 */
172int pkcs7_validate_trust(struct pkcs7_message *pkcs7, 161int pkcs7_validate_trust(struct pkcs7_message *pkcs7,
173 struct key *trust_keyring, 162 struct key *trust_keyring)
174 bool *_trusted)
175{ 163{
176 struct pkcs7_signed_info *sinfo; 164 struct pkcs7_signed_info *sinfo;
177 struct x509_certificate *p; 165 struct x509_certificate *p;
178 int cached_ret = -ENOKEY; 166 int cached_ret = -ENOKEY;
179 int ret; 167 int ret;
180 168
181 *_trusted = false;
182
183 for (p = pkcs7->certs; p; p = p->next) 169 for (p = pkcs7->certs; p; p = p->next)
184 p->seen = false; 170 p->seen = false;
185 171
@@ -193,7 +179,6 @@ int pkcs7_validate_trust(struct pkcs7_message *pkcs7,
193 cached_ret = -ENOPKG; 179 cached_ret = -ENOPKG;
194 continue; 180 continue;
195 case 0: 181 case 0:
196 *_trusted |= sinfo->trusted;
197 cached_ret = 0; 182 cached_ret = 0;
198 continue; 183 continue;
199 default: 184 default:
diff --git a/crypto/asymmetric_keys/pkcs7_verify.c b/crypto/asymmetric_keys/pkcs7_verify.c
index 50be2a15e531..44b746e9df1b 100644
--- a/crypto/asymmetric_keys/pkcs7_verify.c
+++ b/crypto/asymmetric_keys/pkcs7_verify.c
@@ -25,34 +25,36 @@
25static int pkcs7_digest(struct pkcs7_message *pkcs7, 25static int pkcs7_digest(struct pkcs7_message *pkcs7,
26 struct pkcs7_signed_info *sinfo) 26 struct pkcs7_signed_info *sinfo)
27{ 27{
28 struct public_key_signature *sig = sinfo->sig;
28 struct crypto_shash *tfm; 29 struct crypto_shash *tfm;
29 struct shash_desc *desc; 30 struct shash_desc *desc;
30 size_t digest_size, desc_size; 31 size_t desc_size;
31 void *digest;
32 int ret; 32 int ret;
33 33
34 kenter(",%u,%s", sinfo->index, sinfo->sig.hash_algo); 34 kenter(",%u,%s", sinfo->index, sinfo->sig->hash_algo);
35 35
36 if (!sinfo->sig.hash_algo) 36 if (!sinfo->sig->hash_algo)
37 return -ENOPKG; 37 return -ENOPKG;
38 38
39 /* Allocate the hashing algorithm we're going to need and find out how 39 /* Allocate the hashing algorithm we're going to need and find out how
40 * big the hash operational data will be. 40 * big the hash operational data will be.
41 */ 41 */
42 tfm = crypto_alloc_shash(sinfo->sig.hash_algo, 0, 0); 42 tfm = crypto_alloc_shash(sinfo->sig->hash_algo, 0, 0);
43 if (IS_ERR(tfm)) 43 if (IS_ERR(tfm))
44 return (PTR_ERR(tfm) == -ENOENT) ? -ENOPKG : PTR_ERR(tfm); 44 return (PTR_ERR(tfm) == -ENOENT) ? -ENOPKG : PTR_ERR(tfm);
45 45
46 desc_size = crypto_shash_descsize(tfm) + sizeof(*desc); 46 desc_size = crypto_shash_descsize(tfm) + sizeof(*desc);
47 sinfo->sig.digest_size = digest_size = crypto_shash_digestsize(tfm); 47 sig->digest_size = crypto_shash_digestsize(tfm);
48 48
49 ret = -ENOMEM; 49 ret = -ENOMEM;
50 digest = kzalloc(ALIGN(digest_size, __alignof__(*desc)) + desc_size, 50 sig->digest = kmalloc(sig->digest_size, GFP_KERNEL);
51 GFP_KERNEL); 51 if (!sig->digest)
52 if (!digest) 52 goto error_no_desc;
53
54 desc = kzalloc(desc_size, GFP_KERNEL);
55 if (!desc)
53 goto error_no_desc; 56 goto error_no_desc;
54 57
55 desc = PTR_ALIGN(digest + digest_size, __alignof__(*desc));
56 desc->tfm = tfm; 58 desc->tfm = tfm;
57 desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP; 59 desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
58 60
@@ -60,10 +62,11 @@ static int pkcs7_digest(struct pkcs7_message *pkcs7,
60 ret = crypto_shash_init(desc); 62 ret = crypto_shash_init(desc);
61 if (ret < 0) 63 if (ret < 0)
62 goto error; 64 goto error;
63 ret = crypto_shash_finup(desc, pkcs7->data, pkcs7->data_len, digest); 65 ret = crypto_shash_finup(desc, pkcs7->data, pkcs7->data_len,
66 sig->digest);
64 if (ret < 0) 67 if (ret < 0)
65 goto error; 68 goto error;
66 pr_devel("MsgDigest = [%*ph]\n", 8, digest); 69 pr_devel("MsgDigest = [%*ph]\n", 8, sig->digest);
67 70
68 /* However, if there are authenticated attributes, there must be a 71 /* However, if there are authenticated attributes, there must be a
69 * message digest attribute amongst them which corresponds to the 72 * message digest attribute amongst them which corresponds to the
@@ -78,14 +81,15 @@ static int pkcs7_digest(struct pkcs7_message *pkcs7,
78 goto error; 81 goto error;
79 } 82 }
80 83
81 if (sinfo->msgdigest_len != sinfo->sig.digest_size) { 84 if (sinfo->msgdigest_len != sig->digest_size) {
82 pr_debug("Sig %u: Invalid digest size (%u)\n", 85 pr_debug("Sig %u: Invalid digest size (%u)\n",
83 sinfo->index, sinfo->msgdigest_len); 86 sinfo->index, sinfo->msgdigest_len);
84 ret = -EBADMSG; 87 ret = -EBADMSG;
85 goto error; 88 goto error;
86 } 89 }
87 90
88 if (memcmp(digest, sinfo->msgdigest, sinfo->msgdigest_len) != 0) { 91 if (memcmp(sig->digest, sinfo->msgdigest,
92 sinfo->msgdigest_len) != 0) {
89 pr_debug("Sig %u: Message digest doesn't match\n", 93 pr_debug("Sig %u: Message digest doesn't match\n",
90 sinfo->index); 94 sinfo->index);
91 ret = -EKEYREJECTED; 95 ret = -EKEYREJECTED;
@@ -97,7 +101,7 @@ static int pkcs7_digest(struct pkcs7_message *pkcs7,
97 * convert the attributes from a CONT.0 into a SET before we 101 * convert the attributes from a CONT.0 into a SET before we
98 * hash it. 102 * hash it.
99 */ 103 */
100 memset(digest, 0, sinfo->sig.digest_size); 104 memset(sig->digest, 0, sig->digest_size);
101 105
102 ret = crypto_shash_init(desc); 106 ret = crypto_shash_init(desc);
103 if (ret < 0) 107 if (ret < 0)
@@ -107,17 +111,14 @@ static int pkcs7_digest(struct pkcs7_message *pkcs7,
107 if (ret < 0) 111 if (ret < 0)
108 goto error; 112 goto error;
109 ret = crypto_shash_finup(desc, sinfo->authattrs, 113 ret = crypto_shash_finup(desc, sinfo->authattrs,
110 sinfo->authattrs_len, digest); 114 sinfo->authattrs_len, sig->digest);
111 if (ret < 0) 115 if (ret < 0)
112 goto error; 116 goto error;
113 pr_devel("AADigest = [%*ph]\n", 8, digest); 117 pr_devel("AADigest = [%*ph]\n", 8, sig->digest);
114 } 118 }
115 119
116 sinfo->sig.digest = digest;
117 digest = NULL;
118
119error: 120error:
120 kfree(digest); 121 kfree(desc);
121error_no_desc: 122error_no_desc:
122 crypto_free_shash(tfm); 123 crypto_free_shash(tfm);
123 kleave(" = %d", ret); 124 kleave(" = %d", ret);
@@ -144,12 +145,12 @@ static int pkcs7_find_key(struct pkcs7_message *pkcs7,
144 * PKCS#7 message - but I can't be 100% sure of that. It's 145 * PKCS#7 message - but I can't be 100% sure of that. It's
145 * possible this will need element-by-element comparison. 146 * possible this will need element-by-element comparison.
146 */ 147 */
147 if (!asymmetric_key_id_same(x509->id, sinfo->signing_cert_id)) 148 if (!asymmetric_key_id_same(x509->id, sinfo->sig->auth_ids[0]))
148 continue; 149 continue;
149 pr_devel("Sig %u: Found cert serial match X.509[%u]\n", 150 pr_devel("Sig %u: Found cert serial match X.509[%u]\n",
150 sinfo->index, certix); 151 sinfo->index, certix);
151 152
152 if (x509->pub->pkey_algo != sinfo->sig.pkey_algo) { 153 if (x509->pub->pkey_algo != sinfo->sig->pkey_algo) {
153 pr_warn("Sig %u: X.509 algo and PKCS#7 sig algo don't match\n", 154 pr_warn("Sig %u: X.509 algo and PKCS#7 sig algo don't match\n",
154 sinfo->index); 155 sinfo->index);
155 continue; 156 continue;
@@ -164,7 +165,7 @@ static int pkcs7_find_key(struct pkcs7_message *pkcs7,
164 */ 165 */
165 pr_debug("Sig %u: Issuing X.509 cert not found (#%*phN)\n", 166 pr_debug("Sig %u: Issuing X.509 cert not found (#%*phN)\n",
166 sinfo->index, 167 sinfo->index,
167 sinfo->signing_cert_id->len, sinfo->signing_cert_id->data); 168 sinfo->sig->auth_ids[0]->len, sinfo->sig->auth_ids[0]->data);
168 return 0; 169 return 0;
169} 170}
170 171
@@ -174,6 +175,7 @@ static int pkcs7_find_key(struct pkcs7_message *pkcs7,
174static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7, 175static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
175 struct pkcs7_signed_info *sinfo) 176 struct pkcs7_signed_info *sinfo)
176{ 177{
178 struct public_key_signature *sig;
177 struct x509_certificate *x509 = sinfo->signer, *p; 179 struct x509_certificate *x509 = sinfo->signer, *p;
178 struct asymmetric_key_id *auth; 180 struct asymmetric_key_id *auth;
179 int ret; 181 int ret;
@@ -188,34 +190,26 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
188 x509->subject, 190 x509->subject,
189 x509->raw_serial_size, x509->raw_serial); 191 x509->raw_serial_size, x509->raw_serial);
190 x509->seen = true; 192 x509->seen = true;
191 ret = x509_get_sig_params(x509); 193 if (x509->unsupported_key)
192 if (ret < 0) 194 goto unsupported_crypto_in_x509;
193 goto maybe_missing_crypto_in_x509;
194 195
195 pr_debug("- issuer %s\n", x509->issuer); 196 pr_debug("- issuer %s\n", x509->issuer);
196 if (x509->akid_id) 197 sig = x509->sig;
198 if (sig->auth_ids[0])
197 pr_debug("- authkeyid.id %*phN\n", 199 pr_debug("- authkeyid.id %*phN\n",
198 x509->akid_id->len, x509->akid_id->data); 200 sig->auth_ids[0]->len, sig->auth_ids[0]->data);
199 if (x509->akid_skid) 201 if (sig->auth_ids[1])
200 pr_debug("- authkeyid.skid %*phN\n", 202 pr_debug("- authkeyid.skid %*phN\n",
201 x509->akid_skid->len, x509->akid_skid->data); 203 sig->auth_ids[1]->len, sig->auth_ids[1]->data);
202 204
203 if ((!x509->akid_id && !x509->akid_skid) || 205 if (x509->self_signed) {
204 strcmp(x509->subject, x509->issuer) == 0) {
205 /* If there's no authority certificate specified, then 206 /* If there's no authority certificate specified, then
206 * the certificate must be self-signed and is the root 207 * the certificate must be self-signed and is the root
207 * of the chain. Likewise if the cert is its own 208 * of the chain. Likewise if the cert is its own
208 * authority. 209 * authority.
209 */ 210 */
210 pr_debug("- no auth?\n"); 211 if (x509->unsupported_sig)
211 if (x509->raw_subject_size != x509->raw_issuer_size || 212 goto unsupported_crypto_in_x509;
212 memcmp(x509->raw_subject, x509->raw_issuer,
213 x509->raw_issuer_size) != 0)
214 return 0;
215
216 ret = x509_check_signature(x509->pub, x509);
217 if (ret < 0)
218 goto maybe_missing_crypto_in_x509;
219 x509->signer = x509; 213 x509->signer = x509;
220 pr_debug("- self-signed\n"); 214 pr_debug("- self-signed\n");
221 return 0; 215 return 0;
@@ -224,7 +218,7 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
224 /* Look through the X.509 certificates in the PKCS#7 message's 218 /* Look through the X.509 certificates in the PKCS#7 message's
225 * list to see if the next one is there. 219 * list to see if the next one is there.
226 */ 220 */
227 auth = x509->akid_id; 221 auth = sig->auth_ids[0];
228 if (auth) { 222 if (auth) {
229 pr_debug("- want %*phN\n", auth->len, auth->data); 223 pr_debug("- want %*phN\n", auth->len, auth->data);
230 for (p = pkcs7->certs; p; p = p->next) { 224 for (p = pkcs7->certs; p; p = p->next) {
@@ -234,7 +228,7 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
234 goto found_issuer_check_skid; 228 goto found_issuer_check_skid;
235 } 229 }
236 } else { 230 } else {
237 auth = x509->akid_skid; 231 auth = sig->auth_ids[1];
238 pr_debug("- want %*phN\n", auth->len, auth->data); 232 pr_debug("- want %*phN\n", auth->len, auth->data);
239 for (p = pkcs7->certs; p; p = p->next) { 233 for (p = pkcs7->certs; p; p = p->next) {
240 if (!p->skid) 234 if (!p->skid)
@@ -254,8 +248,8 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
254 /* We matched issuer + serialNumber, but if there's an 248 /* We matched issuer + serialNumber, but if there's an
255 * authKeyId.keyId, that must match the CA subjKeyId also. 249 * authKeyId.keyId, that must match the CA subjKeyId also.
256 */ 250 */
257 if (x509->akid_skid && 251 if (sig->auth_ids[1] &&
258 !asymmetric_key_id_same(p->skid, x509->akid_skid)) { 252 !asymmetric_key_id_same(p->skid, sig->auth_ids[1])) {
259 pr_warn("Sig %u: X.509 chain contains auth-skid nonmatch (%u->%u)\n", 253 pr_warn("Sig %u: X.509 chain contains auth-skid nonmatch (%u->%u)\n",
260 sinfo->index, x509->index, p->index); 254 sinfo->index, x509->index, p->index);
261 return -EKEYREJECTED; 255 return -EKEYREJECTED;
@@ -267,7 +261,7 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
267 sinfo->index); 261 sinfo->index);
268 return 0; 262 return 0;
269 } 263 }
270 ret = x509_check_signature(p->pub, x509); 264 ret = public_key_verify_signature(p->pub, p->sig);
271 if (ret < 0) 265 if (ret < 0)
272 return ret; 266 return ret;
273 x509->signer = p; 267 x509->signer = p;
@@ -279,16 +273,14 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
279 might_sleep(); 273 might_sleep();
280 } 274 }
281 275
282maybe_missing_crypto_in_x509: 276unsupported_crypto_in_x509:
283 /* Just prune the certificate chain at this point if we lack some 277 /* Just prune the certificate chain at this point if we lack some
284 * crypto module to go further. Note, however, we don't want to set 278 * crypto module to go further. Note, however, we don't want to set
285 * sinfo->missing_crypto as the signed info block may still be 279 * sinfo->unsupported_crypto as the signed info block may still be
286 * validatable against an X.509 cert lower in the chain that we have a 280 * validatable against an X.509 cert lower in the chain that we have a
287 * trusted copy of. 281 * trusted copy of.
288 */ 282 */
289 if (ret == -ENOPKG) 283 return 0;
290 return 0;
291 return ret;
292} 284}
293 285
294/* 286/*
@@ -332,7 +324,7 @@ static int pkcs7_verify_one(struct pkcs7_message *pkcs7,
332 } 324 }
333 325
334 /* Verify the PKCS#7 binary against the key */ 326 /* Verify the PKCS#7 binary against the key */
335 ret = public_key_verify_signature(sinfo->signer->pub, &sinfo->sig); 327 ret = public_key_verify_signature(sinfo->signer->pub, sinfo->sig);
336 if (ret < 0) 328 if (ret < 0)
337 return ret; 329 return ret;
338 330
@@ -375,9 +367,8 @@ int pkcs7_verify(struct pkcs7_message *pkcs7,
375 enum key_being_used_for usage) 367 enum key_being_used_for usage)
376{ 368{
377 struct pkcs7_signed_info *sinfo; 369 struct pkcs7_signed_info *sinfo;
378 struct x509_certificate *x509;
379 int enopkg = -ENOPKG; 370 int enopkg = -ENOPKG;
380 int ret, n; 371 int ret;
381 372
382 kenter(""); 373 kenter("");
383 374
@@ -419,12 +410,6 @@ int pkcs7_verify(struct pkcs7_message *pkcs7,
419 return -EINVAL; 410 return -EINVAL;
420 } 411 }
421 412
422 for (n = 0, x509 = pkcs7->certs; x509; x509 = x509->next, n++) {
423 ret = x509_get_sig_params(x509);
424 if (ret < 0)
425 return ret;
426 }
427
428 for (sinfo = pkcs7->signed_infos; sinfo; sinfo = sinfo->next) { 413 for (sinfo = pkcs7->signed_infos; sinfo; sinfo = sinfo->next) {
429 ret = pkcs7_verify_one(pkcs7, sinfo); 414 ret = pkcs7_verify_one(pkcs7, sinfo);
430 if (ret < 0) { 415 if (ret < 0) {
diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c
index 0f8b264b3961..fd76b5fc3b3a 100644
--- a/crypto/asymmetric_keys/public_key.c
+++ b/crypto/asymmetric_keys/public_key.c
@@ -39,15 +39,23 @@ static void public_key_describe(const struct key *asymmetric_key,
39/* 39/*
40 * Destroy a public key algorithm key. 40 * Destroy a public key algorithm key.
41 */ 41 */
42void public_key_destroy(void *payload) 42void public_key_free(struct public_key *key)
43{ 43{
44 struct public_key *key = payload; 44 if (key) {
45
46 if (key)
47 kfree(key->key); 45 kfree(key->key);
48 kfree(key); 46 kfree(key);
47 }
48}
49EXPORT_SYMBOL_GPL(public_key_free);
50
51/*
52 * Destroy a public key algorithm key.
53 */
54static void public_key_destroy(void *payload0, void *payload3)
55{
56 public_key_free(payload0);
57 public_key_signature_free(payload3);
49} 58}
50EXPORT_SYMBOL_GPL(public_key_destroy);
51 59
52struct public_key_completion { 60struct public_key_completion {
53 struct completion completion; 61 struct completion completion;
diff --git a/crypto/asymmetric_keys/restrict.c b/crypto/asymmetric_keys/restrict.c
new file mode 100644
index 000000000000..ac4bddf669de
--- /dev/null
+++ b/crypto/asymmetric_keys/restrict.c
@@ -0,0 +1,108 @@
1/* Instantiate a public key crypto key from an X.509 Certificate
2 *
3 * Copyright (C) 2012, 2016 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public Licence
8 * as published by the Free Software Foundation; either version
9 * 2 of the Licence, or (at your option) any later version.
10 */
11
12#define pr_fmt(fmt) "ASYM: "fmt
13#include <linux/module.h>
14#include <linux/kernel.h>
15#include <linux/err.h>
16#include <crypto/public_key.h>
17#include "asymmetric_keys.h"
18
19static bool use_builtin_keys;
20static struct asymmetric_key_id *ca_keyid;
21
22#ifndef MODULE
23static struct {
24 struct asymmetric_key_id id;
25 unsigned char data[10];
26} cakey;
27
28static int __init ca_keys_setup(char *str)
29{
30 if (!str) /* default system keyring */
31 return 1;
32
33 if (strncmp(str, "id:", 3) == 0) {
34 struct asymmetric_key_id *p = &cakey.id;
35 size_t hexlen = (strlen(str) - 3) / 2;
36 int ret;
37
38 if (hexlen == 0 || hexlen > sizeof(cakey.data)) {
39 pr_err("Missing or invalid ca_keys id\n");
40 return 1;
41 }
42
43 ret = __asymmetric_key_hex_to_key_id(str + 3, p, hexlen);
44 if (ret < 0)
45 pr_err("Unparsable ca_keys id hex string\n");
46 else
47 ca_keyid = p; /* owner key 'id:xxxxxx' */
48 } else if (strcmp(str, "builtin") == 0) {
49 use_builtin_keys = true;
50 }
51
52 return 1;
53}
54__setup("ca_keys=", ca_keys_setup);
55#endif
56
57/**
58 * restrict_link_by_signature - Restrict additions to a ring of public keys
59 * @trust_keyring: A ring of keys that can be used to vouch for the new cert.
60 * @type: The type of key being added.
61 * @payload: The payload of the new key.
62 *
63 * Check the new certificate against the ones in the trust keyring. If one of
64 * those is the signing key and validates the new certificate, then mark the
65 * new certificate as being trusted.
66 *
67 * Returns 0 if the new certificate was accepted, -ENOKEY if we couldn't find a
68 * matching parent certificate in the trusted list, -EKEYREJECTED if the
69 * signature check fails or the key is blacklisted and some other error if
70 * there is a matching certificate but the signature check cannot be performed.
71 */
72int restrict_link_by_signature(struct key *trust_keyring,
73 const struct key_type *type,
74 const union key_payload *payload)
75{
76 const struct public_key_signature *sig;
77 struct key *key;
78 int ret;
79
80 pr_devel("==>%s()\n", __func__);
81
82 if (!trust_keyring)
83 return -ENOKEY;
84
85 if (type != &key_type_asymmetric)
86 return -EOPNOTSUPP;
87
88 sig = payload->data[asym_auth];
89 if (!sig->auth_ids[0] && !sig->auth_ids[1])
90 return 0;
91
92 if (ca_keyid && !asymmetric_key_id_partial(sig->auth_ids[1], ca_keyid))
93 return -EPERM;
94
95 /* See if we have a key that signed this one. */
96 key = find_asymmetric_key(trust_keyring,
97 sig->auth_ids[0], sig->auth_ids[1],
98 false);
99 if (IS_ERR(key))
100 return -ENOKEY;
101
102 if (use_builtin_keys && !test_bit(KEY_FLAG_BUILTIN, &key->flags))
103 ret = -ENOKEY;
104 else
105 ret = verify_signature(key, sig);
106 key_put(key);
107 return ret;
108}
diff --git a/crypto/asymmetric_keys/signature.c b/crypto/asymmetric_keys/signature.c
index 004d5fc8e56b..11b7ba170904 100644
--- a/crypto/asymmetric_keys/signature.c
+++ b/crypto/asymmetric_keys/signature.c
@@ -15,9 +15,27 @@
15#include <keys/asymmetric-subtype.h> 15#include <keys/asymmetric-subtype.h>
16#include <linux/export.h> 16#include <linux/export.h>
17#include <linux/err.h> 17#include <linux/err.h>
18#include <linux/slab.h>
18#include <crypto/public_key.h> 19#include <crypto/public_key.h>
19#include "asymmetric_keys.h" 20#include "asymmetric_keys.h"
20 21
22/*
23 * Destroy a public key signature.
24 */
25void public_key_signature_free(struct public_key_signature *sig)
26{
27 int i;
28
29 if (sig) {
30 for (i = 0; i < ARRAY_SIZE(sig->auth_ids); i++)
31 kfree(sig->auth_ids[i]);
32 kfree(sig->s);
33 kfree(sig->digest);
34 kfree(sig);
35 }
36}
37EXPORT_SYMBOL_GPL(public_key_signature_free);
38
21/** 39/**
22 * verify_signature - Initiate the use of an asymmetric key to verify a signature 40 * verify_signature - Initiate the use of an asymmetric key to verify a signature
23 * @key: The asymmetric key to verify against 41 * @key: The asymmetric key to verify against
diff --git a/crypto/asymmetric_keys/verify_pefile.c b/crypto/asymmetric_keys/verify_pefile.c
index 7e8c2338ae25..672a94c2c3ff 100644
--- a/crypto/asymmetric_keys/verify_pefile.c
+++ b/crypto/asymmetric_keys/verify_pefile.c
@@ -16,7 +16,7 @@
16#include <linux/err.h> 16#include <linux/err.h>
17#include <linux/pe.h> 17#include <linux/pe.h>
18#include <linux/asn1.h> 18#include <linux/asn1.h>
19#include <crypto/pkcs7.h> 19#include <linux/verification.h>
20#include <crypto/hash.h> 20#include <crypto/hash.h>
21#include "verify_pefile.h" 21#include "verify_pefile.h"
22 22
@@ -392,9 +392,8 @@ error_no_desc:
392 * verify_pefile_signature - Verify the signature on a PE binary image 392 * verify_pefile_signature - Verify the signature on a PE binary image
393 * @pebuf: Buffer containing the PE binary image 393 * @pebuf: Buffer containing the PE binary image
394 * @pelen: Length of the binary image 394 * @pelen: Length of the binary image
395 * @trust_keyring: Signing certificates to use as starting points 395 * @trust_keys: Signing certificate(s) to use as starting points
396 * @usage: The use to which the key is being put. 396 * @usage: The use to which the key is being put.
397 * @_trusted: Set to true if trustworth, false otherwise
398 * 397 *
399 * Validate that the certificate chain inside the PKCS#7 message inside the PE 398 * Validate that the certificate chain inside the PKCS#7 message inside the PE
400 * binary image intersects keys we already know and trust. 399 * binary image intersects keys we already know and trust.
@@ -418,14 +417,10 @@ error_no_desc:
418 * May also return -ENOMEM. 417 * May also return -ENOMEM.
419 */ 418 */
420int verify_pefile_signature(const void *pebuf, unsigned pelen, 419int verify_pefile_signature(const void *pebuf, unsigned pelen,
421 struct key *trusted_keyring, 420 struct key *trusted_keys,
422 enum key_being_used_for usage, 421 enum key_being_used_for usage)
423 bool *_trusted)
424{ 422{
425 struct pkcs7_message *pkcs7;
426 struct pefile_context ctx; 423 struct pefile_context ctx;
427 const void *data;
428 size_t datalen;
429 int ret; 424 int ret;
430 425
431 kenter(""); 426 kenter("");
@@ -439,19 +434,10 @@ int verify_pefile_signature(const void *pebuf, unsigned pelen,
439 if (ret < 0) 434 if (ret < 0)
440 return ret; 435 return ret;
441 436
442 pkcs7 = pkcs7_parse_message(pebuf + ctx.sig_offset, ctx.sig_len); 437 ret = verify_pkcs7_signature(NULL, 0,
443 if (IS_ERR(pkcs7)) 438 pebuf + ctx.sig_offset, ctx.sig_len,
444 return PTR_ERR(pkcs7); 439 trusted_keys, usage,
445 ctx.pkcs7 = pkcs7; 440 mscode_parse, &ctx);
446
447 ret = pkcs7_get_content_data(ctx.pkcs7, &data, &datalen, false);
448 if (ret < 0 || datalen == 0) {
449 pr_devel("PKCS#7 message does not contain data\n");
450 ret = -EBADMSG;
451 goto error;
452 }
453
454 ret = mscode_parse(&ctx);
455 if (ret < 0) 441 if (ret < 0)
456 goto error; 442 goto error;
457 443
@@ -462,16 +448,8 @@ int verify_pefile_signature(const void *pebuf, unsigned pelen,
462 * contents. 448 * contents.
463 */ 449 */
464 ret = pefile_digest_pe(pebuf, pelen, &ctx); 450 ret = pefile_digest_pe(pebuf, pelen, &ctx);
465 if (ret < 0)
466 goto error;
467
468 ret = pkcs7_verify(pkcs7, usage);
469 if (ret < 0)
470 goto error;
471
472 ret = pkcs7_validate_trust(pkcs7, trusted_keyring, _trusted);
473 451
474error: 452error:
475 pkcs7_free_message(ctx.pkcs7); 453 kfree(ctx.digest);
476 return ret; 454 return ret;
477} 455}
diff --git a/crypto/asymmetric_keys/verify_pefile.h b/crypto/asymmetric_keys/verify_pefile.h
index a133eb81a492..cd4d20930728 100644
--- a/crypto/asymmetric_keys/verify_pefile.h
+++ b/crypto/asymmetric_keys/verify_pefile.h
@@ -9,7 +9,6 @@
9 * 2 of the Licence, or (at your option) any later version. 9 * 2 of the Licence, or (at your option) any later version.
10 */ 10 */
11 11
12#include <linux/verify_pefile.h>
13#include <crypto/pkcs7.h> 12#include <crypto/pkcs7.h>
14#include <crypto/hash_info.h> 13#include <crypto/hash_info.h>
15 14
@@ -23,7 +22,6 @@ struct pefile_context {
23 unsigned sig_offset; 22 unsigned sig_offset;
24 unsigned sig_len; 23 unsigned sig_len;
25 const struct section_header *secs; 24 const struct section_header *secs;
26 struct pkcs7_message *pkcs7;
27 25
28 /* PKCS#7 MS Individual Code Signing content */ 26 /* PKCS#7 MS Individual Code Signing content */
29 const void *digest; /* Digest */ 27 const void *digest; /* Digest */
@@ -39,4 +37,5 @@ struct pefile_context {
39/* 37/*
40 * mscode_parser.c 38 * mscode_parser.c
41 */ 39 */
42extern int mscode_parse(struct pefile_context *ctx); 40extern int mscode_parse(void *_ctx, const void *content_data, size_t data_len,
41 size_t asn1hdrlen);
diff --git a/crypto/asymmetric_keys/x509_cert_parser.c b/crypto/asymmetric_keys/x509_cert_parser.c
index 4a29bac70060..865f46ea724f 100644
--- a/crypto/asymmetric_keys/x509_cert_parser.c
+++ b/crypto/asymmetric_keys/x509_cert_parser.c
@@ -47,15 +47,12 @@ struct x509_parse_context {
47void x509_free_certificate(struct x509_certificate *cert) 47void x509_free_certificate(struct x509_certificate *cert)
48{ 48{
49 if (cert) { 49 if (cert) {
50 public_key_destroy(cert->pub); 50 public_key_free(cert->pub);
51 public_key_signature_free(cert->sig);
51 kfree(cert->issuer); 52 kfree(cert->issuer);
52 kfree(cert->subject); 53 kfree(cert->subject);
53 kfree(cert->id); 54 kfree(cert->id);
54 kfree(cert->skid); 55 kfree(cert->skid);
55 kfree(cert->akid_id);
56 kfree(cert->akid_skid);
57 kfree(cert->sig.digest);
58 kfree(cert->sig.s);
59 kfree(cert); 56 kfree(cert);
60 } 57 }
61} 58}
@@ -78,6 +75,9 @@ struct x509_certificate *x509_cert_parse(const void *data, size_t datalen)
78 cert->pub = kzalloc(sizeof(struct public_key), GFP_KERNEL); 75 cert->pub = kzalloc(sizeof(struct public_key), GFP_KERNEL);
79 if (!cert->pub) 76 if (!cert->pub)
80 goto error_no_ctx; 77 goto error_no_ctx;
78 cert->sig = kzalloc(sizeof(struct public_key_signature), GFP_KERNEL);
79 if (!cert->sig)
80 goto error_no_ctx;
81 ctx = kzalloc(sizeof(struct x509_parse_context), GFP_KERNEL); 81 ctx = kzalloc(sizeof(struct x509_parse_context), GFP_KERNEL);
82 if (!ctx) 82 if (!ctx)
83 goto error_no_ctx; 83 goto error_no_ctx;
@@ -108,6 +108,11 @@ struct x509_certificate *x509_cert_parse(const void *data, size_t datalen)
108 108
109 cert->pub->keylen = ctx->key_size; 109 cert->pub->keylen = ctx->key_size;
110 110
111 /* Grab the signature bits */
112 ret = x509_get_sig_params(cert);
113 if (ret < 0)
114 goto error_decode;
115
111 /* Generate cert issuer + serial number key ID */ 116 /* Generate cert issuer + serial number key ID */
112 kid = asymmetric_key_generate_id(cert->raw_serial, 117 kid = asymmetric_key_generate_id(cert->raw_serial,
113 cert->raw_serial_size, 118 cert->raw_serial_size,
@@ -119,6 +124,11 @@ struct x509_certificate *x509_cert_parse(const void *data, size_t datalen)
119 } 124 }
120 cert->id = kid; 125 cert->id = kid;
121 126
127 /* Detect self-signed certificates */
128 ret = x509_check_for_self_signed(cert);
129 if (ret < 0)
130 goto error_decode;
131
122 kfree(ctx); 132 kfree(ctx);
123 return cert; 133 return cert;
124 134
@@ -188,33 +198,33 @@ int x509_note_pkey_algo(void *context, size_t hdrlen,
188 return -ENOPKG; /* Unsupported combination */ 198 return -ENOPKG; /* Unsupported combination */
189 199
190 case OID_md4WithRSAEncryption: 200 case OID_md4WithRSAEncryption:
191 ctx->cert->sig.hash_algo = "md4"; 201 ctx->cert->sig->hash_algo = "md4";
192 ctx->cert->sig.pkey_algo = "rsa"; 202 ctx->cert->sig->pkey_algo = "rsa";
193 break; 203 break;
194 204
195 case OID_sha1WithRSAEncryption: 205 case OID_sha1WithRSAEncryption:
196 ctx->cert->sig.hash_algo = "sha1"; 206 ctx->cert->sig->hash_algo = "sha1";
197 ctx->cert->sig.pkey_algo = "rsa"; 207 ctx->cert->sig->pkey_algo = "rsa";
198 break; 208 break;
199 209
200 case OID_sha256WithRSAEncryption: 210 case OID_sha256WithRSAEncryption:
201 ctx->cert->sig.hash_algo = "sha256"; 211 ctx->cert->sig->hash_algo = "sha256";
202 ctx->cert->sig.pkey_algo = "rsa"; 212 ctx->cert->sig->pkey_algo = "rsa";
203 break; 213 break;
204 214
205 case OID_sha384WithRSAEncryption: 215 case OID_sha384WithRSAEncryption:
206 ctx->cert->sig.hash_algo = "sha384"; 216 ctx->cert->sig->hash_algo = "sha384";
207 ctx->cert->sig.pkey_algo = "rsa"; 217 ctx->cert->sig->pkey_algo = "rsa";
208 break; 218 break;
209 219
210 case OID_sha512WithRSAEncryption: 220 case OID_sha512WithRSAEncryption:
211 ctx->cert->sig.hash_algo = "sha512"; 221 ctx->cert->sig->hash_algo = "sha512";
212 ctx->cert->sig.pkey_algo = "rsa"; 222 ctx->cert->sig->pkey_algo = "rsa";
213 break; 223 break;
214 224
215 case OID_sha224WithRSAEncryption: 225 case OID_sha224WithRSAEncryption:
216 ctx->cert->sig.hash_algo = "sha224"; 226 ctx->cert->sig->hash_algo = "sha224";
217 ctx->cert->sig.pkey_algo = "rsa"; 227 ctx->cert->sig->pkey_algo = "rsa";
218 break; 228 break;
219 } 229 }
220 230
@@ -572,14 +582,14 @@ int x509_akid_note_kid(void *context, size_t hdrlen,
572 582
573 pr_debug("AKID: keyid: %*phN\n", (int)vlen, value); 583 pr_debug("AKID: keyid: %*phN\n", (int)vlen, value);
574 584
575 if (ctx->cert->akid_skid) 585 if (ctx->cert->sig->auth_ids[1])
576 return 0; 586 return 0;
577 587
578 kid = asymmetric_key_generate_id(value, vlen, "", 0); 588 kid = asymmetric_key_generate_id(value, vlen, "", 0);
579 if (IS_ERR(kid)) 589 if (IS_ERR(kid))
580 return PTR_ERR(kid); 590 return PTR_ERR(kid);
581 pr_debug("authkeyid %*phN\n", kid->len, kid->data); 591 pr_debug("authkeyid %*phN\n", kid->len, kid->data);
582 ctx->cert->akid_skid = kid; 592 ctx->cert->sig->auth_ids[1] = kid;
583 return 0; 593 return 0;
584} 594}
585 595
@@ -611,7 +621,7 @@ int x509_akid_note_serial(void *context, size_t hdrlen,
611 621
612 pr_debug("AKID: serial: %*phN\n", (int)vlen, value); 622 pr_debug("AKID: serial: %*phN\n", (int)vlen, value);
613 623
614 if (!ctx->akid_raw_issuer || ctx->cert->akid_id) 624 if (!ctx->akid_raw_issuer || ctx->cert->sig->auth_ids[0])
615 return 0; 625 return 0;
616 626
617 kid = asymmetric_key_generate_id(value, 627 kid = asymmetric_key_generate_id(value,
@@ -622,6 +632,6 @@ int x509_akid_note_serial(void *context, size_t hdrlen,
622 return PTR_ERR(kid); 632 return PTR_ERR(kid);
623 633
624 pr_debug("authkeyid %*phN\n", kid->len, kid->data); 634 pr_debug("authkeyid %*phN\n", kid->len, kid->data);
625 ctx->cert->akid_id = kid; 635 ctx->cert->sig->auth_ids[0] = kid;
626 return 0; 636 return 0;
627} 637}
diff --git a/crypto/asymmetric_keys/x509_parser.h b/crypto/asymmetric_keys/x509_parser.h
index dbeed6018e63..05eef1c68881 100644
--- a/crypto/asymmetric_keys/x509_parser.h
+++ b/crypto/asymmetric_keys/x509_parser.h
@@ -17,13 +17,11 @@ struct x509_certificate {
17 struct x509_certificate *next; 17 struct x509_certificate *next;
18 struct x509_certificate *signer; /* Certificate that signed this one */ 18 struct x509_certificate *signer; /* Certificate that signed this one */
19 struct public_key *pub; /* Public key details */ 19 struct public_key *pub; /* Public key details */
20 struct public_key_signature sig; /* Signature parameters */ 20 struct public_key_signature *sig; /* Signature parameters */
21 char *issuer; /* Name of certificate issuer */ 21 char *issuer; /* Name of certificate issuer */
22 char *subject; /* Name of certificate subject */ 22 char *subject; /* Name of certificate subject */
23 struct asymmetric_key_id *id; /* Issuer + Serial number */ 23 struct asymmetric_key_id *id; /* Issuer + Serial number */
24 struct asymmetric_key_id *skid; /* Subject + subjectKeyId (optional) */ 24 struct asymmetric_key_id *skid; /* Subject + subjectKeyId (optional) */
25 struct asymmetric_key_id *akid_id; /* CA AuthKeyId matching ->id (optional) */
26 struct asymmetric_key_id *akid_skid; /* CA AuthKeyId matching ->skid (optional) */
27 time64_t valid_from; 25 time64_t valid_from;
28 time64_t valid_to; 26 time64_t valid_to;
29 const void *tbs; /* Signed data */ 27 const void *tbs; /* Signed data */
@@ -41,8 +39,9 @@ struct x509_certificate {
41 unsigned index; 39 unsigned index;
42 bool seen; /* Infinite recursion prevention */ 40 bool seen; /* Infinite recursion prevention */
43 bool verified; 41 bool verified;
44 bool trusted; 42 bool self_signed; /* T if self-signed (check unsupported_sig too) */
45 bool unsupported_crypto; /* T if can't be verified due to missing crypto */ 43 bool unsupported_key; /* T if key uses unsupported crypto */
44 bool unsupported_sig; /* T if signature uses unsupported crypto */
46}; 45};
47 46
48/* 47/*
@@ -58,5 +57,4 @@ extern int x509_decode_time(time64_t *_t, size_t hdrlen,
58 * x509_public_key.c 57 * x509_public_key.c
59 */ 58 */
60extern int x509_get_sig_params(struct x509_certificate *cert); 59extern int x509_get_sig_params(struct x509_certificate *cert);
61extern int x509_check_signature(const struct public_key *pub, 60extern int x509_check_for_self_signed(struct x509_certificate *cert);
62 struct x509_certificate *cert);
diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c
index 733c046aacc6..fb732296cd36 100644
--- a/crypto/asymmetric_keys/x509_public_key.c
+++ b/crypto/asymmetric_keys/x509_public_key.c
@@ -20,256 +20,133 @@
20#include "asymmetric_keys.h" 20#include "asymmetric_keys.h"
21#include "x509_parser.h" 21#include "x509_parser.h"
22 22
23static bool use_builtin_keys;
24static struct asymmetric_key_id *ca_keyid;
25
26#ifndef MODULE
27static struct {
28 struct asymmetric_key_id id;
29 unsigned char data[10];
30} cakey;
31
32static int __init ca_keys_setup(char *str)
33{
34 if (!str) /* default system keyring */
35 return 1;
36
37 if (strncmp(str, "id:", 3) == 0) {
38 struct asymmetric_key_id *p = &cakey.id;
39 size_t hexlen = (strlen(str) - 3) / 2;
40 int ret;
41
42 if (hexlen == 0 || hexlen > sizeof(cakey.data)) {
43 pr_err("Missing or invalid ca_keys id\n");
44 return 1;
45 }
46
47 ret = __asymmetric_key_hex_to_key_id(str + 3, p, hexlen);
48 if (ret < 0)
49 pr_err("Unparsable ca_keys id hex string\n");
50 else
51 ca_keyid = p; /* owner key 'id:xxxxxx' */
52 } else if (strcmp(str, "builtin") == 0) {
53 use_builtin_keys = true;
54 }
55
56 return 1;
57}
58__setup("ca_keys=", ca_keys_setup);
59#endif
60
61/**
62 * x509_request_asymmetric_key - Request a key by X.509 certificate params.
63 * @keyring: The keys to search.
64 * @id: The issuer & serialNumber to look for or NULL.
65 * @skid: The subjectKeyIdentifier to look for or NULL.
66 * @partial: Use partial match if true, exact if false.
67 *
68 * Find a key in the given keyring by identifier. The preferred identifier is
69 * the issuer + serialNumber and the fallback identifier is the
70 * subjectKeyIdentifier. If both are given, the lookup is by the former, but
71 * the latter must also match.
72 */
73struct key *x509_request_asymmetric_key(struct key *keyring,
74 const struct asymmetric_key_id *id,
75 const struct asymmetric_key_id *skid,
76 bool partial)
77{
78 struct key *key;
79 key_ref_t ref;
80 const char *lookup;
81 char *req, *p;
82 int len;
83
84 if (id) {
85 lookup = id->data;
86 len = id->len;
87 } else {
88 lookup = skid->data;
89 len = skid->len;
90 }
91
92 /* Construct an identifier "id:<keyid>". */
93 p = req = kmalloc(2 + 1 + len * 2 + 1, GFP_KERNEL);
94 if (!req)
95 return ERR_PTR(-ENOMEM);
96
97 if (partial) {
98 *p++ = 'i';
99 *p++ = 'd';
100 } else {
101 *p++ = 'e';
102 *p++ = 'x';
103 }
104 *p++ = ':';
105 p = bin2hex(p, lookup, len);
106 *p = 0;
107
108 pr_debug("Look up: \"%s\"\n", req);
109
110 ref = keyring_search(make_key_ref(keyring, 1),
111 &key_type_asymmetric, req);
112 if (IS_ERR(ref))
113 pr_debug("Request for key '%s' err %ld\n", req, PTR_ERR(ref));
114 kfree(req);
115
116 if (IS_ERR(ref)) {
117 switch (PTR_ERR(ref)) {
118 /* Hide some search errors */
119 case -EACCES:
120 case -ENOTDIR:
121 case -EAGAIN:
122 return ERR_PTR(-ENOKEY);
123 default:
124 return ERR_CAST(ref);
125 }
126 }
127
128 key = key_ref_to_ptr(ref);
129 if (id && skid) {
130 const struct asymmetric_key_ids *kids = asymmetric_key_ids(key);
131 if (!kids->id[1]) {
132 pr_debug("issuer+serial match, but expected SKID missing\n");
133 goto reject;
134 }
135 if (!asymmetric_key_id_same(skid, kids->id[1])) {
136 pr_debug("issuer+serial match, but SKID does not\n");
137 goto reject;
138 }
139 }
140
141 pr_devel("<==%s() = 0 [%x]\n", __func__, key_serial(key));
142 return key;
143
144reject:
145 key_put(key);
146 return ERR_PTR(-EKEYREJECTED);
147}
148EXPORT_SYMBOL_GPL(x509_request_asymmetric_key);
149
150/* 23/*
151 * Set up the signature parameters in an X.509 certificate. This involves 24 * Set up the signature parameters in an X.509 certificate. This involves
152 * digesting the signed data and extracting the signature. 25 * digesting the signed data and extracting the signature.
153 */ 26 */
154int x509_get_sig_params(struct x509_certificate *cert) 27int x509_get_sig_params(struct x509_certificate *cert)
155{ 28{
29 struct public_key_signature *sig = cert->sig;
156 struct crypto_shash *tfm; 30 struct crypto_shash *tfm;
157 struct shash_desc *desc; 31 struct shash_desc *desc;
158 size_t digest_size, desc_size; 32 size_t desc_size;
159 void *digest;
160 int ret; 33 int ret;
161 34
162 pr_devel("==>%s()\n", __func__); 35 pr_devel("==>%s()\n", __func__);
163 36
164 if (cert->unsupported_crypto) 37 if (!cert->pub->pkey_algo)
165 return -ENOPKG; 38 cert->unsupported_key = true;
166 if (cert->sig.s) 39
40 if (!sig->pkey_algo)
41 cert->unsupported_sig = true;
42
43 /* We check the hash if we can - even if we can't then verify it */
44 if (!sig->hash_algo) {
45 cert->unsupported_sig = true;
167 return 0; 46 return 0;
47 }
168 48
169 cert->sig.s = kmemdup(cert->raw_sig, cert->raw_sig_size, 49 sig->s = kmemdup(cert->raw_sig, cert->raw_sig_size, GFP_KERNEL);
170 GFP_KERNEL); 50 if (!sig->s)
171 if (!cert->sig.s)
172 return -ENOMEM; 51 return -ENOMEM;
173 52
174 cert->sig.s_size = cert->raw_sig_size; 53 sig->s_size = cert->raw_sig_size;
175 54
176 /* Allocate the hashing algorithm we're going to need and find out how 55 /* Allocate the hashing algorithm we're going to need and find out how
177 * big the hash operational data will be. 56 * big the hash operational data will be.
178 */ 57 */
179 tfm = crypto_alloc_shash(cert->sig.hash_algo, 0, 0); 58 tfm = crypto_alloc_shash(sig->hash_algo, 0, 0);
180 if (IS_ERR(tfm)) { 59 if (IS_ERR(tfm)) {
181 if (PTR_ERR(tfm) == -ENOENT) { 60 if (PTR_ERR(tfm) == -ENOENT) {
182 cert->unsupported_crypto = true; 61 cert->unsupported_sig = true;
183 return -ENOPKG; 62 return 0;
184 } 63 }
185 return PTR_ERR(tfm); 64 return PTR_ERR(tfm);
186 } 65 }
187 66
188 desc_size = crypto_shash_descsize(tfm) + sizeof(*desc); 67 desc_size = crypto_shash_descsize(tfm) + sizeof(*desc);
189 digest_size = crypto_shash_digestsize(tfm); 68 sig->digest_size = crypto_shash_digestsize(tfm);
190 69
191 /* We allocate the hash operational data storage on the end of the
192 * digest storage space.
193 */
194 ret = -ENOMEM; 70 ret = -ENOMEM;
195 digest = kzalloc(ALIGN(digest_size, __alignof__(*desc)) + desc_size, 71 sig->digest = kmalloc(sig->digest_size, GFP_KERNEL);
196 GFP_KERNEL); 72 if (!sig->digest)
197 if (!digest)
198 goto error; 73 goto error;
199 74
200 cert->sig.digest = digest; 75 desc = kzalloc(desc_size, GFP_KERNEL);
201 cert->sig.digest_size = digest_size; 76 if (!desc)
77 goto error;
202 78
203 desc = PTR_ALIGN(digest + digest_size, __alignof__(*desc));
204 desc->tfm = tfm; 79 desc->tfm = tfm;
205 desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP; 80 desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
206 81
207 ret = crypto_shash_init(desc); 82 ret = crypto_shash_init(desc);
208 if (ret < 0) 83 if (ret < 0)
209 goto error; 84 goto error_2;
210 might_sleep(); 85 might_sleep();
211 ret = crypto_shash_finup(desc, cert->tbs, cert->tbs_size, digest); 86 ret = crypto_shash_finup(desc, cert->tbs, cert->tbs_size, sig->digest);
87
88error_2:
89 kfree(desc);
212error: 90error:
213 crypto_free_shash(tfm); 91 crypto_free_shash(tfm);
214 pr_devel("<==%s() = %d\n", __func__, ret); 92 pr_devel("<==%s() = %d\n", __func__, ret);
215 return ret; 93 return ret;
216} 94}
217EXPORT_SYMBOL_GPL(x509_get_sig_params);
218 95
219/* 96/*
220 * Check the signature on a certificate using the provided public key 97 * Check for self-signedness in an X.509 cert and if found, check the signature
98 * immediately if we can.
221 */ 99 */
222int x509_check_signature(const struct public_key *pub, 100int x509_check_for_self_signed(struct x509_certificate *cert)
223 struct x509_certificate *cert)
224{ 101{
225 int ret; 102 int ret = 0;
226 103
227 pr_devel("==>%s()\n", __func__); 104 pr_devel("==>%s()\n", __func__);
228 105
229 ret = x509_get_sig_params(cert); 106 if (cert->raw_subject_size != cert->raw_issuer_size ||
230 if (ret < 0) 107 memcmp(cert->raw_subject, cert->raw_issuer,
231 return ret; 108 cert->raw_issuer_size) != 0)
109 goto not_self_signed;
110
111 if (cert->sig->auth_ids[0] || cert->sig->auth_ids[1]) {
112 /* If the AKID is present it may have one or two parts. If
113 * both are supplied, both must match.
114 */
115 bool a = asymmetric_key_id_same(cert->skid, cert->sig->auth_ids[1]);
116 bool b = asymmetric_key_id_same(cert->id, cert->sig->auth_ids[0]);
117
118 if (!a && !b)
119 goto not_self_signed;
120
121 ret = -EKEYREJECTED;
122 if (((a && !b) || (b && !a)) &&
123 cert->sig->auth_ids[0] && cert->sig->auth_ids[1])
124 goto out;
125 }
232 126
233 ret = public_key_verify_signature(pub, &cert->sig); 127 ret = -EKEYREJECTED;
234 if (ret == -ENOPKG) 128 if (cert->pub->pkey_algo != cert->sig->pkey_algo)
235 cert->unsupported_crypto = true; 129 goto out;
236 pr_debug("Cert Verification: %d\n", ret);
237 return ret;
238}
239EXPORT_SYMBOL_GPL(x509_check_signature);
240 130
241/* 131 ret = public_key_verify_signature(cert->pub, cert->sig);
242 * Check the new certificate against the ones in the trust keyring. If one of 132 if (ret < 0) {
243 * those is the signing key and validates the new certificate, then mark the 133 if (ret == -ENOPKG) {
244 * new certificate as being trusted. 134 cert->unsupported_sig = true;
245 * 135 ret = 0;
246 * Return 0 if the new certificate was successfully validated, 1 if we couldn't 136 }
247 * find a matching parent certificate in the trusted list and an error if there 137 goto out;
248 * is a matching certificate but the signature check fails.
249 */
250static int x509_validate_trust(struct x509_certificate *cert,
251 struct key *trust_keyring)
252{
253 struct key *key;
254 int ret = 1;
255
256 if (!trust_keyring)
257 return -EOPNOTSUPP;
258
259 if (ca_keyid && !asymmetric_key_id_partial(cert->akid_skid, ca_keyid))
260 return -EPERM;
261
262 key = x509_request_asymmetric_key(trust_keyring,
263 cert->akid_id, cert->akid_skid,
264 false);
265 if (!IS_ERR(key)) {
266 if (!use_builtin_keys
267 || test_bit(KEY_FLAG_BUILTIN, &key->flags))
268 ret = x509_check_signature(key->payload.data[asym_crypto],
269 cert);
270 key_put(key);
271 } 138 }
139
140 pr_devel("Cert Self-signature verified");
141 cert->self_signed = true;
142
143out:
144 pr_devel("<==%s() = %d\n", __func__, ret);
272 return ret; 145 return ret;
146
147not_self_signed:
148 pr_devel("<==%s() = 0 [not]\n", __func__);
149 return 0;
273} 150}
274 151
275/* 152/*
@@ -291,34 +168,22 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
291 pr_devel("Cert Issuer: %s\n", cert->issuer); 168 pr_devel("Cert Issuer: %s\n", cert->issuer);
292 pr_devel("Cert Subject: %s\n", cert->subject); 169 pr_devel("Cert Subject: %s\n", cert->subject);
293 170
294 if (!cert->pub->pkey_algo || 171 if (cert->unsupported_key) {
295 !cert->sig.pkey_algo ||
296 !cert->sig.hash_algo) {
297 ret = -ENOPKG; 172 ret = -ENOPKG;
298 goto error_free_cert; 173 goto error_free_cert;
299 } 174 }
300 175
301 pr_devel("Cert Key Algo: %s\n", cert->pub->pkey_algo); 176 pr_devel("Cert Key Algo: %s\n", cert->pub->pkey_algo);
302 pr_devel("Cert Valid period: %lld-%lld\n", cert->valid_from, cert->valid_to); 177 pr_devel("Cert Valid period: %lld-%lld\n", cert->valid_from, cert->valid_to);
303 pr_devel("Cert Signature: %s + %s\n",
304 cert->sig.pkey_algo,
305 cert->sig.hash_algo);
306 178
307 cert->pub->id_type = "X509"; 179 cert->pub->id_type = "X509";
308 180
309 /* Check the signature on the key if it appears to be self-signed */ 181 if (cert->unsupported_sig) {
310 if ((!cert->akid_skid && !cert->akid_id) || 182 public_key_signature_free(cert->sig);
311 asymmetric_key_id_same(cert->skid, cert->akid_skid) || 183 cert->sig = NULL;
312 asymmetric_key_id_same(cert->id, cert->akid_id)) { 184 } else {
313 ret = x509_check_signature(cert->pub, cert); /* self-signed */ 185 pr_devel("Cert Signature: %s + %s\n",
314 if (ret < 0) 186 cert->sig->pkey_algo, cert->sig->hash_algo);
315 goto error_free_cert;
316 } else if (!prep->trusted) {
317 ret = x509_validate_trust(cert, get_system_trusted_keyring());
318 if (ret)
319 ret = x509_validate_trust(cert, get_ima_mok_keyring());
320 if (!ret)
321 prep->trusted = 1;
322 } 187 }
323 188
324 /* Propose a description */ 189 /* Propose a description */
@@ -353,6 +218,7 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
353 prep->payload.data[asym_subtype] = &public_key_subtype; 218 prep->payload.data[asym_subtype] = &public_key_subtype;
354 prep->payload.data[asym_key_ids] = kids; 219 prep->payload.data[asym_key_ids] = kids;
355 prep->payload.data[asym_crypto] = cert->pub; 220 prep->payload.data[asym_crypto] = cert->pub;
221 prep->payload.data[asym_auth] = cert->sig;
356 prep->description = desc; 222 prep->description = desc;
357 prep->quotalen = 100; 223 prep->quotalen = 100;
358 224
@@ -360,6 +226,7 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
360 cert->pub = NULL; 226 cert->pub = NULL;
361 cert->id = NULL; 227 cert->id = NULL;
362 cert->skid = NULL; 228 cert->skid = NULL;
229 cert->sig = NULL;
363 desc = NULL; 230 desc = NULL;
364 ret = 0; 231 ret = 0;
365 232
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
index 3f93125916bf..71e8a56e9479 100644
--- a/fs/cifs/cifsacl.c
+++ b/fs/cifs/cifsacl.c
@@ -360,7 +360,7 @@ init_cifs_idmap(void)
360 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred, 360 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred,
361 (KEY_POS_ALL & ~KEY_POS_SETATTR) | 361 (KEY_POS_ALL & ~KEY_POS_SETATTR) |
362 KEY_USR_VIEW | KEY_USR_READ, 362 KEY_USR_VIEW | KEY_USR_READ,
363 KEY_ALLOC_NOT_IN_QUOTA, NULL); 363 KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL);
364 if (IS_ERR(keyring)) { 364 if (IS_ERR(keyring)) {
365 ret = PTR_ERR(keyring); 365 ret = PTR_ERR(keyring);
366 goto failed_put_cred; 366 goto failed_put_cred;
diff --git a/fs/exec.c b/fs/exec.c
index a98b21d47385..e92419fd78b3 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -850,15 +850,25 @@ int kernel_read_file(struct file *file, void **buf, loff_t *size,
850 if (ret) 850 if (ret)
851 return ret; 851 return ret;
852 852
853 ret = deny_write_access(file);
854 if (ret)
855 return ret;
856
853 i_size = i_size_read(file_inode(file)); 857 i_size = i_size_read(file_inode(file));
854 if (max_size > 0 && i_size > max_size) 858 if (max_size > 0 && i_size > max_size) {
855 return -EFBIG; 859 ret = -EFBIG;
856 if (i_size <= 0) 860 goto out;
857 return -EINVAL; 861 }
862 if (i_size <= 0) {
863 ret = -EINVAL;
864 goto out;
865 }
858 866
859 *buf = vmalloc(i_size); 867 *buf = vmalloc(i_size);
860 if (!*buf) 868 if (!*buf) {
861 return -ENOMEM; 869 ret = -ENOMEM;
870 goto out;
871 }
862 872
863 pos = 0; 873 pos = 0;
864 while (pos < i_size) { 874 while (pos < i_size) {
@@ -876,18 +886,21 @@ int kernel_read_file(struct file *file, void **buf, loff_t *size,
876 886
877 if (pos != i_size) { 887 if (pos != i_size) {
878 ret = -EIO; 888 ret = -EIO;
879 goto out; 889 goto out_free;
880 } 890 }
881 891
882 ret = security_kernel_post_read_file(file, *buf, i_size, id); 892 ret = security_kernel_post_read_file(file, *buf, i_size, id);
883 if (!ret) 893 if (!ret)
884 *size = pos; 894 *size = pos;
885 895
886out: 896out_free:
887 if (ret < 0) { 897 if (ret < 0) {
888 vfree(*buf); 898 vfree(*buf);
889 *buf = NULL; 899 *buf = NULL;
890 } 900 }
901
902out:
903 allow_write_access(file);
891 return ret; 904 return ret;
892} 905}
893EXPORT_SYMBOL_GPL(kernel_read_file); 906EXPORT_SYMBOL_GPL(kernel_read_file);
diff --git a/fs/namei.c b/fs/namei.c
index 9d193d336c9f..5375571cf6e1 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3627,6 +3627,8 @@ retry:
3627 switch (mode & S_IFMT) { 3627 switch (mode & S_IFMT) {
3628 case 0: case S_IFREG: 3628 case 0: case S_IFREG:
3629 error = vfs_create(path.dentry->d_inode,dentry,mode,true); 3629 error = vfs_create(path.dentry->d_inode,dentry,mode,true);
3630 if (!error)
3631 ima_post_path_mknod(dentry);
3630 break; 3632 break;
3631 case S_IFCHR: case S_IFBLK: 3633 case S_IFCHR: case S_IFBLK:
3632 error = vfs_mknod(path.dentry->d_inode,dentry,mode, 3634 error = vfs_mknod(path.dentry->d_inode,dentry,mode,
diff --git a/fs/nfs/nfs4idmap.c b/fs/nfs/nfs4idmap.c
index 5ba22c6b0ffa..c444285bb1b1 100644
--- a/fs/nfs/nfs4idmap.c
+++ b/fs/nfs/nfs4idmap.c
@@ -201,7 +201,7 @@ int nfs_idmap_init(void)
201 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred, 201 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred,
202 (KEY_POS_ALL & ~KEY_POS_SETATTR) | 202 (KEY_POS_ALL & ~KEY_POS_SETATTR) |
203 KEY_USR_VIEW | KEY_USR_READ, 203 KEY_USR_VIEW | KEY_USR_READ,
204 KEY_ALLOC_NOT_IN_QUOTA, NULL); 204 KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL);
205 if (IS_ERR(keyring)) { 205 if (IS_ERR(keyring)) {
206 ret = PTR_ERR(keyring); 206 ret = PTR_ERR(keyring);
207 goto failed_put_cred; 207 goto failed_put_cred;
diff --git a/include/crypto/pkcs7.h b/include/crypto/pkcs7.h
index 441aff9b5aa7..583f199400a3 100644
--- a/include/crypto/pkcs7.h
+++ b/include/crypto/pkcs7.h
@@ -12,6 +12,7 @@
12#ifndef _CRYPTO_PKCS7_H 12#ifndef _CRYPTO_PKCS7_H
13#define _CRYPTO_PKCS7_H 13#define _CRYPTO_PKCS7_H
14 14
15#include <linux/verification.h>
15#include <crypto/public_key.h> 16#include <crypto/public_key.h>
16 17
17struct key; 18struct key;
@@ -26,14 +27,13 @@ extern void pkcs7_free_message(struct pkcs7_message *pkcs7);
26 27
27extern int pkcs7_get_content_data(const struct pkcs7_message *pkcs7, 28extern int pkcs7_get_content_data(const struct pkcs7_message *pkcs7,
28 const void **_data, size_t *_datalen, 29 const void **_data, size_t *_datalen,
29 bool want_wrapper); 30 size_t *_headerlen);
30 31
31/* 32/*
32 * pkcs7_trust.c 33 * pkcs7_trust.c
33 */ 34 */
34extern int pkcs7_validate_trust(struct pkcs7_message *pkcs7, 35extern int pkcs7_validate_trust(struct pkcs7_message *pkcs7,
35 struct key *trust_keyring, 36 struct key *trust_keyring);
36 bool *_trusted);
37 37
38/* 38/*
39 * pkcs7_verify.c 39 * pkcs7_verify.c
diff --git a/include/crypto/public_key.h b/include/crypto/public_key.h
index aa730ea7faf8..882ca0e1e7a5 100644
--- a/include/crypto/public_key.h
+++ b/include/crypto/public_key.h
@@ -15,20 +15,6 @@
15#define _LINUX_PUBLIC_KEY_H 15#define _LINUX_PUBLIC_KEY_H
16 16
17/* 17/*
18 * The use to which an asymmetric key is being put.
19 */
20enum key_being_used_for {
21 VERIFYING_MODULE_SIGNATURE,
22 VERIFYING_FIRMWARE_SIGNATURE,
23 VERIFYING_KEXEC_PE_SIGNATURE,
24 VERIFYING_KEY_SIGNATURE,
25 VERIFYING_KEY_SELF_SIGNATURE,
26 VERIFYING_UNSPECIFIED_SIGNATURE,
27 NR__KEY_BEING_USED_FOR
28};
29extern const char *const key_being_used_for[NR__KEY_BEING_USED_FOR];
30
31/*
32 * Cryptographic data for the public-key subtype of the asymmetric key type. 18 * Cryptographic data for the public-key subtype of the asymmetric key type.
33 * 19 *
34 * Note that this may include private part of the key as well as the public 20 * Note that this may include private part of the key as well as the public
@@ -41,12 +27,13 @@ struct public_key {
41 const char *pkey_algo; 27 const char *pkey_algo;
42}; 28};
43 29
44extern void public_key_destroy(void *payload); 30extern void public_key_free(struct public_key *key);
45 31
46/* 32/*
47 * Public key cryptography signature data 33 * Public key cryptography signature data
48 */ 34 */
49struct public_key_signature { 35struct public_key_signature {
36 struct asymmetric_key_id *auth_ids[2];
50 u8 *s; /* Signature */ 37 u8 *s; /* Signature */
51 u32 s_size; /* Number of bytes in signature */ 38 u32 s_size; /* Number of bytes in signature */
52 u8 *digest; 39 u8 *digest;
@@ -55,17 +42,21 @@ struct public_key_signature {
55 const char *hash_algo; 42 const char *hash_algo;
56}; 43};
57 44
45extern void public_key_signature_free(struct public_key_signature *sig);
46
58extern struct asymmetric_key_subtype public_key_subtype; 47extern struct asymmetric_key_subtype public_key_subtype;
48
59struct key; 49struct key;
50struct key_type;
51union key_payload;
52
53extern int restrict_link_by_signature(struct key *trust_keyring,
54 const struct key_type *type,
55 const union key_payload *payload);
56
60extern int verify_signature(const struct key *key, 57extern int verify_signature(const struct key *key,
61 const struct public_key_signature *sig); 58 const struct public_key_signature *sig);
62 59
63struct asymmetric_key_id;
64extern struct key *x509_request_asymmetric_key(struct key *keyring,
65 const struct asymmetric_key_id *id,
66 const struct asymmetric_key_id *skid,
67 bool partial);
68
69int public_key_verify_signature(const struct public_key *pkey, 60int public_key_verify_signature(const struct public_key *pkey,
70 const struct public_key_signature *sig); 61 const struct public_key_signature *sig);
71 62
diff --git a/include/keys/asymmetric-subtype.h b/include/keys/asymmetric-subtype.h
index 4915d40d3c3c..2480469ce8fb 100644
--- a/include/keys/asymmetric-subtype.h
+++ b/include/keys/asymmetric-subtype.h
@@ -32,7 +32,7 @@ struct asymmetric_key_subtype {
32 void (*describe)(const struct key *key, struct seq_file *m); 32 void (*describe)(const struct key *key, struct seq_file *m);
33 33
34 /* Destroy a key of this subtype */ 34 /* Destroy a key of this subtype */
35 void (*destroy)(void *payload); 35 void (*destroy)(void *payload_crypto, void *payload_auth);
36 36
37 /* Verify the signature on a key of this subtype (optional) */ 37 /* Verify the signature on a key of this subtype (optional) */
38 int (*verify_signature)(const struct key *key, 38 int (*verify_signature)(const struct key *key,
diff --git a/include/keys/asymmetric-type.h b/include/keys/asymmetric-type.h
index 59c1df9cf922..b38240716d41 100644
--- a/include/keys/asymmetric-type.h
+++ b/include/keys/asymmetric-type.h
@@ -15,6 +15,7 @@
15#define _KEYS_ASYMMETRIC_TYPE_H 15#define _KEYS_ASYMMETRIC_TYPE_H
16 16
17#include <linux/key-type.h> 17#include <linux/key-type.h>
18#include <linux/verification.h>
18 19
19extern struct key_type key_type_asymmetric; 20extern struct key_type key_type_asymmetric;
20 21
@@ -23,9 +24,10 @@ extern struct key_type key_type_asymmetric;
23 * follows: 24 * follows:
24 */ 25 */
25enum asymmetric_payload_bits { 26enum asymmetric_payload_bits {
26 asym_crypto, 27 asym_crypto, /* The data representing the key */
27 asym_subtype, 28 asym_subtype, /* Pointer to an asymmetric_key_subtype struct */
28 asym_key_ids, 29 asym_key_ids, /* Pointer to an asymmetric_key_ids struct */
30 asym_auth /* The key's authorisation (signature, parent key ID) */
29}; 31};
30 32
31/* 33/*
@@ -74,6 +76,11 @@ const struct asymmetric_key_ids *asymmetric_key_ids(const struct key *key)
74 return key->payload.data[asym_key_ids]; 76 return key->payload.data[asym_key_ids];
75} 77}
76 78
79extern struct key *find_asymmetric_key(struct key *keyring,
80 const struct asymmetric_key_id *id_0,
81 const struct asymmetric_key_id *id_1,
82 bool partial);
83
77/* 84/*
78 * The payload is at the discretion of the subtype. 85 * The payload is at the discretion of the subtype.
79 */ 86 */
diff --git a/include/keys/system_keyring.h b/include/keys/system_keyring.h
index 39fd38cfa8c9..fbd4647767e9 100644
--- a/include/keys/system_keyring.h
+++ b/include/keys/system_keyring.h
@@ -12,51 +12,40 @@
12#ifndef _KEYS_SYSTEM_KEYRING_H 12#ifndef _KEYS_SYSTEM_KEYRING_H
13#define _KEYS_SYSTEM_KEYRING_H 13#define _KEYS_SYSTEM_KEYRING_H
14 14
15#include <linux/key.h>
16
15#ifdef CONFIG_SYSTEM_TRUSTED_KEYRING 17#ifdef CONFIG_SYSTEM_TRUSTED_KEYRING
16 18
17#include <linux/key.h> 19extern int restrict_link_by_builtin_trusted(struct key *keyring,
18#include <crypto/public_key.h> 20 const struct key_type *type,
21 const union key_payload *payload);
19 22
20extern struct key *system_trusted_keyring;
21static inline struct key *get_system_trusted_keyring(void)
22{
23 return system_trusted_keyring;
24}
25#else 23#else
26static inline struct key *get_system_trusted_keyring(void) 24#define restrict_link_by_builtin_trusted restrict_link_reject
27{
28 return NULL;
29}
30#endif 25#endif
31 26
32#ifdef CONFIG_SYSTEM_DATA_VERIFICATION 27#ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
33extern int system_verify_data(const void *data, unsigned long len, 28extern int restrict_link_by_builtin_and_secondary_trusted(
34 const void *raw_pkcs7, size_t pkcs7_len, 29 struct key *keyring,
35 enum key_being_used_for usage); 30 const struct key_type *type,
31 const union key_payload *payload);
32#else
33#define restrict_link_by_builtin_and_secondary_trusted restrict_link_by_builtin_trusted
36#endif 34#endif
37 35
38#ifdef CONFIG_IMA_MOK_KEYRING 36#ifdef CONFIG_IMA_BLACKLIST_KEYRING
39extern struct key *ima_mok_keyring;
40extern struct key *ima_blacklist_keyring; 37extern struct key *ima_blacklist_keyring;
41 38
42static inline struct key *get_ima_mok_keyring(void)
43{
44 return ima_mok_keyring;
45}
46static inline struct key *get_ima_blacklist_keyring(void) 39static inline struct key *get_ima_blacklist_keyring(void)
47{ 40{
48 return ima_blacklist_keyring; 41 return ima_blacklist_keyring;
49} 42}
50#else 43#else
51static inline struct key *get_ima_mok_keyring(void)
52{
53 return NULL;
54}
55static inline struct key *get_ima_blacklist_keyring(void) 44static inline struct key *get_ima_blacklist_keyring(void)
56{ 45{
57 return NULL; 46 return NULL;
58} 47}
59#endif /* CONFIG_IMA_MOK_KEYRING */ 48#endif /* CONFIG_IMA_BLACKLIST_KEYRING */
60 49
61 50
62#endif /* _KEYS_SYSTEM_KEYRING_H */ 51#endif /* _KEYS_SYSTEM_KEYRING_H */
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 851390c8d75b..10d3d8f8a65b 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2634,15 +2634,34 @@ static inline void i_readcount_inc(struct inode *inode)
2634#endif 2634#endif
2635extern int do_pipe_flags(int *, int); 2635extern int do_pipe_flags(int *, int);
2636 2636
2637#define __kernel_read_file_id(id) \
2638 id(UNKNOWN, unknown) \
2639 id(FIRMWARE, firmware) \
2640 id(MODULE, kernel-module) \
2641 id(KEXEC_IMAGE, kexec-image) \
2642 id(KEXEC_INITRAMFS, kexec-initramfs) \
2643 id(POLICY, security-policy) \
2644 id(MAX_ID, )
2645
2646#define __fid_enumify(ENUM, dummy) READING_ ## ENUM,
2647#define __fid_stringify(dummy, str) #str,
2648
2637enum kernel_read_file_id { 2649enum kernel_read_file_id {
2638 READING_FIRMWARE = 1, 2650 __kernel_read_file_id(__fid_enumify)
2639 READING_MODULE, 2651};
2640 READING_KEXEC_IMAGE, 2652
2641 READING_KEXEC_INITRAMFS, 2653static const char * const kernel_read_file_str[] = {
2642 READING_POLICY, 2654 __kernel_read_file_id(__fid_stringify)
2643 READING_MAX_ID
2644}; 2655};
2645 2656
2657static inline const char *kernel_read_file_id_str(enum kernel_read_file_id id)
2658{
2659 if (id < 0 || id >= READING_MAX_ID)
2660 return kernel_read_file_str[READING_UNKNOWN];
2661
2662 return kernel_read_file_str[id];
2663}
2664
2646extern int kernel_read(struct file *, loff_t, char *, unsigned long); 2665extern int kernel_read(struct file *, loff_t, char *, unsigned long);
2647extern int kernel_read_file(struct file *, void **, loff_t *, loff_t, 2666extern int kernel_read_file(struct file *, void **, loff_t *, loff_t,
2648 enum kernel_read_file_id); 2667 enum kernel_read_file_id);
diff --git a/include/linux/ima.h b/include/linux/ima.h
index e6516cbbe9bf..0eb7c2e7f0d6 100644
--- a/include/linux/ima.h
+++ b/include/linux/ima.h
@@ -21,6 +21,7 @@ extern int ima_file_mmap(struct file *file, unsigned long prot);
21extern int ima_read_file(struct file *file, enum kernel_read_file_id id); 21extern int ima_read_file(struct file *file, enum kernel_read_file_id id);
22extern int ima_post_read_file(struct file *file, void *buf, loff_t size, 22extern int ima_post_read_file(struct file *file, void *buf, loff_t size,
23 enum kernel_read_file_id id); 23 enum kernel_read_file_id id);
24extern void ima_post_path_mknod(struct dentry *dentry);
24 25
25#else 26#else
26static inline int ima_bprm_check(struct linux_binprm *bprm) 27static inline int ima_bprm_check(struct linux_binprm *bprm)
@@ -54,6 +55,11 @@ static inline int ima_post_read_file(struct file *file, void *buf, loff_t size,
54 return 0; 55 return 0;
55} 56}
56 57
58static inline void ima_post_path_mknod(struct dentry *dentry)
59{
60 return;
61}
62
57#endif /* CONFIG_IMA */ 63#endif /* CONFIG_IMA */
58 64
59#ifdef CONFIG_IMA_APPRAISE 65#ifdef CONFIG_IMA_APPRAISE
diff --git a/include/linux/key-type.h b/include/linux/key-type.h
index 7463355a198b..eaee981c5558 100644
--- a/include/linux/key-type.h
+++ b/include/linux/key-type.h
@@ -45,7 +45,6 @@ struct key_preparsed_payload {
45 size_t datalen; /* Raw datalen */ 45 size_t datalen; /* Raw datalen */
46 size_t quotalen; /* Quota length for proposed payload */ 46 size_t quotalen; /* Quota length for proposed payload */
47 time_t expiry; /* Expiry time of key */ 47 time_t expiry; /* Expiry time of key */
48 bool trusted; /* True if key is trusted */
49}; 48};
50 49
51typedef int (*request_key_actor_t)(struct key_construction *key, 50typedef int (*request_key_actor_t)(struct key_construction *key,
diff --git a/include/linux/key.h b/include/linux/key.h
index 5f5b1129dc92..722914798f37 100644
--- a/include/linux/key.h
+++ b/include/linux/key.h
@@ -173,11 +173,9 @@ struct key {
173#define KEY_FLAG_NEGATIVE 5 /* set if key is negative */ 173#define KEY_FLAG_NEGATIVE 5 /* set if key is negative */
174#define KEY_FLAG_ROOT_CAN_CLEAR 6 /* set if key can be cleared by root without permission */ 174#define KEY_FLAG_ROOT_CAN_CLEAR 6 /* set if key can be cleared by root without permission */
175#define KEY_FLAG_INVALIDATED 7 /* set if key has been invalidated */ 175#define KEY_FLAG_INVALIDATED 7 /* set if key has been invalidated */
176#define KEY_FLAG_TRUSTED 8 /* set if key is trusted */ 176#define KEY_FLAG_BUILTIN 8 /* set if key is built in to the kernel */
177#define KEY_FLAG_TRUSTED_ONLY 9 /* set if keyring only accepts links to trusted keys */ 177#define KEY_FLAG_ROOT_CAN_INVAL 9 /* set if key can be invalidated by root without permission */
178#define KEY_FLAG_BUILTIN 10 /* set if key is builtin */ 178#define KEY_FLAG_KEEP 10 /* set if key should not be removed */
179#define KEY_FLAG_ROOT_CAN_INVAL 11 /* set if key can be invalidated by root without permission */
180#define KEY_FLAG_KEEP 12 /* set if key should not be removed */
181 179
182 /* the key type and key description string 180 /* the key type and key description string
183 * - the desc is used to match a key against search criteria 181 * - the desc is used to match a key against search criteria
@@ -205,6 +203,20 @@ struct key {
205 }; 203 };
206 int reject_error; 204 int reject_error;
207 }; 205 };
206
207 /* This is set on a keyring to restrict the addition of a link to a key
208 * to it. If this method isn't provided then it is assumed that the
209 * keyring is open to any addition. It is ignored for non-keyring
210 * keys.
211 *
212 * This is intended for use with rings of trusted keys whereby addition
213 * to the keyring needs to be controlled. KEY_ALLOC_BYPASS_RESTRICTION
214 * overrides this, allowing the kernel to add extra keys without
215 * restriction.
216 */
217 int (*restrict_link)(struct key *keyring,
218 const struct key_type *type,
219 const union key_payload *payload);
208}; 220};
209 221
210extern struct key *key_alloc(struct key_type *type, 222extern struct key *key_alloc(struct key_type *type,
@@ -212,14 +224,17 @@ extern struct key *key_alloc(struct key_type *type,
212 kuid_t uid, kgid_t gid, 224 kuid_t uid, kgid_t gid,
213 const struct cred *cred, 225 const struct cred *cred,
214 key_perm_t perm, 226 key_perm_t perm,
215 unsigned long flags); 227 unsigned long flags,
228 int (*restrict_link)(struct key *,
229 const struct key_type *,
230 const union key_payload *));
216 231
217 232
218#define KEY_ALLOC_IN_QUOTA 0x0000 /* add to quota, reject if would overrun */ 233#define KEY_ALLOC_IN_QUOTA 0x0000 /* add to quota, reject if would overrun */
219#define KEY_ALLOC_QUOTA_OVERRUN 0x0001 /* add to quota, permit even if overrun */ 234#define KEY_ALLOC_QUOTA_OVERRUN 0x0001 /* add to quota, permit even if overrun */
220#define KEY_ALLOC_NOT_IN_QUOTA 0x0002 /* not in quota */ 235#define KEY_ALLOC_NOT_IN_QUOTA 0x0002 /* not in quota */
221#define KEY_ALLOC_TRUSTED 0x0004 /* Key should be flagged as trusted */ 236#define KEY_ALLOC_BUILT_IN 0x0004 /* Key is built into kernel */
222#define KEY_ALLOC_BUILT_IN 0x0008 /* Key is built into kernel */ 237#define KEY_ALLOC_BYPASS_RESTRICTION 0x0008 /* Override the check on restricted keyrings */
223 238
224extern void key_revoke(struct key *key); 239extern void key_revoke(struct key *key);
225extern void key_invalidate(struct key *key); 240extern void key_invalidate(struct key *key);
@@ -288,8 +303,15 @@ extern struct key *keyring_alloc(const char *description, kuid_t uid, kgid_t gid
288 const struct cred *cred, 303 const struct cred *cred,
289 key_perm_t perm, 304 key_perm_t perm,
290 unsigned long flags, 305 unsigned long flags,
306 int (*restrict_link)(struct key *,
307 const struct key_type *,
308 const union key_payload *),
291 struct key *dest); 309 struct key *dest);
292 310
311extern int restrict_link_reject(struct key *keyring,
312 const struct key_type *type,
313 const union key_payload *payload);
314
293extern int keyring_clear(struct key *keyring); 315extern int keyring_clear(struct key *keyring);
294 316
295extern key_ref_t keyring_search(key_ref_t keyring, 317extern key_ref_t keyring_search(key_ref_t keyring,
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 512fd000562b..7ae397669d8b 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -1805,7 +1805,6 @@ struct security_hook_heads {
1805 struct list_head tun_dev_attach_queue; 1805 struct list_head tun_dev_attach_queue;
1806 struct list_head tun_dev_attach; 1806 struct list_head tun_dev_attach;
1807 struct list_head tun_dev_open; 1807 struct list_head tun_dev_open;
1808 struct list_head skb_owned_by;
1809#endif /* CONFIG_SECURITY_NETWORK */ 1808#endif /* CONFIG_SECURITY_NETWORK */
1810#ifdef CONFIG_SECURITY_NETWORK_XFRM 1809#ifdef CONFIG_SECURITY_NETWORK_XFRM
1811 struct list_head xfrm_policy_alloc_security; 1810 struct list_head xfrm_policy_alloc_security;
@@ -1894,5 +1893,10 @@ extern void __init yama_add_hooks(void);
1894#else 1893#else
1895static inline void __init yama_add_hooks(void) { } 1894static inline void __init yama_add_hooks(void) { }
1896#endif 1895#endif
1896#ifdef CONFIG_SECURITY_LOADPIN
1897void __init loadpin_add_hooks(void);
1898#else
1899static inline void loadpin_add_hooks(void) { };
1900#endif
1897 1901
1898#endif /* ! __LINUX_LSM_HOOKS_H */ 1902#endif /* ! __LINUX_LSM_HOOKS_H */
diff --git a/include/linux/string_helpers.h b/include/linux/string_helpers.h
index dabe643eb5fa..5ce9538f290e 100644
--- a/include/linux/string_helpers.h
+++ b/include/linux/string_helpers.h
@@ -3,6 +3,8 @@
3 3
4#include <linux/types.h> 4#include <linux/types.h>
5 5
6struct file;
7
6/* Descriptions of the types of units to 8/* Descriptions of the types of units to
7 * print in */ 9 * print in */
8enum string_size_units { 10enum string_size_units {
@@ -68,4 +70,8 @@ static inline int string_escape_str_any_np(const char *src, char *dst,
68 return string_escape_str(src, dst, sz, ESCAPE_ANY_NP, only); 70 return string_escape_str(src, dst, sz, ESCAPE_ANY_NP, only);
69} 71}
70 72
73char *kstrdup_quotable(const char *src, gfp_t gfp);
74char *kstrdup_quotable_cmdline(struct task_struct *task, gfp_t gfp);
75char *kstrdup_quotable_file(struct file *file, gfp_t gfp);
76
71#endif 77#endif
diff --git a/include/linux/verification.h b/include/linux/verification.h
new file mode 100644
index 000000000000..a10549a6c7cd
--- /dev/null
+++ b/include/linux/verification.h
@@ -0,0 +1,49 @@
1/* Signature verification
2 *
3 * Copyright (C) 2014 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public Licence
8 * as published by the Free Software Foundation; either version
9 * 2 of the Licence, or (at your option) any later version.
10 */
11
12#ifndef _LINUX_VERIFICATION_H
13#define _LINUX_VERIFICATION_H
14
15/*
16 * The use to which an asymmetric key is being put.
17 */
18enum key_being_used_for {
19 VERIFYING_MODULE_SIGNATURE,
20 VERIFYING_FIRMWARE_SIGNATURE,
21 VERIFYING_KEXEC_PE_SIGNATURE,
22 VERIFYING_KEY_SIGNATURE,
23 VERIFYING_KEY_SELF_SIGNATURE,
24 VERIFYING_UNSPECIFIED_SIGNATURE,
25 NR__KEY_BEING_USED_FOR
26};
27extern const char *const key_being_used_for[NR__KEY_BEING_USED_FOR];
28
29#ifdef CONFIG_SYSTEM_DATA_VERIFICATION
30
31struct key;
32
33extern int verify_pkcs7_signature(const void *data, size_t len,
34 const void *raw_pkcs7, size_t pkcs7_len,
35 struct key *trusted_keys,
36 enum key_being_used_for usage,
37 int (*view_content)(void *ctx,
38 const void *data, size_t len,
39 size_t asn1hdrlen),
40 void *ctx);
41
42#ifdef CONFIG_SIGNED_PE_FILE_VERIFICATION
43extern int verify_pefile_signature(const void *pebuf, unsigned pelen,
44 struct key *trusted_keys,
45 enum key_being_used_for usage);
46#endif
47
48#endif /* CONFIG_SYSTEM_DATA_VERIFICATION */
49#endif /* _LINUX_VERIFY_PEFILE_H */
diff --git a/include/linux/verify_pefile.h b/include/linux/verify_pefile.h
deleted file mode 100644
index da2049b5161c..000000000000
--- a/include/linux/verify_pefile.h
+++ /dev/null
@@ -1,22 +0,0 @@
1/* Signed PE file verification
2 *
3 * Copyright (C) 2014 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public Licence
8 * as published by the Free Software Foundation; either version
9 * 2 of the Licence, or (at your option) any later version.
10 */
11
12#ifndef _LINUX_VERIFY_PEFILE_H
13#define _LINUX_VERIFY_PEFILE_H
14
15#include <crypto/public_key.h>
16
17extern int verify_pefile_signature(const void *pebuf, unsigned pelen,
18 struct key *trusted_keyring,
19 enum key_being_used_for usage,
20 bool *_trusted);
21
22#endif /* _LINUX_VERIFY_PEFILE_H */
diff --git a/include/uapi/linux/keyctl.h b/include/uapi/linux/keyctl.h
index 840cb990abe2..86eddd6241f3 100644
--- a/include/uapi/linux/keyctl.h
+++ b/include/uapi/linux/keyctl.h
@@ -12,6 +12,8 @@
12#ifndef _LINUX_KEYCTL_H 12#ifndef _LINUX_KEYCTL_H
13#define _LINUX_KEYCTL_H 13#define _LINUX_KEYCTL_H
14 14
15#include <linux/types.h>
16
15/* special process keyring shortcut IDs */ 17/* special process keyring shortcut IDs */
16#define KEY_SPEC_THREAD_KEYRING -1 /* - key ID for thread-specific keyring */ 18#define KEY_SPEC_THREAD_KEYRING -1 /* - key ID for thread-specific keyring */
17#define KEY_SPEC_PROCESS_KEYRING -2 /* - key ID for process-specific keyring */ 19#define KEY_SPEC_PROCESS_KEYRING -2 /* - key ID for process-specific keyring */
@@ -57,5 +59,13 @@
57#define KEYCTL_INSTANTIATE_IOV 20 /* instantiate a partially constructed key */ 59#define KEYCTL_INSTANTIATE_IOV 20 /* instantiate a partially constructed key */
58#define KEYCTL_INVALIDATE 21 /* invalidate a key */ 60#define KEYCTL_INVALIDATE 21 /* invalidate a key */
59#define KEYCTL_GET_PERSISTENT 22 /* get a user's persistent keyring */ 61#define KEYCTL_GET_PERSISTENT 22 /* get a user's persistent keyring */
62#define KEYCTL_DH_COMPUTE 23 /* Compute Diffie-Hellman values */
63
64/* keyctl structures */
65struct keyctl_dh_params {
66 __s32 private;
67 __s32 prime;
68 __s32 base;
69};
60 70
61#endif /* _LINUX_KEYCTL_H */ 71#endif /* _LINUX_KEYCTL_H */
diff --git a/kernel/module_signing.c b/kernel/module_signing.c
index 64b9dead4a07..937c844bee4a 100644
--- a/kernel/module_signing.c
+++ b/kernel/module_signing.c
@@ -12,7 +12,7 @@
12#include <linux/kernel.h> 12#include <linux/kernel.h>
13#include <linux/errno.h> 13#include <linux/errno.h>
14#include <linux/string.h> 14#include <linux/string.h>
15#include <keys/system_keyring.h> 15#include <linux/verification.h>
16#include <crypto/public_key.h> 16#include <crypto/public_key.h>
17#include "module-internal.h" 17#include "module-internal.h"
18 18
@@ -80,6 +80,7 @@ int mod_verify_sig(const void *mod, unsigned long *_modlen)
80 return -EBADMSG; 80 return -EBADMSG;
81 } 81 }
82 82
83 return system_verify_data(mod, modlen, mod + modlen, sig_len, 83 return verify_pkcs7_signature(mod, modlen, mod + modlen, sig_len,
84 VERIFYING_MODULE_SIGNATURE); 84 NULL, VERIFYING_MODULE_SIGNATURE,
85 NULL, NULL);
85} 86}
diff --git a/kernel/seccomp.c b/kernel/seccomp.c
index e1e5a354854e..6c9bb62ed046 100644
--- a/kernel/seccomp.c
+++ b/kernel/seccomp.c
@@ -915,7 +915,7 @@ long seccomp_get_filter(struct task_struct *task, unsigned long filter_off,
915 915
916 fprog = filter->prog->orig_prog; 916 fprog = filter->prog->orig_prog;
917 if (!fprog) { 917 if (!fprog) {
918 /* This must be a new non-cBPF filter, since we save every 918 /* This must be a new non-cBPF filter, since we save
919 * every cBPF filter's orig_prog above when 919 * every cBPF filter's orig_prog above when
920 * CONFIG_CHECKPOINT_RESTORE is enabled. 920 * CONFIG_CHECKPOINT_RESTORE is enabled.
921 */ 921 */
diff --git a/lib/string_helpers.c b/lib/string_helpers.c
index 5c88204b6f1f..ecaac2c0526f 100644
--- a/lib/string_helpers.c
+++ b/lib/string_helpers.c
@@ -10,6 +10,10 @@
10#include <linux/export.h> 10#include <linux/export.h>
11#include <linux/ctype.h> 11#include <linux/ctype.h>
12#include <linux/errno.h> 12#include <linux/errno.h>
13#include <linux/fs.h>
14#include <linux/limits.h>
15#include <linux/mm.h>
16#include <linux/slab.h>
13#include <linux/string.h> 17#include <linux/string.h>
14#include <linux/string_helpers.h> 18#include <linux/string_helpers.h>
15 19
@@ -534,3 +538,91 @@ int string_escape_mem(const char *src, size_t isz, char *dst, size_t osz,
534 return p - dst; 538 return p - dst;
535} 539}
536EXPORT_SYMBOL(string_escape_mem); 540EXPORT_SYMBOL(string_escape_mem);
541
542/*
543 * Return an allocated string that has been escaped of special characters
544 * and double quotes, making it safe to log in quotes.
545 */
546char *kstrdup_quotable(const char *src, gfp_t gfp)
547{
548 size_t slen, dlen;
549 char *dst;
550 const int flags = ESCAPE_HEX;
551 const char esc[] = "\f\n\r\t\v\a\e\\\"";
552
553 if (!src)
554 return NULL;
555 slen = strlen(src);
556
557 dlen = string_escape_mem(src, slen, NULL, 0, flags, esc);
558 dst = kmalloc(dlen + 1, gfp);
559 if (!dst)
560 return NULL;
561
562 WARN_ON(string_escape_mem(src, slen, dst, dlen, flags, esc) != dlen);
563 dst[dlen] = '\0';
564
565 return dst;
566}
567EXPORT_SYMBOL_GPL(kstrdup_quotable);
568
569/*
570 * Returns allocated NULL-terminated string containing process
571 * command line, with inter-argument NULLs replaced with spaces,
572 * and other special characters escaped.
573 */
574char *kstrdup_quotable_cmdline(struct task_struct *task, gfp_t gfp)
575{
576 char *buffer, *quoted;
577 int i, res;
578
579 buffer = kmalloc(PAGE_SIZE, GFP_TEMPORARY);
580 if (!buffer)
581 return NULL;
582
583 res = get_cmdline(task, buffer, PAGE_SIZE - 1);
584 buffer[res] = '\0';
585
586 /* Collapse trailing NULLs, leave res pointing to last non-NULL. */
587 while (--res >= 0 && buffer[res] == '\0')
588 ;
589
590 /* Replace inter-argument NULLs. */
591 for (i = 0; i <= res; i++)
592 if (buffer[i] == '\0')
593 buffer[i] = ' ';
594
595 /* Make sure result is printable. */
596 quoted = kstrdup_quotable(buffer, gfp);
597 kfree(buffer);
598 return quoted;
599}
600EXPORT_SYMBOL_GPL(kstrdup_quotable_cmdline);
601
602/*
603 * Returns allocated NULL-terminated string containing pathname,
604 * with special characters escaped, able to be safely logged. If
605 * there is an error, the leading character will be "<".
606 */
607char *kstrdup_quotable_file(struct file *file, gfp_t gfp)
608{
609 char *temp, *pathname;
610
611 if (!file)
612 return kstrdup("<unknown>", gfp);
613
614 /* We add 11 spaces for ' (deleted)' to be appended */
615 temp = kmalloc(PATH_MAX + 11, GFP_TEMPORARY);
616 if (!temp)
617 return kstrdup("<no_memory>", gfp);
618
619 pathname = file_path(file, temp, PATH_MAX + 11);
620 if (IS_ERR(pathname))
621 pathname = kstrdup("<too_long>", gfp);
622 else
623 pathname = kstrdup_quotable(pathname, gfp);
624
625 kfree(temp);
626 return pathname;
627}
628EXPORT_SYMBOL_GPL(kstrdup_quotable_file);
diff --git a/net/dns_resolver/dns_key.c b/net/dns_resolver/dns_key.c
index c79b85eb4d4c..8737412c7b27 100644
--- a/net/dns_resolver/dns_key.c
+++ b/net/dns_resolver/dns_key.c
@@ -281,7 +281,7 @@ static int __init init_dns_resolver(void)
281 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred, 281 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred,
282 (KEY_POS_ALL & ~KEY_POS_SETATTR) | 282 (KEY_POS_ALL & ~KEY_POS_SETATTR) |
283 KEY_USR_VIEW | KEY_USR_READ, 283 KEY_USR_VIEW | KEY_USR_READ,
284 KEY_ALLOC_NOT_IN_QUOTA, NULL); 284 KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL);
285 if (IS_ERR(keyring)) { 285 if (IS_ERR(keyring)) {
286 ret = PTR_ERR(keyring); 286 ret = PTR_ERR(keyring);
287 goto failed_put_cred; 287 goto failed_put_cred;
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c
index 28cddc85b700..1325776daa27 100644
--- a/net/netlabel/netlabel_kapi.c
+++ b/net/netlabel/netlabel_kapi.c
@@ -677,7 +677,7 @@ int netlbl_catmap_setrng(struct netlbl_lsm_catmap **catmap,
677 u32 spot = start; 677 u32 spot = start;
678 678
679 while (rc == 0 && spot <= end) { 679 while (rc == 0 && spot <= end) {
680 if (((spot & (BITS_PER_LONG - 1)) != 0) && 680 if (((spot & (BITS_PER_LONG - 1)) == 0) &&
681 ((end - spot) > BITS_PER_LONG)) { 681 ((end - spot) > BITS_PER_LONG)) {
682 rc = netlbl_catmap_setlong(catmap, 682 rc = netlbl_catmap_setlong(catmap,
683 spot, 683 spot,
diff --git a/net/rxrpc/ar-key.c b/net/rxrpc/ar-key.c
index 3fb492eedeb9..1021b4c0bdd2 100644
--- a/net/rxrpc/ar-key.c
+++ b/net/rxrpc/ar-key.c
@@ -965,7 +965,7 @@ int rxrpc_get_server_data_key(struct rxrpc_connection *conn,
965 965
966 key = key_alloc(&key_type_rxrpc, "x", 966 key = key_alloc(&key_type_rxrpc, "x",
967 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred, 0, 967 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred, 0,
968 KEY_ALLOC_NOT_IN_QUOTA); 968 KEY_ALLOC_NOT_IN_QUOTA, NULL);
969 if (IS_ERR(key)) { 969 if (IS_ERR(key)) {
970 _leave(" = -ENOMEM [alloc %ld]", PTR_ERR(key)); 970 _leave(" = -ENOMEM [alloc %ld]", PTR_ERR(key));
971 return -ENOMEM; 971 return -ENOMEM;
@@ -1012,7 +1012,7 @@ struct key *rxrpc_get_null_key(const char *keyname)
1012 1012
1013 key = key_alloc(&key_type_rxrpc, keyname, 1013 key = key_alloc(&key_type_rxrpc, keyname,
1014 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred, 1014 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred,
1015 KEY_POS_SEARCH, KEY_ALLOC_NOT_IN_QUOTA); 1015 KEY_POS_SEARCH, KEY_ALLOC_NOT_IN_QUOTA, NULL);
1016 if (IS_ERR(key)) 1016 if (IS_ERR(key))
1017 return key; 1017 return key;
1018 1018
diff --git a/security/Kconfig b/security/Kconfig
index e45237897b43..176758cdfa57 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -122,6 +122,7 @@ source security/selinux/Kconfig
122source security/smack/Kconfig 122source security/smack/Kconfig
123source security/tomoyo/Kconfig 123source security/tomoyo/Kconfig
124source security/apparmor/Kconfig 124source security/apparmor/Kconfig
125source security/loadpin/Kconfig
125source security/yama/Kconfig 126source security/yama/Kconfig
126 127
127source security/integrity/Kconfig 128source security/integrity/Kconfig
diff --git a/security/Makefile b/security/Makefile
index c9bfbc84ff50..f2d71cdb8e19 100644
--- a/security/Makefile
+++ b/security/Makefile
@@ -8,6 +8,7 @@ subdir-$(CONFIG_SECURITY_SMACK) += smack
8subdir-$(CONFIG_SECURITY_TOMOYO) += tomoyo 8subdir-$(CONFIG_SECURITY_TOMOYO) += tomoyo
9subdir-$(CONFIG_SECURITY_APPARMOR) += apparmor 9subdir-$(CONFIG_SECURITY_APPARMOR) += apparmor
10subdir-$(CONFIG_SECURITY_YAMA) += yama 10subdir-$(CONFIG_SECURITY_YAMA) += yama
11subdir-$(CONFIG_SECURITY_LOADPIN) += loadpin
11 12
12# always enable default capabilities 13# always enable default capabilities
13obj-y += commoncap.o 14obj-y += commoncap.o
@@ -22,6 +23,7 @@ obj-$(CONFIG_AUDIT) += lsm_audit.o
22obj-$(CONFIG_SECURITY_TOMOYO) += tomoyo/ 23obj-$(CONFIG_SECURITY_TOMOYO) += tomoyo/
23obj-$(CONFIG_SECURITY_APPARMOR) += apparmor/ 24obj-$(CONFIG_SECURITY_APPARMOR) += apparmor/
24obj-$(CONFIG_SECURITY_YAMA) += yama/ 25obj-$(CONFIG_SECURITY_YAMA) += yama/
26obj-$(CONFIG_SECURITY_LOADPIN) += loadpin/
25obj-$(CONFIG_CGROUP_DEVICE) += device_cgroup.o 27obj-$(CONFIG_CGROUP_DEVICE) += device_cgroup.o
26 28
27# Object integrity file lists 29# Object integrity file lists
diff --git a/security/integrity/Kconfig b/security/integrity/Kconfig
index 979be65d22c4..da9565891738 100644
--- a/security/integrity/Kconfig
+++ b/security/integrity/Kconfig
@@ -35,7 +35,6 @@ config INTEGRITY_ASYMMETRIC_KEYS
35 default n 35 default n
36 select ASYMMETRIC_KEY_TYPE 36 select ASYMMETRIC_KEY_TYPE
37 select ASYMMETRIC_PUBLIC_KEY_SUBTYPE 37 select ASYMMETRIC_PUBLIC_KEY_SUBTYPE
38 select PUBLIC_KEY_ALGO_RSA
39 select CRYPTO_RSA 38 select CRYPTO_RSA
40 select X509_CERTIFICATE_PARSER 39 select X509_CERTIFICATE_PARSER
41 help 40 help
diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c
index 8ef15118cc78..4304372b323f 100644
--- a/security/integrity/digsig.c
+++ b/security/integrity/digsig.c
@@ -18,6 +18,8 @@
18#include <linux/cred.h> 18#include <linux/cred.h>
19#include <linux/key-type.h> 19#include <linux/key-type.h>
20#include <linux/digsig.h> 20#include <linux/digsig.h>
21#include <crypto/public_key.h>
22#include <keys/system_keyring.h>
21 23
22#include "integrity.h" 24#include "integrity.h"
23 25
@@ -40,6 +42,12 @@ static bool init_keyring __initdata = true;
40static bool init_keyring __initdata; 42static bool init_keyring __initdata;
41#endif 43#endif
42 44
45#ifdef CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY
46#define restrict_link_to_ima restrict_link_by_builtin_and_secondary_trusted
47#else
48#define restrict_link_to_ima restrict_link_by_builtin_trusted
49#endif
50
43int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen, 51int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
44 const char *digest, int digestlen) 52 const char *digest, int digestlen)
45{ 53{
@@ -83,10 +91,9 @@ int __init integrity_init_keyring(const unsigned int id)
83 ((KEY_POS_ALL & ~KEY_POS_SETATTR) | 91 ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
84 KEY_USR_VIEW | KEY_USR_READ | 92 KEY_USR_VIEW | KEY_USR_READ |
85 KEY_USR_WRITE | KEY_USR_SEARCH), 93 KEY_USR_WRITE | KEY_USR_SEARCH),
86 KEY_ALLOC_NOT_IN_QUOTA, NULL); 94 KEY_ALLOC_NOT_IN_QUOTA,
87 if (!IS_ERR(keyring[id])) 95 restrict_link_to_ima, NULL);
88 set_bit(KEY_FLAG_TRUSTED_ONLY, &keyring[id]->flags); 96 if (IS_ERR(keyring[id])) {
89 else {
90 err = PTR_ERR(keyring[id]); 97 err = PTR_ERR(keyring[id]);
91 pr_info("Can't allocate %s keyring (%d)\n", 98 pr_info("Can't allocate %s keyring (%d)\n",
92 keyring_name[id], err); 99 keyring_name[id], err);
diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
index e54a8a8dae94..5487827fa86c 100644
--- a/security/integrity/ima/Kconfig
+++ b/security/integrity/ima/Kconfig
@@ -155,23 +155,33 @@ config IMA_TRUSTED_KEYRING
155 155
156 This option is deprecated in favor of INTEGRITY_TRUSTED_KEYRING 156 This option is deprecated in favor of INTEGRITY_TRUSTED_KEYRING
157 157
158config IMA_MOK_KEYRING 158config IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY
159 bool "Create IMA machine owner keys (MOK) and blacklist keyrings" 159 bool "Permit keys validly signed by a built-in or secondary CA cert (EXPERIMENTAL)"
160 depends on SYSTEM_TRUSTED_KEYRING
161 depends on SECONDARY_TRUSTED_KEYRING
162 depends on INTEGRITY_ASYMMETRIC_KEYS
163 select INTEGRITY_TRUSTED_KEYRING
164 default n
165 help
166 Keys may be added to the IMA or IMA blacklist keyrings, if the
167 key is validly signed by a CA cert in the system built-in or
168 secondary trusted keyrings.
169
170 Intermediate keys between those the kernel has compiled in and the
171 IMA keys to be added may be added to the system secondary keyring,
172 provided they are validly signed by a key already resident in the
173 built-in or secondary trusted keyrings.
174
175config IMA_BLACKLIST_KEYRING
176 bool "Create IMA machine owner blacklist keyrings (EXPERIMENTAL)"
160 depends on SYSTEM_TRUSTED_KEYRING 177 depends on SYSTEM_TRUSTED_KEYRING
161 depends on IMA_TRUSTED_KEYRING 178 depends on IMA_TRUSTED_KEYRING
162 default n 179 default n
163 help 180 help
164 This option creates IMA MOK and blacklist keyrings. IMA MOK is an 181 This option creates an IMA blacklist keyring, which contains all
165 intermediate keyring that sits between .system and .ima keyrings, 182 revoked IMA keys. It is consulted before any other keyring. If
166 effectively forming a simple CA hierarchy. To successfully import a 183 the search is successful the requested operation is rejected and
167 key into .ima_mok it must be signed by a key which CA is in .system 184 an error is returned to the caller.
168 keyring. On turn any key that needs to go in .ima keyring must be
169 signed by CA in either .system or .ima_mok keyrings. IMA MOK is empty
170 at kernel boot.
171
172 IMA blacklist keyring contains all revoked IMA keys. It is consulted
173 before any other keyring. If the search is successful the requested
174 operation is rejected and error is returned to the caller.
175 185
176config IMA_LOAD_X509 186config IMA_LOAD_X509
177 bool "Load X509 certificate onto the '.ima' trusted keyring" 187 bool "Load X509 certificate onto the '.ima' trusted keyring"
diff --git a/security/integrity/ima/Makefile b/security/integrity/ima/Makefile
index a8539f9e060f..9aeaedad1e2b 100644
--- a/security/integrity/ima/Makefile
+++ b/security/integrity/ima/Makefile
@@ -8,4 +8,4 @@ obj-$(CONFIG_IMA) += ima.o
8ima-y := ima_fs.o ima_queue.o ima_init.o ima_main.o ima_crypto.o ima_api.o \ 8ima-y := ima_fs.o ima_queue.o ima_init.o ima_main.o ima_crypto.o ima_api.o \
9 ima_policy.o ima_template.o ima_template_lib.o 9 ima_policy.o ima_template.o ima_template_lib.o
10ima-$(CONFIG_IMA_APPRAISE) += ima_appraise.o 10ima-$(CONFIG_IMA_APPRAISE) += ima_appraise.o
11obj-$(CONFIG_IMA_MOK_KEYRING) += ima_mok.o 11obj-$(CONFIG_IMA_BLACKLIST_KEYRING) += ima_mok.o
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
index 6b4694aedae8..1bcbc12e03d9 100644
--- a/security/integrity/ima/ima_appraise.c
+++ b/security/integrity/ima/ima_appraise.c
@@ -275,6 +275,11 @@ out:
275 xattr_value->type != EVM_IMA_XATTR_DIGSIG)) { 275 xattr_value->type != EVM_IMA_XATTR_DIGSIG)) {
276 if (!ima_fix_xattr(dentry, iint)) 276 if (!ima_fix_xattr(dentry, iint))
277 status = INTEGRITY_PASS; 277 status = INTEGRITY_PASS;
278 } else if ((inode->i_size == 0) &&
279 (iint->flags & IMA_NEW_FILE) &&
280 (xattr_value &&
281 xattr_value->type == EVM_IMA_XATTR_DIGSIG)) {
282 status = INTEGRITY_PASS;
278 } 283 }
279 integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode, filename, 284 integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode, filename,
280 op, cause, rc, 0); 285 op, cause, rc, 0);
@@ -328,7 +333,7 @@ void ima_inode_post_setattr(struct dentry *dentry)
328 if (iint) { 333 if (iint) {
329 iint->flags &= ~(IMA_APPRAISE | IMA_APPRAISED | 334 iint->flags &= ~(IMA_APPRAISE | IMA_APPRAISED |
330 IMA_APPRAISE_SUBMASK | IMA_APPRAISED_SUBMASK | 335 IMA_APPRAISE_SUBMASK | IMA_APPRAISED_SUBMASK |
331 IMA_ACTION_FLAGS); 336 IMA_ACTION_RULE_FLAGS);
332 if (must_appraise) 337 if (must_appraise)
333 iint->flags |= IMA_APPRAISE; 338 iint->flags |= IMA_APPRAISE;
334 } 339 }
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 391f41751021..68b26c340acd 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -246,7 +246,8 @@ static int process_measurement(struct file *file, char *buf, loff_t size,
246 ima_audit_measurement(iint, pathname); 246 ima_audit_measurement(iint, pathname);
247 247
248out_digsig: 248out_digsig:
249 if ((mask & MAY_WRITE) && (iint->flags & IMA_DIGSIG)) 249 if ((mask & MAY_WRITE) && (iint->flags & IMA_DIGSIG) &&
250 !(iint->flags & IMA_NEW_FILE))
250 rc = -EACCES; 251 rc = -EACCES;
251 kfree(xattr_value); 252 kfree(xattr_value);
252out_free: 253out_free:
@@ -316,6 +317,28 @@ int ima_file_check(struct file *file, int mask, int opened)
316EXPORT_SYMBOL_GPL(ima_file_check); 317EXPORT_SYMBOL_GPL(ima_file_check);
317 318
318/** 319/**
320 * ima_post_path_mknod - mark as a new inode
321 * @dentry: newly created dentry
322 *
323 * Mark files created via the mknodat syscall as new, so that the
324 * file data can be written later.
325 */
326void ima_post_path_mknod(struct dentry *dentry)
327{
328 struct integrity_iint_cache *iint;
329 struct inode *inode = dentry->d_inode;
330 int must_appraise;
331
332 must_appraise = ima_must_appraise(inode, MAY_ACCESS, FILE_CHECK);
333 if (!must_appraise)
334 return;
335
336 iint = integrity_inode_get(inode);
337 if (iint)
338 iint->flags |= IMA_NEW_FILE;
339}
340
341/**
319 * ima_read_file - pre-measure/appraise hook decision based on policy 342 * ima_read_file - pre-measure/appraise hook decision based on policy
320 * @file: pointer to the file to be measured/appraised/audit 343 * @file: pointer to the file to be measured/appraised/audit
321 * @read_id: caller identifier 344 * @read_id: caller identifier
diff --git a/security/integrity/ima/ima_mok.c b/security/integrity/ima/ima_mok.c
index 676885e4320e..74a279957464 100644
--- a/security/integrity/ima/ima_mok.c
+++ b/security/integrity/ima/ima_mok.c
@@ -17,38 +17,29 @@
17#include <linux/cred.h> 17#include <linux/cred.h>
18#include <linux/err.h> 18#include <linux/err.h>
19#include <linux/init.h> 19#include <linux/init.h>
20#include <keys/asymmetric-type.h> 20#include <keys/system_keyring.h>
21 21
22 22
23struct key *ima_mok_keyring;
24struct key *ima_blacklist_keyring; 23struct key *ima_blacklist_keyring;
25 24
26/* 25/*
27 * Allocate the IMA MOK and blacklist keyrings 26 * Allocate the IMA blacklist keyring
28 */ 27 */
29__init int ima_mok_init(void) 28__init int ima_mok_init(void)
30{ 29{
31 pr_notice("Allocating IMA MOK and blacklist keyrings.\n"); 30 pr_notice("Allocating IMA blacklist keyring.\n");
32
33 ima_mok_keyring = keyring_alloc(".ima_mok",
34 KUIDT_INIT(0), KGIDT_INIT(0), current_cred(),
35 (KEY_POS_ALL & ~KEY_POS_SETATTR) |
36 KEY_USR_VIEW | KEY_USR_READ |
37 KEY_USR_WRITE | KEY_USR_SEARCH,
38 KEY_ALLOC_NOT_IN_QUOTA, NULL);
39 31
40 ima_blacklist_keyring = keyring_alloc(".ima_blacklist", 32 ima_blacklist_keyring = keyring_alloc(".ima_blacklist",
41 KUIDT_INIT(0), KGIDT_INIT(0), current_cred(), 33 KUIDT_INIT(0), KGIDT_INIT(0), current_cred(),
42 (KEY_POS_ALL & ~KEY_POS_SETATTR) | 34 (KEY_POS_ALL & ~KEY_POS_SETATTR) |
43 KEY_USR_VIEW | KEY_USR_READ | 35 KEY_USR_VIEW | KEY_USR_READ |
44 KEY_USR_WRITE | KEY_USR_SEARCH, 36 KEY_USR_WRITE | KEY_USR_SEARCH,
45 KEY_ALLOC_NOT_IN_QUOTA, NULL); 37 KEY_ALLOC_NOT_IN_QUOTA,
38 restrict_link_by_builtin_trusted, NULL);
46 39
47 if (IS_ERR(ima_mok_keyring) || IS_ERR(ima_blacklist_keyring)) 40 if (IS_ERR(ima_blacklist_keyring))
48 panic("Can't allocate IMA MOK or blacklist keyrings."); 41 panic("Can't allocate IMA blacklist keyring.");
49 set_bit(KEY_FLAG_TRUSTED_ONLY, &ima_mok_keyring->flags);
50 42
51 set_bit(KEY_FLAG_TRUSTED_ONLY, &ima_blacklist_keyring->flags);
52 set_bit(KEY_FLAG_KEEP, &ima_blacklist_keyring->flags); 43 set_bit(KEY_FLAG_KEEP, &ima_blacklist_keyring->flags);
53 return 0; 44 return 0;
54} 45}
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
index e08935cf343f..90bc57d796ec 100644
--- a/security/integrity/integrity.h
+++ b/security/integrity/integrity.h
@@ -28,6 +28,7 @@
28 28
29/* iint cache flags */ 29/* iint cache flags */
30#define IMA_ACTION_FLAGS 0xff000000 30#define IMA_ACTION_FLAGS 0xff000000
31#define IMA_ACTION_RULE_FLAGS 0x06000000
31#define IMA_DIGSIG 0x01000000 32#define IMA_DIGSIG 0x01000000
32#define IMA_DIGSIG_REQUIRED 0x02000000 33#define IMA_DIGSIG_REQUIRED 0x02000000
33#define IMA_PERMIT_DIRECTIO 0x04000000 34#define IMA_PERMIT_DIRECTIO 0x04000000
diff --git a/security/keys/Kconfig b/security/keys/Kconfig
index fe4d74e126a7..f826e8739023 100644
--- a/security/keys/Kconfig
+++ b/security/keys/Kconfig
@@ -41,6 +41,10 @@ config BIG_KEYS
41 bool "Large payload keys" 41 bool "Large payload keys"
42 depends on KEYS 42 depends on KEYS
43 depends on TMPFS 43 depends on TMPFS
44 select CRYPTO
45 select CRYPTO_AES
46 select CRYPTO_ECB
47 select CRYPTO_RNG
44 help 48 help
45 This option provides support for holding large keys within the kernel 49 This option provides support for holding large keys within the kernel
46 (for example Kerberos ticket caches). The data may be stored out to 50 (for example Kerberos ticket caches). The data may be stored out to
@@ -81,3 +85,14 @@ config ENCRYPTED_KEYS
81 Userspace only ever sees/stores encrypted blobs. 85 Userspace only ever sees/stores encrypted blobs.
82 86
83 If you are unsure as to whether this is required, answer N. 87 If you are unsure as to whether this is required, answer N.
88
89config KEY_DH_OPERATIONS
90 bool "Diffie-Hellman operations on retained keys"
91 depends on KEYS
92 select MPILIB
93 help
94 This option provides support for calculating Diffie-Hellman
95 public keys and shared secrets using values stored as keys
96 in the kernel.
97
98 If you are unsure as to whether this is required, answer N.
diff --git a/security/keys/Makefile b/security/keys/Makefile
index dfb3a7bededf..1fd4a16e6daf 100644
--- a/security/keys/Makefile
+++ b/security/keys/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_KEYS_COMPAT) += compat.o
19obj-$(CONFIG_PROC_FS) += proc.o 19obj-$(CONFIG_PROC_FS) += proc.o
20obj-$(CONFIG_SYSCTL) += sysctl.o 20obj-$(CONFIG_SYSCTL) += sysctl.o
21obj-$(CONFIG_PERSISTENT_KEYRINGS) += persistent.o 21obj-$(CONFIG_PERSISTENT_KEYRINGS) += persistent.o
22obj-$(CONFIG_KEY_DH_OPERATIONS) += dh.o
22 23
23# 24#
24# Key types 25# Key types
diff --git a/security/keys/big_key.c b/security/keys/big_key.c
index c721e398893a..9e443fccad4c 100644
--- a/security/keys/big_key.c
+++ b/security/keys/big_key.c
@@ -14,8 +14,10 @@
14#include <linux/file.h> 14#include <linux/file.h>
15#include <linux/shmem_fs.h> 15#include <linux/shmem_fs.h>
16#include <linux/err.h> 16#include <linux/err.h>
17#include <linux/scatterlist.h>
17#include <keys/user-type.h> 18#include <keys/user-type.h>
18#include <keys/big_key-type.h> 19#include <keys/big_key-type.h>
20#include <crypto/rng.h>
19 21
20/* 22/*
21 * Layout of key payload words. 23 * Layout of key payload words.
@@ -28,6 +30,14 @@ enum {
28}; 30};
29 31
30/* 32/*
33 * Crypto operation with big_key data
34 */
35enum big_key_op {
36 BIG_KEY_ENC,
37 BIG_KEY_DEC,
38};
39
40/*
31 * If the data is under this limit, there's no point creating a shm file to 41 * If the data is under this limit, there's no point creating a shm file to
32 * hold it as the permanently resident metadata for the shmem fs will be at 42 * hold it as the permanently resident metadata for the shmem fs will be at
33 * least as large as the data. 43 * least as large as the data.
@@ -35,6 +45,11 @@ enum {
35#define BIG_KEY_FILE_THRESHOLD (sizeof(struct inode) + sizeof(struct dentry)) 45#define BIG_KEY_FILE_THRESHOLD (sizeof(struct inode) + sizeof(struct dentry))
36 46
37/* 47/*
48 * Key size for big_key data encryption
49 */
50#define ENC_KEY_SIZE 16
51
52/*
38 * big_key defined keys take an arbitrary string as the description and an 53 * big_key defined keys take an arbitrary string as the description and an
39 * arbitrary blob of data as the payload 54 * arbitrary blob of data as the payload
40 */ 55 */
@@ -50,12 +65,62 @@ struct key_type key_type_big_key = {
50}; 65};
51 66
52/* 67/*
68 * Crypto names for big_key data encryption
69 */
70static const char big_key_rng_name[] = "stdrng";
71static const char big_key_alg_name[] = "ecb(aes)";
72
73/*
74 * Crypto algorithms for big_key data encryption
75 */
76static struct crypto_rng *big_key_rng;
77static struct crypto_blkcipher *big_key_blkcipher;
78
79/*
80 * Generate random key to encrypt big_key data
81 */
82static inline int big_key_gen_enckey(u8 *key)
83{
84 return crypto_rng_get_bytes(big_key_rng, key, ENC_KEY_SIZE);
85}
86
87/*
88 * Encrypt/decrypt big_key data
89 */
90static int big_key_crypt(enum big_key_op op, u8 *data, size_t datalen, u8 *key)
91{
92 int ret = -EINVAL;
93 struct scatterlist sgio;
94 struct blkcipher_desc desc;
95
96 if (crypto_blkcipher_setkey(big_key_blkcipher, key, ENC_KEY_SIZE)) {
97 ret = -EAGAIN;
98 goto error;
99 }
100
101 desc.flags = 0;
102 desc.tfm = big_key_blkcipher;
103
104 sg_init_one(&sgio, data, datalen);
105
106 if (op == BIG_KEY_ENC)
107 ret = crypto_blkcipher_encrypt(&desc, &sgio, &sgio, datalen);
108 else
109 ret = crypto_blkcipher_decrypt(&desc, &sgio, &sgio, datalen);
110
111error:
112 return ret;
113}
114
115/*
53 * Preparse a big key 116 * Preparse a big key
54 */ 117 */
55int big_key_preparse(struct key_preparsed_payload *prep) 118int big_key_preparse(struct key_preparsed_payload *prep)
56{ 119{
57 struct path *path = (struct path *)&prep->payload.data[big_key_path]; 120 struct path *path = (struct path *)&prep->payload.data[big_key_path];
58 struct file *file; 121 struct file *file;
122 u8 *enckey;
123 u8 *data = NULL;
59 ssize_t written; 124 ssize_t written;
60 size_t datalen = prep->datalen; 125 size_t datalen = prep->datalen;
61 int ret; 126 int ret;
@@ -73,16 +138,43 @@ int big_key_preparse(struct key_preparsed_payload *prep)
73 /* Create a shmem file to store the data in. This will permit the data 138 /* Create a shmem file to store the data in. This will permit the data
74 * to be swapped out if needed. 139 * to be swapped out if needed.
75 * 140 *
76 * TODO: Encrypt the stored data with a temporary key. 141 * File content is stored encrypted with randomly generated key.
77 */ 142 */
78 file = shmem_kernel_file_setup("", datalen, 0); 143 size_t enclen = ALIGN(datalen, crypto_blkcipher_blocksize(big_key_blkcipher));
144
145 /* prepare aligned data to encrypt */
146 data = kmalloc(enclen, GFP_KERNEL);
147 if (!data)
148 return -ENOMEM;
149
150 memcpy(data, prep->data, datalen);
151 memset(data + datalen, 0x00, enclen - datalen);
152
153 /* generate random key */
154 enckey = kmalloc(ENC_KEY_SIZE, GFP_KERNEL);
155 if (!enckey) {
156 ret = -ENOMEM;
157 goto error;
158 }
159
160 ret = big_key_gen_enckey(enckey);
161 if (ret)
162 goto err_enckey;
163
164 /* encrypt aligned data */
165 ret = big_key_crypt(BIG_KEY_ENC, data, enclen, enckey);
166 if (ret)
167 goto err_enckey;
168
169 /* save aligned data to file */
170 file = shmem_kernel_file_setup("", enclen, 0);
79 if (IS_ERR(file)) { 171 if (IS_ERR(file)) {
80 ret = PTR_ERR(file); 172 ret = PTR_ERR(file);
81 goto error; 173 goto err_enckey;
82 } 174 }
83 175
84 written = kernel_write(file, prep->data, prep->datalen, 0); 176 written = kernel_write(file, data, enclen, 0);
85 if (written != datalen) { 177 if (written != enclen) {
86 ret = written; 178 ret = written;
87 if (written >= 0) 179 if (written >= 0)
88 ret = -ENOMEM; 180 ret = -ENOMEM;
@@ -92,12 +184,15 @@ int big_key_preparse(struct key_preparsed_payload *prep)
92 /* Pin the mount and dentry to the key so that we can open it again 184 /* Pin the mount and dentry to the key so that we can open it again
93 * later 185 * later
94 */ 186 */
187 prep->payload.data[big_key_data] = enckey;
95 *path = file->f_path; 188 *path = file->f_path;
96 path_get(path); 189 path_get(path);
97 fput(file); 190 fput(file);
191 kfree(data);
98 } else { 192 } else {
99 /* Just store the data in a buffer */ 193 /* Just store the data in a buffer */
100 void *data = kmalloc(datalen, GFP_KERNEL); 194 void *data = kmalloc(datalen, GFP_KERNEL);
195
101 if (!data) 196 if (!data)
102 return -ENOMEM; 197 return -ENOMEM;
103 198
@@ -108,7 +203,10 @@ int big_key_preparse(struct key_preparsed_payload *prep)
108 203
109err_fput: 204err_fput:
110 fput(file); 205 fput(file);
206err_enckey:
207 kfree(enckey);
111error: 208error:
209 kfree(data);
112 return ret; 210 return ret;
113} 211}
114 212
@@ -119,10 +217,10 @@ void big_key_free_preparse(struct key_preparsed_payload *prep)
119{ 217{
120 if (prep->datalen > BIG_KEY_FILE_THRESHOLD) { 218 if (prep->datalen > BIG_KEY_FILE_THRESHOLD) {
121 struct path *path = (struct path *)&prep->payload.data[big_key_path]; 219 struct path *path = (struct path *)&prep->payload.data[big_key_path];
220
122 path_put(path); 221 path_put(path);
123 } else {
124 kfree(prep->payload.data[big_key_data]);
125 } 222 }
223 kfree(prep->payload.data[big_key_data]);
126} 224}
127 225
128/* 226/*
@@ -147,15 +245,15 @@ void big_key_destroy(struct key *key)
147{ 245{
148 size_t datalen = (size_t)key->payload.data[big_key_len]; 246 size_t datalen = (size_t)key->payload.data[big_key_len];
149 247
150 if (datalen) { 248 if (datalen > BIG_KEY_FILE_THRESHOLD) {
151 struct path *path = (struct path *)&key->payload.data[big_key_path]; 249 struct path *path = (struct path *)&key->payload.data[big_key_path];
250
152 path_put(path); 251 path_put(path);
153 path->mnt = NULL; 252 path->mnt = NULL;
154 path->dentry = NULL; 253 path->dentry = NULL;
155 } else {
156 kfree(key->payload.data[big_key_data]);
157 key->payload.data[big_key_data] = NULL;
158 } 254 }
255 kfree(key->payload.data[big_key_data]);
256 key->payload.data[big_key_data] = NULL;
159} 257}
160 258
161/* 259/*
@@ -188,17 +286,41 @@ long big_key_read(const struct key *key, char __user *buffer, size_t buflen)
188 if (datalen > BIG_KEY_FILE_THRESHOLD) { 286 if (datalen > BIG_KEY_FILE_THRESHOLD) {
189 struct path *path = (struct path *)&key->payload.data[big_key_path]; 287 struct path *path = (struct path *)&key->payload.data[big_key_path];
190 struct file *file; 288 struct file *file;
191 loff_t pos; 289 u8 *data;
290 u8 *enckey = (u8 *)key->payload.data[big_key_data];
291 size_t enclen = ALIGN(datalen, crypto_blkcipher_blocksize(big_key_blkcipher));
292
293 data = kmalloc(enclen, GFP_KERNEL);
294 if (!data)
295 return -ENOMEM;
192 296
193 file = dentry_open(path, O_RDONLY, current_cred()); 297 file = dentry_open(path, O_RDONLY, current_cred());
194 if (IS_ERR(file)) 298 if (IS_ERR(file)) {
195 return PTR_ERR(file); 299 ret = PTR_ERR(file);
300 goto error;
301 }
196 302
197 pos = 0; 303 /* read file to kernel and decrypt */
198 ret = vfs_read(file, buffer, datalen, &pos); 304 ret = kernel_read(file, 0, data, enclen);
199 fput(file); 305 if (ret >= 0 && ret != enclen) {
200 if (ret >= 0 && ret != datalen)
201 ret = -EIO; 306 ret = -EIO;
307 goto err_fput;
308 }
309
310 ret = big_key_crypt(BIG_KEY_DEC, data, enclen, enckey);
311 if (ret)
312 goto err_fput;
313
314 ret = datalen;
315
316 /* copy decrypted data to user */
317 if (copy_to_user(buffer, data, datalen) != 0)
318 ret = -EFAULT;
319
320err_fput:
321 fput(file);
322error:
323 kfree(data);
202 } else { 324 } else {
203 ret = datalen; 325 ret = datalen;
204 if (copy_to_user(buffer, key->payload.data[big_key_data], 326 if (copy_to_user(buffer, key->payload.data[big_key_data],
@@ -209,8 +331,48 @@ long big_key_read(const struct key *key, char __user *buffer, size_t buflen)
209 return ret; 331 return ret;
210} 332}
211 333
334/*
335 * Register key type
336 */
212static int __init big_key_init(void) 337static int __init big_key_init(void)
213{ 338{
214 return register_key_type(&key_type_big_key); 339 return register_key_type(&key_type_big_key);
215} 340}
341
342/*
343 * Initialize big_key crypto and RNG algorithms
344 */
345static int __init big_key_crypto_init(void)
346{
347 int ret = -EINVAL;
348
349 /* init RNG */
350 big_key_rng = crypto_alloc_rng(big_key_rng_name, 0, 0);
351 if (IS_ERR(big_key_rng)) {
352 big_key_rng = NULL;
353 return -EFAULT;
354 }
355
356 /* seed RNG */
357 ret = crypto_rng_reset(big_key_rng, NULL, crypto_rng_seedsize(big_key_rng));
358 if (ret)
359 goto error;
360
361 /* init block cipher */
362 big_key_blkcipher = crypto_alloc_blkcipher(big_key_alg_name, 0, 0);
363 if (IS_ERR(big_key_blkcipher)) {
364 big_key_blkcipher = NULL;
365 ret = -EFAULT;
366 goto error;
367 }
368
369 return 0;
370
371error:
372 crypto_free_rng(big_key_rng);
373 big_key_rng = NULL;
374 return ret;
375}
376
216device_initcall(big_key_init); 377device_initcall(big_key_init);
378late_initcall(big_key_crypto_init);
diff --git a/security/keys/compat.c b/security/keys/compat.c
index 25430a3aa7f7..c8783b3b628c 100644
--- a/security/keys/compat.c
+++ b/security/keys/compat.c
@@ -132,6 +132,10 @@ COMPAT_SYSCALL_DEFINE5(keyctl, u32, option,
132 case KEYCTL_GET_PERSISTENT: 132 case KEYCTL_GET_PERSISTENT:
133 return keyctl_get_persistent(arg2, arg3); 133 return keyctl_get_persistent(arg2, arg3);
134 134
135 case KEYCTL_DH_COMPUTE:
136 return keyctl_dh_compute(compat_ptr(arg2), compat_ptr(arg3),
137 arg4);
138
135 default: 139 default:
136 return -EOPNOTSUPP; 140 return -EOPNOTSUPP;
137 } 141 }
diff --git a/security/keys/dh.c b/security/keys/dh.c
new file mode 100644
index 000000000000..880505a4b9f1
--- /dev/null
+++ b/security/keys/dh.c
@@ -0,0 +1,160 @@
1/* Crypto operations using stored keys
2 *
3 * Copyright (c) 2016, Intel Corporation
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version
8 * 2 of the License, or (at your option) any later version.
9 */
10
11#include <linux/mpi.h>
12#include <linux/slab.h>
13#include <linux/uaccess.h>
14#include <keys/user-type.h>
15#include "internal.h"
16
17/*
18 * Public key or shared secret generation function [RFC2631 sec 2.1.1]
19 *
20 * ya = g^xa mod p;
21 * or
22 * ZZ = yb^xa mod p;
23 *
24 * where xa is the local private key, ya is the local public key, g is
25 * the generator, p is the prime, yb is the remote public key, and ZZ
26 * is the shared secret.
27 *
28 * Both are the same calculation, so g or yb are the "base" and ya or
29 * ZZ are the "result".
30 */
31static int do_dh(MPI result, MPI base, MPI xa, MPI p)
32{
33 return mpi_powm(result, base, xa, p);
34}
35
36static ssize_t mpi_from_key(key_serial_t keyid, size_t maxlen, MPI *mpi)
37{
38 struct key *key;
39 key_ref_t key_ref;
40 long status;
41 ssize_t ret;
42
43 key_ref = lookup_user_key(keyid, 0, KEY_NEED_READ);
44 if (IS_ERR(key_ref)) {
45 ret = -ENOKEY;
46 goto error;
47 }
48
49 key = key_ref_to_ptr(key_ref);
50
51 ret = -EOPNOTSUPP;
52 if (key->type == &key_type_user) {
53 down_read(&key->sem);
54 status = key_validate(key);
55 if (status == 0) {
56 const struct user_key_payload *payload;
57
58 payload = user_key_payload(key);
59
60 if (maxlen == 0) {
61 *mpi = NULL;
62 ret = payload->datalen;
63 } else if (payload->datalen <= maxlen) {
64 *mpi = mpi_read_raw_data(payload->data,
65 payload->datalen);
66 if (*mpi)
67 ret = payload->datalen;
68 } else {
69 ret = -EINVAL;
70 }
71 }
72 up_read(&key->sem);
73 }
74
75 key_put(key);
76error:
77 return ret;
78}
79
80long keyctl_dh_compute(struct keyctl_dh_params __user *params,
81 char __user *buffer, size_t buflen)
82{
83 long ret;
84 MPI base, private, prime, result;
85 unsigned nbytes;
86 struct keyctl_dh_params pcopy;
87 uint8_t *kbuf;
88 ssize_t keylen;
89 size_t resultlen;
90
91 if (!params || (!buffer && buflen)) {
92 ret = -EINVAL;
93 goto out;
94 }
95 if (copy_from_user(&pcopy, params, sizeof(pcopy)) != 0) {
96 ret = -EFAULT;
97 goto out;
98 }
99
100 keylen = mpi_from_key(pcopy.prime, buflen, &prime);
101 if (keylen < 0 || !prime) {
102 /* buflen == 0 may be used to query the required buffer size,
103 * which is the prime key length.
104 */
105 ret = keylen;
106 goto out;
107 }
108
109 /* The result is never longer than the prime */
110 resultlen = keylen;
111
112 keylen = mpi_from_key(pcopy.base, SIZE_MAX, &base);
113 if (keylen < 0 || !base) {
114 ret = keylen;
115 goto error1;
116 }
117
118 keylen = mpi_from_key(pcopy.private, SIZE_MAX, &private);
119 if (keylen < 0 || !private) {
120 ret = keylen;
121 goto error2;
122 }
123
124 result = mpi_alloc(0);
125 if (!result) {
126 ret = -ENOMEM;
127 goto error3;
128 }
129
130 kbuf = kmalloc(resultlen, GFP_KERNEL);
131 if (!kbuf) {
132 ret = -ENOMEM;
133 goto error4;
134 }
135
136 ret = do_dh(result, base, private, prime);
137 if (ret)
138 goto error5;
139
140 ret = mpi_read_buffer(result, kbuf, resultlen, &nbytes, NULL);
141 if (ret != 0)
142 goto error5;
143
144 ret = nbytes;
145 if (copy_to_user(buffer, kbuf, nbytes) != 0)
146 ret = -EFAULT;
147
148error5:
149 kfree(kbuf);
150error4:
151 mpi_free(result);
152error3:
153 mpi_free(private);
154error2:
155 mpi_free(base);
156error1:
157 mpi_free(prime);
158out:
159 return ret;
160}
diff --git a/security/keys/internal.h b/security/keys/internal.h
index 5105c2c2da75..8ec7a528365d 100644
--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -15,6 +15,7 @@
15#include <linux/sched.h> 15#include <linux/sched.h>
16#include <linux/key-type.h> 16#include <linux/key-type.h>
17#include <linux/task_work.h> 17#include <linux/task_work.h>
18#include <linux/keyctl.h>
18 19
19struct iovec; 20struct iovec;
20 21
@@ -257,6 +258,17 @@ static inline long keyctl_get_persistent(uid_t uid, key_serial_t destring)
257} 258}
258#endif 259#endif
259 260
261#ifdef CONFIG_KEY_DH_OPERATIONS
262extern long keyctl_dh_compute(struct keyctl_dh_params __user *, char __user *,
263 size_t);
264#else
265static inline long keyctl_dh_compute(struct keyctl_dh_params __user *params,
266 char __user *buffer, size_t buflen)
267{
268 return -EOPNOTSUPP;
269}
270#endif
271
260/* 272/*
261 * Debugging key validation 273 * Debugging key validation
262 */ 274 */
diff --git a/security/keys/key.c b/security/keys/key.c
index b28755131687..bd5a272f28a6 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -201,6 +201,7 @@ serial_exists:
201 * @cred: The credentials specifying UID namespace. 201 * @cred: The credentials specifying UID namespace.
202 * @perm: The permissions mask of the new key. 202 * @perm: The permissions mask of the new key.
203 * @flags: Flags specifying quota properties. 203 * @flags: Flags specifying quota properties.
204 * @restrict_link: Optional link restriction method for new keyrings.
204 * 205 *
205 * Allocate a key of the specified type with the attributes given. The key is 206 * Allocate a key of the specified type with the attributes given. The key is
206 * returned in an uninstantiated state and the caller needs to instantiate the 207 * returned in an uninstantiated state and the caller needs to instantiate the
@@ -223,7 +224,10 @@ serial_exists:
223 */ 224 */
224struct key *key_alloc(struct key_type *type, const char *desc, 225struct key *key_alloc(struct key_type *type, const char *desc,
225 kuid_t uid, kgid_t gid, const struct cred *cred, 226 kuid_t uid, kgid_t gid, const struct cred *cred,
226 key_perm_t perm, unsigned long flags) 227 key_perm_t perm, unsigned long flags,
228 int (*restrict_link)(struct key *,
229 const struct key_type *,
230 const union key_payload *))
227{ 231{
228 struct key_user *user = NULL; 232 struct key_user *user = NULL;
229 struct key *key; 233 struct key *key;
@@ -291,11 +295,10 @@ struct key *key_alloc(struct key_type *type, const char *desc,
291 key->uid = uid; 295 key->uid = uid;
292 key->gid = gid; 296 key->gid = gid;
293 key->perm = perm; 297 key->perm = perm;
298 key->restrict_link = restrict_link;
294 299
295 if (!(flags & KEY_ALLOC_NOT_IN_QUOTA)) 300 if (!(flags & KEY_ALLOC_NOT_IN_QUOTA))
296 key->flags |= 1 << KEY_FLAG_IN_QUOTA; 301 key->flags |= 1 << KEY_FLAG_IN_QUOTA;
297 if (flags & KEY_ALLOC_TRUSTED)
298 key->flags |= 1 << KEY_FLAG_TRUSTED;
299 if (flags & KEY_ALLOC_BUILT_IN) 302 if (flags & KEY_ALLOC_BUILT_IN)
300 key->flags |= 1 << KEY_FLAG_BUILTIN; 303 key->flags |= 1 << KEY_FLAG_BUILTIN;
301 304
@@ -496,6 +499,12 @@ int key_instantiate_and_link(struct key *key,
496 } 499 }
497 500
498 if (keyring) { 501 if (keyring) {
502 if (keyring->restrict_link) {
503 ret = keyring->restrict_link(keyring, key->type,
504 &prep.payload);
505 if (ret < 0)
506 goto error;
507 }
499 ret = __key_link_begin(keyring, &key->index_key, &edit); 508 ret = __key_link_begin(keyring, &key->index_key, &edit);
500 if (ret < 0) 509 if (ret < 0)
501 goto error; 510 goto error;
@@ -551,8 +560,12 @@ int key_reject_and_link(struct key *key,
551 awaken = 0; 560 awaken = 0;
552 ret = -EBUSY; 561 ret = -EBUSY;
553 562
554 if (keyring) 563 if (keyring) {
564 if (keyring->restrict_link)
565 return -EPERM;
566
555 link_ret = __key_link_begin(keyring, &key->index_key, &edit); 567 link_ret = __key_link_begin(keyring, &key->index_key, &edit);
568 }
556 569
557 mutex_lock(&key_construction_mutex); 570 mutex_lock(&key_construction_mutex);
558 571
@@ -793,6 +806,9 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
793 struct key *keyring, *key = NULL; 806 struct key *keyring, *key = NULL;
794 key_ref_t key_ref; 807 key_ref_t key_ref;
795 int ret; 808 int ret;
809 int (*restrict_link)(struct key *,
810 const struct key_type *,
811 const union key_payload *) = NULL;
796 812
797 /* look up the key type to see if it's one of the registered kernel 813 /* look up the key type to see if it's one of the registered kernel
798 * types */ 814 * types */
@@ -811,6 +827,10 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
811 827
812 key_check(keyring); 828 key_check(keyring);
813 829
830 key_ref = ERR_PTR(-EPERM);
831 if (!(flags & KEY_ALLOC_BYPASS_RESTRICTION))
832 restrict_link = keyring->restrict_link;
833
814 key_ref = ERR_PTR(-ENOTDIR); 834 key_ref = ERR_PTR(-ENOTDIR);
815 if (keyring->type != &key_type_keyring) 835 if (keyring->type != &key_type_keyring)
816 goto error_put_type; 836 goto error_put_type;
@@ -819,7 +839,6 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
819 prep.data = payload; 839 prep.data = payload;
820 prep.datalen = plen; 840 prep.datalen = plen;
821 prep.quotalen = index_key.type->def_datalen; 841 prep.quotalen = index_key.type->def_datalen;
822 prep.trusted = flags & KEY_ALLOC_TRUSTED;
823 prep.expiry = TIME_T_MAX; 842 prep.expiry = TIME_T_MAX;
824 if (index_key.type->preparse) { 843 if (index_key.type->preparse) {
825 ret = index_key.type->preparse(&prep); 844 ret = index_key.type->preparse(&prep);
@@ -835,10 +854,13 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
835 } 854 }
836 index_key.desc_len = strlen(index_key.description); 855 index_key.desc_len = strlen(index_key.description);
837 856
838 key_ref = ERR_PTR(-EPERM); 857 if (restrict_link) {
839 if (!prep.trusted && test_bit(KEY_FLAG_TRUSTED_ONLY, &keyring->flags)) 858 ret = restrict_link(keyring, index_key.type, &prep.payload);
840 goto error_free_prep; 859 if (ret < 0) {
841 flags |= prep.trusted ? KEY_ALLOC_TRUSTED : 0; 860 key_ref = ERR_PTR(ret);
861 goto error_free_prep;
862 }
863 }
842 864
843 ret = __key_link_begin(keyring, &index_key, &edit); 865 ret = __key_link_begin(keyring, &index_key, &edit);
844 if (ret < 0) { 866 if (ret < 0) {
@@ -879,7 +901,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
879 901
880 /* allocate a new key */ 902 /* allocate a new key */
881 key = key_alloc(index_key.type, index_key.description, 903 key = key_alloc(index_key.type, index_key.description,
882 cred->fsuid, cred->fsgid, cred, perm, flags); 904 cred->fsuid, cred->fsgid, cred, perm, flags, NULL);
883 if (IS_ERR(key)) { 905 if (IS_ERR(key)) {
884 key_ref = ERR_CAST(key); 906 key_ref = ERR_CAST(key);
885 goto error_link_end; 907 goto error_link_end;
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index ed73c6c1c326..3b135a0af344 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -1686,6 +1686,11 @@ SYSCALL_DEFINE5(keyctl, int, option, unsigned long, arg2, unsigned long, arg3,
1686 case KEYCTL_GET_PERSISTENT: 1686 case KEYCTL_GET_PERSISTENT:
1687 return keyctl_get_persistent((uid_t)arg2, (key_serial_t)arg3); 1687 return keyctl_get_persistent((uid_t)arg2, (key_serial_t)arg3);
1688 1688
1689 case KEYCTL_DH_COMPUTE:
1690 return keyctl_dh_compute((struct keyctl_dh_params __user *) arg2,
1691 (char __user *) arg3,
1692 (size_t) arg4);
1693
1689 default: 1694 default:
1690 return -EOPNOTSUPP; 1695 return -EOPNOTSUPP;
1691 } 1696 }
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index f931ccfeefb0..c91e4e0cea08 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -491,13 +491,17 @@ static long keyring_read(const struct key *keyring,
491 */ 491 */
492struct key *keyring_alloc(const char *description, kuid_t uid, kgid_t gid, 492struct key *keyring_alloc(const char *description, kuid_t uid, kgid_t gid,
493 const struct cred *cred, key_perm_t perm, 493 const struct cred *cred, key_perm_t perm,
494 unsigned long flags, struct key *dest) 494 unsigned long flags,
495 int (*restrict_link)(struct key *,
496 const struct key_type *,
497 const union key_payload *),
498 struct key *dest)
495{ 499{
496 struct key *keyring; 500 struct key *keyring;
497 int ret; 501 int ret;
498 502
499 keyring = key_alloc(&key_type_keyring, description, 503 keyring = key_alloc(&key_type_keyring, description,
500 uid, gid, cred, perm, flags); 504 uid, gid, cred, perm, flags, restrict_link);
501 if (!IS_ERR(keyring)) { 505 if (!IS_ERR(keyring)) {
502 ret = key_instantiate_and_link(keyring, NULL, 0, dest, NULL); 506 ret = key_instantiate_and_link(keyring, NULL, 0, dest, NULL);
503 if (ret < 0) { 507 if (ret < 0) {
@@ -510,6 +514,26 @@ struct key *keyring_alloc(const char *description, kuid_t uid, kgid_t gid,
510} 514}
511EXPORT_SYMBOL(keyring_alloc); 515EXPORT_SYMBOL(keyring_alloc);
512 516
517/**
518 * restrict_link_reject - Give -EPERM to restrict link
519 * @keyring: The keyring being added to.
520 * @type: The type of key being added.
521 * @payload: The payload of the key intended to be added.
522 *
523 * Reject the addition of any links to a keyring. It can be overridden by
524 * passing KEY_ALLOC_BYPASS_RESTRICTION to key_instantiate_and_link() when
525 * adding a key to a keyring.
526 *
527 * This is meant to be passed as the restrict_link parameter to
528 * keyring_alloc().
529 */
530int restrict_link_reject(struct key *keyring,
531 const struct key_type *type,
532 const union key_payload *payload)
533{
534 return -EPERM;
535}
536
513/* 537/*
514 * By default, we keys found by getting an exact match on their descriptions. 538 * By default, we keys found by getting an exact match on their descriptions.
515 */ 539 */
@@ -1191,6 +1215,16 @@ void __key_link_end(struct key *keyring,
1191 up_write(&keyring->sem); 1215 up_write(&keyring->sem);
1192} 1216}
1193 1217
1218/*
1219 * Check addition of keys to restricted keyrings.
1220 */
1221static int __key_link_check_restriction(struct key *keyring, struct key *key)
1222{
1223 if (!keyring->restrict_link)
1224 return 0;
1225 return keyring->restrict_link(keyring, key->type, &key->payload);
1226}
1227
1194/** 1228/**
1195 * key_link - Link a key to a keyring 1229 * key_link - Link a key to a keyring
1196 * @keyring: The keyring to make the link in. 1230 * @keyring: The keyring to make the link in.
@@ -1221,14 +1255,12 @@ int key_link(struct key *keyring, struct key *key)
1221 key_check(keyring); 1255 key_check(keyring);
1222 key_check(key); 1256 key_check(key);
1223 1257
1224 if (test_bit(KEY_FLAG_TRUSTED_ONLY, &keyring->flags) &&
1225 !test_bit(KEY_FLAG_TRUSTED, &key->flags))
1226 return -EPERM;
1227
1228 ret = __key_link_begin(keyring, &key->index_key, &edit); 1258 ret = __key_link_begin(keyring, &key->index_key, &edit);
1229 if (ret == 0) { 1259 if (ret == 0) {
1230 kdebug("begun {%d,%d}", keyring->serial, atomic_read(&keyring->usage)); 1260 kdebug("begun {%d,%d}", keyring->serial, atomic_read(&keyring->usage));
1231 ret = __key_link_check_live_key(keyring, key); 1261 ret = __key_link_check_restriction(keyring, key);
1262 if (ret == 0)
1263 ret = __key_link_check_live_key(keyring, key);
1232 if (ret == 0) 1264 if (ret == 0)
1233 __key_link(key, &edit); 1265 __key_link(key, &edit);
1234 __key_link_end(keyring, &key->index_key, edit); 1266 __key_link_end(keyring, &key->index_key, edit);
diff --git a/security/keys/persistent.c b/security/keys/persistent.c
index c9fae5ea89fe..2ef45b319dd9 100644
--- a/security/keys/persistent.c
+++ b/security/keys/persistent.c
@@ -26,7 +26,7 @@ static int key_create_persistent_register(struct user_namespace *ns)
26 current_cred(), 26 current_cred(),
27 ((KEY_POS_ALL & ~KEY_POS_SETATTR) | 27 ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
28 KEY_USR_VIEW | KEY_USR_READ), 28 KEY_USR_VIEW | KEY_USR_READ),
29 KEY_ALLOC_NOT_IN_QUOTA, NULL); 29 KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL);
30 if (IS_ERR(reg)) 30 if (IS_ERR(reg))
31 return PTR_ERR(reg); 31 return PTR_ERR(reg);
32 32
@@ -60,7 +60,7 @@ static key_ref_t key_create_persistent(struct user_namespace *ns, kuid_t uid,
60 uid, INVALID_GID, current_cred(), 60 uid, INVALID_GID, current_cred(),
61 ((KEY_POS_ALL & ~KEY_POS_SETATTR) | 61 ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
62 KEY_USR_VIEW | KEY_USR_READ), 62 KEY_USR_VIEW | KEY_USR_READ),
63 KEY_ALLOC_NOT_IN_QUOTA, 63 KEY_ALLOC_NOT_IN_QUOTA, NULL,
64 ns->persistent_keyring_register); 64 ns->persistent_keyring_register);
65 if (IS_ERR(persistent)) 65 if (IS_ERR(persistent))
66 return ERR_CAST(persistent); 66 return ERR_CAST(persistent);
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index e6d50172872f..40a885239782 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -76,7 +76,8 @@ int install_user_keyrings(void)
76 if (IS_ERR(uid_keyring)) { 76 if (IS_ERR(uid_keyring)) {
77 uid_keyring = keyring_alloc(buf, user->uid, INVALID_GID, 77 uid_keyring = keyring_alloc(buf, user->uid, INVALID_GID,
78 cred, user_keyring_perm, 78 cred, user_keyring_perm,
79 KEY_ALLOC_IN_QUOTA, NULL); 79 KEY_ALLOC_IN_QUOTA,
80 NULL, NULL);
80 if (IS_ERR(uid_keyring)) { 81 if (IS_ERR(uid_keyring)) {
81 ret = PTR_ERR(uid_keyring); 82 ret = PTR_ERR(uid_keyring);
82 goto error; 83 goto error;
@@ -92,7 +93,8 @@ int install_user_keyrings(void)
92 session_keyring = 93 session_keyring =
93 keyring_alloc(buf, user->uid, INVALID_GID, 94 keyring_alloc(buf, user->uid, INVALID_GID,
94 cred, user_keyring_perm, 95 cred, user_keyring_perm,
95 KEY_ALLOC_IN_QUOTA, NULL); 96 KEY_ALLOC_IN_QUOTA,
97 NULL, NULL);
96 if (IS_ERR(session_keyring)) { 98 if (IS_ERR(session_keyring)) {
97 ret = PTR_ERR(session_keyring); 99 ret = PTR_ERR(session_keyring);
98 goto error_release; 100 goto error_release;
@@ -134,7 +136,8 @@ int install_thread_keyring_to_cred(struct cred *new)
134 136
135 keyring = keyring_alloc("_tid", new->uid, new->gid, new, 137 keyring = keyring_alloc("_tid", new->uid, new->gid, new,
136 KEY_POS_ALL | KEY_USR_VIEW, 138 KEY_POS_ALL | KEY_USR_VIEW,
137 KEY_ALLOC_QUOTA_OVERRUN, NULL); 139 KEY_ALLOC_QUOTA_OVERRUN,
140 NULL, NULL);
138 if (IS_ERR(keyring)) 141 if (IS_ERR(keyring))
139 return PTR_ERR(keyring); 142 return PTR_ERR(keyring);
140 143
@@ -180,7 +183,8 @@ int install_process_keyring_to_cred(struct cred *new)
180 183
181 keyring = keyring_alloc("_pid", new->uid, new->gid, new, 184 keyring = keyring_alloc("_pid", new->uid, new->gid, new,
182 KEY_POS_ALL | KEY_USR_VIEW, 185 KEY_POS_ALL | KEY_USR_VIEW,
183 KEY_ALLOC_QUOTA_OVERRUN, NULL); 186 KEY_ALLOC_QUOTA_OVERRUN,
187 NULL, NULL);
184 if (IS_ERR(keyring)) 188 if (IS_ERR(keyring))
185 return PTR_ERR(keyring); 189 return PTR_ERR(keyring);
186 190
@@ -231,7 +235,7 @@ int install_session_keyring_to_cred(struct cred *cred, struct key *keyring)
231 235
232 keyring = keyring_alloc("_ses", cred->uid, cred->gid, cred, 236 keyring = keyring_alloc("_ses", cred->uid, cred->gid, cred,
233 KEY_POS_ALL | KEY_USR_VIEW | KEY_USR_READ, 237 KEY_POS_ALL | KEY_USR_VIEW | KEY_USR_READ,
234 flags, NULL); 238 flags, NULL, NULL);
235 if (IS_ERR(keyring)) 239 if (IS_ERR(keyring))
236 return PTR_ERR(keyring); 240 return PTR_ERR(keyring);
237 } else { 241 } else {
@@ -785,7 +789,7 @@ long join_session_keyring(const char *name)
785 keyring = keyring_alloc( 789 keyring = keyring_alloc(
786 name, old->uid, old->gid, old, 790 name, old->uid, old->gid, old,
787 KEY_POS_ALL | KEY_USR_VIEW | KEY_USR_READ | KEY_USR_LINK, 791 KEY_POS_ALL | KEY_USR_VIEW | KEY_USR_READ | KEY_USR_LINK,
788 KEY_ALLOC_IN_QUOTA, NULL); 792 KEY_ALLOC_IN_QUOTA, NULL, NULL);
789 if (IS_ERR(keyring)) { 793 if (IS_ERR(keyring)) {
790 ret = PTR_ERR(keyring); 794 ret = PTR_ERR(keyring);
791 goto error2; 795 goto error2;
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index c7a117c9a8f3..a29e3554751e 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -116,7 +116,7 @@ static int call_sbin_request_key(struct key_construction *cons,
116 cred = get_current_cred(); 116 cred = get_current_cred();
117 keyring = keyring_alloc(desc, cred->fsuid, cred->fsgid, cred, 117 keyring = keyring_alloc(desc, cred->fsuid, cred->fsgid, cred,
118 KEY_POS_ALL | KEY_USR_VIEW | KEY_USR_READ, 118 KEY_POS_ALL | KEY_USR_VIEW | KEY_USR_READ,
119 KEY_ALLOC_QUOTA_OVERRUN, NULL); 119 KEY_ALLOC_QUOTA_OVERRUN, NULL, NULL);
120 put_cred(cred); 120 put_cred(cred);
121 if (IS_ERR(keyring)) { 121 if (IS_ERR(keyring)) {
122 ret = PTR_ERR(keyring); 122 ret = PTR_ERR(keyring);
@@ -355,7 +355,7 @@ static int construct_alloc_key(struct keyring_search_context *ctx,
355 355
356 key = key_alloc(ctx->index_key.type, ctx->index_key.description, 356 key = key_alloc(ctx->index_key.type, ctx->index_key.description,
357 ctx->cred->fsuid, ctx->cred->fsgid, ctx->cred, 357 ctx->cred->fsuid, ctx->cred->fsgid, ctx->cred,
358 perm, flags); 358 perm, flags, NULL);
359 if (IS_ERR(key)) 359 if (IS_ERR(key))
360 goto alloc_failed; 360 goto alloc_failed;
361 361
diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c
index 4f0f112fe276..9db8b4a82787 100644
--- a/security/keys/request_key_auth.c
+++ b/security/keys/request_key_auth.c
@@ -202,7 +202,7 @@ struct key *request_key_auth_new(struct key *target, const void *callout_info,
202 authkey = key_alloc(&key_type_request_key_auth, desc, 202 authkey = key_alloc(&key_type_request_key_auth, desc,
203 cred->fsuid, cred->fsgid, cred, 203 cred->fsuid, cred->fsgid, cred,
204 KEY_POS_VIEW | KEY_POS_READ | KEY_POS_SEARCH | 204 KEY_POS_VIEW | KEY_POS_READ | KEY_POS_SEARCH |
205 KEY_USR_VIEW, KEY_ALLOC_NOT_IN_QUOTA); 205 KEY_USR_VIEW, KEY_ALLOC_NOT_IN_QUOTA, NULL);
206 if (IS_ERR(authkey)) { 206 if (IS_ERR(authkey)) {
207 ret = PTR_ERR(authkey); 207 ret = PTR_ERR(authkey);
208 goto error_alloc; 208 goto error_alloc;
diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c
index 8705d79b2c6f..66b1840b4110 100644
--- a/security/keys/user_defined.c
+++ b/security/keys/user_defined.c
@@ -96,45 +96,25 @@ EXPORT_SYMBOL_GPL(user_free_preparse);
96 */ 96 */
97int user_update(struct key *key, struct key_preparsed_payload *prep) 97int user_update(struct key *key, struct key_preparsed_payload *prep)
98{ 98{
99 struct user_key_payload *upayload, *zap; 99 struct user_key_payload *zap = NULL;
100 size_t datalen = prep->datalen;
101 int ret; 100 int ret;
102 101
103 ret = -EINVAL;
104 if (datalen <= 0 || datalen > 32767 || !prep->data)
105 goto error;
106
107 /* construct a replacement payload */
108 ret = -ENOMEM;
109 upayload = kmalloc(sizeof(*upayload) + datalen, GFP_KERNEL);
110 if (!upayload)
111 goto error;
112
113 upayload->datalen = datalen;
114 memcpy(upayload->data, prep->data, datalen);
115
116 /* check the quota and attach the new data */ 102 /* check the quota and attach the new data */
117 zap = upayload; 103 ret = key_payload_reserve(key, prep->datalen);
118 104 if (ret < 0)
119 ret = key_payload_reserve(key, datalen); 105 return ret;
120 106
121 if (ret == 0) { 107 /* attach the new data, displacing the old */
122 /* attach the new data, displacing the old */ 108 key->expiry = prep->expiry;
123 if (!test_bit(KEY_FLAG_NEGATIVE, &key->flags)) 109 if (!test_bit(KEY_FLAG_NEGATIVE, &key->flags))
124 zap = key->payload.data[0]; 110 zap = rcu_dereference_key(key);
125 else 111 rcu_assign_keypointer(key, prep->payload.data[0]);
126 zap = NULL; 112 prep->payload.data[0] = NULL;
127 rcu_assign_keypointer(key, upayload);
128 key->expiry = 0;
129 }
130 113
131 if (zap) 114 if (zap)
132 kfree_rcu(zap, rcu); 115 kfree_rcu(zap, rcu);
133
134error:
135 return ret; 116 return ret;
136} 117}
137
138EXPORT_SYMBOL_GPL(user_update); 118EXPORT_SYMBOL_GPL(user_update);
139 119
140/* 120/*
diff --git a/security/loadpin/Kconfig b/security/loadpin/Kconfig
new file mode 100644
index 000000000000..dd01aa91e521
--- /dev/null
+++ b/security/loadpin/Kconfig
@@ -0,0 +1,19 @@
1config SECURITY_LOADPIN
2 bool "Pin load of kernel files (modules, fw, etc) to one filesystem"
3 depends on SECURITY && BLOCK
4 help
5 Any files read through the kernel file reading interface
6 (kernel modules, firmware, kexec images, security policy)
7 can be pinned to the first filesystem used for loading. When
8 enabled, any files that come from other filesystems will be
9 rejected. This is best used on systems without an initrd that
10 have a root filesystem backed by a read-only device such as
11 dm-verity or a CDROM.
12
13config SECURITY_LOADPIN_ENABLED
14 bool "Enforce LoadPin at boot"
15 depends on SECURITY_LOADPIN
16 help
17 If selected, LoadPin will enforce pinning at boot. If not
18 selected, it can be enabled at boot with the kernel parameter
19 "loadpin.enabled=1".
diff --git a/security/loadpin/Makefile b/security/loadpin/Makefile
new file mode 100644
index 000000000000..c2d77f83037b
--- /dev/null
+++ b/security/loadpin/Makefile
@@ -0,0 +1 @@
obj-$(CONFIG_SECURITY_LOADPIN) += loadpin.o
diff --git a/security/loadpin/loadpin.c b/security/loadpin/loadpin.c
new file mode 100644
index 000000000000..89a46f10b8a7
--- /dev/null
+++ b/security/loadpin/loadpin.c
@@ -0,0 +1,190 @@
1/*
2 * Module and Firmware Pinning Security Module
3 *
4 * Copyright 2011-2016 Google Inc.
5 *
6 * Author: Kees Cook <keescook@chromium.org>
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
18#define pr_fmt(fmt) "LoadPin: " fmt
19
20#include <linux/module.h>
21#include <linux/fs.h>
22#include <linux/fs_struct.h>
23#include <linux/lsm_hooks.h>
24#include <linux/mount.h>
25#include <linux/path.h>
26#include <linux/sched.h> /* current */
27#include <linux/string_helpers.h>
28
29static void report_load(const char *origin, struct file *file, char *operation)
30{
31 char *cmdline, *pathname;
32
33 pathname = kstrdup_quotable_file(file, GFP_KERNEL);
34 cmdline = kstrdup_quotable_cmdline(current, GFP_KERNEL);
35
36 pr_notice("%s %s obj=%s%s%s pid=%d cmdline=%s%s%s\n",
37 origin, operation,
38 (pathname && pathname[0] != '<') ? "\"" : "",
39 pathname,
40 (pathname && pathname[0] != '<') ? "\"" : "",
41 task_pid_nr(current),
42 cmdline ? "\"" : "", cmdline, cmdline ? "\"" : "");
43
44 kfree(cmdline);
45 kfree(pathname);
46}
47
48static int enabled = IS_ENABLED(CONFIG_SECURITY_LOADPIN_ENABLED);
49static struct super_block *pinned_root;
50static DEFINE_SPINLOCK(pinned_root_spinlock);
51
52#ifdef CONFIG_SYSCTL
53static int zero;
54static int one = 1;
55
56static struct ctl_path loadpin_sysctl_path[] = {
57 { .procname = "kernel", },
58 { .procname = "loadpin", },
59 { }
60};
61
62static struct ctl_table loadpin_sysctl_table[] = {
63 {
64 .procname = "enabled",
65 .data = &enabled,
66 .maxlen = sizeof(int),
67 .mode = 0644,
68 .proc_handler = proc_dointvec_minmax,
69 .extra1 = &zero,
70 .extra2 = &one,
71 },
72 { }
73};
74
75/*
76 * This must be called after early kernel init, since then the rootdev
77 * is available.
78 */
79static void check_pinning_enforcement(struct super_block *mnt_sb)
80{
81 bool ro = false;
82
83 /*
84 * If load pinning is not enforced via a read-only block
85 * device, allow sysctl to change modes for testing.
86 */
87 if (mnt_sb->s_bdev) {
88 ro = bdev_read_only(mnt_sb->s_bdev);
89 pr_info("dev(%u,%u): %s\n",
90 MAJOR(mnt_sb->s_bdev->bd_dev),
91 MINOR(mnt_sb->s_bdev->bd_dev),
92 ro ? "read-only" : "writable");
93 } else
94 pr_info("mnt_sb lacks block device, treating as: writable\n");
95
96 if (!ro) {
97 if (!register_sysctl_paths(loadpin_sysctl_path,
98 loadpin_sysctl_table))
99 pr_notice("sysctl registration failed!\n");
100 else
101 pr_info("load pinning can be disabled.\n");
102 } else
103 pr_info("load pinning engaged.\n");
104}
105#else
106static void check_pinning_enforcement(struct super_block *mnt_sb)
107{
108 pr_info("load pinning engaged.\n");
109}
110#endif
111
112static void loadpin_sb_free_security(struct super_block *mnt_sb)
113{
114 /*
115 * When unmounting the filesystem we were using for load
116 * pinning, we acknowledge the superblock release, but make sure
117 * no other modules or firmware can be loaded.
118 */
119 if (!IS_ERR_OR_NULL(pinned_root) && mnt_sb == pinned_root) {
120 pinned_root = ERR_PTR(-EIO);
121 pr_info("umount pinned fs: refusing further loads\n");
122 }
123}
124
125static int loadpin_read_file(struct file *file, enum kernel_read_file_id id)
126{
127 struct super_block *load_root;
128 const char *origin = kernel_read_file_id_str(id);
129
130 /* This handles the older init_module API that has a NULL file. */
131 if (!file) {
132 if (!enabled) {
133 report_load(origin, NULL, "old-api-pinning-ignored");
134 return 0;
135 }
136
137 report_load(origin, NULL, "old-api-denied");
138 return -EPERM;
139 }
140
141 load_root = file->f_path.mnt->mnt_sb;
142
143 /* First loaded module/firmware defines the root for all others. */
144 spin_lock(&pinned_root_spinlock);
145 /*
146 * pinned_root is only NULL at startup. Otherwise, it is either
147 * a valid reference, or an ERR_PTR.
148 */
149 if (!pinned_root) {
150 pinned_root = load_root;
151 /*
152 * Unlock now since it's only pinned_root we care about.
153 * In the worst case, we will (correctly) report pinning
154 * failures before we have announced that pinning is
155 * enabled. This would be purely cosmetic.
156 */
157 spin_unlock(&pinned_root_spinlock);
158 check_pinning_enforcement(pinned_root);
159 report_load(origin, file, "pinned");
160 } else {
161 spin_unlock(&pinned_root_spinlock);
162 }
163
164 if (IS_ERR_OR_NULL(pinned_root) || load_root != pinned_root) {
165 if (unlikely(!enabled)) {
166 report_load(origin, file, "pinning-ignored");
167 return 0;
168 }
169
170 report_load(origin, file, "denied");
171 return -EPERM;
172 }
173
174 return 0;
175}
176
177static struct security_hook_list loadpin_hooks[] = {
178 LSM_HOOK_INIT(sb_free_security, loadpin_sb_free_security),
179 LSM_HOOK_INIT(kernel_read_file, loadpin_read_file),
180};
181
182void __init loadpin_add_hooks(void)
183{
184 pr_info("ready to pin (currently %sabled)", enabled ? "en" : "dis");
185 security_add_hooks(loadpin_hooks, ARRAY_SIZE(loadpin_hooks));
186}
187
188/* Should not be mutable after boot, so not listed in sysfs (perm == 0). */
189module_param(enabled, int, 0);
190MODULE_PARM_DESC(enabled, "Pin module/firmware loading (default: true)");
diff --git a/security/security.c b/security/security.c
index d17e4a6d269c..709569305d32 100644
--- a/security/security.c
+++ b/security/security.c
@@ -60,6 +60,7 @@ int __init security_init(void)
60 */ 60 */
61 capability_add_hooks(); 61 capability_add_hooks();
62 yama_add_hooks(); 62 yama_add_hooks();
63 loadpin_add_hooks();
63 64
64 /* 65 /*
65 * Load all the remaining security modules. 66 * Load all the remaining security modules.
@@ -1848,7 +1849,6 @@ struct security_hook_heads security_hook_heads = {
1848 .tun_dev_attach = 1849 .tun_dev_attach =
1849 LIST_HEAD_INIT(security_hook_heads.tun_dev_attach), 1850 LIST_HEAD_INIT(security_hook_heads.tun_dev_attach),
1850 .tun_dev_open = LIST_HEAD_INIT(security_hook_heads.tun_dev_open), 1851 .tun_dev_open = LIST_HEAD_INIT(security_hook_heads.tun_dev_open),
1851 .skb_owned_by = LIST_HEAD_INIT(security_hook_heads.skb_owned_by),
1852#endif /* CONFIG_SECURITY_NETWORK */ 1852#endif /* CONFIG_SECURITY_NETWORK */
1853#ifdef CONFIG_SECURITY_NETWORK_XFRM 1853#ifdef CONFIG_SECURITY_NETWORK_XFRM
1854 .xfrm_policy_alloc_security = 1854 .xfrm_policy_alloc_security =
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 3140efa76a75..a86d537eb79b 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -259,7 +259,7 @@ static int __inode_security_revalidate(struct inode *inode,
259 259
260 might_sleep_if(may_sleep); 260 might_sleep_if(may_sleep);
261 261
262 if (isec->initialized == LABEL_INVALID) { 262 if (ss_initialized && isec->initialized != LABEL_INITIALIZED) {
263 if (!may_sleep) 263 if (!may_sleep)
264 return -ECHILD; 264 return -ECHILD;
265 265
@@ -297,6 +297,13 @@ static struct inode_security_struct *inode_security(struct inode *inode)
297 return inode->i_security; 297 return inode->i_security;
298} 298}
299 299
300static struct inode_security_struct *backing_inode_security_novalidate(struct dentry *dentry)
301{
302 struct inode *inode = d_backing_inode(dentry);
303
304 return inode->i_security;
305}
306
300/* 307/*
301 * Get the security label of a dentry's backing inode. 308 * Get the security label of a dentry's backing inode.
302 */ 309 */
@@ -687,7 +694,7 @@ static int selinux_set_mnt_opts(struct super_block *sb,
687 struct superblock_security_struct *sbsec = sb->s_security; 694 struct superblock_security_struct *sbsec = sb->s_security;
688 const char *name = sb->s_type->name; 695 const char *name = sb->s_type->name;
689 struct dentry *root = sbsec->sb->s_root; 696 struct dentry *root = sbsec->sb->s_root;
690 struct inode_security_struct *root_isec = backing_inode_security(root); 697 struct inode_security_struct *root_isec;
691 u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0; 698 u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0;
692 u32 defcontext_sid = 0; 699 u32 defcontext_sid = 0;
693 char **mount_options = opts->mnt_opts; 700 char **mount_options = opts->mnt_opts;
@@ -730,6 +737,8 @@ static int selinux_set_mnt_opts(struct super_block *sb,
730 && (num_opts == 0)) 737 && (num_opts == 0))
731 goto out; 738 goto out;
732 739
740 root_isec = backing_inode_security_novalidate(root);
741
733 /* 742 /*
734 * parse the mount options, check if they are valid sids. 743 * parse the mount options, check if they are valid sids.
735 * also check if someone is trying to mount the same sb more 744 * also check if someone is trying to mount the same sb more
@@ -1623,7 +1632,7 @@ static int current_has_perm(const struct task_struct *tsk,
1623 1632
1624/* Check whether a task is allowed to use a capability. */ 1633/* Check whether a task is allowed to use a capability. */
1625static int cred_has_capability(const struct cred *cred, 1634static int cred_has_capability(const struct cred *cred,
1626 int cap, int audit) 1635 int cap, int audit, bool initns)
1627{ 1636{
1628 struct common_audit_data ad; 1637 struct common_audit_data ad;
1629 struct av_decision avd; 1638 struct av_decision avd;
@@ -1637,10 +1646,10 @@ static int cred_has_capability(const struct cred *cred,
1637 1646
1638 switch (CAP_TO_INDEX(cap)) { 1647 switch (CAP_TO_INDEX(cap)) {
1639 case 0: 1648 case 0:
1640 sclass = SECCLASS_CAPABILITY; 1649 sclass = initns ? SECCLASS_CAPABILITY : SECCLASS_CAP_USERNS;
1641 break; 1650 break;
1642 case 1: 1651 case 1:
1643 sclass = SECCLASS_CAPABILITY2; 1652 sclass = initns ? SECCLASS_CAPABILITY2 : SECCLASS_CAP2_USERNS;
1644 break; 1653 break;
1645 default: 1654 default:
1646 printk(KERN_ERR 1655 printk(KERN_ERR
@@ -1782,7 +1791,6 @@ static int selinux_determine_inode_label(struct inode *dir,
1782 u32 *_new_isid) 1791 u32 *_new_isid)
1783{ 1792{
1784 const struct superblock_security_struct *sbsec = dir->i_sb->s_security; 1793 const struct superblock_security_struct *sbsec = dir->i_sb->s_security;
1785 const struct inode_security_struct *dsec = inode_security(dir);
1786 const struct task_security_struct *tsec = current_security(); 1794 const struct task_security_struct *tsec = current_security();
1787 1795
1788 if ((sbsec->flags & SE_SBINITIALIZED) && 1796 if ((sbsec->flags & SE_SBINITIALIZED) &&
@@ -1792,6 +1800,7 @@ static int selinux_determine_inode_label(struct inode *dir,
1792 tsec->create_sid) { 1800 tsec->create_sid) {
1793 *_new_isid = tsec->create_sid; 1801 *_new_isid = tsec->create_sid;
1794 } else { 1802 } else {
1803 const struct inode_security_struct *dsec = inode_security(dir);
1795 return security_transition_sid(tsec->sid, dsec->sid, tclass, 1804 return security_transition_sid(tsec->sid, dsec->sid, tclass,
1796 name, _new_isid); 1805 name, _new_isid);
1797 } 1806 }
@@ -2076,7 +2085,7 @@ static int selinux_binder_transfer_file(struct task_struct *from,
2076 u32 sid = task_sid(to); 2085 u32 sid = task_sid(to);
2077 struct file_security_struct *fsec = file->f_security; 2086 struct file_security_struct *fsec = file->f_security;
2078 struct dentry *dentry = file->f_path.dentry; 2087 struct dentry *dentry = file->f_path.dentry;
2079 struct inode_security_struct *isec = backing_inode_security(dentry); 2088 struct inode_security_struct *isec;
2080 struct common_audit_data ad; 2089 struct common_audit_data ad;
2081 int rc; 2090 int rc;
2082 2091
@@ -2095,6 +2104,7 @@ static int selinux_binder_transfer_file(struct task_struct *from,
2095 if (unlikely(IS_PRIVATE(d_backing_inode(dentry)))) 2104 if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
2096 return 0; 2105 return 0;
2097 2106
2107 isec = backing_inode_security(dentry);
2098 return avc_has_perm(sid, isec->sid, isec->sclass, file_to_av(file), 2108 return avc_has_perm(sid, isec->sid, isec->sclass, file_to_av(file),
2099 &ad); 2109 &ad);
2100} 2110}
@@ -2143,7 +2153,7 @@ static int selinux_capset(struct cred *new, const struct cred *old,
2143static int selinux_capable(const struct cred *cred, struct user_namespace *ns, 2153static int selinux_capable(const struct cred *cred, struct user_namespace *ns,
2144 int cap, int audit) 2154 int cap, int audit)
2145{ 2155{
2146 return cred_has_capability(cred, cap, audit); 2156 return cred_has_capability(cred, cap, audit, ns == &init_user_ns);
2147} 2157}
2148 2158
2149static int selinux_quotactl(int cmds, int type, int id, struct super_block *sb) 2159static int selinux_quotactl(int cmds, int type, int id, struct super_block *sb)
@@ -2221,7 +2231,7 @@ static int selinux_vm_enough_memory(struct mm_struct *mm, long pages)
2221 int rc, cap_sys_admin = 0; 2231 int rc, cap_sys_admin = 0;
2222 2232
2223 rc = cred_has_capability(current_cred(), CAP_SYS_ADMIN, 2233 rc = cred_has_capability(current_cred(), CAP_SYS_ADMIN,
2224 SECURITY_CAP_NOAUDIT); 2234 SECURITY_CAP_NOAUDIT, true);
2225 if (rc == 0) 2235 if (rc == 0)
2226 cap_sys_admin = 1; 2236 cap_sys_admin = 1;
2227 2237
@@ -2230,6 +2240,20 @@ static int selinux_vm_enough_memory(struct mm_struct *mm, long pages)
2230 2240
2231/* binprm security operations */ 2241/* binprm security operations */
2232 2242
2243static u32 ptrace_parent_sid(struct task_struct *task)
2244{
2245 u32 sid = 0;
2246 struct task_struct *tracer;
2247
2248 rcu_read_lock();
2249 tracer = ptrace_parent(task);
2250 if (tracer)
2251 sid = task_sid(tracer);
2252 rcu_read_unlock();
2253
2254 return sid;
2255}
2256
2233static int check_nnp_nosuid(const struct linux_binprm *bprm, 2257static int check_nnp_nosuid(const struct linux_binprm *bprm,
2234 const struct task_security_struct *old_tsec, 2258 const struct task_security_struct *old_tsec,
2235 const struct task_security_struct *new_tsec) 2259 const struct task_security_struct *new_tsec)
@@ -2351,18 +2375,7 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm)
2351 * changes its SID has the appropriate permit */ 2375 * changes its SID has the appropriate permit */
2352 if (bprm->unsafe & 2376 if (bprm->unsafe &
2353 (LSM_UNSAFE_PTRACE | LSM_UNSAFE_PTRACE_CAP)) { 2377 (LSM_UNSAFE_PTRACE | LSM_UNSAFE_PTRACE_CAP)) {
2354 struct task_struct *tracer; 2378 u32 ptsid = ptrace_parent_sid(current);
2355 struct task_security_struct *sec;
2356 u32 ptsid = 0;
2357
2358 rcu_read_lock();
2359 tracer = ptrace_parent(current);
2360 if (likely(tracer != NULL)) {
2361 sec = __task_cred(tracer)->security;
2362 ptsid = sec->sid;
2363 }
2364 rcu_read_unlock();
2365
2366 if (ptsid != 0) { 2379 if (ptsid != 0) {
2367 rc = avc_has_perm(ptsid, new_tsec->sid, 2380 rc = avc_has_perm(ptsid, new_tsec->sid,
2368 SECCLASS_PROCESS, 2381 SECCLASS_PROCESS,
@@ -3046,7 +3059,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
3046 const void *value, size_t size, int flags) 3059 const void *value, size_t size, int flags)
3047{ 3060{
3048 struct inode *inode = d_backing_inode(dentry); 3061 struct inode *inode = d_backing_inode(dentry);
3049 struct inode_security_struct *isec = backing_inode_security(dentry); 3062 struct inode_security_struct *isec;
3050 struct superblock_security_struct *sbsec; 3063 struct superblock_security_struct *sbsec;
3051 struct common_audit_data ad; 3064 struct common_audit_data ad;
3052 u32 newsid, sid = current_sid(); 3065 u32 newsid, sid = current_sid();
@@ -3065,6 +3078,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
3065 ad.type = LSM_AUDIT_DATA_DENTRY; 3078 ad.type = LSM_AUDIT_DATA_DENTRY;
3066 ad.u.dentry = dentry; 3079 ad.u.dentry = dentry;
3067 3080
3081 isec = backing_inode_security(dentry);
3068 rc = avc_has_perm(sid, isec->sid, isec->sclass, 3082 rc = avc_has_perm(sid, isec->sid, isec->sclass,
3069 FILE__RELABELFROM, &ad); 3083 FILE__RELABELFROM, &ad);
3070 if (rc) 3084 if (rc)
@@ -3123,7 +3137,7 @@ static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name,
3123 int flags) 3137 int flags)
3124{ 3138{
3125 struct inode *inode = d_backing_inode(dentry); 3139 struct inode *inode = d_backing_inode(dentry);
3126 struct inode_security_struct *isec = backing_inode_security(dentry); 3140 struct inode_security_struct *isec;
3127 u32 newsid; 3141 u32 newsid;
3128 int rc; 3142 int rc;
3129 3143
@@ -3140,6 +3154,7 @@ static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name,
3140 return; 3154 return;
3141 } 3155 }
3142 3156
3157 isec = backing_inode_security(dentry);
3143 isec->sclass = inode_mode_to_security_class(inode->i_mode); 3158 isec->sclass = inode_mode_to_security_class(inode->i_mode);
3144 isec->sid = newsid; 3159 isec->sid = newsid;
3145 isec->initialized = LABEL_INITIALIZED; 3160 isec->initialized = LABEL_INITIALIZED;
@@ -3181,7 +3196,7 @@ static int selinux_inode_getsecurity(struct inode *inode, const char *name, void
3181 u32 size; 3196 u32 size;
3182 int error; 3197 int error;
3183 char *context = NULL; 3198 char *context = NULL;
3184 struct inode_security_struct *isec = inode_security(inode); 3199 struct inode_security_struct *isec;
3185 3200
3186 if (strcmp(name, XATTR_SELINUX_SUFFIX)) 3201 if (strcmp(name, XATTR_SELINUX_SUFFIX))
3187 return -EOPNOTSUPP; 3202 return -EOPNOTSUPP;
@@ -3199,7 +3214,8 @@ static int selinux_inode_getsecurity(struct inode *inode, const char *name, void
3199 SECURITY_CAP_NOAUDIT); 3214 SECURITY_CAP_NOAUDIT);
3200 if (!error) 3215 if (!error)
3201 error = cred_has_capability(current_cred(), CAP_MAC_ADMIN, 3216 error = cred_has_capability(current_cred(), CAP_MAC_ADMIN,
3202 SECURITY_CAP_NOAUDIT); 3217 SECURITY_CAP_NOAUDIT, true);
3218 isec = inode_security(inode);
3203 if (!error) 3219 if (!error)
3204 error = security_sid_to_context_force(isec->sid, &context, 3220 error = security_sid_to_context_force(isec->sid, &context,
3205 &size); 3221 &size);
@@ -3220,7 +3236,7 @@ out_nofree:
3220static int selinux_inode_setsecurity(struct inode *inode, const char *name, 3236static int selinux_inode_setsecurity(struct inode *inode, const char *name,
3221 const void *value, size_t size, int flags) 3237 const void *value, size_t size, int flags)
3222{ 3238{
3223 struct inode_security_struct *isec = inode_security(inode); 3239 struct inode_security_struct *isec = inode_security_novalidate(inode);
3224 u32 newsid; 3240 u32 newsid;
3225 int rc; 3241 int rc;
3226 3242
@@ -3309,7 +3325,7 @@ static int ioctl_has_perm(const struct cred *cred, struct file *file,
3309 struct common_audit_data ad; 3325 struct common_audit_data ad;
3310 struct file_security_struct *fsec = file->f_security; 3326 struct file_security_struct *fsec = file->f_security;
3311 struct inode *inode = file_inode(file); 3327 struct inode *inode = file_inode(file);
3312 struct inode_security_struct *isec = inode_security(inode); 3328 struct inode_security_struct *isec;
3313 struct lsm_ioctlop_audit ioctl; 3329 struct lsm_ioctlop_audit ioctl;
3314 u32 ssid = cred_sid(cred); 3330 u32 ssid = cred_sid(cred);
3315 int rc; 3331 int rc;
@@ -3333,6 +3349,7 @@ static int ioctl_has_perm(const struct cred *cred, struct file *file,
3333 if (unlikely(IS_PRIVATE(inode))) 3349 if (unlikely(IS_PRIVATE(inode)))
3334 return 0; 3350 return 0;
3335 3351
3352 isec = inode_security(inode);
3336 rc = avc_has_extended_perms(ssid, isec->sid, isec->sclass, 3353 rc = avc_has_extended_perms(ssid, isec->sid, isec->sclass,
3337 requested, driver, xperm, &ad); 3354 requested, driver, xperm, &ad);
3338out: 3355out:
@@ -3374,7 +3391,7 @@ static int selinux_file_ioctl(struct file *file, unsigned int cmd,
3374 case KDSKBENT: 3391 case KDSKBENT:
3375 case KDSKBSENT: 3392 case KDSKBSENT:
3376 error = cred_has_capability(cred, CAP_SYS_TTY_CONFIG, 3393 error = cred_has_capability(cred, CAP_SYS_TTY_CONFIG,
3377 SECURITY_CAP_AUDIT); 3394 SECURITY_CAP_AUDIT, true);
3378 break; 3395 break;
3379 3396
3380 /* default case assumes that the command will go 3397 /* default case assumes that the command will go
@@ -3463,8 +3480,9 @@ static int selinux_file_mprotect(struct vm_area_struct *vma,
3463 vma->vm_end <= vma->vm_mm->brk) { 3480 vma->vm_end <= vma->vm_mm->brk) {
3464 rc = cred_has_perm(cred, cred, PROCESS__EXECHEAP); 3481 rc = cred_has_perm(cred, cred, PROCESS__EXECHEAP);
3465 } else if (!vma->vm_file && 3482 } else if (!vma->vm_file &&
3466 vma->vm_start <= vma->vm_mm->start_stack && 3483 ((vma->vm_start <= vma->vm_mm->start_stack &&
3467 vma->vm_end >= vma->vm_mm->start_stack) { 3484 vma->vm_end >= vma->vm_mm->start_stack) ||
3485 vma_is_stack_for_task(vma, current))) {
3468 rc = current_has_perm(current, PROCESS__EXECSTACK); 3486 rc = current_has_perm(current, PROCESS__EXECSTACK);
3469 } else if (vma->vm_file && vma->anon_vma) { 3487 } else if (vma->vm_file && vma->anon_vma) {
3470 /* 3488 /*
@@ -3720,6 +3738,52 @@ static int selinux_kernel_module_request(char *kmod_name)
3720 SYSTEM__MODULE_REQUEST, &ad); 3738 SYSTEM__MODULE_REQUEST, &ad);
3721} 3739}
3722 3740
3741static int selinux_kernel_module_from_file(struct file *file)
3742{
3743 struct common_audit_data ad;
3744 struct inode_security_struct *isec;
3745 struct file_security_struct *fsec;
3746 u32 sid = current_sid();
3747 int rc;
3748
3749 /* init_module */
3750 if (file == NULL)
3751 return avc_has_perm(sid, sid, SECCLASS_SYSTEM,
3752 SYSTEM__MODULE_LOAD, NULL);
3753
3754 /* finit_module */
3755
3756 ad.type = LSM_AUDIT_DATA_PATH;
3757 ad.u.path = file->f_path;
3758
3759 fsec = file->f_security;
3760 if (sid != fsec->sid) {
3761 rc = avc_has_perm(sid, fsec->sid, SECCLASS_FD, FD__USE, &ad);
3762 if (rc)
3763 return rc;
3764 }
3765
3766 isec = inode_security(file_inode(file));
3767 return avc_has_perm(sid, isec->sid, SECCLASS_SYSTEM,
3768 SYSTEM__MODULE_LOAD, &ad);
3769}
3770
3771static int selinux_kernel_read_file(struct file *file,
3772 enum kernel_read_file_id id)
3773{
3774 int rc = 0;
3775
3776 switch (id) {
3777 case READING_MODULE:
3778 rc = selinux_kernel_module_from_file(file);
3779 break;
3780 default:
3781 break;
3782 }
3783
3784 return rc;
3785}
3786
3723static int selinux_task_setpgid(struct task_struct *p, pid_t pgid) 3787static int selinux_task_setpgid(struct task_struct *p, pid_t pgid)
3724{ 3788{
3725 return current_has_perm(p, PROCESS__SETPGID); 3789 return current_has_perm(p, PROCESS__SETPGID);
@@ -4599,6 +4663,7 @@ static int selinux_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *
4599{ 4663{
4600 u32 peer_secid = SECSID_NULL; 4664 u32 peer_secid = SECSID_NULL;
4601 u16 family; 4665 u16 family;
4666 struct inode_security_struct *isec;
4602 4667
4603 if (skb && skb->protocol == htons(ETH_P_IP)) 4668 if (skb && skb->protocol == htons(ETH_P_IP))
4604 family = PF_INET; 4669 family = PF_INET;
@@ -4609,9 +4674,10 @@ static int selinux_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *
4609 else 4674 else
4610 goto out; 4675 goto out;
4611 4676
4612 if (sock && family == PF_UNIX) 4677 if (sock && family == PF_UNIX) {
4613 selinux_inode_getsecid(SOCK_INODE(sock), &peer_secid); 4678 isec = inode_security_novalidate(SOCK_INODE(sock));
4614 else if (skb) 4679 peer_secid = isec->sid;
4680 } else if (skb)
4615 selinux_skb_peerlbl_sid(skb, family, &peer_secid); 4681 selinux_skb_peerlbl_sid(skb, family, &peer_secid);
4616 4682
4617out: 4683out:
@@ -5676,7 +5742,6 @@ static int selinux_setprocattr(struct task_struct *p,
5676 char *name, void *value, size_t size) 5742 char *name, void *value, size_t size)
5677{ 5743{
5678 struct task_security_struct *tsec; 5744 struct task_security_struct *tsec;
5679 struct task_struct *tracer;
5680 struct cred *new; 5745 struct cred *new;
5681 u32 sid = 0, ptsid; 5746 u32 sid = 0, ptsid;
5682 int error; 5747 int error;
@@ -5783,14 +5848,8 @@ static int selinux_setprocattr(struct task_struct *p,
5783 5848
5784 /* Check for ptracing, and update the task SID if ok. 5849 /* Check for ptracing, and update the task SID if ok.
5785 Otherwise, leave SID unchanged and fail. */ 5850 Otherwise, leave SID unchanged and fail. */
5786 ptsid = 0; 5851 ptsid = ptrace_parent_sid(p);
5787 rcu_read_lock(); 5852 if (ptsid != 0) {
5788 tracer = ptrace_parent(p);
5789 if (tracer)
5790 ptsid = task_sid(tracer);
5791 rcu_read_unlock();
5792
5793 if (tracer) {
5794 error = avc_has_perm(ptsid, sid, SECCLASS_PROCESS, 5853 error = avc_has_perm(ptsid, sid, SECCLASS_PROCESS,
5795 PROCESS__PTRACE, NULL); 5854 PROCESS__PTRACE, NULL);
5796 if (error) 5855 if (error)
@@ -6021,6 +6080,7 @@ static struct security_hook_list selinux_hooks[] = {
6021 LSM_HOOK_INIT(kernel_act_as, selinux_kernel_act_as), 6080 LSM_HOOK_INIT(kernel_act_as, selinux_kernel_act_as),
6022 LSM_HOOK_INIT(kernel_create_files_as, selinux_kernel_create_files_as), 6081 LSM_HOOK_INIT(kernel_create_files_as, selinux_kernel_create_files_as),
6023 LSM_HOOK_INIT(kernel_module_request, selinux_kernel_module_request), 6082 LSM_HOOK_INIT(kernel_module_request, selinux_kernel_module_request),
6083 LSM_HOOK_INIT(kernel_read_file, selinux_kernel_read_file),
6024 LSM_HOOK_INIT(task_setpgid, selinux_task_setpgid), 6084 LSM_HOOK_INIT(task_setpgid, selinux_task_setpgid),
6025 LSM_HOOK_INIT(task_getpgid, selinux_task_getpgid), 6085 LSM_HOOK_INIT(task_getpgid, selinux_task_getpgid),
6026 LSM_HOOK_INIT(task_getsid, selinux_task_getsid), 6086 LSM_HOOK_INIT(task_getsid, selinux_task_getsid),
diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h
index ef83c4b85a33..1f1f4b2f6018 100644
--- a/security/selinux/include/classmap.h
+++ b/security/selinux/include/classmap.h
@@ -12,6 +12,18 @@
12#define COMMON_IPC_PERMS "create", "destroy", "getattr", "setattr", "read", \ 12#define COMMON_IPC_PERMS "create", "destroy", "getattr", "setattr", "read", \
13 "write", "associate", "unix_read", "unix_write" 13 "write", "associate", "unix_read", "unix_write"
14 14
15#define COMMON_CAP_PERMS "chown", "dac_override", "dac_read_search", \
16 "fowner", "fsetid", "kill", "setgid", "setuid", "setpcap", \
17 "linux_immutable", "net_bind_service", "net_broadcast", \
18 "net_admin", "net_raw", "ipc_lock", "ipc_owner", "sys_module", \
19 "sys_rawio", "sys_chroot", "sys_ptrace", "sys_pacct", "sys_admin", \
20 "sys_boot", "sys_nice", "sys_resource", "sys_time", \
21 "sys_tty_config", "mknod", "lease", "audit_write", \
22 "audit_control", "setfcap"
23
24#define COMMON_CAP2_PERMS "mac_override", "mac_admin", "syslog", \
25 "wake_alarm", "block_suspend", "audit_read"
26
15/* 27/*
16 * Note: The name for any socket class should be suffixed by "socket", 28 * Note: The name for any socket class should be suffixed by "socket",
17 * and doesn't contain more than one substr of "socket". 29 * and doesn't contain more than one substr of "socket".
@@ -32,16 +44,9 @@ struct security_class_mapping secclass_map[] = {
32 "setsockcreate", NULL } }, 44 "setsockcreate", NULL } },
33 { "system", 45 { "system",
34 { "ipc_info", "syslog_read", "syslog_mod", 46 { "ipc_info", "syslog_read", "syslog_mod",
35 "syslog_console", "module_request", NULL } }, 47 "syslog_console", "module_request", "module_load", NULL } },
36 { "capability", 48 { "capability",
37 { "chown", "dac_override", "dac_read_search", 49 { COMMON_CAP_PERMS, NULL } },
38 "fowner", "fsetid", "kill", "setgid", "setuid", "setpcap",
39 "linux_immutable", "net_bind_service", "net_broadcast",
40 "net_admin", "net_raw", "ipc_lock", "ipc_owner", "sys_module",
41 "sys_rawio", "sys_chroot", "sys_ptrace", "sys_pacct", "sys_admin",
42 "sys_boot", "sys_nice", "sys_resource", "sys_time",
43 "sys_tty_config", "mknod", "lease", "audit_write",
44 "audit_control", "setfcap", NULL } },
45 { "filesystem", 50 { "filesystem",
46 { "mount", "remount", "unmount", "getattr", 51 { "mount", "remount", "unmount", "getattr",
47 "relabelfrom", "relabelto", "associate", "quotamod", 52 "relabelfrom", "relabelto", "associate", "quotamod",
@@ -150,12 +155,15 @@ struct security_class_mapping secclass_map[] = {
150 { "memprotect", { "mmap_zero", NULL } }, 155 { "memprotect", { "mmap_zero", NULL } },
151 { "peer", { "recv", NULL } }, 156 { "peer", { "recv", NULL } },
152 { "capability2", 157 { "capability2",
153 { "mac_override", "mac_admin", "syslog", "wake_alarm", "block_suspend", 158 { COMMON_CAP2_PERMS, NULL } },
154 "audit_read", NULL } },
155 { "kernel_service", { "use_as_override", "create_files_as", NULL } }, 159 { "kernel_service", { "use_as_override", "create_files_as", NULL } },
156 { "tun_socket", 160 { "tun_socket",
157 { COMMON_SOCK_PERMS, "attach_queue", NULL } }, 161 { COMMON_SOCK_PERMS, "attach_queue", NULL } },
158 { "binder", { "impersonate", "call", "set_context_mgr", "transfer", 162 { "binder", { "impersonate", "call", "set_context_mgr", "transfer",
159 NULL } }, 163 NULL } },
164 { "cap_userns",
165 { COMMON_CAP_PERMS, NULL } },
166 { "cap2_userns",
167 { COMMON_CAP2_PERMS, NULL } },
160 { NULL } 168 { NULL }
161 }; 169 };
diff --git a/security/selinux/include/conditional.h b/security/selinux/include/conditional.h
index 67ce7a8d8301..ff4fddca9050 100644
--- a/security/selinux/include/conditional.h
+++ b/security/selinux/include/conditional.h
@@ -17,6 +17,6 @@ int security_get_bools(int *len, char ***names, int **values);
17 17
18int security_set_bools(int len, int *values); 18int security_set_bools(int len, int *values);
19 19
20int security_get_bool_value(int bool); 20int security_get_bool_value(int index);
21 21
22#endif 22#endif
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h
index a2ae05414ba1..c21e135460a5 100644
--- a/security/selinux/include/objsec.h
+++ b/security/selinux/include/objsec.h
@@ -38,9 +38,8 @@ struct task_security_struct {
38}; 38};
39 39
40enum label_initialized { 40enum label_initialized {
41 LABEL_MISSING, /* not initialized */ 41 LABEL_INVALID, /* invalid or not initialized */
42 LABEL_INITIALIZED, /* inizialized */ 42 LABEL_INITIALIZED /* initialized */
43 LABEL_INVALID /* invalid */
44}; 43};
45 44
46struct inode_security_struct { 45struct inode_security_struct {
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index ebda97333f1b..89df64672b89 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -2696,7 +2696,7 @@ out:
2696 return rc; 2696 return rc;
2697} 2697}
2698 2698
2699int security_get_bool_value(int bool) 2699int security_get_bool_value(int index)
2700{ 2700{
2701 int rc; 2701 int rc;
2702 int len; 2702 int len;
@@ -2705,10 +2705,10 @@ int security_get_bool_value(int bool)
2705 2705
2706 rc = -EFAULT; 2706 rc = -EFAULT;
2707 len = policydb.p_bools.nprim; 2707 len = policydb.p_bools.nprim;
2708 if (bool >= len) 2708 if (index >= len)
2709 goto out; 2709 goto out;
2710 2710
2711 rc = policydb.bool_val_to_struct[bool]->state; 2711 rc = policydb.bool_val_to_struct[index]->state;
2712out: 2712out:
2713 read_unlock(&policy_rwlock); 2713 read_unlock(&policy_rwlock);
2714 return rc; 2714 return rc;
diff --git a/security/yama/yama_lsm.c b/security/yama/yama_lsm.c
index cb6ed10816d4..9b756b1f3dc5 100644
--- a/security/yama/yama_lsm.c
+++ b/security/yama/yama_lsm.c
@@ -18,6 +18,7 @@
18#include <linux/prctl.h> 18#include <linux/prctl.h>
19#include <linux/ratelimit.h> 19#include <linux/ratelimit.h>
20#include <linux/workqueue.h> 20#include <linux/workqueue.h>
21#include <linux/string_helpers.h>
21 22
22#define YAMA_SCOPE_DISABLED 0 23#define YAMA_SCOPE_DISABLED 0
23#define YAMA_SCOPE_RELATIONAL 1 24#define YAMA_SCOPE_RELATIONAL 1
@@ -41,6 +42,22 @@ static DEFINE_SPINLOCK(ptracer_relations_lock);
41static void yama_relation_cleanup(struct work_struct *work); 42static void yama_relation_cleanup(struct work_struct *work);
42static DECLARE_WORK(yama_relation_work, yama_relation_cleanup); 43static DECLARE_WORK(yama_relation_work, yama_relation_cleanup);
43 44
45static void report_access(const char *access, struct task_struct *target,
46 struct task_struct *agent)
47{
48 char *target_cmd, *agent_cmd;
49
50 target_cmd = kstrdup_quotable_cmdline(target, GFP_ATOMIC);
51 agent_cmd = kstrdup_quotable_cmdline(agent, GFP_ATOMIC);
52
53 pr_notice_ratelimited(
54 "ptrace %s of \"%s\"[%d] was attempted by \"%s\"[%d]\n",
55 access, target_cmd, target->pid, agent_cmd, agent->pid);
56
57 kfree(agent_cmd);
58 kfree(target_cmd);
59}
60
44/** 61/**
45 * yama_relation_cleanup - remove invalid entries from the relation list 62 * yama_relation_cleanup - remove invalid entries from the relation list
46 * 63 *
@@ -307,11 +324,8 @@ static int yama_ptrace_access_check(struct task_struct *child,
307 } 324 }
308 } 325 }
309 326
310 if (rc && (mode & PTRACE_MODE_NOAUDIT) == 0) { 327 if (rc && (mode & PTRACE_MODE_NOAUDIT) == 0)
311 printk_ratelimited(KERN_NOTICE 328 report_access("attach", child, current);
312 "ptrace of pid %d was attempted by: %s (pid %d)\n",
313 child->pid, current->comm, current->pid);
314 }
315 329
316 return rc; 330 return rc;
317} 331}
@@ -337,11 +351,8 @@ int yama_ptrace_traceme(struct task_struct *parent)
337 break; 351 break;
338 } 352 }
339 353
340 if (rc) { 354 if (rc)
341 printk_ratelimited(KERN_NOTICE 355 report_access("traceme", current, parent);
342 "ptraceme of pid %d was attempted by: %s (pid %d)\n",
343 current->pid, parent->comm, parent->pid);
344 }
345 356
346 return rc; 357 return rc;
347} 358}