Subject: mprotect(2) strange behaviour under compat linux
To: NetBSD current <current-users@netbsd.org>
From: Nicolas Joly <njoly@pasteur.fr>
List: current-users
Date: 12/17/2007 23:30:29
--jI8keyz6grp/JLjh
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline


Hi,

While working on compat linux i encountered some strange mprotect(2)
behaviour.

The attached piece of code work on NetBSD i386/amd64, Linux
i386/x86_64, but not under compat linux/i386 or linux32/amd64.

njoly@cixy [~]> uname -a
NetBSD cixy.sis.pasteur.fr 4.99.42 NetBSD 4.99.42 (CIXY_DEVEL) #48: Sun Dec 16 22:59:40 CET 2007  njoly@cixy.si.pasteur.fr:/local/src/NetBSD/obj.i386/sys/arch/i386/compile/CIXY_DEVEL i386

njoly@cixy [~]> file ./mprotect
./mprotect: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.4.1, dynamically linked (uses shared libs), not stripped
njoly@cixy [~]> ktrace -di ./mprotect
zsh: segmentation fault (core dumped)  ktrace -di ./mprotect
njoly@cixy [~]> kdump
[...]
 17981      1 mprotect CALL  old_mmap(0xbfbfe810)
 17981      1 mprotect RET   old_mmap -1146380288/0xbbaba000
 17981      1 mprotect CALL  mprotect(0xbbaba000,0xa000,2)
 17981      1 mprotect RET   mprotect 0
 17981      1 mprotect PSIG  SIGSEGV SIG_DFL
 17981      1 mprotect NAMI  "mprotect.core"

njoly@cixy [~]> gdb ./mprotect
GNU gdb 6.5
Copyright (C) 2006 Free Software Foundation, Inc.
[...]
(gdb) b main
Breakpoint 1 at 0x80484d4: file mprotect.c, line 13.
(gdb) run
Starting program: /home/njoly/mprotect 
warning: no shared library support for this OS / ABI

Breakpoint 1, main () at mprotect.c:13
13        len = 10 * getpagesize();
(gdb) n
15        buf = mmap(NULL, len, PROT_NONE, MAP_ANON|MAP_SHARED, -1, 0);
(gdb) 
16        if (buf == MAP_FAILED)
(gdb) 
19        res = mprotect(buf, len, PROT_WRITE);
(gdb) 
20        if (res == -1)
(gdb) 
23        (void)memset(buf, 0, len);
(gdb) 

Program received signal SIGSEGV, Segmentation fault.
0xbbb2f7dd in ?? ()

In the mean time, if i modify mprotect protection option from
`PROT_WRITE' to `PROT_READ|PROT_WRITE', the program does not crash
anymore.

Any idea ?

-- 
Nicolas Joly

Biological Software and Databanks.
Institut Pasteur, Paris.

--jI8keyz6grp/JLjh
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="mprotect.c"


#include <sys/mman.h>

#include <err.h>
#include <string.h>
#include <unistd.h>

int main() {
  int res;
  size_t len;
  void *buf;

  len = 10 * getpagesize();

  buf = mmap(NULL, len, PROT_NONE, MAP_ANON|MAP_SHARED, -1, 0);
  if (buf == MAP_FAILED)
    err(1, "mmap failed");

  res = mprotect(buf, len, PROT_WRITE);
  if (res == -1)
    err(1, "mprotect failed");

  (void)memset(buf, 0, len);

  res = munmap(buf, len);
  if (res == -1)
    err(1, "munmap failed");

  return 0; }

--jI8keyz6grp/JLjh--