Date: Mon, 27 Jul 1998 21:53:18 -0700 (PDT) From: Matthew Dillon <dillon@backplane.com> To: FreeBSD-gnats-submit@FreeBSD.ORG Subject: kern/7422: VM system fails to remove mapped page on truncate in some situations Message-ID: <199807280453.VAA18002@apollo.backplane.com>
next in thread | raw e-mail | index | archive | help
>Number: 7422 >Category: kern >Synopsis: FreeBSD-current VM systems do not properly remove mapped pages on truncate in some situations. -stable does. >Confidential: no >Severity: critical >Priority: high >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Mon Jul 27 22:00:02 PDT 1998 >Last-Modified: >Originator: Matthew Dillon >Organization: Best Internet Communications, Inc. >Release: FreeBSD 3.0-CURRENT i386 >Environment: Generic FreeBSD-current machine (CVS as of 26 Jul 98) Generic FreeBSD-stable machine (CVS somewhere between 2.2.6 and 2.2.7) >Description: ON a -current machine: If you open a file and use write() to write to it and either you or another process mmap()'s the file, if the file is then truncated mmap()'d pages that should have been removed (made illegal) are sometimes not and can still be referenced with the original data still intact. Example: create a file, write 4096+(512 to 4095) bytes to it. mmap the file, reference the second page of the mmap (volatile x = ptr[4096];), then ftruncate the file to 4096 bytes. You can still reference the second page of the mmap (which should now be illegal) and it still contains the original data written to it. Now repeat the process but write 4096+4096 bytes to the file. now when you ftruncate, referencing ptr[4096] after the ftruncate call will correctly segfault. (NOTE: This is different from the file corruption bug previously reported. This bug does not corrupt the file but does 'corrupt' the mmap. It may or may not be related to the previously reported file corruption-on- mmap while appending bug). (NOTE: The program properly segfaults in both cases on a -stable machine). >How-To-Repeat: /* * BADVM.C */ #include <sys/types.h> #include <sys/fcntl.h> #include <sys/types.h> #include <sys/mman.h> #include <stdio.h> #include <string.h> #include <fcntl.h> #include <unistd.h> #include <stdlib.h> #include <stdarg.h> int main(int ac, char **av) { int fd; char buf[4096 + 4096]; volatile char *base; volatile int x; int n; if (ac == 1) { printf("Run with an argument of '512' and then run with an argument of '4096'\n"); exit(1); } n = strtol(av[1], NULL, 0); if (n < 0 || n > 4096) { printf("argument out of bounds\n"); exit(1); } remove("test"); if ((fd = open("test", O_RDWR|O_CREAT, 0644)) < 0) perror("open"); memset(buf, 1, sizeof(buf)); if (write(fd, buf, 4096 + n) != 4096 + n) perror("write"); base = mmap((caddr_t)0, 8192, PROT_READ, MAP_SHARED, fd, 0); printf("map: %08lx\n", (long)base); printf("base[4096] should be 1: %d\n", base[4096]); ftruncate(fd, 4096); printf("base[4096] should fault: "); fflush(stdout); printf("%d\n", base[4096]); puts("oops, it didn't"); lseek(fd, 4096, 0); memset(buf, 2, sizeof(buf)); if (write(fd, buf, 4096) != 4096) perror("write"); printf("base[4096] should be 2: %d\n", base[4096]); return(0); } >Fix: >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?199807280453.VAA18002>