diff options
Diffstat (limited to 'drivers/s390/char/keyboard.c')
| -rw-r--r-- | drivers/s390/char/keyboard.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/drivers/s390/char/keyboard.c b/drivers/s390/char/keyboard.c index 01463b052ae7..ef04a9f7a704 100644 --- a/drivers/s390/char/keyboard.c +++ b/drivers/s390/char/keyboard.c | |||
| @@ -433,20 +433,23 @@ do_kdgkb_ioctl(struct kbd_data *kbd, struct kbsentry __user *u_kbs, | |||
| 433 | case KDSKBSENT: | 433 | case KDSKBSENT: |
| 434 | if (!perm) | 434 | if (!perm) |
| 435 | return -EPERM; | 435 | return -EPERM; |
| 436 | len = strnlen_user(u_kbs->kb_string, | 436 | len = strnlen_user(u_kbs->kb_string, sizeof(u_kbs->kb_string)); |
| 437 | sizeof(u_kbs->kb_string) - 1); | ||
| 438 | if (!len) | 437 | if (!len) |
| 439 | return -EFAULT; | 438 | return -EFAULT; |
| 440 | if (len > sizeof(u_kbs->kb_string) - 1) | 439 | if (len > sizeof(u_kbs->kb_string)) |
| 441 | return -EINVAL; | 440 | return -EINVAL; |
| 442 | p = kmalloc(len + 1, GFP_KERNEL); | 441 | p = kmalloc(len, GFP_KERNEL); |
| 443 | if (!p) | 442 | if (!p) |
| 444 | return -ENOMEM; | 443 | return -ENOMEM; |
| 445 | if (copy_from_user(p, u_kbs->kb_string, len)) { | 444 | if (copy_from_user(p, u_kbs->kb_string, len)) { |
| 446 | kfree(p); | 445 | kfree(p); |
| 447 | return -EFAULT; | 446 | return -EFAULT; |
| 448 | } | 447 | } |
| 449 | p[len] = 0; | 448 | /* |
| 449 | * Make sure the string is terminated by 0. User could have | ||
| 450 | * modified it between us running strnlen_user() and copying it. | ||
| 451 | */ | ||
| 452 | p[len - 1] = 0; | ||
| 450 | kfree(kbd->func_table[kb_func]); | 453 | kfree(kbd->func_table[kb_func]); |
| 451 | kbd->func_table[kb_func] = p; | 454 | kbd->func_table[kb_func] = p; |
| 452 | break; | 455 | break; |
