ANDROID: keychord: Fix a slab out-of-bounds read.

Fix a slab out of bounds read in keychord_write(), detected by KASAN.

Signed-off-by: Mohan Srinivasan <srmohan@google.com>
Bug: 63962952
Change-Id: Iafef48b5d7283750ac0f39f5aaa767b1c3bf2004
(cherry picked from commit 913d980e07)
This commit is contained in:
Mohan Srinivasan
2017-07-26 12:14:41 -07:00
parent 6f227409a1
commit eac37ad2df

View File

@@ -232,9 +232,11 @@ static ssize_t keychord_write(struct file *file, const char __user *buffer,
{
struct keychord_device *kdev = file->private_data;
struct input_keychord *keychords = 0;
struct input_keychord *keychord, *next, *end;
struct input_keychord *keychord;
int ret, i, key;
unsigned long flags;
size_t resid = count;
size_t key_bytes;
if (count < sizeof(struct input_keychord))
return -EINVAL;
@@ -265,15 +267,29 @@ static ssize_t keychord_write(struct file *file, const char __user *buffer,
kdev->head = kdev->tail = 0;
keychord = keychords;
end = (struct input_keychord *)((char *)keychord + count);
while (keychord < end) {
next = NEXT_KEYCHORD(keychord);
if (keychord->count <= 0 || next > end) {
while (resid > 0) {
/* Is the entire keychord entry header present ? */
if (resid < sizeof(struct input_keychord)) {
pr_err("keychord: Insufficient bytes present for header %lu\n",
resid);
goto err_unlock_return;
}
resid -= sizeof(struct input_keychord);
if (keychord->count <= 0) {
pr_err("keychord: invalid keycode count %d\n",
keychord->count);
goto err_unlock_return;
}
key_bytes = keychord->count * sizeof(keychord->keycodes[0]);
/* Do we have all the expected keycodes ? */
if (resid < key_bytes) {
pr_err("keychord: Insufficient bytes present for keycount %lu\n",
resid);
goto err_unlock_return;
}
resid -= key_bytes;
if (keychord->version != KEYCHORD_VERSION) {
pr_err("keychord: unsupported version %d\n",
keychord->version);
@@ -292,7 +308,7 @@ static ssize_t keychord_write(struct file *file, const char __user *buffer,
}
kdev->keychord_count++;
keychord = next;
keychord = NEXT_KEYCHORD(keychord);
}
kdev->keychords = keychords;