440c7a9d9e
On uClibc up to at least v1.0.32, syscall() for x86_64 is defined in libc/sysdeps/linux/x86_64/syscall.S as syscall: movq %rdi, %rax /* Syscall number -> rax. */ movq %rsi, %rdi /* shift arg1 - arg5. */ movq %rdx, %rsi movq %rcx, %rdx movq %r8, %r10 movq %r9, %r8 movq 8(%rsp),%r9 /* arg6 is on the stack. */ syscall /* Do the system call. */ cmpq $-4095, %rax /* Check %rax for error. */ jae __syscall_error /* Branch forward if it failed. */ ret /* Return to caller. */ And __syscall_error is defined in libc/sysdeps/linux/x86_64/__syscall_error.c as int __syscall_error(void) attribute_hidden; int __syscall_error(void) { register int err_no __asm__ ("%rcx"); __asm__ ("mov %rax, %rcx\n\t" "neg %rcx"); __set_errno(err_no); return -1; } Notice that __syscall_error returns -1 as a 32-bit int in %rax, a 64-bit register i.e. 0x00000000ffffffff (decimal 4294967295). When this value is compared to -1 in _sys_chk_seccomp_flag_kernel() the result is false, leading the function to always return 0. Prevent the error by coercing the return value of syscall() to int in a temporary variable before comparing it to -1. We could use just an (int) cast but the variable makes the code more readable and the machine code generated by the compiler is the same in both cases. All other syscall() invocations were inspected and they either already coerce the result to int or do not compare it to -1. The same problem probably occurs on other 64-bit systems but so far only x86_64 was tested. A bug report is being submitted to uClibc. Upstream status: https://github.com/seccomp/libseccomp/pull/175 Signed-off-by: Carlos Santos <unixmania@gmail.com> Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be> |
||
---|---|---|
.. | ||
0001-remove-static.patch | ||
0002-Circumvent-bug-in-uClibc-ng-syscall-on-x86_64-system.patch | ||
Config.in | ||
libseccomp.hash | ||
libseccomp.mk |