[PATCH v14 8/8] kselftest/arm64: Verify that TCO is enabled in load_unaligned_zeropad()
From: Vincenzo Frascino <vincenzo.frascino@arm.com>
Date: 2021-03-08 16:16:08
Also in:
lkml
Subsystem:
arm64 port (aarch64 architecture), kernel selftest framework, the rest · Maintainers:
Catalin Marinas, Will Deacon, Shuah Khan, Shuah Khan, Linus Torvalds
load_unaligned_zeropad() and __get/put_kernel_nofault() functions can read passed some buffer limits which may include some MTE granule with a different tag. When MTE async mode is enable, the load operation crosses the boundaries and the next granule has a different tag the PE sets the TFSR_EL1.TF1 bit as if an asynchronous tag fault is happened: ================================================================== BUG: KASAN: invalid-access Asynchronous mode enabled: no access details available CPU: 0 PID: 1 Comm: init Not tainted 5.12.0-rc1-ge1045c86620d-dirty #8 Hardware name: FVP Base RevC (DT) Call trace: dump_backtrace+0x0/0x1c0 show_stack+0x18/0x24 dump_stack+0xcc/0x14c kasan_report_async+0x54/0x70 mte_check_tfsr_el1+0x48/0x4c exit_to_user_mode+0x18/0x38 finish_ret_to_user+0x4/0x15c ================================================================== Verify that Tag Check Override (TCO) is enabled in these functions before the load and disable it afterwards to prevent this to happen. Note: The issue has been observed only with an MTE enabled userspace. Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Will Deacon <will@kernel.org> Reported-by: Branislav Rankov <redacted> Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com> --- .../arm64/mte/check_read_beyond_buffer.c | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 tools/testing/selftests/arm64/mte/check_read_beyond_buffer.c
diff --git a/tools/testing/selftests/arm64/mte/check_read_beyond_buffer.c b/tools/testing/selftests/arm64/mte/check_read_beyond_buffer.c
new file mode 100644
index 000000000000..eb03cd52a58e
--- /dev/null
+++ b/tools/testing/selftests/arm64/mte/check_read_beyond_buffer.c@@ -0,0 +1,78 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2020 ARM Limited + +#define _GNU_SOURCE + +#include <errno.h> +#include <fcntl.h> +#include <pthread.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <unistd.h> +#include <sys/auxv.h> +#include <sys/mman.h> +#include <sys/prctl.h> +#include <sys/types.h> +#include <sys/wait.h> + +#include "kselftest.h" +#include "mte_common_util.h" +#include "mte_def.h" + +#define NUM_DEVICES 8 + +static char *dev[NUM_DEVICES] = { + "/proc/cmdline", + "/fstab.fvp", + "/dev/null", + "/proc/mounts", + "/proc/filesystems", + "/proc/cmdline", + "/proc/device-tre", /* incorrect path */ + "", +}; + +#define FAKE_PERMISSION 0x88000 +#define MAX_DESCRIPTOR 0xffffffff + +int mte_read_beyond_buffer_test(void) +{ + int fd[NUM_DEVICES]; + unsigned int _desc, _dev; + + for (_desc = 0; _desc <= MAX_DESCRIPTOR; _desc++) { + for (_dev = 0; _dev < NUM_DEVICES; _dev++) { +#ifdef _TEST_DEBUG + printf("[TEST]: openat(0x%x, %s, 0x%x)\n", _desc, dev[_dev], FAKE_PERMISSION); +#endif + + fd[_dev] = openat(_desc, dev[_dev], FAKE_PERMISSION); + } + + for (_dev = 0; _dev <= NUM_DEVICES; _dev++) + close(fd[_dev]); + } + + return KSFT_PASS; +} + +int main(int argc, char *argv[]) +{ + int err; + + err = mte_default_setup(); + if (err) + return err; + + ksft_set_plan(1); + + evaluate_test(mte_read_beyond_buffer_test(), + "Verify that TCO is enabled correctly if a read beyond buffer occurs\n"); + + mte_restore_setup(); + ksft_print_cnts(); + + return ksft_get_fail_cnt() == 0 ? KSFT_PASS : KSFT_FAIL; +}
--
2.30.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel