misc/118304: freebsd 7 delivers unanticipated signal for page
faults to freebsd <= 6 binaries
carl shapiro
carl.shapiro at gmail.com
Wed Nov 28 01:00:04 PST 2007
>Number: 118304
>Category: misc
>Synopsis: freebsd 7 delivers unanticipated signal for page faults to freebsd <= 6 binaries
>Confidential: no
>Severity: critical
>Priority: high
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Wed Nov 28 09:00:03 UTC 2007
>Closed-Date:
>Last-Modified:
>Originator: carl shapiro
>Release: 7.0-BETA3
>Organization:
self
>Environment:
FreeBSD freebsd7 7.0-BETA3 FreeBSD 7.0-BETA3 #0: Fri Nov 16 22:20:33 UTC 2007 root at logan.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC i386
>Description:
Prior to FreeBSD 7 a SIGBUS is delivered if a page's protection is violated. FreeBSD 7 changed this to SIGSEGV. Older executables which expect SIGBUS when a page's protection is violated now unexpectedly receive a SIGSEGV. This breaks applications which attempt to handle page protection binaries. Garbage collectors that implement write barriers through page protection (boehm gc, cmucl, etc.) are one such application.
>How-To-Repeat:
Start on a FreeBSD 6 system.
freebsd6 $ cc -o mmap6 mmap.c
freebsd6 $ ./mmap6
__FreeBSD_version=601000
signum=10,info->si_code=12,context=0xbfbfe880
Transfer the mmap6 binary to a FreeBSD 7 system to resume the test case.
freebsd7 $ ./mmap6
__FreeBSD_version=601000
signum=11,info->si_code=2,context=0xbfbfe9d0
freebsd7 $ cc -o mmap7 mmap.c
freebsd7 $ ./mmap7
__FreeBSD_version=700055
signum=11,info->si_code=2,context=0xbfbfe9e0
Note the different signal and different subcode.
Here is the test program.
/* mmap.c */
#include <sys/mman.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <osreldate.h>
void handler(int signum, siginfo_t *info, void *context) {
fprintf(stderr, "__FreeBSD_version=%d\n", __FreeBSD_version);
fprintf(stderr, "signum=%d,info->si_code=%d,context=%p\n", signum, info->si_code, context);
exit(1);
}
int main(int argc, char *argv[]) {
struct sigaction sa;
size_t len = 0x1000;
char *p = mmap(0, len, PROT_NONE, MAP_ANON, -1, 0);
if (p == MAP_FAILED) {
perror("mmap");
exit(1);
}
sa.sa_sigaction = handler;
sa.sa_flags = SA_SIGINFO;
sigaction(SIGBUS, &sa, NULL);
sigaction(SIGSEGV, &sa, NULL);
*p = 0xff;
if (munmap(p, len) == -1) {
perror("munmap");
exit(1);
}
return 0;
}
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list