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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
vnc: 0.093
other: 0.093
socket: 0.087
network: 0.082
semantic: 0.081
PID: 0.073
files: 0.070
device: 0.069
graphic: 0.064
performance: 0.061
debug: 0.060
permissions: 0.058
KVM: 0.056
boot: 0.051
vnc: 0.149
PID: 0.137
device: 0.112
socket: 0.107
files: 0.096
network: 0.071
KVM: 0.064
boot: 0.058
debug: 0.054
semantic: 0.053
other: 0.048
graphic: 0.018
performance: 0.017
permissions: 0.015
SIOCGIFNAME takes a struct ifreq not an integer
The ioctl SIOCGIFNAME takes a pointer to a struct ifreq, not an integer. This leads to if_indextoname() not correctly returning interface names (well, not if they're longer than 4 characters including the trailing NULL ;-).
This is observed on v3.1.0.
The following one-line patch will be sent to the qemu-devel mailing list:
"""
diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h
index ae8951625f..37501f575c 100644
--- a/linux-user/ioctls.h
+++ b/linux-user/ioctls.h
@@ -178,7 +178,7 @@
#endif /* CONFIG_USBFS */
IOCTL(SIOCATMARK, IOC_R, MK_PTR(TYPE_INT))
- IOCTL(SIOCGIFNAME, IOC_RW, MK_PTR(TYPE_INT))
+ IOCTL(SIOCGIFNAME, IOC_RW, MK_PTR(MK_STRUCT(STRUCT_int_ifreq)))
IOCTL(SIOCGIFFLAGS, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_short_ifreq)))
IOCTL(SIOCSIFFLAGS, IOC_W, MK_PTR(MK_STRUCT(STRUCT_short_ifreq)))
IOCTL(SIOCGIFADDR, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq)))
"""
Your suggested fix looks good -- did you want to send it to qemu-devel with a suitable Signed-off-by: line ?
Sure. Looking at HEAD, and even the surrounding the lines, I think I
should have tried STRUCT_short_ifreq instead of STRUCT_int_ifreq, though
I'm not sure what the real difference would be.
I'll try to test internally with the _short_ version and if that works send
that.
On Wed, 10 Apr 2019 at 01:26, Erik Kline <email address hidden> wrote:
> Sure. Looking at HEAD, and even the surrounding the lines, I think I
> should have tried STRUCT_short_ifreq instead of STRUCT_int_ifreq, though
> I'm not sure what the real difference would be.
The multiple STRUCT_*_ifreq are working around the fact that
our MK_STRUCT infrastructure can't handle unions. The struct
ifreq is a char array followed by a union whose members are
various different types. You should use the STRUCT_*_ifreq
corresponding to whatever type the union field used by this
particular ioctl is. For SIOCGIFNAME the ifr_ifindex is read,
and that's an int, so you want STRUCT_int_ifreq. (If you used
the 'short' version by mistake this would probably break for the
case of big-endian guest and little-endian host or vice-versa
because we'd swap the wrong amount of data.)
thanks
-- PMM
Patch sent to the list. Apologies for the delay.
Please let me know if further work or another patch submission is required.
Please let me know if further work or another patch submission is required.
https://git.qemu.org/?p=qemu.git;a=commit;h=43330b7169ae76222472a4b20c7f4db9d8880527
Thank you, all.
Released as part of v4.1.0.
|