| Summary: | Filling up the disk using mmap(2) causes livelock. | ||
|---|---|---|---|
| Product: | Base System | Reporter: | trasz <trasz> |
| Component: | kern | Assignee: | freebsd-bugs (Nobody) <bugs> |
| Status: | Closed FIXED | ||
| Severity: | Affects Only Me | ||
| Priority: | Normal | ||
| Version: | 6.2-PRERELEASE | ||
| Hardware: | Any | ||
| OS: | Any | ||
State Changed From-To: open->closed Already fixed in -STABLE. |
Filling up a disk using mmap(2) causes some kind of livelock. The system becomes unresponsive. These messages appear on the console: Oct 29 14:54:16 sonne kernel: pid 7 (pagedaemon), uid 0 inumber 131261 on /: filesystem full vnode_pager_putpages: I/O error 28 vnode_pager_putpages: residual I/O 131072 at 44656 vnode_pager_putpages: I/O error 28 vnode_pager_putpages: residual I/O 131072 at 45689 vnode_pager_putpages: I/O error 28 vnode_pager_putpages: residual I/O 131072 at 45391 etc. It's easy to reproduce by unpriviledged user, so it's kind of DoS bug. How-To-Repeat: Make sure you have _not_ enough disk space and run the following program: #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <fcntl.h> #include <sys/mman.h> /* * if there is not enough space in the filesystem, this will crash freebsd. */ int main(void) { int fd; int ret; char *addr; size_t len=1000000000L; char *path="big_file"; int i; fd=open(path, O_RDWR | O_CREAT | O_EXCL, 0664); if (fd<0) { perror("open"); exit(-1); } ret=ftruncate(fd, len); if (ret!=0) { perror("ftruncate"); unlink(path); exit(-1); } addr=mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (addr==MAP_FAILED) { perror("mmap"); unlink(path); exit(-1); } for (i=0; i<len; i++) *(addr+i)='\42'; printf("somehow, it survived.\n"); unlink(path); return 0; }