[Buildroot] [PATCH] package/libseccomp: circumvent uClibc-ng bug on x86_64
Arnout Vandecappelle
arnout at mind.be
Sat Oct 19 19:34:03 UTC 2019
On 19/10/2019 03:15, unixmania at gmail.com wrote:
> From: Carlos Santos <unixmania at gmail.com>
>
> On uClibc up to v1.0.31, 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
Actually, I disagree with that. The intermediate variable hides the cast, and
the cast is the essential thing here. So if I were upstream, I'd want the
explicit cast, *and* a big fat comment above it to explain why it is needed.
For us, however, that reasoning doesn't really fly because we see the full
patch, not the source code.
> 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 at gmail.com>
I updated both the commit message and the patch to refer to uClibc 1.0.32
instead and applied to master, thanks.
Regards,
Arnout
More information about the buildroot
mailing list