aboutsummaryrefslogtreecommitdiffstats
path: root/security/keys/proc.c
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/keys/proc.c
parentMerge tag 'docs-5.3' of git://git.lwn.net/linux (diff)
downloadlinux-dev-028db3e290f15ac509084c0fc3b9d021f668f877.tar.xz
linux-dev-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/keys/proc.c')
-rw-r--r--security/keys/proc.c22
1 files changed, 9 insertions, 13 deletions
diff --git a/security/keys/proc.c b/security/keys/proc.c
index b394ad1e874b..415f3f1c2da0 100644
--- a/security/keys/proc.c
+++ b/security/keys/proc.c
@@ -110,13 +110,11 @@ static struct key *find_ge_key(struct seq_file *p, key_serial_t id)
}
static void *proc_keys_start(struct seq_file *p, loff_t *_pos)
- __acquires(rcu)
__acquires(key_serial_lock)
{
key_serial_t pos = *_pos;
struct key *key;
- rcu_read_lock();
spin_lock(&key_serial_lock);
if (*_pos > INT_MAX)
@@ -146,15 +144,12 @@ static void *proc_keys_next(struct seq_file *p, void *v, loff_t *_pos)
static void proc_keys_stop(struct seq_file *p, void *v)
__releases(key_serial_lock)
- __releases(rcu)
{
spin_unlock(&key_serial_lock);
- rcu_read_unlock();
}
static int proc_keys_show(struct seq_file *m, void *v)
{
- const struct key_acl *acl;
struct rb_node *_p = v;
struct key *key = rb_entry(_p, struct key, serial_node);
unsigned long flags;
@@ -162,7 +157,6 @@ static int proc_keys_show(struct seq_file *m, void *v)
time64_t now, expiry;
char xbuf[16];
short state;
- bool check_pos;
u64 timo;
int rc;
@@ -176,15 +170,15 @@ static int proc_keys_show(struct seq_file *m, void *v)
KEYRING_SEARCH_RECURSE),
};
- acl = rcu_dereference(key->acl);
- check_pos = acl->possessor_viewable;
+ key_ref = make_key_ref(key, 0);
/* determine if the key is possessed by this process (a test we can
* skip if the key does not indicate the possessor can view it
*/
- key_ref = make_key_ref(key, 0);
- if (check_pos) {
+ if (key->perm & KEY_POS_VIEW) {
+ rcu_read_lock();
skey_ref = search_cred_keyrings_rcu(&ctx);
+ rcu_read_unlock();
if (!IS_ERR(skey_ref)) {
key_ref_put(skey_ref);
key_ref = make_key_ref(key, 1);
@@ -194,10 +188,12 @@ static int proc_keys_show(struct seq_file *m, void *v)
/* check whether the current task is allowed to view the key */
rc = key_task_permission(key_ref, ctx.cred, KEY_NEED_VIEW);
if (rc < 0)
- goto out;
+ return 0;
now = ktime_get_real_seconds();
+ rcu_read_lock();
+
/* come up with a suitable timeout value */
expiry = READ_ONCE(key->expiry);
if (expiry == 0) {
@@ -236,7 +232,7 @@ static int proc_keys_show(struct seq_file *m, void *v)
showflag(flags, 'i', KEY_FLAG_INVALIDATED),
refcount_read(&key->usage),
xbuf,
- key_acl_to_perm(acl),
+ key->perm,
from_kuid_munged(seq_user_ns(m), key->uid),
from_kgid_munged(seq_user_ns(m), key->gid),
key->type->name);
@@ -247,7 +243,7 @@ static int proc_keys_show(struct seq_file *m, void *v)
key->type->describe(key, m);
seq_putc(m, '\n');
-out:
+ rcu_read_unlock();
return 0;
}