Description:
When compiling rsync 3.4.3 on a Linux 5.10.x system with kernel-headers-5.10.256 (LTS), the build fails with the following error:
syscall.c: In function 'secure_relative_open_linux':
syscall.c:1723:19: error: 'SYS_openat2' undeclared (first use in this function); did you mean 'SYS_openat'?
dirfd = syscall(SYS_openat2, AT_FDCWD, basedir, &bhow, sizeof bhow);
^~~~~~~~~~~
SYS_openat
Environment:
- Kernel: 5.10.256 (running)
- kernel-headers: 5.10.256 (installed)
- Architecture: x86_64 (also affects i386 builds)
- glibc: 2.30
Root cause analysis:
The secure_relative_open_linux() function introduced in PR #887 assumes that if <linux/openat2.h> is included and the running kernel is >=5.6, then the macro SYS_openat2 will be defined. This assumption is false.
Although the running kernel (5.10.256) supports the openat2 syscall, the constant SYS_openat2 is not defined in the standard user-space headers provided by kernel-headers-5.10.256. Specifically, it is missing from /usr/include/asm/unistd_64.h (and equivalent for i386).
The issue occurs because:
- The code includes
<linux/openat2.h> (defines RESOLVE_BENEATH, struct open_how, etc.)
- However,
SYS_openat2 (the syscall number) is defined in <asm/unistd.h> which is not consistently exported or may be outdated in distribution kernel-header packages.
Temporary workaround used:
Adding -DSYS_openat2=437 to CFLAGS resolves the compilation. The syscall number 437 is correct for both x86_64 and i386 architectures.
Expected behavior:
The build should succeed on Linux 5.10+ systems without requiring manual definition of SYS_openat2. The code should either:
- Include the necessary headers in the correct order to ensure
SYS_openat2 is defined, or
- Use the
syscall number directly (e.g., __NR_openat2 from an appropriate kernel header), or
- Provide a fallback definition when
SYS_openat2 is not defined by the system headers.
Additional notes:
- This issue affects both 64-bit and 32-bit builds.
- The problem is not specific to an outdated kernel; the running kernel (5.10.256 LTS) fully supports openat2.
Proposed fix suggestion:
Modify syscall.c to conditionally define SYS_openat2 if not already provided by system headers, for example:
#ifdef __linux__
#include <sys/syscall.h>
#include <linux/openat2.h>
#ifndef SYS_openat2
#define SYS_openat2 __NR_openat2
#endif
#endif
Alternatively, use runtime detection of the syscall number via syscall(__NR_openat2, ...) if __NR_openat2 is defined, or add a configure-time check.
Versions affected:
Thank you for maintaining rsync!
Description:
When compiling rsync 3.4.3 on a Linux 5.10.x system with kernel-headers-5.10.256 (LTS), the build fails with the following error:
Environment:
Root cause analysis:
The
secure_relative_open_linux()function introduced in PR #887 assumes that if<linux/openat2.h>is included and the running kernel is >=5.6, then the macroSYS_openat2will be defined. This assumption is false.Although the running kernel (5.10.256) supports the openat2 syscall, the constant
SYS_openat2is not defined in the standard user-space headers provided by kernel-headers-5.10.256. Specifically, it is missing from/usr/include/asm/unistd_64.h(and equivalent for i386).The issue occurs because:
<linux/openat2.h>(definesRESOLVE_BENEATH,struct open_how, etc.)SYS_openat2(thesyscallnumber) is defined in<asm/unistd.h>which is not consistently exported or may be outdated in distribution kernel-header packages.Temporary workaround used:
Adding
-DSYS_openat2=437toCFLAGSresolves the compilation. Thesyscallnumber437is correct for both x86_64 and i386 architectures.Expected behavior:
The build should succeed on Linux 5.10+ systems without requiring manual definition of SYS_openat2. The code should either:
SYS_openat2is defined, orsyscallnumber directly (e.g.,__NR_openat2from an appropriate kernel header), orSYS_openat2is not defined by the system headers.Additional notes:
Proposed fix suggestion:
Modify syscall.c to conditionally define SYS_openat2 if not already provided by system headers, for example:
Alternatively, use runtime detection of the syscall number via
syscall(__NR_openat2, ...) if__NR_openat2is defined, or add a configure-time check.Versions affected:
Thank you for maintaining rsync!