Failed to build with musl libc due to integer overflow in the argument for ioctl
erinacio opened this issue · 0 comments
This issue is found when trying to build nanobench latest bench and master commit on Alpine Linux (docker pull alpine:3.17) and a homemade musl toolchain on Arch Linux.
On Alpine Linux, a simple cmake <nanobench-dir> && make will show:
In file included from /tmp/nanobench/src/test/app/nanobench.cpp:2:
/tmp/nanobench/src/include/nanobench.h: In member function 'bool ankerl::nanobench::detail::LinuxPerformanceCounters::monitor(uint32_t, uint64_t, Target)':
/tmp/nanobench/src/include/nanobench.h:2679:25: error: overflow in conversion from 'long unsigned int' to 'int' changes value from '2148017159' to '-2146950137' [-Werror=overflow]
2679 | if (-1 == ioctl(fd, PERF_EVENT_IOC_ID, &id)) {
| ^~~~~~~~~~~~~~~~~
cc1plus: all warnings being treated as errors
make[2]: *** [CMakeFiles/nb.dir/build.make:76: CMakeFiles/nb.dir/src/test/app/nanobench.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:186: CMakeFiles/nb.dir/all] Error 2
make: *** [Makefile:136: all] Error 2
Clang has similar error message:
In file included from /tmp/nanobench/src/test/app/nanobench.cpp:2:
/tmp/nanobench/src/include/nanobench.h:2679:25: error: implicit conversion changes signedness: 'unsigned long' to 'int' [-Werror,-Wsign-conversion]
if (-1 == ioctl(fd, PERF_EVENT_IOC_ID, &id)) {
~~~~~ ^~~~~~~~~~~~~~~~~
/usr/include/linux/perf_event.h:507:29: note: expanded from macro 'PERF_EVENT_IOC_ID'
#define PERF_EVENT_IOC_ID _IOR('$', 7, __u64 *)
^~~~~~~~~~~~~~~~~~~~~
/usr/include/bits/ioctl.h:8:21: note: expanded from macro '_IOR'
#define _IOR(a,b,c) _IOC(_IOC_READ,(a),(b),sizeof(c))
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/bits/ioctl.h:1:52: note: expanded from macro '_IOC'
#define _IOC(a,b,c,d) ( ((a)<<30) | ((b)<<8) | (c) | ((d)<<16) )
~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~
1 error generated.
make[2]: *** [CMakeFiles/nb.dir/build.make:76: CMakeFiles/nb.dir/src/test/app/nanobench.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:186: CMakeFiles/nb.dir/all] Error 2
make: *** [Makefile:136: all] Error 2
After some investigation, turns out that this issue may be caused by glibc and musl using different signatures for ioctl. In glibc, ioctl is defined like (copied from Arch Linux /usr/include/sys/ioctl.h):
extern int ioctl (int __fd, unsigned long int __request, ...) __THROW;while in musl libc:
int ioctl (int, int, ...);PERF_EVENT_IOC_ID is evaluated to 2148017159 and thus overflows int, triggering -Woverflow.
Some Alpine Linux users already found this problem and reported it to musl. However, seems that musl maintainers were not willing to change it as that's exactly what POSIX specified.