SIOCGIFNAME takes a struct ifreq not an integer

Bug #1814352 reported by Erik Kline on 2019-02-02
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
QEMU
Undecided
Unassigned

Bug Description

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)))
"""

Peter Maydell (pmaydell) wrote :

Your suggested fix looks good -- did you want to send it to qemu-devel with a suitable Signed-off-by: line ?

tags: added: linux-user
Changed in qemu:
status: New → Confirmed

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

Erik Kline (ekline) wrote :

Patch sent to the list. Apologies for the delay.

Erik Kline (ekline) wrote :

Please let me know if further work or another patch submission is required.

Erik Kline (ekline) wrote :

Thank you, all.

Changed in qemu:
status: Confirmed → Fix Committed
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers