Use 'strlen' of the string, add one for NUL 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 'from'. The original check for overflow could never trigger as the func_buf (called 'from' here) strings are always shorter or equal to struct kbsentry's. Signed-off-by: Jiri Slaby <jslaby@xxxxxxx> --- drivers/tty/vt/keyboard.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c index d8e2452da1bd..68f9f6a62d02 100644 --- a/drivers/tty/vt/keyboard.c +++ b/drivers/tty/vt/keyboard.c @@ -1995,9 +1995,7 @@ int vt_do_kdsk_ioctl(int cmd, struct kbentry __user *user_kbe, int perm, int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm) { char *kbs; - char *p; u_char *q; - u_char __user *up; int sz, fnw_sz; int delta; char *first_free, *fj, *fnw; @@ -2014,20 +2012,15 @@ int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm) i = array_index_nospec(i, MAX_NR_FUNC); switch (cmd) { - case KDGKBSENT: - /* sz should have been a struct member */ - sz = sizeof_field(struct kbsentry, kb_string) - 1; - up = user_kdgkb->kb_string; - p = func_table[i]; - if(p) - for ( ; *p && sz; p++, sz--) - if (put_user(*p, up++)) - return -EFAULT; - - if (put_user('\0', up)) + case KDGKBSENT: { + /* size should have been a struct member */ + unsigned char *from = func_table[i] ? : ""; + + if (copy_to_user(user_kdgkb->kb_string, from, strlen(from) + 1)) return -EFAULT; - return ((p && *p) ? -EOVERFLOW : 0); + return 0; + } case KDSKBSENT: if (!perm) return -EPERM; -- 2.28.0