Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 25 Jul 1999 05:10:47 +0200 (CEST)
From:      Tor Egge <tegge@not.fast.no>
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   kern/12800: buffer leak in cluster_wbuild
Message-ID:  <199907250310.FAA03328@not.fast.no>

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

>Number:         12800
>Category:       kern
>Synopsis:       buffer leak in cluster_wbuild
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sat Jul 24 20:20:00 PDT 1999
>Closed-Date:
>Last-Modified:
>Originator:     Tor Egge
>Release:        FreeBSD 4.0-CURRENT i386
>Organization:
Fast Search & Transfer ASA
>Environment:

FreeBSD not.fast.no 4.0-CURRENT FreeBSD 4.0-CURRENT #0: Fri Jul 23 02:23:08 CEST 1999     root@not.fast.no:/usr/src/sys/compile/NOT_SMP  i386

>Description:

If a candidate buffer for clustering contains a page marked BUSY,
cluster_wbuild fails to return the buffer to the appropriate previous state.
This causes processes to be stuck in getblk, due to the buffer
being marked busy, with noone around to unbusy it.

When running the program below for reproducing the problem, some other
symptomps were also present:

	- Spurious SIGBUS signals.

	  mmap returned success, but the address area returned by mmap
	  is apparently not always accessible, causing the SIGBUS during
	  the memset operation.

	- corrupt coredumps.  Probably due to problems accessing the
	  area returned by mmap().

>How-To-Repeat:

On a machine with 512MB memory with > 1GB swap:

  As root:

	sysctl -w vm.swap_enabled=0
	sysctl -w kern.corefile='%N.core.%P'

  As a normal user, on a file system with lots of free space:

	cc -g -O2 -static -o badwrite badwrite.c
	ulimit -c unlimited
	./badwrite 400
	
  Wait 10-15 minutes, then use Ctrl-C to stop the program.

  There should be some corrupt core files in the current directory, and
  some stuck processes on the machines.

-------------- start of badwrite.c -----
#include <sys/types.h>
#include <sys/mman.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>

#define PAGESIZE 4096

#define TRASHSIZE (2*1024*1024)

void writeit(void);

int main(int argc, char **argv)
{
  int childcnt, i;
  pid_t pid;

  if (argc  >= 2)
    childcnt = atoi(argv[1]);
  else
    childcnt = 20;

  if (childcnt < 0)
    childcnt = 1;

  if (childcnt > 800)
    childcnt = 800;

  for (i = 0; i < childcnt; i++) {
    pid = fork();
    if (pid < 0)
      exit(1);
    if (pid == 0) {
      writeit();
      exit(0);
    }
  }

  while (wait(NULL) >= 0) {
  }
  exit(0);
}


void writeit(void)
{
  char buf[100];
  pid_t pid;
  int fd;
  int tbuf[8192];
  char *trashmem;
  int trashpos;
  char *mapos;
  off_t fd_off, map_off;
  int pageoffset;
  
  int wgot, wtry;

  pid = getpid();
  sprintf(buf, "tmpfile.%d", (int) pid);

  srandom(time(NULL) + pid);
  
  fd = open(buf, O_RDWR | O_CREAT | O_TRUNC | O_APPEND, 0666);
  if (fd < 0)
    exit(1);

  unlink(buf);

  trashmem = malloc(TRASHSIZE);

  memset(tbuf, 0, sizeof(tbuf));

  fd_off = 0;

  while (1) {
    wtry = 1 + (random() % sizeof(tbuf));
    
    wgot = write(fd, tbuf, wtry);
    
    if (wgot != wtry)
      exit(1);

    usleep(random() % 65536);

#if 1
    trashpos = (random() % (TRASHSIZE / PAGESIZE)) * PAGESIZE;
    trashmem[trashpos]++;
#endif

    fd_off += wgot;

    pageoffset = fd_off & (PAGESIZE - 1);

    map_off = fd_off - pageoffset;

    mapos = mmap(NULL, PAGESIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE,
		 fd, map_off);

    if (mapos == NULL || mapos == (char *) -1)
      exit(1);
    
    memset(mapos + pageoffset, 0, PAGESIZE - pageoffset);

    munmap(mapos, PAGESIZE);
  }
  
}
----------------

>Fix:

>Release-Note:
>Audit-Trail:
>Unformatted:


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




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