mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 12:17:12 +09:00
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:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user