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
|
network: 0.882
graphic: 0.879
vnc: 0.870
other: 0.865
socket: 0.857
semantic: 0.844
device: 0.834
instruction: 0.833
mistranslation: 0.801
boot: 0.776
KVM: 0.767
assembly: 0.725
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.
|