Subject: kern/2801: SVR4 emulation wrong for zero-length mmap
To: None <gnats-bugs@gnats.netbsd.org>
From: None <abrown@eecs.harvard.edu>
List: netbsd-bugs
Date: 10/03/1996 10:44:44
>Number:         2801
>Category:       kern
>Synopsis:       A zero-length mmap is EINVAL under Solaris; emul returns addr
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    kern-bug-people (Kernel Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Oct  3 07:50:01 1996
>Last-Modified:
>Originator:     Aaron Brown
>Organization:
Harvard University Computer Science
>Release:        1.2A as of 3 October 1996
>Environment:
	Sun SS20 SuperSPARC, NetBSD1.2A built this morning from newly cvs'd
	files. Wabi 2.1. Solaris libs from Solaris 5.4.
System: NetBSD abrown-2 1.2A NetBSD 1.2A (ABROWN) #15: Mon Sep 30 18:24:41 EDT 1996 abrown@abrown-2:/usr/src/sys/arch/sparc/compile/ABROWN sparc

>Description:
	Mmap /dev/zero with a zero-byte length. Solaris returns EINVAL;
	NetBSD under emulation returns an address. 
	WABI 2.1 tends to hang randomly; ktrace indicates that this is
	the last syscall call that it makes. Applying the patch below
	makes it get past the mmap, but it still hangs later :-(
>How-To-Repeat:
	Run this simple C program, compiled under Solaris. It should
	print that addr1 and addr2 are 0xffffffff (-1), but it doesn't
	under NetBSD emulation:

/*---------- CUT HERE ----------*/
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>

int
main(void)
{
        int fd;
        char *addr1, *addr2;

        fd = open("/dev/zero",0x2);
        addr1 = mmap(0, 0, 0x7, 0x80000002, fd, 0);
        addr2 = mmap(0, 0, 0x7, 0x80000002, fd, 0);

        printf("Addr1 = 0x%x, Addr2 = 0x%x\n",addr1,addr2);
        
        return 0;
}
/* -------- CUT HERE --------- */
>Fix:
	Apply this patch; it doesn't seem to break anything (yet...) :-)

Index: svr4_misc.c
===================================================================
RCS file: /cvsroot/src/sys/compat/svr4/svr4_misc.c,v
retrieving revision 1.40
diff -c -r1.40 svr4_misc.c
*** svr4_misc.c	1996/09/25 04:37:13	1.40
--- svr4_misc.c	1996/10/03 14:39:22
***************
*** 333,338 ****
--- 333,341 ----
  	if (SCARG(uap, prot) & ~(PROT_READ | PROT_WRITE | PROT_EXEC))
  		return EINVAL;	/* XXX still needed? */
  
+ 	if (SCARG(uap, len) == 0)
+ 		return EINVAL;
+ 
  	SCARG(&mm, prot) = SCARG(uap, prot);
  	SCARG(&mm, len) = SCARG(uap, len);
  	SCARG(&mm, flags) = SCARG(uap, flags) & ~_MAP_NEW;
>Audit-Trail:
>Unformatted: