Subject: Bug in mmap() for files with holes
To: None <tech-kern@netbsd.org>
From: Thor Lancelot Simon <tls@rek.tjls.com>
List: tech-kern
Date: 11/14/2007 16:57:16
Lots of operating systems, over the years, have had bugs in mmap() such
that, for example, writing a byte into a page notionally backed by a
file that has a hole in it causes a segfault or bus error.
We appear to have such a bug for _reading_ files consisting only of holes;
see the program below. Modifying the program to write one byte to the
file before the lseek() that extends it causes the segfault to go away.
#include <sys/types.h>
#include <sys/mman.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (int argc, char **argv)
{
int dfd;
char bu[32], copybuf[1024];
void *ret;
/* Get a temporary file to soak up writes for this stream */
snprintf(bu, sizeof(bu), "/tmp/divo%d.XXXXXXXX", getpid());
dfd = mkstemp(bu);
if (dfd < 0) exit(1);
/* Remove it from the filesystem: now it's private to us */
if (unlink(bu)) exit(2);
/* Extend temporary file to requested length */
if (lseek(dfd, (off_t)1024, SEEK_SET) != (off_t)1024) exit(3);
(void)lseek(dfd, (off_t)0, SEEK_SET);
/* Map it! */
ret = mmap(NULL, 1024, PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED,
dfd, (off_t)0);
if (ret == MAP_FAILED) exit(4);
(void)memcpy(copybuf, ret, 1024);
exit(0);
}