Commit 18026d86 authored by Eric Biggers's avatar Eric Biggers Committed by David Howells

KEYS: reject NULL restriction string when type is specified

keyctl_restrict_keyring() allows through a NULL restriction when the
"type" is non-NULL, which causes a NULL pointer dereference in
asymmetric_lookup_restriction() when it calls strcmp() on the
restriction string.

But no key types actually use a "NULL restriction" to mean anything, so
update keyctl_restrict_keyring() to reject it with EINVAL.
Reported-by: default avatarsyzbot <syzkaller@googlegroups.com>
Fixes: 97d3aa0f ("KEYS: Add a lookup_restriction function for the asymmetric key type")
Cc: <stable@vger.kernel.org> # v4.12+
Signed-off-by: default avatarEric Biggers <ebiggers@google.com>
Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
parent 3d1f0255
...@@ -1588,9 +1588,8 @@ long keyctl_session_to_parent(void) ...@@ -1588,9 +1588,8 @@ long keyctl_session_to_parent(void)
* The caller must have Setattr permission to change keyring restrictions. * The caller must have Setattr permission to change keyring restrictions.
* *
* The requested type name may be a NULL pointer to reject all attempts * 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 * to link to the keyring. In this case, _restriction must also be NULL.
* NULL or a pointer to a string describing the restriction. If _type is * Otherwise, both _type and _restriction must be non-NULL.
* NULL, _restriction must also be NULL.
* *
* Returns 0 if successful. * Returns 0 if successful.
*/ */
...@@ -1598,7 +1597,6 @@ long keyctl_restrict_keyring(key_serial_t id, const char __user *_type, ...@@ -1598,7 +1597,6 @@ long keyctl_restrict_keyring(key_serial_t id, const char __user *_type,
const char __user *_restriction) const char __user *_restriction)
{ {
key_ref_t key_ref; key_ref_t key_ref;
bool link_reject = !_type;
char type[32]; char type[32];
char *restriction = NULL; char *restriction = NULL;
long ret; long ret;
...@@ -1607,31 +1605,29 @@ long keyctl_restrict_keyring(key_serial_t id, const char __user *_type, ...@@ -1607,31 +1605,29 @@ long keyctl_restrict_keyring(key_serial_t id, const char __user *_type,
if (IS_ERR(key_ref)) if (IS_ERR(key_ref))
return PTR_ERR(key_ref); return PTR_ERR(key_ref);
ret = -EINVAL;
if (_type) { if (_type) {
ret = key_get_type_from_user(type, _type, sizeof(type)); if (!_restriction)
if (ret < 0)
goto error; goto error;
}
if (_restriction) { ret = key_get_type_from_user(type, _type, sizeof(type));
if (!_type) { if (ret < 0)
ret = -EINVAL;
goto error; goto error;
}
restriction = strndup_user(_restriction, PAGE_SIZE); restriction = strndup_user(_restriction, PAGE_SIZE);
if (IS_ERR(restriction)) { if (IS_ERR(restriction)) {
ret = PTR_ERR(restriction); ret = PTR_ERR(restriction);
goto error; goto error;
} }
} else {
if (_restriction)
goto error;
} }
ret = keyring_restrict(key_ref, link_reject ? NULL : type, restriction); ret = keyring_restrict(key_ref, _type ? type : NULL, restriction);
kfree(restriction); kfree(restriction);
error: error:
key_ref_put(key_ref); key_ref_put(key_ref);
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment