aboutsummaryrefslogtreecommitdiffstats
path: root/security/keys/keyctl.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2012-05-11 10:56:56 +0100
committerDavid Howells <dhowells@redhat.com>2012-05-11 10:56:56 +0100
commitfd75815f727f157a05f4c96b5294a4617c0557da (patch)
treeb2e76abf176d37b5d810b0c813b8c0219754b88c /security/keys/keyctl.c
parentKEYS: Do LRU discard in full keyrings (diff)
downloadlinux-dev-fd75815f727f157a05f4c96b5294a4617c0557da.tar.xz
linux-dev-fd75815f727f157a05f4c96b5294a4617c0557da.zip
KEYS: Add invalidation support
Add support for invalidating a key - which renders it immediately invisible to further searches and causes the garbage collector to immediately wake up, remove it from keyrings and then destroy it when it's no longer referenced. It's better not to do this with keyctl_revoke() as that marks the key to start returning -EKEYREVOKED to searches when what is actually desired is to have the key refetched. To invalidate a key the caller must be granted SEARCH permission by the key. This may be too strict. It may be better to also permit invalidation if the caller has any of READ, WRITE or SETATTR permission. The primary use for this is to evict keys that are cached in special keyrings, such as the DNS resolver or an ID mapper. Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'security/keys/keyctl.c')
-rw-r--r--security/keys/keyctl.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index fb767c6cd99f..ddb3e05bc5fc 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -375,6 +375,37 @@ error:
}
/*
+ * Invalidate a key.
+ *
+ * The key must be grant the caller Invalidate permission for this to work.
+ * The key and any links to the key will be automatically garbage collected
+ * immediately.
+ *
+ * If successful, 0 is returned.
+ */
+long keyctl_invalidate_key(key_serial_t id)
+{
+ key_ref_t key_ref;
+ long ret;
+
+ kenter("%d", id);
+
+ key_ref = lookup_user_key(id, 0, KEY_SEARCH);
+ if (IS_ERR(key_ref)) {
+ ret = PTR_ERR(key_ref);
+ goto error;
+ }
+
+ key_invalidate(key_ref_to_ptr(key_ref));
+ ret = 0;
+
+ key_ref_put(key_ref);
+error:
+ kleave(" = %ld", ret);
+ return ret;
+}
+
+/*
* Clear the specified keyring, creating an empty process keyring if one of the
* special keyring IDs is used.
*
@@ -1622,6 +1653,9 @@ SYSCALL_DEFINE5(keyctl, int, option, unsigned long, arg2, unsigned long, arg3,
(unsigned) arg4,
(key_serial_t) arg5);
+ case KEYCTL_INVALIDATE:
+ return keyctl_invalidate_key((key_serial_t) arg2);
+
default:
return -EOPNOTSUPP;
}