[PATCH] arm64: Allow user pointer tags to be passed into the kernel

From: Catalin Marinas
Date: Tue Feb 06 2018 - 12:54:05 EST


The current tagged pointer ABI disallows the top byte of a user pointer
to be non-zero when invoking a syscall. This patch allows such pointer
to be passed into the kernel and the kernel will mask them out
automatically. Page-based syscall ABI (mmap, mprotect, madvise etc.)
expect the pointer tag to be 0 (see include/linux/syscalls.h for the ABI
functions taking __user pointers).

Signed-off-by: Catalin Marinas <catalin.marinas@xxxxxxx>
---
arch/arm64/include/asm/unistd.h | 9 +++++++++
include/linux/syscalls.h | 2 ++
2 files changed, 11 insertions(+)

diff --git a/arch/arm64/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h
index a0baa9af5487..cd68ad969e3a 100644
--- a/arch/arm64/include/asm/unistd.h
+++ b/arch/arm64/include/asm/unistd.h
@@ -53,3 +53,12 @@
#endif

#define NR_syscalls (__NR_syscalls)
+
+/* copied from arch/s390/ */
+#define __TYPE_IS_PTR(t) (!__builtin_types_compatible_p( \
+ typeof(0?(__force t)0:0ULL), u64))
+/* sign-extend bit 55 to mask out the pointer tag */
+#define __SC_CAST(t, a) \
+ (__TYPE_IS_PTR(t) \
+ ? (__force t)((__s64)((__u64)a << 8) >> 8) \
+ : (__force t)a)
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index a78186d826d7..279497207a31 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -105,7 +105,9 @@ union bpf_attr;
#define __TYPE_IS_UL(t) (__TYPE_AS(t, 0UL))
#define __TYPE_IS_LL(t) (__TYPE_AS(t, 0LL) || __TYPE_AS(t, 0ULL))
#define __SC_LONG(t, a) __typeof(__builtin_choose_expr(__TYPE_IS_LL(t), 0LL, 0L)) a
+#ifndef __SC_CAST
#define __SC_CAST(t, a) (__force t) a
+#endif
#define __SC_ARGS(t, a) a
#define __SC_TEST(t, a) (void)BUILD_BUG_ON_ZERO(!__TYPE_IS_LL(t) && sizeof(t) > sizeof(long))

--
Catalin