From eee045021fb22aeac7f5d6f2092430b530c880ee Mon Sep 17 00:00:00 2001 From: David Howells Date: Wed, 27 Jan 2016 01:02:03 +0000 Subject: [PATCH] KEYS: Only apply KEY_FLAG_KEEP to a key if a parent keyring has it set KEY_FLAG_KEEP should only be applied to a key if the keyring it is being linked into has KEY_FLAG_KEEP set. To this end, partially revert the following patch: commit 1d6d167c2efcfe9539d9cffb1a1be9c92e39c2c0 Author: Mimi Zohar Date: Thu Jan 7 07:46:36 2016 -0500 KEYS: refcount bug fix to undo the change that made it unconditional (Mimi got it right the first time). Without undoing this change, it becomes impossible to delete, revoke or invalidate keys added to keyrings through __key_instantiate_and_link() where the keyring has itself been linked to. To test this, run the following command sequence: keyctl newring foo @s keyctl add user a a %:foo keyctl unlink %user:a %:foo keyctl clear %:foo With the commit mentioned above the third and fourth commands fail with EPERM when they should succeed. Reported-by: Stephen Gallager Signed-off-by: David Howells Acked-by: Mimi Zohar cc: Mimi Zohar cc: keyrings@vger.kernel.org cc: stable@vger.kernel.org Signed-off-by: James Morris --- security/keys/key.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/security/keys/key.c b/security/keys/key.c index 07a8731..09ef276 100644 --- a/security/keys/key.c +++ b/security/keys/key.c @@ -430,7 +430,8 @@ static int __key_instantiate_and_link(struct key *key, /* and link it into the destination keyring */ if (keyring) { - set_bit(KEY_FLAG_KEEP, &key->flags); + if (test_bit(KEY_FLAG_KEEP, &keyring->flags)) + set_bit(KEY_FLAG_KEEP, &key->flags); __key_link(key, _edit); } -- 2.7.4