NetBSD-SA1998-003: problem with mmap(2) and append-only files.
X-RDate: Tue, 12 May 1998 11:57:18 +0600 (YEKST)
X-UIDL: 35317d340000021c
Date: Mon, 11 May 1998 00:49:33 +1000
From: matthew green <mrg@ETERNA.COM.AU>
To: BUGTRAQ@NETSPACE.ORG
Subject: Re: NetBSD-SA1998-003: problem with mmap(2) and append-only files.
i meant to include this test program. oops.
.mrg.
/*
* 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 <sys/types.h>
#include <sys/cdefs.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
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 <file>");
/* 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);
}