summaryrefslogtreecommitdiff
path: root/security/keys/process_keys.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-07-11 04:43:43 +0300
committerLinus Torvalds <torvalds@linux-foundation.org>2019-07-11 04:43:43 +0300
commit028db3e290f15ac509084c0fc3b9d021f668f877 (patch)
tree7497244a90100f2464403063f88f83a555da03b3 /security/keys/process_keys.c
parente9a83bd2322035ed9d7dcf35753d3f984d76c6a5 (diff)
downloadlinux-028db3e290f15ac509084c0fc3b9d021f668f877.tar.xz
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/keys/process_keys.c')
-rw-r--r--security/keys/process_keys.c86
1 files changed, 22 insertions, 64 deletions
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index aa3bfcadbc66..09541de31f2f 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -32,47 +32,6 @@ struct key_user root_key_user = {
.uid = GLOBAL_ROOT_UID,
};
-static struct key_acl user_reg_keyring_acl = {
- .usage = REFCOUNT_INIT(1),
- .possessor_viewable = true,
- .nr_ace = 2,
- .aces = {
- KEY_POSSESSOR_ACE(KEY_ACE_WRITE | KEY_ACE_SEARCH),
- KEY_OWNER_ACE(KEY_ACE_VIEW | KEY_ACE_READ),
- }
-};
-
-static struct key_acl user_keyring_acl = {
- .usage = REFCOUNT_INIT(1),
- .possessor_viewable = true,
- .nr_ace = 2,
- .aces = {
- KEY_POSSESSOR_ACE(KEY_ACE_VIEW | KEY_ACE_READ | KEY_ACE_WRITE |
- KEY_ACE_SEARCH | KEY_ACE_LINK),
- KEY_OWNER_ACE(KEY_ACE__PERMS & ~(KEY_ACE_JOIN | KEY_ACE_SET_SECURITY)),
- }
-};
-
-static struct key_acl session_keyring_acl = {
- .usage = REFCOUNT_INIT(1),
- .possessor_viewable = true,
- .nr_ace = 2,
- .aces = {
- KEY_POSSESSOR_ACE(KEY_ACE__PERMS & ~KEY_ACE_JOIN),
- KEY_OWNER_ACE(KEY_ACE_VIEW | KEY_ACE_READ),
- }
-};
-
-static struct key_acl thread_and_process_keyring_acl = {
- .usage = REFCOUNT_INIT(1),
- .possessor_viewable = true,
- .nr_ace = 2,
- .aces = {
- KEY_POSSESSOR_ACE(KEY_ACE__PERMS & ~(KEY_ACE_JOIN | KEY_ACE_SET_SECURITY)),
- KEY_OWNER_ACE(KEY_ACE_VIEW),
- }
-};
-
/*
* Get or create a user register keyring.
*/
@@ -92,8 +51,11 @@ static struct key *get_user_register(struct user_namespace *user_ns)
if (!reg_keyring) {
reg_keyring = keyring_alloc(".user_reg",
user_ns->owner, INVALID_GID,
- &init_cred, &user_reg_keyring_acl,
- 0, NULL, NULL);
+ &init_cred,
+ KEY_POS_WRITE | KEY_POS_SEARCH |
+ KEY_USR_VIEW | KEY_USR_READ,
+ 0,
+ NULL, NULL);
if (!IS_ERR(reg_keyring))
smp_store_release(&user_ns->user_keyring_register,
reg_keyring);
@@ -115,11 +77,14 @@ int look_up_user_keyrings(struct key **_user_keyring,
const struct cred *cred = current_cred();
struct user_namespace *user_ns = current_user_ns();
struct key *reg_keyring, *uid_keyring, *session_keyring;
+ key_perm_t user_keyring_perm;
key_ref_t uid_keyring_r, session_keyring_r;
uid_t uid = from_kuid(user_ns, cred->user->uid);
char buf[20];
int ret;
+ user_keyring_perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL;
+
kenter("%u", uid);
reg_keyring = get_user_register(user_ns);
@@ -139,7 +104,7 @@ int look_up_user_keyrings(struct key **_user_keyring,
kdebug("_uid %p", uid_keyring_r);
if (uid_keyring_r == ERR_PTR(-EAGAIN)) {
uid_keyring = keyring_alloc(buf, cred->user->uid, INVALID_GID,
- cred, &user_keyring_acl,
+ cred, user_keyring_perm,
KEY_ALLOC_UID_KEYRING |
KEY_ALLOC_IN_QUOTA,
NULL, reg_keyring);
@@ -161,7 +126,7 @@ int look_up_user_keyrings(struct key **_user_keyring,
kdebug("_uid_ses %p", session_keyring_r);
if (session_keyring_r == ERR_PTR(-EAGAIN)) {
session_keyring = keyring_alloc(buf, cred->user->uid, INVALID_GID,
- cred, &user_keyring_acl,
+ cred, user_keyring_perm,
KEY_ALLOC_UID_KEYRING |
KEY_ALLOC_IN_QUOTA,
NULL, NULL);
@@ -261,7 +226,7 @@ int install_thread_keyring_to_cred(struct cred *new)
return 0;
keyring = keyring_alloc("_tid", new->uid, new->gid, new,
- &thread_and_process_keyring_acl,
+ KEY_POS_ALL | KEY_USR_VIEW,
KEY_ALLOC_QUOTA_OVERRUN,
NULL, NULL);
if (IS_ERR(keyring))
@@ -308,7 +273,7 @@ int install_process_keyring_to_cred(struct cred *new)
return 0;
keyring = keyring_alloc("_pid", new->uid, new->gid, new,
- &thread_and_process_keyring_acl,
+ KEY_POS_ALL | KEY_USR_VIEW,
KEY_ALLOC_QUOTA_OVERRUN,
NULL, NULL);
if (IS_ERR(keyring))
@@ -363,7 +328,8 @@ int install_session_keyring_to_cred(struct cred *cred, struct key *keyring)
flags = KEY_ALLOC_IN_QUOTA;
keyring = keyring_alloc("_ses", cred->uid, cred->gid, cred,
- &session_keyring_acl, flags, NULL, NULL);
+ KEY_POS_ALL | KEY_USR_VIEW | KEY_USR_READ,
+ flags, NULL, NULL);
if (IS_ERR(keyring))
return PTR_ERR(keyring);
} else {
@@ -643,7 +609,7 @@ bool lookup_user_key_possessed(const struct key *key,
* returned key reference.
*/
key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags,
- unsigned int desired_perm)
+ key_perm_t perm)
{
struct keyring_search_context ctx = {
.match_data.cmp = lookup_user_key_possessed,
@@ -818,12 +784,12 @@ try_again:
case -ERESTARTSYS:
goto invalid_key;
default:
- if (desired_perm)
+ if (perm)
goto invalid_key;
case 0:
break;
}
- } else if (desired_perm) {
+ } else if (perm) {
ret = key_validate(key);
if (ret < 0)
goto invalid_key;
@@ -835,11 +801,9 @@ try_again:
goto invalid_key;
/* check the permissions */
- if (desired_perm) {
- ret = key_task_permission(key_ref, ctx.cred, desired_perm);
- if (ret < 0)
- goto invalid_key;
- }
+ ret = key_task_permission(key_ref, ctx.cred, perm);
+ if (ret < 0)
+ goto invalid_key;
key->last_used_at = ktime_get_real_seconds();
@@ -904,13 +868,13 @@ long join_session_keyring(const char *name)
if (PTR_ERR(keyring) == -ENOKEY) {
/* not found - try and create a new one */
keyring = keyring_alloc(
- name, old->uid, old->gid, old, &joinable_keyring_acl,
+ name, old->uid, old->gid, old,
+ KEY_POS_ALL | KEY_USR_VIEW | KEY_USR_READ | KEY_USR_LINK,
KEY_ALLOC_IN_QUOTA, NULL, NULL);
if (IS_ERR(keyring)) {
ret = PTR_ERR(keyring);
goto error2;
}
- goto no_perm_test;
} else if (IS_ERR(keyring)) {
ret = PTR_ERR(keyring);
goto error2;
@@ -919,12 +883,6 @@ long join_session_keyring(const char *name)
goto error3;
}
- ret = key_task_permission(make_key_ref(keyring, false), old,
- KEY_NEED_JOIN);
- if (ret < 0)
- goto error3;
-
-no_perm_test:
/* we've got a keyring - now to install it */
ret = install_session_keyring_to_cred(new, keyring);
if (ret < 0)