Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933028AbdC3KMz (ORCPT ); Thu, 30 Mar 2017 06:12:55 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:54498 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932275AbdC3KMy (ORCPT ); Thu, 30 Mar 2017 06:12:54 -0400 From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Dave Martin , Linus Torvalds Subject: [PATCH 4.10 09/17] h8300/ptrace: Fix incorrect register transfer count Date: Thu, 30 Mar 2017 12:00:24 +0200 Message-Id: <20170330095927.287645288@linuxfoundation.org> X-Mailer: git-send-email 2.12.1 In-Reply-To: <20170330095925.918515862@linuxfoundation.org> References: <20170330095925.918515862@linuxfoundation.org> User-Agent: quilt/0.65 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 1906 Lines: 55 4.10-stable review patch. If anyone has any objections, please let me know. ------------------ From: Dave Martin 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 Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- arch/h8300/kernel/ptrace.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) --- a/arch/h8300/kernel/ptrace.c +++ b/arch/h8300/kernel/ptrace.c @@ -95,7 +95,8 @@ static int regs_get(struct task_struct * 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 * 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 * 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; }