aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/security/integrity
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-07-10 18:43:43 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2019-07-10 18:43:43 -0700
commit028db3e290f15ac509084c0fc3b9d021f668f877 (patch)
tree7497244a90100f2464403063f88f83a555da03b3 /security/integrity
parentMerge tag 'docs-5.3' of git://git.lwn.net/linux (diff)
downloadwireguard-linux-028db3e290f15ac509084c0fc3b9d021f668f877.tar.xz
wireguard-linux-028db3e290f15ac509084c0fc3b9d021f668f877.zip
Revert "Merge tag 'keys-acl-20190703' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs"
This reverts merge 0f75ef6a9cff49ff612f7ce0578bced9d0b38325 (and thus effectively commits 7a1ade847596 ("keys: Provide KEYCTL_GRANT_PERMISSION") 2e12256b9a76 ("keys: Replace uid/gid/perm permissions checking with an ACL") that the merge brought in). It turns out that it breaks booting with an encrypted volume, and Eric biggers reports that it also breaks the fscrypt tests [1] and loading of in-kernel X.509 certificates [2]. The root cause of all the breakage is likely the same, but David Howells is off email so rather than try to work it out it's getting reverted in order to not impact the rest of the merge window. [1] https://lore.kernel.org/lkml/20190710011559.GA7973@sol.localdomain/ [2] https://lore.kernel.org/lkml/20190710013225.GB7973@sol.localdomain/ Link: https://lore.kernel.org/lkml/CAHk-=wjxoeMJfeBahnWH=9zShKp2bsVy527vo3_y8HfOdhwAAw@mail.gmail.com/ Reported-by: Eric Biggers <ebiggers@kernel.org> Cc: David Howells <dhowells@redhat.com> Cc: James Morris <jmorris@namei.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'security/integrity')
-rw-r--r--security/integrity/digsig.c31
-rw-r--r--security/integrity/digsig_asymmetric.c2
-rw-r--r--security/integrity/evm/evm_crypto.c2
-rw-r--r--security/integrity/ima/ima_mok.c13
-rw-r--r--security/integrity/integrity.h6
-rw-r--r--security/integrity/platform_certs/platform_keyring.c14
6 files changed, 29 insertions, 39 deletions
diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c
index f9f3c8ffe786..868ade3e8970 100644
--- a/security/integrity/digsig.c
+++ b/security/integrity/digsig.c
@@ -47,8 +47,7 @@ int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
if (!keyring[id]) {
keyring[id] =
- request_key(&key_type_keyring, keyring_name[id],
- NULL, NULL);
+ request_key(&key_type_keyring, keyring_name[id], NULL);
if (IS_ERR(keyring[id])) {
int err = PTR_ERR(keyring[id]);
pr_err("no %s keyring: %d\n", keyring_name[id], err);
@@ -71,14 +70,14 @@ int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
}
static int __init __integrity_init_keyring(const unsigned int id,
- struct key_acl *acl,
+ key_perm_t perm,
struct key_restriction *restriction)
{
const struct cred *cred = current_cred();
int err = 0;
keyring[id] = keyring_alloc(keyring_name[id], KUIDT_INIT(0),
- KGIDT_INIT(0), cred, acl,
+ KGIDT_INIT(0), cred, perm,
KEY_ALLOC_NOT_IN_QUOTA, restriction, NULL);
if (IS_ERR(keyring[id])) {
err = PTR_ERR(keyring[id]);
@@ -96,7 +95,10 @@ static int __init __integrity_init_keyring(const unsigned int id,
int __init integrity_init_keyring(const unsigned int id)
{
struct key_restriction *restriction;
- struct key_acl *acl = &internal_keyring_acl;
+ key_perm_t perm;
+
+ perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW
+ | KEY_USR_READ | KEY_USR_SEARCH;
if (id == INTEGRITY_KEYRING_PLATFORM) {
restriction = NULL;
@@ -111,14 +113,14 @@ int __init integrity_init_keyring(const unsigned int id)
return -ENOMEM;
restriction->check = restrict_link_to_ima;
- acl = &internal_writable_keyring_acl;
+ perm |= KEY_USR_WRITE;
out:
- return __integrity_init_keyring(id, acl, restriction);
+ return __integrity_init_keyring(id, perm, restriction);
}
-static int __init integrity_add_key(const unsigned int id, const void *data,
- off_t size, struct key_acl *acl)
+int __init integrity_add_key(const unsigned int id, const void *data,
+ off_t size, key_perm_t perm)
{
key_ref_t key;
int rc = 0;
@@ -127,7 +129,7 @@ static int __init integrity_add_key(const unsigned int id, const void *data,
return -EINVAL;
key = key_create_or_update(make_key_ref(keyring[id], 1), "asymmetric",
- NULL, data, size, acl ?: &internal_key_acl,
+ NULL, data, size, perm,
KEY_ALLOC_NOT_IN_QUOTA);
if (IS_ERR(key)) {
rc = PTR_ERR(key);
@@ -147,6 +149,7 @@ int __init integrity_load_x509(const unsigned int id, const char *path)
void *data;
loff_t size;
int rc;
+ key_perm_t perm;
rc = kernel_read_file_from_path(path, &data, &size, 0,
READING_X509_CERTIFICATE);
@@ -155,19 +158,21 @@ int __init integrity_load_x509(const unsigned int id, const char *path)
return rc;
}
+ perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW | KEY_USR_READ;
+
pr_info("Loading X.509 certificate: %s\n", path);
- rc = integrity_add_key(id, data, size, NULL);
+ rc = integrity_add_key(id, (const void *)data, size, perm);
vfree(data);
return rc;
}
int __init integrity_load_cert(const unsigned int id, const char *source,
- const void *data, size_t len, struct key_acl *acl)
+ const void *data, size_t len, key_perm_t perm)
{
if (!data)
return -EINVAL;
pr_info("Loading X.509 certificate: %s\n", source);
- return integrity_add_key(id, data, len, acl);
+ return integrity_add_key(id, data, len, perm);
}
diff --git a/security/integrity/digsig_asymmetric.c b/security/integrity/digsig_asymmetric.c
index a29df775fdd8..55aec161d0e1 100644
--- a/security/integrity/digsig_asymmetric.c
+++ b/security/integrity/digsig_asymmetric.c
@@ -53,7 +53,7 @@ static struct key *request_asymmetric_key(struct key *keyring, uint32_t keyid)
else
key = key_ref_to_ptr(kref);
} else {
- key = request_key(&key_type_asymmetric, name, NULL, NULL);
+ key = request_key(&key_type_asymmetric, name, NULL);
}
if (IS_ERR(key)) {
diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c
index 466eebd3b4aa..d485f6fc908e 100644
--- a/security/integrity/evm/evm_crypto.c
+++ b/security/integrity/evm/evm_crypto.c
@@ -356,7 +356,7 @@ int evm_init_key(void)
struct encrypted_key_payload *ekp;
int rc;
- evm_key = request_key(&key_type_encrypted, EVMKEY, NULL, NULL);
+ evm_key = request_key(&key_type_encrypted, EVMKEY, NULL);
if (IS_ERR(evm_key))
return -ENOENT;
diff --git a/security/integrity/ima/ima_mok.c b/security/integrity/ima/ima_mok.c
index b52ae1476ec3..36cadadbfba4 100644
--- a/security/integrity/ima/ima_mok.c
+++ b/security/integrity/ima/ima_mok.c
@@ -16,15 +16,6 @@
#include <keys/system_keyring.h>
-static struct key_acl integrity_blacklist_keyring_acl = {
- .usage = REFCOUNT_INIT(1),
- .nr_ace = 2,
- .aces = {
- KEY_POSSESSOR_ACE(KEY_ACE_SEARCH | KEY_ACE_WRITE),
- KEY_OWNER_ACE(KEY_ACE_VIEW | KEY_ACE_READ | KEY_ACE_WRITE | KEY_ACE_SEARCH),
- }
-};
-
struct key *ima_blacklist_keyring;
/*
@@ -44,7 +35,9 @@ __init int ima_mok_init(void)
ima_blacklist_keyring = keyring_alloc(".ima_blacklist",
KUIDT_INIT(0), KGIDT_INIT(0), current_cred(),
- &integrity_blacklist_keyring_acl,
+ (KEY_POS_ALL & ~KEY_POS_SETATTR) |
+ KEY_USR_VIEW | KEY_USR_READ |
+ KEY_USR_WRITE | KEY_USR_SEARCH,
KEY_ALLOC_NOT_IN_QUOTA,
restriction, NULL);
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
index 875c6a7a5af1..ed12d8e13d04 100644
--- a/security/integrity/integrity.h
+++ b/security/integrity/integrity.h
@@ -12,8 +12,6 @@
#include <linux/key.h>
#include <linux/audit.h>
-struct key_acl;
-
/* iint action cache flags */
#define IMA_MEASURE 0x00000001
#define IMA_MEASURED 0x00000002
@@ -157,7 +155,7 @@ int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
int __init integrity_init_keyring(const unsigned int id);
int __init integrity_load_x509(const unsigned int id, const char *path);
int __init integrity_load_cert(const unsigned int id, const char *source,
- const void *data, size_t len, struct key_acl *acl);
+ const void *data, size_t len, key_perm_t perm);
#else
static inline int integrity_digsig_verify(const unsigned int id,
@@ -175,7 +173,7 @@ static inline int integrity_init_keyring(const unsigned int id)
static inline int __init integrity_load_cert(const unsigned int id,
const char *source,
const void *data, size_t len,
- struct key_acl *acl)
+ key_perm_t perm)
{
return 0;
}
diff --git a/security/integrity/platform_certs/platform_keyring.c b/security/integrity/platform_certs/platform_keyring.c
index 7646e35f2d91..bcafd7387729 100644
--- a/security/integrity/platform_certs/platform_keyring.c
+++ b/security/integrity/platform_certs/platform_keyring.c
@@ -14,15 +14,6 @@
#include <linux/slab.h>
#include "../integrity.h"
-static struct key_acl platform_key_acl = {
- .usage = REFCOUNT_INIT(1),
- .nr_ace = 2,
- .aces = {
- KEY_POSSESSOR_ACE(KEY_ACE_SEARCH | KEY_ACE_READ),
- KEY_OWNER_ACE(KEY_ACE_VIEW),
- }
-};
-
/**
* add_to_platform_keyring - Add to platform keyring without validation.
* @source: Source of key
@@ -35,10 +26,13 @@ static struct key_acl platform_key_acl = {
void __init add_to_platform_keyring(const char *source, const void *data,
size_t len)
{
+ key_perm_t perm;
int rc;
+ perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW;
+
rc = integrity_load_cert(INTEGRITY_KEYRING_PLATFORM, source, data, len,
- &platform_key_acl);
+ perm);
if (rc)
pr_info("Error adding keys to platform keyring %s\n", source);
}