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--