Merge branch 'fixes-v4.14-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security
Pull key handling fixes from James Morris: "Fixes for the Keys subsystem by Eric Biggers" * 'fixes-v4.14-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: KEYS: fix out-of-bounds read during ASN.1 parsing KEYS: trusted: fix writing past end of buffer in trusted_read() KEYS: return full count in keyring_read() if buffer is too small
This commit is contained in:
@@ -284,6 +284,9 @@ next_op:
|
|||||||
if (unlikely(len > datalen - dp))
|
if (unlikely(len > datalen - dp))
|
||||||
goto data_overrun_error;
|
goto data_overrun_error;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if (unlikely(len > datalen - dp))
|
||||||
|
goto data_overrun_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & FLAG_CONS) {
|
if (flags & FLAG_CONS) {
|
||||||
|
|||||||
@@ -459,34 +459,33 @@ static long keyring_read(const struct key *keyring,
|
|||||||
char __user *buffer, size_t buflen)
|
char __user *buffer, size_t buflen)
|
||||||
{
|
{
|
||||||
struct keyring_read_iterator_context ctx;
|
struct keyring_read_iterator_context ctx;
|
||||||
unsigned long nr_keys;
|
long ret;
|
||||||
int ret;
|
|
||||||
|
|
||||||
kenter("{%d},,%zu", key_serial(keyring), buflen);
|
kenter("{%d},,%zu", key_serial(keyring), buflen);
|
||||||
|
|
||||||
if (buflen & (sizeof(key_serial_t) - 1))
|
if (buflen & (sizeof(key_serial_t) - 1))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
nr_keys = keyring->keys.nr_leaves_on_tree;
|
/* Copy as many key IDs as fit into the buffer */
|
||||||
if (nr_keys == 0)
|
if (buffer && buflen) {
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* Calculate how much data we could return */
|
|
||||||
if (!buffer || !buflen)
|
|
||||||
return nr_keys * sizeof(key_serial_t);
|
|
||||||
|
|
||||||
/* Copy the IDs of the subscribed keys into the buffer */
|
|
||||||
ctx.buffer = (key_serial_t __user *)buffer;
|
ctx.buffer = (key_serial_t __user *)buffer;
|
||||||
ctx.buflen = buflen;
|
ctx.buflen = buflen;
|
||||||
ctx.count = 0;
|
ctx.count = 0;
|
||||||
ret = assoc_array_iterate(&keyring->keys, keyring_read_iterator, &ctx);
|
ret = assoc_array_iterate(&keyring->keys,
|
||||||
|
keyring_read_iterator, &ctx);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
kleave(" = %d [iterate]", ret);
|
kleave(" = %ld [iterate]", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
kleave(" = %zu [ok]", ctx.count);
|
/* Return the size of the buffer needed */
|
||||||
return ctx.count;
|
ret = keyring->keys.nr_leaves_on_tree * sizeof(key_serial_t);
|
||||||
|
if (ret <= buflen)
|
||||||
|
kleave("= %ld [ok]", ret);
|
||||||
|
else
|
||||||
|
kleave("= %ld [buffer too small]", ret);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -1147,8 +1147,8 @@ static long trusted_read(const struct key *key, char __user *buffer,
|
|||||||
p = dereference_key_locked(key);
|
p = dereference_key_locked(key);
|
||||||
if (!p)
|
if (!p)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (!buffer || buflen <= 0)
|
|
||||||
return 2 * p->blob_len;
|
if (buffer && buflen >= 2 * p->blob_len) {
|
||||||
ascii_buf = kmalloc(2 * p->blob_len, GFP_KERNEL);
|
ascii_buf = kmalloc(2 * p->blob_len, GFP_KERNEL);
|
||||||
if (!ascii_buf)
|
if (!ascii_buf)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
@@ -1156,11 +1156,12 @@ static long trusted_read(const struct key *key, char __user *buffer,
|
|||||||
bufp = ascii_buf;
|
bufp = ascii_buf;
|
||||||
for (i = 0; i < p->blob_len; i++)
|
for (i = 0; i < p->blob_len; i++)
|
||||||
bufp = hex_byte_pack(bufp, p->blob[i]);
|
bufp = hex_byte_pack(bufp, p->blob[i]);
|
||||||
if ((copy_to_user(buffer, ascii_buf, 2 * p->blob_len)) != 0) {
|
if (copy_to_user(buffer, ascii_buf, 2 * p->blob_len) != 0) {
|
||||||
kzfree(ascii_buf);
|
kzfree(ascii_buf);
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
kzfree(ascii_buf);
|
kzfree(ascii_buf);
|
||||||
|
}
|
||||||
return 2 * p->blob_len;
|
return 2 * p->blob_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user