Details
Description
When building Qt on unix systems without support for getifaddrs(), the code path that populates the hardware address details reported by QNetworkInterface::hardwareAddress() contains a bug. The bug results in the reported hardware address appearing to be the real hardware address shifted along by two fields, with the first two fields containing random data.
After dissecting the code and performing tests on subsets of it, there appears to be a bug in qnetworkinterface_unix.cpp along a code path that only gets used on unix systems with QT_NO_GETIFADDRS defined. At the end of the findInterface() function, around line 219, there is the following block of code:
#ifdef SIOCGIFHWADDR // Get the HW address if (qt_safe_ioctl(socket, SIOCGIFHWADDR, &req) >= 0) { uchar *addr = (uchar *)&req.ifr_addr; iface->hardwareAddress = iface->makeHwAddress(6, addr); } #endif
The assignment to uchar *addr looks to be incorrect, since req.ifr_addr is a struct, not the raw char/uchar buffer that the above code seems to expect. The sa_data member within req.ifr_addr seems to be what should be used. The reason that the code above results in the reported hardware address being offset by a couple of bytes is that the ifr_addr struct is of type sockaddr and this has a couple of bytes of data before the sa_data member. I believe the correct line should be:
uchar *addr = (uchar *)req.ifr_addr.sa_data;
Note that when building Qt with the LSB compilers, getifaddrs() is not available since it is not part of the LSB standard.
I will submit a merge request with this change tomorrow after I rebuild Qt with the fix applied.