Subject: kern/25607: New code uncovers long standing incorrect casts in kern/sys_process.c
To: None <gnats-bugs@gnats.NetBSD.org>
From: None <paul@Plectere.com>
List: netbsd-bugs
Date: 05/17/2004 00:35:47
>Number: 25607
>Category: kern
>Synopsis: ptrace fails on any machine which uses top 1/2 of memory space
>Confidential: no
>Severity: critical
>Priority: high
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Mon May 17 07:36:00 UTC 2004
>Closed-Date:
>Last-Modified:
>Originator: Paul Shupak
>Release: NetBSD 2.0E
>Organization:
>Environment:
System: NetBSD cobalt 2.0E NetBSD 2.0E (COBALT-$Revision: 1.4 $) #452: Mon May 17 00:07:26 PDT 2004 root@svcs:/sys/arch/i386/compile/COBALT i386
Architecture: i386
Machine: i386
>Description:
Whenever a memory request (read or write) to ptrace references the
upper half of a machines address space, the newly added tests at the beginning
of process_domem() will fail with EINVAL.
This manifests itself on machines like the i386 as gdb can't read
local variables if the stack is located at a virtual address above 0x80000000.
>How-To-Repeat:
Try gdb on current; The program below is sufficient:
$ cat > x.c << EOF
#include <stdio.h>
int main(int argc, char **argv) { int x = 0; puts("Hello World"); return x; }
EOF
$ cc -g x.c; gdb a.out
(gdb) b main
(gdb) r
(gdb) p x
See the problem.
>Fix:
This is a two line fix for all 32-bit machines and all 64-bit
machines which disallow user code addresses above 0x8000000000000000
(think mmap()!?).
Index: sys_process.c
===================================================================
RCS file: /cvsroot/src/sys/kern/sys_process.c,v
retrieving revision 1.89
diff -c -r1.89 sys_process.c
*** sys_process.c 14 May 2004 16:36:33 -0000 1.89
--- sys_process.c 17 May 2004 07:14:21 -0000
***************
*** 310,316 ****
iov.iov_len = sizeof(tmp);
uio.uio_iov = &iov;
uio.uio_iovcnt = 1;
! uio.uio_offset = (off_t)(long)SCARG(uap, addr);
uio.uio_resid = sizeof(tmp);
uio.uio_segflg = UIO_SYSSPACE;
uio.uio_rw = write ? UIO_WRITE : UIO_READ;
--- 310,316 ----
iov.iov_len = sizeof(tmp);
uio.uio_iov = &iov;
uio.uio_iovcnt = 1;
! uio.uio_offset = (off_t)(unsigned long)SCARG(uap, addr);
uio.uio_resid = sizeof(tmp);
uio.uio_segflg = UIO_SYSSPACE;
uio.uio_rw = write ? UIO_WRITE : UIO_READ;
***************
*** 328,334 ****
iov.iov_len = piod.piod_len;
uio.uio_iov = &iov;
uio.uio_iovcnt = 1;
! uio.uio_offset = (off_t)(long)piod.piod_offs;
uio.uio_resid = piod.piod_len;
uio.uio_segflg = UIO_USERSPACE;
uio.uio_procp = p;
--- 328,334 ----
iov.iov_len = piod.piod_len;
uio.uio_iov = &iov;
uio.uio_iovcnt = 1;
! uio.uio_offset = (off_t)(unsigned long)piod.piod_offs;
uio.uio_resid = piod.piod_len;
uio.uio_segflg = UIO_USERSPACE;
uio.uio_procp = p;
>Release-Note:
>Audit-Trail:
>Unformatted: