From owner-freebsd-bugs Sat Jul 24 20:20:35 1999 Delivered-To: freebsd-bugs@freebsd.org Received: from freefall.freebsd.org (freefall.FreeBSD.ORG [204.216.27.21]) by hub.freebsd.org (Postfix) with ESMTP id 1301614E70 for ; Sat, 24 Jul 1999 20:20:32 -0700 (PDT) (envelope-from gnats@FreeBSD.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.9.3/8.9.2) id UAA91800; Sat, 24 Jul 1999 20:20:01 -0700 (PDT) (envelope-from gnats@FreeBSD.org) Received: from midten.fast.no (midten.fast.no [195.139.251.11]) by hub.freebsd.org (Postfix) with ESMTP id 7951014D5A for ; Sat, 24 Jul 1999 20:12:55 -0700 (PDT) (envelope-from tegge@not.fast.no) Received: from not.fast.no (IDENT:tegge@not.fast.no [195.139.251.12]) by midten.fast.no (8.9.3/8.9.3) with ESMTP id FAA22010 for ; Sun, 25 Jul 1999 05:10:47 +0200 (CEST) Received: (from tegge@localhost) by not.fast.no (8.9.3/8.8.8) id FAA03328; Sun, 25 Jul 1999 05:10:47 +0200 (CEST) (envelope-from tegge@not.fast.no) Message-Id: <199907250310.FAA03328@not.fast.no> Date: Sun, 25 Jul 1999 05:10:47 +0200 (CEST) From: Tor Egge Reply-To: tegge@not.fast.no To: FreeBSD-gnats-submit@freebsd.org X-Send-Pr-Version: 3.2 Subject: kern/12800: buffer leak in cluster_wbuild Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org >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 #include #include #include #include #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