Message ID | e31d9364eb0c2eba8ce246a558422e811d82d21b.1557160186.git.andreyknvl@google.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | arm64: untag user pointers passed to the kernel | expand |
On Mon, May 06, 2019 at 06:31:03PM +0200, Andrey Konovalov wrote: > This patch is a part of a series that extends arm64 kernel ABI to allow to > pass tagged user pointers (with the top byte set to something else other > than 0x00) as syscall arguments. > > This patch adds a simple test, that calls the uname syscall with a > tagged user pointer as an argument. Without the kernel accepting tagged > user pointers the test fails with EFAULT. That's probably sufficient for a simple example. Something we could add to Documentation maybe is a small library that can be LD_PRELOAD'ed so that you can run a lot more tests like LTP. We could add this to selftests but I think it's too glibc specific. --------------------8<------------------------------------ #include <stdlib.h> #define TAG_SHIFT (56) #define TAG_MASK (0xffUL << TAG_SHIFT) void *__libc_malloc(size_t size); void __libc_free(void *ptr); void *__libc_realloc(void *ptr, size_t size); void *__libc_calloc(size_t nmemb, size_t size); static void *tag_ptr(void *ptr) { unsigned long tag = rand() & 0xff; if (!ptr) return ptr; return (void *)((unsigned long)ptr | (tag << TAG_SHIFT)); } static void *untag_ptr(void *ptr) { return (void *)((unsigned long)ptr & ~TAG_MASK); } void *malloc(size_t size) { return tag_ptr(__libc_malloc(size)); } void free(void *ptr) { __libc_free(untag_ptr(ptr)); } void *realloc(void *ptr, size_t size) { return tag_ptr(__libc_realloc(untag_ptr(ptr), size)); } void *calloc(size_t nmemb, size_t size) { return tag_ptr(__libc_calloc(nmemb, size)); }
On Wed, May 22, 2019 at 4:16 PM Catalin Marinas <catalin.marinas@arm.com> wrote: > > On Mon, May 06, 2019 at 06:31:03PM +0200, Andrey Konovalov wrote: > > This patch is a part of a series that extends arm64 kernel ABI to allow to > > pass tagged user pointers (with the top byte set to something else other > > than 0x00) as syscall arguments. > > > > This patch adds a simple test, that calls the uname syscall with a > > tagged user pointer as an argument. Without the kernel accepting tagged > > user pointers the test fails with EFAULT. > > That's probably sufficient for a simple example. Something we could add > to Documentation maybe is a small library that can be LD_PRELOAD'ed so > that you can run a lot more tests like LTP. Should I add this into this series, or should this go into Vincenzo's patchset? > > We could add this to selftests but I think it's too glibc specific. > > --------------------8<------------------------------------ > #include <stdlib.h> > > #define TAG_SHIFT (56) > #define TAG_MASK (0xffUL << TAG_SHIFT) > > void *__libc_malloc(size_t size); > void __libc_free(void *ptr); > void *__libc_realloc(void *ptr, size_t size); > void *__libc_calloc(size_t nmemb, size_t size); > > static void *tag_ptr(void *ptr) > { > unsigned long tag = rand() & 0xff; > if (!ptr) > return ptr; > return (void *)((unsigned long)ptr | (tag << TAG_SHIFT)); > } > > static void *untag_ptr(void *ptr) > { > return (void *)((unsigned long)ptr & ~TAG_MASK); > } > > void *malloc(size_t size) > { > return tag_ptr(__libc_malloc(size)); > } > > void free(void *ptr) > { > __libc_free(untag_ptr(ptr)); > } > > void *realloc(void *ptr, size_t size) > { > return tag_ptr(__libc_realloc(untag_ptr(ptr), size)); > } > > void *calloc(size_t nmemb, size_t size) > { > return tag_ptr(__libc_calloc(nmemb, size)); > }
On Fri, May 31, 2019 at 04:21:48PM +0200, Andrey Konovalov wrote: > On Wed, May 22, 2019 at 4:16 PM Catalin Marinas <catalin.marinas@arm.com> wrote: > > On Mon, May 06, 2019 at 06:31:03PM +0200, Andrey Konovalov wrote: > > > This patch is a part of a series that extends arm64 kernel ABI to allow to > > > pass tagged user pointers (with the top byte set to something else other > > > than 0x00) as syscall arguments. > > > > > > This patch adds a simple test, that calls the uname syscall with a > > > tagged user pointer as an argument. Without the kernel accepting tagged > > > user pointers the test fails with EFAULT. > > > > That's probably sufficient for a simple example. Something we could add > > to Documentation maybe is a small library that can be LD_PRELOAD'ed so > > that you can run a lot more tests like LTP. > > Should I add this into this series, or should this go into Vincenzo's patchset? If you can tweak the selftest Makefile to build a library and force it with LD_PRELOAD, you can keep it with this patch. It would be easier to extend to other syscall tests, signal handling etc.
diff --git a/tools/testing/selftests/arm64/.gitignore b/tools/testing/selftests/arm64/.gitignore new file mode 100644 index 000000000000..e8fae8d61ed6 --- /dev/null +++ b/tools/testing/selftests/arm64/.gitignore @@ -0,0 +1 @@ +tags_test diff --git a/tools/testing/selftests/arm64/Makefile b/tools/testing/selftests/arm64/Makefile new file mode 100644 index 000000000000..a61b2e743e99 --- /dev/null +++ b/tools/testing/selftests/arm64/Makefile @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: GPL-2.0 + +# ARCH can be overridden by the user for cross compiling +ARCH ?= $(shell uname -m 2>/dev/null || echo not) + +ifneq (,$(filter $(ARCH),aarch64 arm64)) +TEST_GEN_PROGS := tags_test +TEST_PROGS := run_tags_test.sh +endif + +include ../lib.mk diff --git a/tools/testing/selftests/arm64/run_tags_test.sh b/tools/testing/selftests/arm64/run_tags_test.sh new file mode 100755 index 000000000000..745f11379930 --- /dev/null +++ b/tools/testing/selftests/arm64/run_tags_test.sh @@ -0,0 +1,12 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 + +echo "--------------------" +echo "running tags test" +echo "--------------------" +./tags_test +if [ $? -ne 0 ]; then + echo "[FAIL]" +else + echo "[PASS]" +fi diff --git a/tools/testing/selftests/arm64/tags_test.c b/tools/testing/selftests/arm64/tags_test.c new file mode 100644 index 000000000000..2bd1830a7ebe --- /dev/null +++ b/tools/testing/selftests/arm64/tags_test.c @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <stdint.h> +#include <sys/utsname.h> + +#define SHIFT_TAG(tag) ((uint64_t)(tag) << 56) +#define SET_TAG(ptr, tag) (((uint64_t)(ptr) & ~SHIFT_TAG(0xff)) | \ + SHIFT_TAG(tag)) + +int main(void) +{ + struct utsname *ptr = (struct utsname *)malloc(sizeof(*ptr)); + void *tagged_ptr = (void *)SET_TAG(ptr, 0x42); + int err = uname(tagged_ptr); + + free(ptr); + return err; +}
This patch is a part of a series that extends arm64 kernel ABI to allow to pass tagged user pointers (with the top byte set to something else other than 0x00) as syscall arguments. This patch adds a simple test, that calls the uname syscall with a tagged user pointer as an argument. Without the kernel accepting tagged user pointers the test fails with EFAULT. Signed-off-by: Andrey Konovalov <andreyknvl@google.com> --- tools/testing/selftests/arm64/.gitignore | 1 + tools/testing/selftests/arm64/Makefile | 11 ++++++++++ .../testing/selftests/arm64/run_tags_test.sh | 12 +++++++++++ tools/testing/selftests/arm64/tags_test.c | 21 +++++++++++++++++++ 4 files changed, 45 insertions(+) create mode 100644 tools/testing/selftests/arm64/.gitignore create mode 100644 tools/testing/selftests/arm64/Makefile create mode 100755 tools/testing/selftests/arm64/run_tags_test.sh create mode 100644 tools/testing/selftests/arm64/tags_test.c