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