Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 1 Mar 1997 21:17:49 +0100 (MET)
From:      Tor Egge <Tor.Egge@idt.ntnu.no>
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   kern/2840: mlock+minherit+fork+munlock causes panics or freezes
Message-ID:  <199703012017.VAA00598@ikke.idt.unit.no>
Resent-Message-ID: <199703012020.MAA27606@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         2840
>Category:       kern
>Synopsis:       mlock+minherit+fork+munlock causes panics or freezes
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sat Mar  1 12:20:01 PST 1997
>Last-Modified:
>Originator:     Tor Egge
>Organization:
Norwegian University of Science and Technology, Trondheim, Norway

>Release:        FreeBSD 3.0-CURRENT i386
>Environment:

FreeBSD ikke.idt.unit.no 3.0-CURRENT FreeBSD 3.0-CURRENT #2: Sat Feb  1 03:55:57 MET 1997     root@ikke.idt.unit.no:/usr/src/sys-UP/compile/TEGGE  i386

>Description:

Accounting of wired pages is not consistent under all circumstances.
By using mlock() and minherit(), then fork(), then munlock() in both child
and parent processes, the wired count is reduced by both munlocks(), causing
a too small (or even negative) value.for wired count. 

Other side effects are freezes (i.e. kernel is alive, but all programs hangs),
or panics.

>How-To-Repeat:

Look at wire count (using top or systat). Run the appended program as root.
If the program crashes, run it again. Look at wire count again.

---
#include <sys/types.h>
#include <sys/param.h>
#include <sys/time.h>
#include <time.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <errno.h>
#include <sys/wait.h>
#include <sys/mman.h>
#include <vm/vm.h>
#include <vm/vm_inherit.h>

int main(int argc,char **argv)
{
  int i;
  int j;
  char *a;
  char *b;
  char *aend;
  char *p;
  size_t alen;
  size_t blen;
  pid_t pid;
  int wres;
  int sum;
  int res;

  alen = 1024 * 1024 * 1;
  blen = 1024 * 1024 * 1;
  a = malloc(alen);
  assert(a);
  aend = a + alen;
  sum = 0;
  for (p=a;p<aend;p++) 
    sum += *p; 
  res = minherit(a,alen,VM_INHERIT_SHARE);
  printf("minherit: a=%p, alen=0x%x, res=%d, errno=%d\n",a,alen, res,errno);
  for (j=0;j<10;j++) {
    b = malloc(blen);
    assert(b);
    res = mlock(b,blen);
    printf("mlock: res=%d, errno=%d\n",res,errno);
    printf("pass %d\n",j);
    for (i=0;i<3;i++) {
      pid = fork();
      if (pid<0) {
	perror("fork");
	exit(1);
      }
      if (pid==0) {
	munlock(b,blen);
	printf("munlock: res=%d, errno=%d\n",res,errno);
	free(b);
	sleep(2);
	exit(0);
      }
    }
    for (p=a;p<aend;p++) 
      sum += *p; 
    sleep(3);
    while (waitpid(-1,&wres,WNOHANG)>0) {
      /* */
    }
    munlock(b,blen);
    printf("munlock: res=%d, errno=%d\n",res,errno);
    free(b);
  }
  exit(0);
}

>Fix:
	

>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199703012017.VAA00598>