There's a subtle bug in the DL_SYSCALL() implementation on arm64.
Upon error we're supposed to return -errno.  The code does a negate of
the lower 32-bit bits.  This means that syscalls that return a 64-bit
number (i.e. ssize_t) still return a positive number as the upper 32
bits remain zero.  So we should negate the full 64 bits.  That's safe
even for system calls that return a 32-bit number since setting the
lower 32 bits zeroes the upper 32 bits on arm64 just like on amd64.

Fixes a crash I saw during ports building where dl_readlink()
returning EINVAL resulted in an out-of-bounds access.

ok?


Index: libexec/ld.so/aarch64/SYS.h
===================================================================
RCS file: /cvs/src/libexec/ld.so/aarch64/SYS.h,v
retrieving revision 1.1
diff -u -p -r1.1 SYS.h
--- libexec/ld.so/aarch64/SYS.h 27 Aug 2017 21:59:51 -0000      1.1
+++ libexec/ld.so/aarch64/SYS.h 15 May 2018 18:13:42 -0000
@@ -42,5 +42,5 @@ __CONCAT(_dl_,n):                                     ;\
        ret
 
 .L_cerr:
-       neg     w0, w0          /* r0 = -errno */
+       neg     x0, x0          /* r0 = -errno */
        ret

Reply via email to