diff options
author | David Howells <dhowells@redhat.com> | 2014-07-22 16:54:43 -0400 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2014-07-22 16:54:43 -0400 |
commit | 64724cfc6eea920dbaada14f0fb978b1dd31192d (patch) | |
tree | d2f491be07a05e2d96b5c8b8e5a0a878f285eb22 | |
parent | 6204e0025566ad3992ce649d4f44b7e8cdde2293 (diff) | |
parent | 7d2ce2320e8efdc4a6dcbae7b329ed3f0d1cd778 (diff) |
Merge remote-tracking branch 'integrity/next-with-keys' into keys-next
Signed-off-by: David Howells <dhowells@redhat.com>
-rw-r--r-- | Documentation/kernel-parameters.txt | 5 | ||||
-rw-r--r-- | crypto/asymmetric_keys/asymmetric_keys.h | 2 | ||||
-rw-r--r-- | crypto/asymmetric_keys/asymmetric_type.c | 51 | ||||
-rw-r--r-- | crypto/asymmetric_keys/x509_public_key.c | 109 | ||||
-rw-r--r-- | include/keys/system_keyring.h | 10 | ||||
-rw-r--r-- | include/linux/key.h | 1 | ||||
-rw-r--r-- | kernel/system_keyring.c | 1 | ||||
-rw-r--r-- | security/integrity/digsig.c | 28 | ||||
-rw-r--r-- | security/integrity/ima/Kconfig | 10 | ||||
-rw-r--r-- | security/integrity/ima/ima.h | 12 | ||||
-rw-r--r-- | security/integrity/ima/ima_main.c | 10 | ||||
-rw-r--r-- | security/integrity/integrity.h | 5 | ||||
-rw-r--r-- | security/keys/keyctl.c | 6 |
13 files changed, 225 insertions, 25 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 8b2ab548b6e4..90c12c591168 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -566,6 +566,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
566 | possible to determine what the correct size should be. | 566 | possible to determine what the correct size should be. |
567 | This option provides an override for these situations. | 567 | This option provides an override for these situations. |
568 | 568 | ||
569 | ca_keys= [KEYS] This parameter identifies a specific key(s) on | ||
570 | the system trusted keyring to be used for certificate | ||
571 | trust validation. | ||
572 | format: { id:<keyid> | builtin } | ||
573 | |||
569 | ccw_timeout_log [S390] | 574 | ccw_timeout_log [S390] |
570 | See Documentation/s390/CommonIO for details. | 575 | See Documentation/s390/CommonIO for details. |
571 | 576 | ||
diff --git a/crypto/asymmetric_keys/asymmetric_keys.h b/crypto/asymmetric_keys/asymmetric_keys.h index 515b63430812..a63c551c6557 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 | int asymmetric_keyid_match(const char *kid, const char *id); | ||
13 | |||
12 | static inline const char *asymmetric_key_id(const struct key *key) | 14 | static inline const char *asymmetric_key_id(const struct key *key) |
13 | { | 15 | { |
14 | return key->type_data.p[1]; | 16 | return key->type_data.p[1]; |
diff --git a/crypto/asymmetric_keys/asymmetric_type.c b/crypto/asymmetric_keys/asymmetric_type.c index 21960a4e74e8..eb8cd46961a5 100644 --- a/crypto/asymmetric_keys/asymmetric_type.c +++ b/crypto/asymmetric_keys/asymmetric_type.c | |||
@@ -23,6 +23,35 @@ static LIST_HEAD(asymmetric_key_parsers); | |||
23 | static DECLARE_RWSEM(asymmetric_key_parsers_sem); | 23 | static DECLARE_RWSEM(asymmetric_key_parsers_sem); |
24 | 24 | ||
25 | /* | 25 | /* |
26 | * Match asymmetric key id with partial match | ||
27 | * @id: key id to match in a form "id:<id>" | ||
28 | */ | ||
29 | int asymmetric_keyid_match(const char *kid, const char *id) | ||
30 | { | ||
31 | size_t idlen, kidlen; | ||
32 | |||
33 | if (!kid || !id) | ||
34 | return 0; | ||
35 | |||
36 | /* make it possible to use id as in the request: "id:<id>" */ | ||
37 | if (strncmp(id, "id:", 3) == 0) | ||
38 | id += 3; | ||
39 | |||
40 | /* Anything after here requires a partial match on the ID string */ | ||
41 | idlen = strlen(id); | ||
42 | kidlen = strlen(kid); | ||
43 | if (idlen > kidlen) | ||
44 | return 0; | ||
45 | |||
46 | kid += kidlen - idlen; | ||
47 | if (strcasecmp(id, kid) != 0) | ||
48 | return 0; | ||
49 | |||
50 | return 1; | ||
51 | } | ||
52 | EXPORT_SYMBOL_GPL(asymmetric_keyid_match); | ||
53 | |||
54 | /* | ||
26 | * Match asymmetric keys on (part of) their name | 55 | * Match asymmetric keys on (part of) their name |
27 | * We have some shorthand methods for matching keys. We allow: | 56 | * We have some shorthand methods for matching keys. We allow: |
28 | * | 57 | * |
@@ -34,9 +63,8 @@ static int asymmetric_key_match(const struct key *key, const void *description) | |||
34 | { | 63 | { |
35 | const struct asymmetric_key_subtype *subtype = asymmetric_key_subtype(key); | 64 | const struct asymmetric_key_subtype *subtype = asymmetric_key_subtype(key); |
36 | const char *spec = description; | 65 | const char *spec = description; |
37 | const char *id, *kid; | 66 | const char *id; |
38 | ptrdiff_t speclen; | 67 | ptrdiff_t speclen; |
39 | size_t idlen, kidlen; | ||
40 | 68 | ||
41 | if (!subtype || !spec || !*spec) | 69 | if (!subtype || !spec || !*spec) |
42 | return 0; | 70 | return 0; |
@@ -55,23 +83,8 @@ static int asymmetric_key_match(const struct key *key, const void *description) | |||
55 | speclen = id - spec; | 83 | speclen = id - spec; |
56 | id++; | 84 | id++; |
57 | 85 | ||
58 | /* Anything after here requires a partial match on the ID string */ | 86 | if (speclen == 2 && memcmp(spec, "id", 2) == 0) |
59 | kid = asymmetric_key_id(key); | 87 | return asymmetric_keyid_match(asymmetric_key_id(key), id); |
60 | if (!kid) | ||
61 | return 0; | ||
62 | |||
63 | idlen = strlen(id); | ||
64 | kidlen = strlen(kid); | ||
65 | if (idlen > kidlen) | ||
66 | return 0; | ||
67 | |||
68 | kid += kidlen - idlen; | ||
69 | if (strcasecmp(id, kid) != 0) | ||
70 | return 0; | ||
71 | |||
72 | if (speclen == 2 && | ||
73 | memcmp(spec, "id", 2) == 0) | ||
74 | return 1; | ||
75 | 88 | ||
76 | if (speclen == subtype->name_len && | 89 | if (speclen == subtype->name_len && |
77 | memcmp(spec, subtype->name, speclen) == 0) | 90 | memcmp(spec, subtype->name, speclen) == 0) |
diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c index 3fc8a0634ed7..a0f7cd196c9b 100644 --- a/crypto/asymmetric_keys/x509_public_key.c +++ b/crypto/asymmetric_keys/x509_public_key.c | |||
@@ -18,11 +18,80 @@ | |||
18 | #include <linux/asn1_decoder.h> | 18 | #include <linux/asn1_decoder.h> |
19 | #include <keys/asymmetric-subtype.h> | 19 | #include <keys/asymmetric-subtype.h> |
20 | #include <keys/asymmetric-parser.h> | 20 | #include <keys/asymmetric-parser.h> |
21 | #include <keys/system_keyring.h> | ||
21 | #include <crypto/hash.h> | 22 | #include <crypto/hash.h> |
22 | #include "asymmetric_keys.h" | 23 | #include "asymmetric_keys.h" |
23 | #include "public_key.h" | 24 | #include "public_key.h" |
24 | #include "x509_parser.h" | 25 | #include "x509_parser.h" |
25 | 26 | ||
27 | static bool use_builtin_keys; | ||
28 | static char *ca_keyid; | ||
29 | |||
30 | #ifndef MODULE | ||
31 | static int __init ca_keys_setup(char *str) | ||
32 | { | ||
33 | if (!str) /* default system keyring */ | ||
34 | return 1; | ||
35 | |||
36 | if (strncmp(str, "id:", 3) == 0) | ||
37 | ca_keyid = str; /* owner key 'id:xxxxxx' */ | ||
38 | else if (strcmp(str, "builtin") == 0) | ||
39 | use_builtin_keys = true; | ||
40 | |||
41 | return 1; | ||
42 | } | ||
43 | __setup("ca_keys=", ca_keys_setup); | ||
44 | #endif | ||
45 | |||
46 | /* | ||
47 | * Find a key in the given keyring by issuer and authority. | ||
48 | */ | ||
49 | static struct key *x509_request_asymmetric_key(struct key *keyring, | ||
50 | const char *signer, | ||
51 | size_t signer_len, | ||
52 | const char *authority, | ||
53 | size_t auth_len) | ||
54 | { | ||
55 | key_ref_t key; | ||
56 | char *id; | ||
57 | |||
58 | /* Construct an identifier. */ | ||
59 | id = kmalloc(signer_len + 2 + auth_len + 1, GFP_KERNEL); | ||
60 | if (!id) | ||
61 | return ERR_PTR(-ENOMEM); | ||
62 | |||
63 | memcpy(id, signer, signer_len); | ||
64 | id[signer_len + 0] = ':'; | ||
65 | id[signer_len + 1] = ' '; | ||
66 | memcpy(id + signer_len + 2, authority, auth_len); | ||
67 | id[signer_len + 2 + auth_len] = 0; | ||
68 | |||
69 | pr_debug("Look up: \"%s\"\n", id); | ||
70 | |||
71 | key = keyring_search(make_key_ref(keyring, 1), | ||
72 | &key_type_asymmetric, id); | ||
73 | if (IS_ERR(key)) | ||
74 | pr_debug("Request for module key '%s' err %ld\n", | ||
75 | id, PTR_ERR(key)); | ||
76 | kfree(id); | ||
77 | |||
78 | if (IS_ERR(key)) { | ||
79 | switch (PTR_ERR(key)) { | ||
80 | /* Hide some search errors */ | ||
81 | case -EACCES: | ||
82 | case -ENOTDIR: | ||
83 | case -EAGAIN: | ||
84 | return ERR_PTR(-ENOKEY); | ||
85 | default: | ||
86 | return ERR_CAST(key); | ||
87 | } | ||
88 | } | ||
89 | |||
90 | pr_devel("<==%s() = 0 [%x]\n", __func__, | ||
91 | key_serial(key_ref_to_ptr(key))); | ||
92 | return key_ref_to_ptr(key); | ||
93 | } | ||
94 | |||
26 | /* | 95 | /* |
27 | * Set up the signature parameters in an X.509 certificate. This involves | 96 | * Set up the signature parameters in an X.509 certificate. This involves |
28 | * digesting the signed data and extracting the signature. | 97 | * digesting the signed data and extracting the signature. |
@@ -103,6 +172,40 @@ int x509_check_signature(const struct public_key *pub, | |||
103 | EXPORT_SYMBOL_GPL(x509_check_signature); | 172 | EXPORT_SYMBOL_GPL(x509_check_signature); |
104 | 173 | ||
105 | /* | 174 | /* |
175 | * Check the new certificate against the ones in the trust keyring. If one of | ||
176 | * those is the signing key and validates the new certificate, then mark the | ||
177 | * new certificate as being trusted. | ||
178 | * | ||
179 | * Return 0 if the new certificate was successfully validated, 1 if we couldn't | ||
180 | * find a matching parent certificate in the trusted list and an error if there | ||
181 | * is a matching certificate but the signature check fails. | ||
182 | */ | ||
183 | static int x509_validate_trust(struct x509_certificate *cert, | ||
184 | struct key *trust_keyring) | ||
185 | { | ||
186 | struct key *key; | ||
187 | int ret = 1; | ||
188 | |||
189 | if (!trust_keyring) | ||
190 | return -EOPNOTSUPP; | ||
191 | |||
192 | if (ca_keyid && !asymmetric_keyid_match(cert->authority, ca_keyid)) | ||
193 | return -EPERM; | ||
194 | |||
195 | key = x509_request_asymmetric_key(trust_keyring, | ||
196 | cert->issuer, strlen(cert->issuer), | ||
197 | cert->authority, | ||
198 | strlen(cert->authority)); | ||
199 | if (!IS_ERR(key)) { | ||
200 | if (!use_builtin_keys | ||
201 | || test_bit(KEY_FLAG_BUILTIN, &key->flags)) | ||
202 | ret = x509_check_signature(key->payload.data, cert); | ||
203 | key_put(key); | ||
204 | } | ||
205 | return ret; | ||
206 | } | ||
207 | |||
208 | /* | ||
106 | * Attempt to parse a data blob for a key as an X509 certificate. | 209 | * Attempt to parse a data blob for a key as an X509 certificate. |
107 | */ | 210 | */ |
108 | static int x509_key_preparse(struct key_preparsed_payload *prep) | 211 | static int x509_key_preparse(struct key_preparsed_payload *prep) |
@@ -155,9 +258,13 @@ static int x509_key_preparse(struct key_preparsed_payload *prep) | |||
155 | /* Check the signature on the key if it appears to be self-signed */ | 258 | /* Check the signature on the key if it appears to be self-signed */ |
156 | if (!cert->authority || | 259 | if (!cert->authority || |
157 | strcmp(cert->fingerprint, cert->authority) == 0) { | 260 | strcmp(cert->fingerprint, cert->authority) == 0) { |
158 | ret = x509_check_signature(cert->pub, cert); | 261 | ret = x509_check_signature(cert->pub, cert); /* self-signed */ |
159 | if (ret < 0) | 262 | if (ret < 0) |
160 | goto error_free_cert; | 263 | goto error_free_cert; |
264 | } else if (!prep->trusted) { | ||
265 | ret = x509_validate_trust(cert, get_system_trusted_keyring()); | ||
266 | if (!ret) | ||
267 | prep->trusted = 1; | ||
161 | } | 268 | } |
162 | 269 | ||
163 | /* Propose a description */ | 270 | /* Propose a description */ |
diff --git a/include/keys/system_keyring.h b/include/keys/system_keyring.h index 8dabc399bd1d..72665eb80692 100644 --- a/include/keys/system_keyring.h +++ b/include/keys/system_keyring.h | |||
@@ -17,7 +17,15 @@ | |||
17 | #include <linux/key.h> | 17 | #include <linux/key.h> |
18 | 18 | ||
19 | extern struct key *system_trusted_keyring; | 19 | extern struct key *system_trusted_keyring; |
20 | 20 | static inline struct key *get_system_trusted_keyring(void) | |
21 | { | ||
22 | return system_trusted_keyring; | ||
23 | } | ||
24 | #else | ||
25 | static inline struct key *get_system_trusted_keyring(void) | ||
26 | { | ||
27 | return NULL; | ||
28 | } | ||
21 | #endif | 29 | #endif |
22 | 30 | ||
23 | #endif /* _KEYS_SYSTEM_KEYRING_H */ | 31 | #endif /* _KEYS_SYSTEM_KEYRING_H */ |
diff --git a/include/linux/key.h b/include/linux/key.h index 017b0826642f..65316f7ae794 100644 --- a/include/linux/key.h +++ b/include/linux/key.h | |||
@@ -170,6 +170,7 @@ struct key { | |||
170 | #define KEY_FLAG_INVALIDATED 7 /* set if key has been invalidated */ | 170 | #define KEY_FLAG_INVALIDATED 7 /* set if key has been invalidated */ |
171 | #define KEY_FLAG_TRUSTED 8 /* set if key is trusted */ | 171 | #define KEY_FLAG_TRUSTED 8 /* set if key is trusted */ |
172 | #define KEY_FLAG_TRUSTED_ONLY 9 /* set if keyring only accepts links to trusted keys */ | 172 | #define KEY_FLAG_TRUSTED_ONLY 9 /* set if keyring only accepts links to trusted keys */ |
173 | #define KEY_FLAG_BUILTIN 10 /* set if key is builtin */ | ||
173 | 174 | ||
174 | /* the key type and key description string | 175 | /* the key type and key description string |
175 | * - the desc is used to match a key against search criteria | 176 | * - the desc is used to match a key against search criteria |
diff --git a/kernel/system_keyring.c b/kernel/system_keyring.c index 52ebc70263f4..875f64e8935b 100644 --- a/kernel/system_keyring.c +++ b/kernel/system_keyring.c | |||
@@ -89,6 +89,7 @@ static __init int load_system_certificate_list(void) | |||
89 | pr_err("Problem loading in-kernel X.509 certificate (%ld)\n", | 89 | pr_err("Problem loading in-kernel X.509 certificate (%ld)\n", |
90 | PTR_ERR(key)); | 90 | PTR_ERR(key)); |
91 | } else { | 91 | } else { |
92 | set_bit(KEY_FLAG_BUILTIN, &key_ref_to_ptr(key)->flags); | ||
92 | pr_notice("Loaded X.509 cert '%s'\n", | 93 | pr_notice("Loaded X.509 cert '%s'\n", |
93 | key_ref_to_ptr(key)->description); | 94 | key_ref_to_ptr(key)->description); |
94 | key_ref_put(key); | 95 | key_ref_put(key); |
diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c index b4af4ebc5be2..8d4fbff8b87c 100644 --- a/security/integrity/digsig.c +++ b/security/integrity/digsig.c | |||
@@ -13,7 +13,9 @@ | |||
13 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 13 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
14 | 14 | ||
15 | #include <linux/err.h> | 15 | #include <linux/err.h> |
16 | #include <linux/sched.h> | ||
16 | #include <linux/rbtree.h> | 17 | #include <linux/rbtree.h> |
18 | #include <linux/cred.h> | ||
17 | #include <linux/key-type.h> | 19 | #include <linux/key-type.h> |
18 | #include <linux/digsig.h> | 20 | #include <linux/digsig.h> |
19 | 21 | ||
@@ -24,7 +26,11 @@ static struct key *keyring[INTEGRITY_KEYRING_MAX]; | |||
24 | static const char *keyring_name[INTEGRITY_KEYRING_MAX] = { | 26 | static const char *keyring_name[INTEGRITY_KEYRING_MAX] = { |
25 | "_evm", | 27 | "_evm", |
26 | "_module", | 28 | "_module", |
29 | #ifndef CONFIG_IMA_TRUSTED_KEYRING | ||
27 | "_ima", | 30 | "_ima", |
31 | #else | ||
32 | ".ima", | ||
33 | #endif | ||
28 | }; | 34 | }; |
29 | 35 | ||
30 | int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen, | 36 | int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen, |
@@ -56,3 +62,25 @@ int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen, | |||
56 | 62 | ||
57 | return -EOPNOTSUPP; | 63 | return -EOPNOTSUPP; |
58 | } | 64 | } |
65 | |||
66 | int integrity_init_keyring(const unsigned int id) | ||
67 | { | ||
68 | const struct cred *cred = current_cred(); | ||
69 | int err = 0; | ||
70 | |||
71 | keyring[id] = keyring_alloc(keyring_name[id], KUIDT_INIT(0), | ||
72 | KGIDT_INIT(0), cred, | ||
73 | ((KEY_POS_ALL & ~KEY_POS_SETATTR) | | ||
74 | KEY_USR_VIEW | KEY_USR_READ | | ||
75 | KEY_USR_WRITE | KEY_USR_SEARCH), | ||
76 | KEY_ALLOC_NOT_IN_QUOTA, NULL); | ||
77 | if (!IS_ERR(keyring[id])) | ||
78 | set_bit(KEY_FLAG_TRUSTED_ONLY, &keyring[id]->flags); | ||
79 | else { | ||
80 | err = PTR_ERR(keyring[id]); | ||
81 | pr_info("Can't allocate %s keyring (%d)\n", | ||
82 | keyring_name[id], err); | ||
83 | keyring[id] = NULL; | ||
84 | } | ||
85 | return err; | ||
86 | } | ||
diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig index 81a27971d884..08758fbd496f 100644 --- a/security/integrity/ima/Kconfig +++ b/security/integrity/ima/Kconfig | |||
@@ -123,3 +123,13 @@ config IMA_APPRAISE | |||
123 | For more information on integrity appraisal refer to: | 123 | For more information on integrity appraisal refer to: |
124 | <http://linux-ima.sourceforge.net> | 124 | <http://linux-ima.sourceforge.net> |
125 | If unsure, say N. | 125 | If unsure, say N. |
126 | |||
127 | config IMA_TRUSTED_KEYRING | ||
128 | bool "Require all keys on the .ima keyring be signed" | ||
129 | depends on IMA_APPRAISE && SYSTEM_TRUSTED_KEYRING | ||
130 | depends on INTEGRITY_ASYMMETRIC_KEYS | ||
131 | select KEYS_DEBUG_PROC_KEYS | ||
132 | default y | ||
133 | help | ||
134 | This option requires that all keys added to the .ima | ||
135 | keyring be signed by a key on the system trusted keyring. | ||
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index f79fa8be203c..c42056edfc97 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h | |||
@@ -249,4 +249,16 @@ static inline int security_filter_rule_match(u32 secid, u32 field, u32 op, | |||
249 | return -EINVAL; | 249 | return -EINVAL; |
250 | } | 250 | } |
251 | #endif /* CONFIG_IMA_LSM_RULES */ | 251 | #endif /* CONFIG_IMA_LSM_RULES */ |
252 | |||
253 | #ifdef CONFIG_IMA_TRUSTED_KEYRING | ||
254 | static inline int ima_init_keyring(const unsigned int id) | ||
255 | { | ||
256 | return integrity_init_keyring(id); | ||
257 | } | ||
258 | #else | ||
259 | static inline int ima_init_keyring(const unsigned int id) | ||
260 | { | ||
261 | return 0; | ||
262 | } | ||
263 | #endif /* CONFIG_IMA_TRUSTED_KEYRING */ | ||
252 | #endif | 264 | #endif |
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index f474c608fa11..0d696431209c 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c | |||
@@ -325,8 +325,14 @@ static int __init init_ima(void) | |||
325 | 325 | ||
326 | hash_setup(CONFIG_IMA_DEFAULT_HASH); | 326 | hash_setup(CONFIG_IMA_DEFAULT_HASH); |
327 | error = ima_init(); | 327 | error = ima_init(); |
328 | if (!error) | 328 | if (error) |
329 | ima_initialized = 1; | 329 | goto out; |
330 | |||
331 | error = ima_init_keyring(INTEGRITY_KEYRING_IMA); | ||
332 | if (error) | ||
333 | goto out; | ||
334 | ima_initialized = 1; | ||
335 | out: | ||
330 | return error; | 336 | return error; |
331 | } | 337 | } |
332 | 338 | ||
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h index 33c0a70f6b15..09c440d9aaee 100644 --- a/security/integrity/integrity.h +++ b/security/integrity/integrity.h | |||
@@ -124,6 +124,7 @@ struct integrity_iint_cache *integrity_iint_find(struct inode *inode); | |||
124 | int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen, | 124 | int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen, |
125 | const char *digest, int digestlen); | 125 | const char *digest, int digestlen); |
126 | 126 | ||
127 | int integrity_init_keyring(const unsigned int id); | ||
127 | #else | 128 | #else |
128 | 129 | ||
129 | static inline int integrity_digsig_verify(const unsigned int id, | 130 | static inline int integrity_digsig_verify(const unsigned int id, |
@@ -133,6 +134,10 @@ static inline int integrity_digsig_verify(const unsigned int id, | |||
133 | return -EOPNOTSUPP; | 134 | return -EOPNOTSUPP; |
134 | } | 135 | } |
135 | 136 | ||
137 | static inline int integrity_init_keyring(const unsigned int id) | ||
138 | { | ||
139 | return 0; | ||
140 | } | ||
136 | #endif /* CONFIG_INTEGRITY_SIGNATURE */ | 141 | #endif /* CONFIG_INTEGRITY_SIGNATURE */ |
137 | 142 | ||
138 | #ifdef CONFIG_INTEGRITY_ASYMMETRIC_KEYS | 143 | #ifdef CONFIG_INTEGRITY_ASYMMETRIC_KEYS |
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index cd5bd0cef25d..8a8c23357291 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c | |||
@@ -37,8 +37,6 @@ static int key_get_type_from_user(char *type, | |||
37 | return ret; | 37 | return ret; |
38 | if (ret == 0 || ret >= len) | 38 | if (ret == 0 || ret >= len) |
39 | return -EINVAL; | 39 | return -EINVAL; |
40 | if (type[0] == '.') | ||
41 | return -EPERM; | ||
42 | type[len - 1] = '\0'; | 40 | type[len - 1] = '\0'; |
43 | return 0; | 41 | return 0; |
44 | } | 42 | } |
@@ -86,6 +84,10 @@ SYSCALL_DEFINE5(add_key, const char __user *, _type, | |||
86 | if (!*description) { | 84 | if (!*description) { |
87 | kfree(description); | 85 | kfree(description); |
88 | description = NULL; | 86 | description = NULL; |
87 | } else if ((description[0] == '.') && | ||
88 | (strncmp(type, "keyring", 7) == 0)) { | ||
89 | ret = -EPERM; | ||
90 | goto error2; | ||
89 | } | 91 | } |
90 | } | 92 | } |
91 | 93 | ||