| From 6ca03f90527e499dd5e32d6522909e2ad390896b Mon Sep 17 00:00:00 2001 |
| From: Jiri Slaby <jirislaby@kernel.org> |
| Date: Mon, 19 Oct 2020 10:55:16 +0200 |
| Subject: vt: keyboard, simplify vt_kdgkbsent |
| |
| From: Jiri Slaby <jslaby@suse.cz> |
| |
| commit 6ca03f90527e499dd5e32d6522909e2ad390896b upstream. |
| |
| Use 'strlen' of the string, add one for NUL terminator and simply do |
| 'copy_to_user' instead of the explicit 'for' loop. This makes the |
| KDGKBSENT case more compact. |
| |
| The only thing we need to take care about is NULL 'func_table[i]'. Use |
| an empty string in that case. |
| |
| The original check for overflow could never trigger as the func_buf |
| strings are always shorter or equal to 'struct kbsentry's. |
| |
| Cc: <stable@vger.kernel.org> |
| Signed-off-by: Jiri Slaby <jslaby@suse.cz> |
| Link: https://lore.kernel.org/r/20201019085517.10176-1-jslaby@suse.cz |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/tty/vt/keyboard.c | 28 +++++++++------------------- |
| 1 file changed, 9 insertions(+), 19 deletions(-) |
| |
| --- a/drivers/tty/vt/keyboard.c |
| +++ b/drivers/tty/vt/keyboard.c |
| @@ -1995,9 +1995,7 @@ out: |
| int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm) |
| { |
| struct kbsentry *kbs; |
| - char *p; |
| u_char *q; |
| - u_char __user *up; |
| int sz, fnw_sz; |
| int delta; |
| char *first_free, *fj, *fnw; |
| @@ -2023,23 +2021,15 @@ int vt_do_kdgkb_ioctl(int cmd, struct kb |
| i = array_index_nospec(kbs->kb_func, MAX_NR_FUNC); |
| |
| switch (cmd) { |
| - case KDGKBSENT: |
| - sz = sizeof(kbs->kb_string) - 1; /* sz should have been |
| - a struct member */ |
| - up = user_kdgkb->kb_string; |
| - p = func_table[i]; |
| - if(p) |
| - for ( ; *p && sz; p++, sz--) |
| - if (put_user(*p, up++)) { |
| - ret = -EFAULT; |
| - goto reterr; |
| - } |
| - if (put_user('\0', up)) { |
| - ret = -EFAULT; |
| - goto reterr; |
| - } |
| - kfree(kbs); |
| - return ((p && *p) ? -EOVERFLOW : 0); |
| + case KDGKBSENT: { |
| + /* size should have been a struct member */ |
| + unsigned char *from = func_table[i] ? : ""; |
| + |
| + ret = copy_to_user(user_kdgkb->kb_string, from, |
| + strlen(from) + 1) ? -EFAULT : 0; |
| + |
| + goto reterr; |
| + } |
| case KDSKBSENT: |
| if (!perm) { |
| ret = -EPERM; |