kern/68690: write(2) returns wrong vlalue when EFAULT
KOIE Hidetaka
koie at suri.co.jp
Mon Jul 5 05:30:23 PDT 2004
>Number: 68690
>Category: kern
>Synopsis: write(2) returns wrong vlalue when EFAULT
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Mon Jul 05 12:30:22 GMT 2004
>Closed-Date:
>Last-Modified:
>Originator: KOIE Hidetaka
>Release: FreeBSD-5.2 CURRENT
>Organization:
SURIGIKEN
>Environment:
FreeBSD sakura.suri.co.jp 5.2-CURRENT FreeBSD 5.2-CURRENT #1: Tue Jun 15 11:43:02 JST 2004 koie at sakura.suri.co.jp:/usr/obj/usr/src/sys/SAKURA i386
>Description:
Invoking write(fd, buf, size), if buf has both validand invalid segment,
write return -1, but it's file pointer has been advanced.
The caller mistakes the pointer stays.
>How-To-Repeat:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <unistd.h>
int
main()
{
const int PAGESIZE = sysconf(_SC_PAGESIZE);
const int N = 5;
const int SIZE = N * PAGESIZE;
int ifd = open("in.dat", O_RDWR|O_CREAT|O_TRUNC, 0600);
if (ifd < 0) {
perror("open");
goto out;
}
int should = 0;
for (int i = 0; i < N - 2; i++) {
char buf[PAGESIZE];
if (write(ifd, buf, sizeof buf) != sizeof buf) {
perror("write");
goto out;
}
should += sizeof buf;
}
int ofd = open("out.dat", O_WRONLY|O_CREAT|O_TRUNC, 0600);
if (ofd < 0) {
perror("open");
goto out;
}
void *addr = mmap(0, SIZE, PROT_READ, MAP_PRIVATE, ifd, 0);
if (addr == MAP_FAILED) {
perror("mmap");
goto out;
}
fprintf(stderr, "pos=%ld\n", (long)lseek(ofd, 0, SEEK_CUR));
int n = write(ofd, addr, SIZE);
fprintf(stderr, "write(%d)->%d (should be %d)\n", SIZE, n, should);
perror("write");
fprintf(stderr, "pos=%ld (should be %d)\n", (long)lseek(ofd, 0, SEEK_CUR), should);
out:
exit(0);
}
>Fix:
Sorry, I don't know.
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list