aboutsummaryrefslogtreecommitdiffstats
path: root/security/keys/keyctl.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2017-04-04 22:33:00 +0100
committerDavid Howells <dhowells@redhat.com>2017-04-04 22:33:00 +0100
commitf0df90cd7cf2f4a8195c3fff0d2f4c85088fd39c (patch)
treebb473a491f791be1c0f9c42b66c4b700ff151d74 /security/keys/keyctl.c
parentMerge branch 'keys-blacklist' into keys-next (diff)
parentKEYS: Keyring asymmetric key restrict method with chaining (diff)
downloadlinux-dev-f0df90cd7cf2f4a8195c3fff0d2f4c85088fd39c.tar.xz
linux-dev-f0df90cd7cf2f4a8195c3fff0d2f4c85088fd39c.zip
Merge branch 'keyctl-restrict' of git://git.kernel.org/pub/scm/linux/kernel/git/martineau/linux into keys-next
To quote Mat Martineau: """ Keyrings recently acquired the ability to validate keys before they are linked using kernel internal APIs. This patch set enables configuration of restricted keyrings from userspace. These patches apply to linux-fs/keys-misc and are also available here: https://git.kernel.org/cgit/linux/kernel/git/martineau/linux.git/log/?h=keyctl-restrict v13: Detect and avoid cycles in restriction references, and change restrictions to store a single key pointer rather than arbitrary data. v12: Rework the KEYCTL_RESTRICT_KEYRING command to take an additional parameter, renamed some functions based on feedback, and dropped an unnecessary locking change (patch 1 in previous set). v11: Configure restrictions using KEYCTL_RESTRICT_KEYRING instead of using a keyring payload at creation time. Make the garbage collector aware of restrictions. v10: Fixups from maintainer feedback. Added some missing documentation. v9: Rebased on linux-fs/keys-misc (v4.9-rc5) v8: Add option to look for signing keys within the destination keyring. Fix a consistency issue with keyring locking and restriction checks. v7: Rework key restriction payload syntax. Move key-type-specific payload parsing to the key-type. Attach more restriction information to keyrings (restriction function, data, and data free) so future restrictions are not limited to storing a key ID to use for key validation. Validate key before using it to verify another key. Modify key type locking model to allow key type lookup during keyring creation. v6: Return error if only restrict_key is supplied, address misc. review comments. v5: Fixed signature bypass problem in patch 3/6 v4: Added userspace restriction options based on builtin keyrings. restrict_link_by_signature implementation is no longer modified. Split up v3's patch 2/5 to isolate the change to key.h. v3: Updated commit message for patch 2/5 (restrict_link_by_signature_indirect) v2: Payload is now preparsed """ Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to '')
-rw-r--r--security/keys/keyctl.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index 52c34532c785..6ee2826a2d06 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -1583,6 +1583,59 @@ error_keyring:
}
/*
+ * Apply a restriction to a given keyring.
+ *
+ * The caller must have Setattr permission to change keyring restrictions.
+ *
+ * The requested type name may be a NULL pointer to reject all attempts
+ * to link to the keyring. If _type is non-NULL, _restriction can be
+ * NULL or a pointer to a string describing the restriction. If _type is
+ * NULL, _restriction must also be NULL.
+ *
+ * Returns 0 if successful.
+ */
+long keyctl_restrict_keyring(key_serial_t id, const char __user *_type,
+ const char __user *_restriction)
+{
+ key_ref_t key_ref;
+ bool link_reject = !_type;
+ char type[32];
+ char *restriction = NULL;
+ long ret;
+
+ key_ref = lookup_user_key(id, 0, KEY_NEED_SETATTR);
+ if (IS_ERR(key_ref))
+ return PTR_ERR(key_ref);
+
+ if (_type) {
+ ret = key_get_type_from_user(type, _type, sizeof(type));
+ if (ret < 0)
+ goto error;
+ }
+
+ if (_restriction) {
+ if (!_type) {
+ ret = -EINVAL;
+ goto error;
+ }
+
+ restriction = strndup_user(_restriction, PAGE_SIZE);
+ if (IS_ERR(restriction)) {
+ ret = PTR_ERR(restriction);
+ goto error;
+ }
+ }
+
+ ret = keyring_restrict(key_ref, link_reject ? NULL : type, restriction);
+ kfree(restriction);
+
+error:
+ key_ref_put(key_ref);
+
+ return ret;
+}
+
+/*
* The key control system call
*/
SYSCALL_DEFINE5(keyctl, int, option, unsigned long, arg2, unsigned long, arg3,
@@ -1693,6 +1746,11 @@ SYSCALL_DEFINE5(keyctl, int, option, unsigned long, arg2, unsigned long, arg3,
(char __user *) arg3, (size_t) arg4,
(void __user *) arg5);
+ case KEYCTL_RESTRICT_KEYRING:
+ return keyctl_restrict_keyring((key_serial_t) arg2,
+ (const char __user *) arg3,
+ (const char __user *) arg4);
+
default:
return -EOPNOTSUPP;
}