Subject: port-amd64/36967: netbsd-32 emulation broken on amd64
To: None <port-amd64-maintainer@netbsd.org, gnats-admin@netbsd.org,>
From: None <christos@zoulas.com>
List: netbsd-bugs
Date: 09/10/2007 15:55:00
>Number:         36967
>Category:       port-amd64
>Synopsis:       netbsd-32 emulation broken on amd64
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    port-amd64-maintainer
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Sep 10 15:55:00 +0000 2007
>Originator:     Christos Zoulas
>Release:        NetBSD 4.99.31
>Organization:
	None, but trying.
>Environment:
System: NetBSD quasar.astron.com 4.99.31 NetBSD 4.99.31 (QUASAR) #40: Mon Sep 10 09:06:44 EDT 2007 christos@quasar.astron.com:/usr/src/sys/arch/amd64/compile/QUASAR amd64
Architecture: x86_64
Machine: amd64
>Description:

The dynamic linker tries to mprotect the text segment of libc
in order to perform text relocations. While this works on i386
it does not seem to work on x86_64. Here's the trace:

   701      1 ls       CALL  netbsd32_open(0xffffcf30,0,0x400)
   701      1 ls       NAMI  "/emul/netbsd32/usr/lib/libc.so.12"
   701      1 ls       RET   netbsd32_open 3
   701      1 ls       CALL  __fstat30(3,0xffffce78)
   701      1 ls       RET   __fstat30 0
   701      1 ls       CALL  netbsd32_mmap(0,0x1000,1,1,3,0,0,0)
   701      1 ls       RET   netbsd32_mmap 4227559424/0xfbfb7000
   701      1 ls       CALL  netbsd32_munmap(0xfbfb7000,0x1000)
   701      1 ls       RET   netbsd32_munmap 0
   701      1 ls       CALL  netbsd32_mmap(0,0xe8000,5,2,3,0,0,0)

Here we map the segment with permission 5 [r-x]

   701      1 ls       RET   netbsd32_mmap 4226613248/0xfbed0000
   701      1 ls       CALL  netbsd32_mmap(0xfbfa1000,0x7000,3,0x12,3,0,0xd0000,0)
   701      1 ls       RET   netbsd32_mmap 4227469312/0xfbfa1000
   701      1 ls       CALL  netbsd32_mmap(0xfbfa8000,0x10000,3,0x1012,0xffffffff,0,0,0)
   701      1 ls       RET   netbsd32_mmap 4227497984/0xfbfa8000
   701      1 ls       CALL  netbsd32_close(3)
   701      1 ls       RET   netbsd32_close 0
   701      1 ls       CALL  netbsd32_mprotect(0xfbed0000,0xd1000,7)

Here we try to re-map it with 7 [rwx] and we fail.

   701      1 ls       RET   netbsd32_mprotect -1 errno 13 Permission denied
   701      1 ls       CALL  netbsd32_write(2,0xffffd488,0x48)
   701      1 ls       GIO   fd 2 wrote 72 bytes
       "/usr/lib/libc.so.12: Cannot write-enable text segment: Permission deni\
	ed"
   701      1 ls       RET   netbsd32_write 72/0x48
   701      1 ls       CALL  netbsd32_write(2,0xfbff78e3,1)
   701      1 ls       GIO   fd 2 wrote 1 bytes
       "\n"
   701      1 ls       RET   netbsd32_write 1
   701      1 ls       CALL  netbsd32_exit(1)

I don't understand how this works on i386 either. It appears to be failing
the test in uvm_map.c:

                if ((new_prot & current->max_protection) != new_prot) {
                        error = EACCES;
                        goto out;
                }

where max_protection = 5, and new_prot = 7...


>How-To-Repeat:
	Install netbsd-32 libraries from head and try to run any binary.
	$ ./ls
	/usr/lib/libc.so.12: Cannot write-enable text segment: Permission denied

>Fix:
	?