/* * mmap-bug.c: test for the presense of mmap bug with append-only * files. if it fails (and the bug is not present), it will probably * exit with an error from a system call. this program will only * compile on systems with 4.4BSD-compatible `file flags'. * * Copyright (c) 1998 Matthew Green. All Rights Reserved. */ #include #include #include #include #include #include #include #include #include #include char filedata[] = "you do NOT have the bug.\n"; char data[] = "you do have the bug.\n"; void child __P((const char *)); int main(argc, argv) int argc; char *argv[]; { caddr_t f; pid_t pid; int fd; if (argc < 2) errx(1, "usage: mmap-bug "); /* first create the file, and set APPEND */ fd = open(argv[1], O_CREAT|O_TRUNC|O_WRONLY, 0644); if (fd < 0) err(1, "open"); if (write(fd, filedata, sizeof filedata) < 0) err(1, "write"); if (fchflags(fd, SF_APPEND|UF_APPEND) < 0) err(1, "fchflags"); if (close(fd) < 0) err(1, "close"); /* now fork the child */ pid = fork(); if (pid < 0) err(1, "fork"); if (pid == 0) child(argv[1]); /* ok, in parent: open file append/read/write, and map it in */ fd = open(argv[1], O_APPEND|O_RDWR, 0); if (fd < 0) err(1, "parent open"); f = mmap(0, 4096, PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0); if (f == (caddr_t)-1) err(1, "parent mmap"); /* modify the file, and write it out */ strcpy(f, data); /* wait for the child, and clean up */ wait(NULL); if (fchflags(fd, 0) < 0) err(1, "fchflags 2"); if (unlink(argv[1]) < 0) err(1, "unlink"); exit(0); } void child(path) const char *path; { caddr_t f; int fd; sleep(3); /* ok, in child: open file read, and map it in */ fd = open(path, O_RDONLY); if (fd < 0) err(1, "child open"); f = mmap(0, 4096, PROT_READ, MAP_SHARED, fd, 0); if (f == (caddr_t)-1) err(1, "child mmap"); /* write it out */ write(1, f, strlen(f)); exit(0); }