All of lore.kernel.org
 help / color / mirror / Atom feed
From: Helge Deller <deller@gmx.de>
To: linux-kernel@vger.kernel.org, akpm@linux-foundation.org,
	torvalds@linux-foundation.org,
	Kyle Mc Martin <kyle@hera.kernel.org>,
	linux-parisc@vger.kernel.org, Christoph Hellwig <hch@lst.de>
Subject: [PATCH] parisc: fix bug in compat_arch_ptrace
Date: Thu, 20 Nov 2008 10:54:09 +0100	[thread overview]
Message-ID: <200811201054.09930.deller@gmx.de> (raw)

This commit in 2.6.28-rc:
	81e192d6ce303b6792aa38ff35f41a1a7357f23a
	parisc: convert to generic compat_sys_ptrace

introduced a bug which segfaults the parisc 64bit kernel 
when stracing 32bit applications:

Kernel Fault: Code=15 regs=00000000bafa42b0 (Addr=00000001baf5ab57)
     YZrvWESTHLNXBCVMcbcbcbcbOGFRQPDI
PSW: 00001000000001101111111100001011 Tainted: G        W
r00-03  000000ff0806ff0b 000000004068edc0 00000000401203f8 00000000fb3e2508
r04-07  0000000040686dc0 00000000baf5a800 fffffffffffffffc fffffffffb3e2508
r08-11  00000000baf5a800 000000000004b068 00000000000402b0 0000000000040d68
r12-15  0000000000042a9c 0000000000040a9c 0000000000040d60 0000000000042e9c
r16-19  000000000004b060 000000000004b058 0000000000042d9c ffffffffffffffff
r20-23  000000000800000b 0000000000000000 000000000800000b fffffffffb3e2508
r24-27  00000000fffffffc 0000000000000003 00000000fffffffc 0000000040686dc0
r28-31  00000001baf5a7ff 00000000bafa4280 00000000bafa42b0 00000000000001d7
sr00-03  0000000000fca000 0000000000000000 0000000000000000 0000000000fca000
sr04-07  0000000000000000 0000000000000000 0000000000000000 0000000000000000

IASQ: 0000000000000000 0000000000000000 IAOQ: 0000000040120400 0000000040120404
 IIR: 4b9a06b0    ISR: 0000000000000000  IOR: 00000001baf5ab57
 CPU:        0   CR30: 00000000bafa4000 CR31: 00000000d22344e0
 ORIG_R28: 00000000fb3e2248
 IAOQ[0]: compat_arch_ptrace+0xb8/0x160
 IAOQ[1]: compat_arch_ptrace+0xbc/0x160
 RP(r2): compat_arch_ptrace+0xb0/0x160
Backtrace:
 [<00000000401612ac>] compat_sys_ptrace+0x15c/0x180
 [<0000000040104ef8>] syscall_exit+0x0/0x14

Problem is, that compat_arch_ptrace() enters with an addr value of type 
compat_ulong_t and calls translate_usr_offset() to translate the 
address offset into a struct pt_regs offset like this:
	addr = translate_usr_offset(addr)
This means, any return value of translate_usr_offset() is
stored back as compat_ulong_t type into the addr variable.

But since translate_usr_offset() returns -1 for invalid offsets,
addr can now get the value 0xffffffff which then fails the next
return-value sanity check and thus the kernel tries to access 
invalid memory:
	if (addr < 0)
		break;

Fix this bug by modifying translate_usr_offset() to take and return
values of type compat_ulong_t, and by returning the value 
"sizeof(struct pt_regs)" as an error indicator.
Additionally change the sanity check to check for return values
for >= sizeof(struct pt_regs).

This patch survived my compile and run-tests.

Signed-off-by: Helge Deller <deller@gmx.de>

diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c
index 90904f9..927db36 100644
--- a/arch/parisc/kernel/ptrace.c
+++ b/arch/parisc/kernel/ptrace.c
@@ -183,10 +183,10 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
  * being 64 bit in both cases.
  */
 
-static long translate_usr_offset(long offset)
+static compat_ulong_t translate_usr_offset(compat_ulong_t offset)
 {
 	if (offset < 0)
-		return -1;
+		return sizeof(struct pt_regs);
 	else if (offset <= 32*4)	/* gr[0..31] */
 		return offset * 2 + 4;
 	else if (offset <= 32*4+32*8)	/* gr[0..31] + fr[0..31] */
@@ -194,7 +194,7 @@ static long translate_usr_offset(long offset)
 	else if (offset < sizeof(struct pt_regs)/2 + 32*4)
 		return offset * 2 + 4 - 32*8;
 	else
-		return -1;
+		return sizeof(struct pt_regs);
 }
 
 long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
@@ -209,7 +209,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
 		if (addr & (sizeof(compat_uint_t)-1))
 			break;
 		addr = translate_usr_offset(addr);
-		if (addr < 0)
+		if (addr >= sizeof(struct pt_regs))
 			break;
 
 		tmp = *(compat_uint_t *) ((char *) task_regs(child) + addr);
@@ -236,7 +236,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
 			if (addr & (sizeof(compat_uint_t)-1))
 				break;
 			addr = translate_usr_offset(addr);
-			if (addr < 0)
+			if (addr >= sizeof(struct pt_regs))
 				break;
 			if (addr >= PT_FR0 && addr <= PT_FR31 + 4) {
 				/* Special case, fp regs are 64 bits anyway */

             reply	other threads:[~2008-11-20  9:54 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-11-20  9:54 Helge Deller [this message]
2008-11-25 17:04 ` [PATCH] parisc: fix bug in compat_arch_ptrace Kyle McMartin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200811201054.09930.deller@gmx.de \
    --to=deller@gmx.de \
    --cc=akpm@linux-foundation.org \
    --cc=hch@lst.de \
    --cc=kyle@hera.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-parisc@vger.kernel.org \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.