Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Failed to build with musl libc due to integer overflow in the argument for ioctl #92

Open
erinacio opened this issue Mar 6, 2023 · 0 comments

Comments

@erinacio
Copy link

erinacio commented Mar 6, 2023

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant