blob: 6ef332c89c5a746658a04de2230a7df99ff2290c (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
semantic: 0.866
graphic: 0.865
assembly: 0.827
device: 0.819
instruction: 0.817
socket: 0.783
other: 0.774
network: 0.759
KVM: 0.756
boot: 0.739
vnc: 0.715
mistranslation: 0.595
O_CLOEXEC not handled in dup3 system call in user mode
In qemu user mode, for hppa and sparc64 targets, the parameter of the dup3 is not passed correctly when it contains the O_CLOEXEC flag.
When the attached program runs, the expected output is:
errno=9=EBADF
How to reproduce on hppa:
- Compile the program: hppa-linux-gnu-gcc-5 -O -Wall -static testdup3.c -o testdup3-hppa
- Set environment variables for running qemu-hppa.
- ~/inst-qemu/2.9.0/bin/qemu-hppa testdup3-hppa
errno=22=EINVAL
testdup3.c:54: assertion 'errno == EBADF' failed
How to reproduce on sparc64:
- Compile the program: sparc64-linux-gnu-gcc-5 -O -Wall -static testdup3.c -o testdup3-sparc64
- Set environment variables for running qemu-sparc64.
- ~/inst-qemu/2.9.0/bin/qemu-sparc64 testdup3-sparc64
errno=22=EINVAL
testdup3.c:54: assertion 'errno == EBADF' failed
I see this bug for hppa, sparc64.
I don't see it for m68k, mips, mips64, powerpc, powerpc64.
Most likely because the binary values of O_CLOEXEC on hppa and sparc64 are different than on other platforms. Looking in the glibc source code:
$ grep -r 'define.*O_CLOEXEC' glibc
glibc/bits/fcntl.h:# define O_CLOEXEC 0x00400000 /* Set close_on_exec. */
glibc/sysdeps/mach/hurd/bits/fcntl.h:# define O_CLOEXEC 0x00400000 /* Set FD_CLOEXEC. */
glibc/sysdeps/unix/sysv/linux/sparc/bits/fcntl.h:#define __O_CLOEXEC 0x400000 /* Set close_on_exit. */
glibc/sysdeps/unix/sysv/linux/bits/fcntl-linux.h:# define __O_CLOEXEC 02000000
glibc/sysdeps/unix/sysv/linux/bits/fcntl-linux.h:# define O_CLOEXEC __O_CLOEXEC /* Set close_on_exec. */
glibc/sysdeps/unix/sysv/linux/hppa/bits/fcntl.h:#define __O_CLOEXEC 010000000 /* Set close_on_exec. */
glibc/sysdeps/unix/sysv/linux/microblaze/bits/fcntl.h:#define __O_CLOEXEC 02000000 /* Set close_on_exec. */
glibc/sysdeps/unix/sysv/linux/alpha/bits/fcntl.h:#define __O_CLOEXEC 010000000 /* Set close_on_exec. */
glibc/sysdeps/nacl/bits/fcntl.h:# define O_CLOEXEC 02000000 /* Set close_on_exec. */
So, what's missing is probably that the O_CLOEXEC of the target platform gets mapped to O_CLOEXEC of the host platform, during the dup3 system call emulation.
The behaviour in qemu-2.10 is the same as in qemu-2.9.
The behaviour in qemu-2.11 is the same as in qemu-2.9.
Should be fixed by http://patchwork.ozlabs.org/patch/849226/
Fix has been included here:
https://git.qemu.org/?p=qemu.git;a=commitdiff;h=10fa993aae539fa8d0da1d
Confirmed: It's fixed in qemu-2.12.
|