| From 502585c7555083d4a949c08350306b9ec196779e Mon Sep 17 00:00:00 2001 |
| From: Dave Martin <Dave.Martin@arm.com> |
| Date: Mon, 27 Mar 2017 15:10:54 +0100 |
| Subject: [PATCH] h8300/ptrace: Fix incorrect register transfer count |
| |
| commit 502585c7555083d4a949c08350306b9ec196779e upstream. |
| |
| regs_set() and regs_get() are vulnerable to an off-by-1 buffer overrun |
| if CONFIG_CPU_H8S is set, since this adds an extra entry to |
| register_offset[] but not to user_regs_struct. |
| |
| So, iterate over user_regs_struct based on its actual size, not based on |
| the length of register_offset[]. |
| |
| Signed-off-by: Dave Martin <Dave.Martin@arm.com> |
| Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> |
| |
| diff --git a/arch/h8300/kernel/ptrace.c b/arch/h8300/kernel/ptrace.c |
| index 92075544a19a..0dc1c8f622bc 100644 |
| --- a/arch/h8300/kernel/ptrace.c |
| +++ b/arch/h8300/kernel/ptrace.c |
| @@ -95,7 +95,8 @@ static int regs_get(struct task_struct *target, |
| long *reg = (long *)®s; |
| |
| /* build user regs in buffer */ |
| - for (r = 0; r < ARRAY_SIZE(register_offset); r++) |
| + BUILD_BUG_ON(sizeof(regs) % sizeof(long) != 0); |
| + for (r = 0; r < sizeof(regs) / sizeof(long); r++) |
| *reg++ = h8300_get_reg(target, r); |
| |
| return user_regset_copyout(&pos, &count, &kbuf, &ubuf, |
| @@ -113,7 +114,8 @@ static int regs_set(struct task_struct *target, |
| long *reg; |
| |
| /* build user regs in buffer */ |
| - for (reg = (long *)®s, r = 0; r < ARRAY_SIZE(register_offset); r++) |
| + BUILD_BUG_ON(sizeof(regs) % sizeof(long) != 0); |
| + for (reg = (long *)®s, r = 0; r < sizeof(regs) / sizeof(long); r++) |
| *reg++ = h8300_get_reg(target, r); |
| |
| ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, |
| @@ -122,7 +124,7 @@ static int regs_set(struct task_struct *target, |
| return ret; |
| |
| /* write back to pt_regs */ |
| - for (reg = (long *)®s, r = 0; r < ARRAY_SIZE(register_offset); r++) |
| + for (reg = (long *)®s, r = 0; r < sizeof(regs) / sizeof(long); r++) |
| h8300_put_reg(target, r, *reg++); |
| return 0; |
| } |
| -- |
| 2.12.0 |
| |