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: