pread()/pwrite() fail with EBADF in child process if already used before fork()

Cedric Blancher cedric.blancher@gmail.com
Fri Oct 4 14:56:44 GMT 2024


On Tue, 24 Sept 2024 at 12:16, Christian Franke via Cygwin
<cygwin@cygwin.com> wrote:
>
> Christian Franke via Cygwin wrote:
> > Christian Franke via Cygwin wrote:
> >> Found during test of 'stress-ng --pseek ...' from current upstream
> >> stress-ng git HEAD:
> >>
> >> Testcase:
> >>
> >> $ uname -r
> >> 3.5.4-1.x86_64
> >>
> >> $ cat pfail.c
> >> #include <fcntl.h>
> >> #include <stdio.h>
> >> #include <unistd.h>
> >> #include <sys/wait.h>
> >>
> >> int main()
> >> {
> >>   int fd = open("pwrite.tmp", O_RDWR|O_CREAT|O_BINARY, 0666);
> >>   if (fd < 0) {
> >>     perror("open"); return 1;
> >>   }
> >>
> >>   char c = 42;
> >>   if (pwrite(fd, &c, 1, 0) < 0)
> >>     perror("pwrite");
> >>
> >>   if (fork() == 0) {
> >>     if (pread(fd, &c, 1, 0) < 0)
> >>       perror("pread");
> >>     _exit(0);
> >>   }
> >>
> >>   int status;
> >>   wait(&status);
> >>   return 0;
> >> }
> >>
> >> $ make pfail
> >> cc     pfail.c   -o pfail
> >>
> >> $ ./pfail
> >> pread: Bad file descriptor
> >>
> >> $ strace ./pfail
> >> ...
> >>   617   75356 [main] pfail 10826 dofork: 10827 = fork()
> >>    82   11289 [main] pfail 10827 seterrno_from_nt_status:
> >> /usr/src/debug/cygwin-3.5.4-1/winsup/cygwin/fhandler/disk_file.cc:1883
> >> status 0xC0000008 -> windows error 6
> >>    80   75436 [main] pfail 10826 wait4: calling proc_subproc, pid -1,
> >> options 0
> >>    76   11365 [main] pfail 10827 geterrno_from_win_error: windows
> >> error 6 == errno 9
> >>    78   75514 [main] pfail 10826 proc_subproc: args: 5, -7728
> >>    64   11429 [main] pfail 10827 pread: -1 = pread(3, 0x7FFFFCC0B, 1,
> >> 0), errno 9
> >> ...
> >>
> >>
> >> The problem does not occur if there is no pread()/pwrite() before the
> >> fork(). This suggests that the child process inherits the extra
> >> handle value used to keep the original seek position, but not the
> >> actual handle.
> >>
> >
> >
> > The mentioned extra handle 'prw_handle' is set to null after fork here:
> > https://cygwin.com/git/?p=newlib-cygwin.git;a=blob;f=winsup/cygwin/fhandler/disk_file.cc;h=f4c21d3#l1698
> >
> >
> > But a test suggests that fhandler_disk_file::fixup_after_fork() is
> > never called or debug_printf() does not work if called in this function.
>
> Possible fix:
> https://sourceware.org/pipermail/cygwin-patches/2024q3/012793.html
>

Is this fix going to be committed to Cygwin 3.6 anytime soon?

Ced
-- 
Cedric Blancher <cedric.blancher@gmail.com>
[https://plus.google.com/u/0/+CedricBlancher/]
Institute Pasteur


More information about the Cygwin mailing list