Subject: port-arm32/7838: copyoutstr go boom.
To: None <gnats-bugs@gnats.netbsd.org>
From: Bill Sommerfeld <sommerfeld@orchard.arlington.ma.us>
List: netbsd-bugs
Date: 06/23/1999 07:36:48
>Number:         7838
>Category:       port-arm32
>Synopsis:       copyoutstr go boom.
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    port-arm32-maintainer (NetBSD/arm32 Portmaster)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed Jun 23 07:35:00 1999
>Last-Modified:
>Originator:     Bill Sommerfeld
>Organization:
	none
>Release:        19990620
>Environment:

>Description:

	The enclosed test program crashes a shark.

[u]vm_fault(0xf010af58, f40000000, 3, 0) -> 1
Unhandled trap (frame = 0xf3727d80)
Data abort: 'Translation fault(section)' status=005 address=f4000050
PC=f00ebf0c
Stopped in bar at	_copyoutstr+0x8c:	str	r6, [r4, #0x0050]

traceback:

_sys_execve(_sys_execve+0x10)
_syscall(_syscall+0x10)

I *think* this is actually a copyinstr (the assembly code for both
shares the same tail) call because $r1 (the "destination" pointer in
the copy) points into kernel space.

r4 contains 0xf4000000; it should contain the contents of curpcb,
which at the time is 0xf3726000

Also noticed at the same time: copyoutstr doesn't do the COW
emulation which is done by copyout in bcopyinout.S, which seems.. poor.

>How-To-Repeat:

compile and run the following:

#include <string.h>
#include <stdlib.h>
#include <sys/param.h>
#include <unistd.h>
#include <stdio.h>

#define CHECK_LEN       (NCARGS+3)
 
static  char    **array = NULL;
 
main(argc, argv, envp)
        int argc;
        char *argv[];
        char *envp[];
{
        int i;
 
        array = (char **)malloc(CHECK_LEN * sizeof(char *));
        for (i = 0; i < (CHECK_LEN - 1); i++)
                array[i] = "/bin/sh";
        array[CHECK_LEN - 1] = NULL;
        execve("/bin/sh", array, envp);
        exit(0);
}

>Fix:

??? don't know arm assembly that well
>Audit-Trail:
>Unformatted: