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
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Nov 28 09:00:03 UTC 2007
>Originator:     carl shapiro
>Release:        7.0-BETA3
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

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. 

Start on a FreeBSD 6 system.

freebsd6 $ cc -o mmap6 mmap.c
freebsd6 $ ./mmap6

Transfer the mmap6 binary to a FreeBSD 7 system to resume the test case.

freebsd7 $ ./mmap6
freebsd7 $ cc -o mmap7 mmap.c
freebsd7 $ ./mmap7

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

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) {
  sa.sa_sigaction = handler;
  sa.sa_flags = SA_SIGINFO;
  sigaction(SIGBUS, &sa, NULL);
  sigaction(SIGSEGV, &sa, NULL);
  *p = 0xff;
  if (munmap(p, len) == -1) {
  return 0;



More information about the freebsd-bugs mailing list