|
@@ -1,80 +0,0 @@
|
|
|
-From 613e601bb4b50dc359b41f162a5b629449e4bbea Mon Sep 17 00:00:00 2001
|
|
|
-From: Carlos Santos <casantos@redhat.com>
|
|
|
-Date: Fri, 18 Oct 2019 22:02:49 -0300
|
|
|
-Subject: [PATCH] Circumvent bug in uClibc-ng syscall() on x86_64 systems
|
|
|
-
|
|
|
-On uClibc at least up to 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.
|
|
|
-
|
|
|
-Signed-off-by: Carlos Santos <casantos@redhat.com>
|
|
|
----
|
|
|
- src/system.c | 8 +++++---
|
|
|
- 1 file changed, 5 insertions(+), 3 deletions(-)
|
|
|
-
|
|
|
-diff --git a/src/system.c b/src/system.c
|
|
|
-index 8e5aafc..811b401 100644
|
|
|
---- a/src/system.c
|
|
|
-+++ b/src/system.c
|
|
|
-@@ -215,10 +215,12 @@ static int _sys_chk_seccomp_flag_kernel(int flag)
|
|
|
- /* this is an invalid seccomp(2) call because the last argument
|
|
|
- * is NULL, but depending on the errno value of EFAULT we can
|
|
|
- * guess if the filter flag is supported or not */
|
|
|
-- if (sys_chk_seccomp_syscall() == 1 &&
|
|
|
-- syscall(_nr_seccomp, SECCOMP_SET_MODE_FILTER, flag, NULL) == -1 &&
|
|
|
-- errno == EFAULT)
|
|
|
-+ int rc;
|
|
|
-+ if (sys_chk_seccomp_syscall() == 1) {
|
|
|
-+ rc = syscall(_nr_seccomp, SECCOMP_SET_MODE_FILTER, flag, NULL);
|
|
|
-+ if (rc == -1 && errno == EFAULT)
|
|
|
- return 1;
|
|
|
-+ }
|
|
|
-
|
|
|
- return 0;
|
|
|
- }
|
|
|
---
|
|
|
-2.18.1
|
|
|
-
|