Skip to content

adapter/syscall: fix ioctl conflicting types compile error on older glibc#1048

Merged
jfb8856606 merged 4 commits intodevfrom
fix/ioctl-variadic-conflicting-types
Mar 17, 2026
Merged

adapter/syscall: fix ioctl conflicting types compile error on older glibc#1048
jfb8856606 merged 4 commits intodevfrom
fix/ioctl-variadic-conflicting-types

Conversation

@jfb8856606
Copy link
Contributor

Problem

On systems where sys/ioctl.h is pulled in transitively before the strong_alias macro expansion (e.g. Amazon Linux 2, glibc 2.26, kernel 5.15), the LD_PRELOAD adapter fails to compile with:

./ff_declare_syscalls.h:25:22: error: conflicting types for 'ioctl'; have 'int(int, long unsigned int, long unsigned int)'
   25 | FF_SYSCALL_DECL(int, ioctl, (int, unsigned long, unsigned long));
/usr/include/sys/ioctl.h:42:12: note: previous declaration of 'ioctl' with type 'int(int, long unsigned int, ...)'
   42 | extern int ioctl (int __fd, unsigned long int __request, ...) __THROW;
make: *** [Makefile:129: ff_hook_syscall.o] Error 1

Root Cause

ioctl(2) is declared as variadic in glibc:

extern int ioctl(int __fd, unsigned long int __request, ...) __THROW;

But ff_declare_syscalls.h registered it with a fixed-arg prototype:

FF_SYSCALL_DECL(int, ioctl, (int, unsigned long, unsigned long));

When strong_alias() expands, __typeof(ff_hook_ioctl) yields a fixed-arg type that conflicts with the already-declared variadic ioctl from sys/ioctl.h. Whether the error triggers depends on the glibc version's header include chain — on newer glibc (2.38+) epoll.h does not pull in ioctl.h, so the conflict never surfaces; on older glibc it does.

Fix

  • Remove ioctl from ff_declare_syscalls.h (it cannot be handled by the generic FF_SYSCALL_DECL / strong_alias mechanism due to its variadic signature).
  • Add an explicit variadic public wrapper ioctl() in ff_hook_syscall.c that extracts the third argument via va_arg and forwards to ff_hook_ioctl(). This matches glibc's declaration exactly.
  • Update all files that previously relied on ff_declare_syscalls.h to auto-generate ioctl-related symbols:
    • ff_linux_syscall.h: explicit declaration of ff_linux_ioctl()
    • ff_linux_syscall.c: manual pf_ioctl struct member and dlsym() load

Testing

Compiled and verified on TencentOS (kernel 5.4, GCC 12.3.1, glibc 2.38). The error can be reproduced on any GCC version by manually including sys/ioctl.h before the macro expansion.

Fixes #942

@jfb8856606 jfb8856606 merged commit 2958b02 into dev Mar 17, 2026
7 checks passed
@jfb8856606 jfb8856606 deleted the fix/ioctl-variadic-conflicting-types branch March 17, 2026 14:37
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

Successfully merging this pull request may close these issues.

compile error on LD_PRELOAD version

1 participant