* [PATCH 1/2] lib: kasan: remove reference of non-existent test_kasan.o
@ 2020-09-28 14:41 Ahmad Fatoum
2020-09-28 14:41 ` [PATCH 2/2] lib: kasan: migrate Kconfig option to Debugging menu Ahmad Fatoum
2020-09-28 14:58 ` [PATCH 1/2] lib: kasan: remove reference of non-existent test_kasan.o Sascha Hauer
0 siblings, 2 replies; 7+ messages in thread
From: Ahmad Fatoum @ 2020-09-28 14:41 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
We don't have anything that test_kasan.o can be generated out of,
thus drop it to fix the build.
It would still be nice to have this as a command, but that
should be a separate patch.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
lib/kasan/Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/kasan/Makefile b/lib/kasan/Makefile
index 31e9d890d538..11106574e0c2 100644
--- a/lib/kasan/Makefile
+++ b/lib/kasan/Makefile
@@ -1,5 +1,5 @@
-obj-y += generic_report.o generic.o report.o common.o test_kasan.o
+obj-y += generic_report.o generic.o report.o common.o
KASAN_SANITIZE_generic_report.o := n
KASAN_SANITIZE_generic.o := n
KASAN_SANITIZE_report.o := n
--
2.28.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 2/2] lib: kasan: migrate Kconfig option to Debugging menu
2020-09-28 14:41 [PATCH 1/2] lib: kasan: remove reference of non-existent test_kasan.o Ahmad Fatoum
@ 2020-09-28 14:41 ` Ahmad Fatoum
2020-09-29 6:37 ` Sascha Hauer
2020-09-28 14:58 ` [PATCH 1/2] lib: kasan: remove reference of non-existent test_kasan.o Sascha Hauer
1 sibling, 1 reply; 7+ messages in thread
From: Ahmad Fatoum @ 2020-09-28 14:41 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
UBSAN and ASAN as well as other debugging aids are all in the
Debugging menu. Relocate KASAN to be there as well.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
common/Kconfig | 1 +
lib/Kconfig | 2 --
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/common/Kconfig b/common/Kconfig
index 8b8b30db0fc7..9419977276b2 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -1379,6 +1379,7 @@ config PBL_BREAK
on early pbl init. This option should be used only with JTAG debugger!
source "lib/Kconfig.ubsan"
+source "lib/kasan/Kconfig"
config ASAN
bool "ASAN: runtime memory debugger"
diff --git a/lib/Kconfig b/lib/Kconfig
index 6d909c1ac8f0..90552f3c2762 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -154,8 +154,6 @@ source "lib/logo/Kconfig"
source "lib/bootstrap/Kconfig"
-source "lib/kasan/Kconfig"
-
config PRINTF_UUID
bool
--
2.28.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] lib: kasan: remove reference of non-existent test_kasan.o
2020-09-28 14:41 [PATCH 1/2] lib: kasan: remove reference of non-existent test_kasan.o Ahmad Fatoum
2020-09-28 14:41 ` [PATCH 2/2] lib: kasan: migrate Kconfig option to Debugging menu Ahmad Fatoum
@ 2020-09-28 14:58 ` Sascha Hauer
2020-09-28 14:59 ` Ahmad Fatoum
1 sibling, 1 reply; 7+ messages in thread
From: Sascha Hauer @ 2020-09-28 14:58 UTC (permalink / raw)
To: Ahmad Fatoum; +Cc: barebox
On Mon, Sep 28, 2020 at 04:41:45PM +0200, Ahmad Fatoum wrote:
> We don't have anything that test_kasan.o can be generated out of,
> thus drop it to fix the build.
>
> It would still be nice to have this as a command, but that
> should be a separate patch.
>
> Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
> ---
> lib/kasan/Makefile | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
I prefer to add the code that I have forgotten to git add ;)
Sascha
----------------------8<-----------------
From ff5cbfcbbe21d7883e3ce661fec3751f7cb7e58c Mon Sep 17 00:00:00 2001
From: Sascha Hauer <s.hauer@pengutronix.de>
Date: Mon, 28 Sep 2020 16:56:36 +0200
Subject: [PATCH] KASan: Add missing test code
Add missing test code.
Fixes: 6cd9d2d600 ("Add KASan support")
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
lib/kasan/test_kasan.c | 478 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 478 insertions(+)
create mode 100644 lib/kasan/test_kasan.c
diff --git a/lib/kasan/test_kasan.c b/lib/kasan/test_kasan.c
new file mode 100644
index 0000000000..e472bb3499
--- /dev/null
+++ b/lib/kasan/test_kasan.c
@@ -0,0 +1,478 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Author: Andrey Ryabinin <a.ryabinin@samsung.com>
+ */
+
+#define pr_fmt(fmt) "kasan test: " fmt
+
+#include <common.h>
+#include <command.h>
+#include <complete.h>
+
+#include "kasan.h"
+
+/*
+ * We assign some test results to these globals to make sure the tests
+ * are not eliminated as dead code.
+ */
+
+int kasan_int_result;
+void *kasan_ptr_result;
+
+/*
+ * Note: test functions are marked noinline so that their names appear in
+ * reports.
+ */
+
+static noinline void malloc_oob_right(void)
+{
+ char *ptr;
+ size_t size = 123;
+
+ pr_info("out-of-bounds to right\n");
+ ptr = malloc(size);
+ if (!ptr) {
+ pr_err("Allocation failed\n");
+ return;
+ }
+
+ ptr[size] = 'x';
+
+ free(ptr);
+}
+
+static noinline void malloc_oob_left(void)
+{
+ char *ptr;
+ size_t size = 15;
+
+ pr_info("out-of-bounds to left\n");
+ ptr = malloc(size);
+ if (!ptr) {
+ pr_err("Allocation failed\n");
+ return;
+ }
+
+ *ptr = *(ptr - 1);
+ free(ptr);
+}
+
+static noinline void malloc_oob_realloc_more(void)
+{
+ char *ptr1, *ptr2;
+ size_t size1 = 17;
+ size_t size2 = 19;
+
+ pr_info("out-of-bounds after krealloc more\n");
+ ptr1 = malloc(size1);
+ ptr2 = realloc(ptr1, size2);
+ if (!ptr1 || !ptr2) {
+ pr_err("Allocation failed\n");
+ free(ptr1);
+ free(ptr2);
+ return;
+ }
+
+ ptr2[size2] = 'x';
+
+ free(ptr2);
+}
+
+static noinline void malloc_oob_realloc_less(void)
+{
+ char *ptr1, *ptr2;
+ size_t size1 = 17;
+ size_t size2 = 15;
+
+ pr_info("out-of-bounds after krealloc less\n");
+ ptr1 = malloc(size1);
+ ptr2 = realloc(ptr1, size2);
+ if (!ptr1 || !ptr2) {
+ pr_err("Allocation failed\n");
+ free(ptr1);
+ return;
+ }
+
+ ptr2[size2] = 'x';
+
+ free(ptr2);
+}
+
+static noinline void malloc_oob_16(void)
+{
+ struct {
+ u64 words[2];
+ } *ptr1, *ptr2;
+
+ pr_info("malloc out-of-bounds for 16-bytes access\n");
+ ptr1 = malloc(sizeof(*ptr1) - 3);
+ ptr2 = malloc(sizeof(*ptr2));
+ if (!ptr1 || !ptr2) {
+ pr_err("Allocation failed\n");
+ free(ptr1);
+ free(ptr2);
+ return;
+ }
+ *ptr1 = *ptr2;
+ free(ptr1);
+ free(ptr2);
+}
+
+static noinline void malloc_oob_memset_2(void)
+{
+ char *ptr;
+ size_t size = 8;
+
+ pr_info("out-of-bounds in memset2\n");
+ ptr = malloc(size);
+ if (!ptr) {
+ pr_err("Allocation failed\n");
+ return;
+ }
+
+ memset(ptr + 7, 0, 2);
+
+ free(ptr);
+}
+
+static noinline void malloc_oob_memset_4(void)
+{
+ char *ptr;
+ size_t size = 8;
+
+ pr_info("out-of-bounds in memset4\n");
+ ptr = malloc(size);
+ if (!ptr) {
+ pr_err("Allocation failed\n");
+ return;
+ }
+
+ memset(ptr + 5, 0, 4);
+
+ free(ptr);
+}
+
+
+static noinline void malloc_oob_memset_8(void)
+{
+ char *ptr;
+ size_t size = 8;
+
+ pr_info("out-of-bounds in memset8\n");
+ ptr = malloc(size);
+ if (!ptr) {
+ pr_err("Allocation failed\n");
+ return;
+ }
+
+ memset(ptr + 1, 0, 8);
+
+ free(ptr);
+}
+
+static noinline void malloc_oob_memset_16(void)
+{
+ char *ptr;
+ size_t size = 16;
+
+ pr_info("out-of-bounds in memset16\n");
+ ptr = malloc(size);
+ if (!ptr) {
+ pr_err("Allocation failed\n");
+ return;
+ }
+
+ memset(ptr + 1, 0, 16);
+
+ free(ptr);
+}
+
+static noinline void malloc_oob_in_memset(void)
+{
+ char *ptr;
+ size_t size = 666;
+
+ pr_info("out-of-bounds in memset\n");
+ ptr = malloc(size);
+ if (!ptr) {
+ pr_err("Allocation failed\n");
+ return;
+ }
+
+ memset(ptr, 0, size + 5);
+
+ free(ptr);
+}
+
+static noinline void malloc_uaf(void)
+{
+ char *ptr;
+ size_t size = 10;
+
+ pr_info("use-after-free\n");
+ ptr = malloc(size);
+ if (!ptr) {
+ pr_err("Allocation failed\n");
+ return;
+ }
+
+ free(ptr);
+ *(ptr + 8) = 'x';
+}
+
+static noinline void malloc_uaf_memset(void)
+{
+ char *ptr;
+ size_t size = 33;
+
+ pr_info("use-after-free in memset\n");
+ ptr = malloc(size);
+ if (!ptr) {
+ pr_err("Allocation failed\n");
+ return;
+ }
+
+ free(ptr);
+ memset(ptr, 0, size);
+}
+
+static noinline void malloc_uaf2(void)
+{
+ char *ptr1, *ptr2;
+ size_t size = 43;
+
+ pr_info("use-after-free after another malloc\n");
+ ptr1 = malloc(size);
+ if (!ptr1) {
+ pr_err("Allocation failed\n");
+ return;
+ }
+
+ free(ptr1);
+ ptr2 = malloc(size);
+ if (!ptr2) {
+ pr_err("Allocation failed\n");
+ return;
+ }
+
+ ptr1[40] = 'x';
+ if (ptr1 == ptr2)
+ pr_err("Could not detect use-after-free: ptr1 == ptr2\n");
+ free(ptr2);
+}
+
+static char global_array[10];
+
+static noinline void kasan_global_oob(void)
+{
+ volatile int i = 3;
+ char *p = &global_array[ARRAY_SIZE(global_array) + i];
+
+ pr_info("out-of-bounds global variable\n");
+ *(volatile char *)p;
+}
+
+static noinline void kasan_stack_oob(void)
+{
+ char stack_array[10];
+ volatile int i = 0;
+ char *p = &stack_array[ARRAY_SIZE(stack_array) + i];
+
+ pr_info("out-of-bounds on stack\n");
+ *(volatile char *)p;
+}
+
+static noinline void kasan_alloca_oob_left(void)
+{
+ volatile int i = 10;
+ char alloca_array[i];
+ char *p = alloca_array - 1;
+
+ pr_info("out-of-bounds to left on alloca\n");
+ *(volatile char *)p;
+}
+
+static noinline void kasan_alloca_oob_right(void)
+{
+ volatile int i = 10;
+ char alloca_array[i];
+ char *p = alloca_array + i;
+
+ pr_info("out-of-bounds to right on alloca\n");
+ *(volatile char *)p;
+}
+
+static noinline void kasan_memchr(void)
+{
+ char *ptr;
+ size_t size = 24;
+
+ pr_info("out-of-bounds in memchr\n");
+ ptr = kzalloc(size, 0);
+ if (!ptr)
+ return;
+
+ kasan_ptr_result = memchr(ptr, '1', size + 1);
+ free(ptr);
+}
+
+static noinline void kasan_memcmp(void)
+{
+ char *ptr;
+ size_t size = 24;
+ int arr[9];
+
+ pr_info("out-of-bounds in memcmp\n");
+ ptr = kzalloc(size, 0);
+ if (!ptr)
+ return;
+
+ memset(arr, 0, sizeof(arr));
+ kasan_int_result = memcmp(ptr, arr, size + 1);
+ free(ptr);
+}
+
+static noinline void kasan_strings(void)
+{
+ char *ptr;
+ size_t size = 24;
+
+ pr_info("use-after-free in strchr\n");
+ ptr = malloc(size);
+ if (!ptr)
+ return;
+
+ free(ptr);
+
+ /*
+ * Try to cause only 1 invalid access (less spam in dmesg).
+ * For that we need ptr to point to zeroed byte.
+ * Skip metadata that could be stored in freed object so ptr
+ * will likely point to zeroed byte.
+ */
+ ptr += 16;
+ kasan_ptr_result = strchr(ptr, '1');
+
+ pr_info("use-after-free in strrchr\n");
+ kasan_ptr_result = strrchr(ptr, '1');
+
+ pr_info("use-after-free in strcmp\n");
+ kasan_int_result = strcmp(ptr, "2");
+
+ pr_info("use-after-free in strncmp\n");
+ kasan_int_result = strncmp(ptr, "2", 1);
+
+ pr_info("use-after-free in strlen\n");
+ kasan_int_result = strlen(ptr);
+
+ pr_info("use-after-free in strnlen\n");
+ kasan_int_result = strnlen(ptr, 1);
+}
+
+static noinline void kasan_bitops(void)
+{
+ /*
+ * Allocate 1 more byte, which causes kzalloc to round up to 16-bytes;
+ * this way we do not actually corrupt other memory.
+ */
+ long *bits = xzalloc(sizeof(*bits) + 1);
+ if (!bits)
+ return;
+
+ /*
+ * Below calls try to access bit within allocated memory; however, the
+ * below accesses are still out-of-bounds, since bitops are defined to
+ * operate on the whole long the bit is in.
+ */
+ pr_info("out-of-bounds in set_bit\n");
+ set_bit(BITS_PER_LONG, bits);
+
+ pr_info("out-of-bounds in __set_bit\n");
+ __set_bit(BITS_PER_LONG, bits);
+
+ pr_info("out-of-bounds in clear_bit\n");
+ clear_bit(BITS_PER_LONG, bits);
+
+ pr_info("out-of-bounds in __clear_bit\n");
+ __clear_bit(BITS_PER_LONG, bits);
+
+ pr_info("out-of-bounds in change_bit\n");
+ change_bit(BITS_PER_LONG, bits);
+
+ pr_info("out-of-bounds in __change_bit\n");
+ __change_bit(BITS_PER_LONG, bits);
+
+ /*
+ * Below calls try to access bit beyond allocated memory.
+ */
+ pr_info("out-of-bounds in test_and_set_bit\n");
+ test_and_set_bit(BITS_PER_LONG + BITS_PER_BYTE, bits);
+
+ pr_info("out-of-bounds in __test_and_set_bit\n");
+ __test_and_set_bit(BITS_PER_LONG + BITS_PER_BYTE, bits);
+
+ pr_info("out-of-bounds in test_and_clear_bit\n");
+ test_and_clear_bit(BITS_PER_LONG + BITS_PER_BYTE, bits);
+
+ pr_info("out-of-bounds in __test_and_clear_bit\n");
+ __test_and_clear_bit(BITS_PER_LONG + BITS_PER_BYTE, bits);
+
+ pr_info("out-of-bounds in test_and_change_bit\n");
+ test_and_change_bit(BITS_PER_LONG + BITS_PER_BYTE, bits);
+
+ pr_info("out-of-bounds in __test_and_change_bit\n");
+ __test_and_change_bit(BITS_PER_LONG + BITS_PER_BYTE, bits);
+
+ pr_info("out-of-bounds in test_bit\n");
+ kasan_int_result = test_bit(BITS_PER_LONG + BITS_PER_BYTE, bits);
+
+#if defined(clear_bit_unlock_is_negative_byte)
+ pr_info("out-of-bounds in clear_bit_unlock_is_negative_byte\n");
+ kasan_int_result = clear_bit_unlock_is_negative_byte(BITS_PER_LONG +
+ BITS_PER_BYTE, bits);
+#endif
+ free(bits);
+}
+
+static int do_kasan_test(int argc, char *argv[])
+{
+ /*
+ * Temporarily enable multi-shot mode. Otherwise, we'd only get a
+ * report for the first case.
+ */
+ bool multishot = kasan_save_enable_multi_shot();
+
+ malloc_oob_right();
+ malloc_oob_left();
+ malloc_oob_realloc_more();
+ malloc_oob_realloc_less();
+ malloc_oob_16();
+ malloc_oob_in_memset();
+ malloc_oob_memset_2();
+ malloc_oob_memset_4();
+ malloc_oob_memset_8();
+ malloc_oob_memset_16();
+ malloc_uaf();
+ malloc_uaf_memset();
+ malloc_uaf2();
+ kasan_stack_oob();
+ kasan_global_oob();
+ kasan_alloca_oob_left();
+ kasan_alloca_oob_right();
+ kasan_memchr();
+ kasan_memcmp();
+ kasan_strings();
+ kasan_bitops();
+
+ kasan_restore_multi_shot(multishot);
+
+ return 0;
+}
+
+BAREBOX_CMD_START(kasan_tests)
+ .cmd = do_kasan_test,
+ BAREBOX_CMD_DESC("Run KAsan tests")
+ BAREBOX_CMD_COMPLETE(empty_complete)
+BAREBOX_CMD_END
--
2.28.0
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] lib: kasan: remove reference of non-existent test_kasan.o
2020-09-28 14:58 ` [PATCH 1/2] lib: kasan: remove reference of non-existent test_kasan.o Sascha Hauer
@ 2020-09-28 14:59 ` Ahmad Fatoum
2020-09-28 15:32 ` Sascha Hauer
0 siblings, 1 reply; 7+ messages in thread
From: Ahmad Fatoum @ 2020-09-28 14:59 UTC (permalink / raw)
To: Sascha Hauer; +Cc: barebox
On 9/28/20 4:58 PM, Sascha Hauer wrote:
> On Mon, Sep 28, 2020 at 04:41:45PM +0200, Ahmad Fatoum wrote:
>> We don't have anything that test_kasan.o can be generated out of,
>> thus drop it to fix the build.
>>
>> It would still be nice to have this as a command, but that
>> should be a separate patch.
>>
>> Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
>> ---
>> lib/kasan/Makefile | 2 +-
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> I prefer to add the code that I have forgotten to git add ;)
Wouldn't locating it in commands/ be better?
>
> Sascha
>
> ----------------------8<-----------------
>
>
> From ff5cbfcbbe21d7883e3ce661fec3751f7cb7e58c Mon Sep 17 00:00:00 2001
> From: Sascha Hauer <s.hauer@pengutronix.de>
> Date: Mon, 28 Sep 2020 16:56:36 +0200
> Subject: [PATCH] KASan: Add missing test code
>
> Add missing test code.
>
> Fixes: 6cd9d2d600 ("Add KASan support")
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
> lib/kasan/test_kasan.c | 478 +++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 478 insertions(+)
> create mode 100644 lib/kasan/test_kasan.c
>
> diff --git a/lib/kasan/test_kasan.c b/lib/kasan/test_kasan.c
> new file mode 100644
> index 0000000000..e472bb3499
> --- /dev/null
> +++ b/lib/kasan/test_kasan.c
> @@ -0,0 +1,478 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + *
> + * Copyright (c) 2014 Samsung Electronics Co., Ltd.
> + * Author: Andrey Ryabinin <a.ryabinin@samsung.com>
> + */
> +
> +#define pr_fmt(fmt) "kasan test: " fmt
> +
> +#include <common.h>
> +#include <command.h>
> +#include <complete.h>
> +
> +#include "kasan.h"
> +
> +/*
> + * We assign some test results to these globals to make sure the tests
> + * are not eliminated as dead code.
> + */
> +
> +int kasan_int_result;
> +void *kasan_ptr_result;
> +
> +/*
> + * Note: test functions are marked noinline so that their names appear in
> + * reports.
> + */
> +
> +static noinline void malloc_oob_right(void)
> +{
> + char *ptr;
> + size_t size = 123;
> +
> + pr_info("out-of-bounds to right\n");
> + ptr = malloc(size);
> + if (!ptr) {
> + pr_err("Allocation failed\n");
> + return;
> + }
> +
> + ptr[size] = 'x';
> +
> + free(ptr);
> +}
> +
> +static noinline void malloc_oob_left(void)
> +{
> + char *ptr;
> + size_t size = 15;
> +
> + pr_info("out-of-bounds to left\n");
> + ptr = malloc(size);
> + if (!ptr) {
> + pr_err("Allocation failed\n");
> + return;
> + }
> +
> + *ptr = *(ptr - 1);
> + free(ptr);
> +}
> +
> +static noinline void malloc_oob_realloc_more(void)
> +{
> + char *ptr1, *ptr2;
> + size_t size1 = 17;
> + size_t size2 = 19;
> +
> + pr_info("out-of-bounds after krealloc more\n");
> + ptr1 = malloc(size1);
> + ptr2 = realloc(ptr1, size2);
> + if (!ptr1 || !ptr2) {
> + pr_err("Allocation failed\n");
> + free(ptr1);
> + free(ptr2);
> + return;
> + }
> +
> + ptr2[size2] = 'x';
> +
> + free(ptr2);
> +}
> +
> +static noinline void malloc_oob_realloc_less(void)
> +{
> + char *ptr1, *ptr2;
> + size_t size1 = 17;
> + size_t size2 = 15;
> +
> + pr_info("out-of-bounds after krealloc less\n");
> + ptr1 = malloc(size1);
> + ptr2 = realloc(ptr1, size2);
> + if (!ptr1 || !ptr2) {
> + pr_err("Allocation failed\n");
> + free(ptr1);
> + return;
> + }
> +
> + ptr2[size2] = 'x';
> +
> + free(ptr2);
> +}
> +
> +static noinline void malloc_oob_16(void)
> +{
> + struct {
> + u64 words[2];
> + } *ptr1, *ptr2;
> +
> + pr_info("malloc out-of-bounds for 16-bytes access\n");
> + ptr1 = malloc(sizeof(*ptr1) - 3);
> + ptr2 = malloc(sizeof(*ptr2));
> + if (!ptr1 || !ptr2) {
> + pr_err("Allocation failed\n");
> + free(ptr1);
> + free(ptr2);
> + return;
> + }
> + *ptr1 = *ptr2;
> + free(ptr1);
> + free(ptr2);
> +}
> +
> +static noinline void malloc_oob_memset_2(void)
> +{
> + char *ptr;
> + size_t size = 8;
> +
> + pr_info("out-of-bounds in memset2\n");
> + ptr = malloc(size);
> + if (!ptr) {
> + pr_err("Allocation failed\n");
> + return;
> + }
> +
> + memset(ptr + 7, 0, 2);
> +
> + free(ptr);
> +}
> +
> +static noinline void malloc_oob_memset_4(void)
> +{
> + char *ptr;
> + size_t size = 8;
> +
> + pr_info("out-of-bounds in memset4\n");
> + ptr = malloc(size);
> + if (!ptr) {
> + pr_err("Allocation failed\n");
> + return;
> + }
> +
> + memset(ptr + 5, 0, 4);
> +
> + free(ptr);
> +}
> +
> +
> +static noinline void malloc_oob_memset_8(void)
> +{
> + char *ptr;
> + size_t size = 8;
> +
> + pr_info("out-of-bounds in memset8\n");
> + ptr = malloc(size);
> + if (!ptr) {
> + pr_err("Allocation failed\n");
> + return;
> + }
> +
> + memset(ptr + 1, 0, 8);
> +
> + free(ptr);
> +}
> +
> +static noinline void malloc_oob_memset_16(void)
> +{
> + char *ptr;
> + size_t size = 16;
> +
> + pr_info("out-of-bounds in memset16\n");
> + ptr = malloc(size);
> + if (!ptr) {
> + pr_err("Allocation failed\n");
> + return;
> + }
> +
> + memset(ptr + 1, 0, 16);
> +
> + free(ptr);
> +}
> +
> +static noinline void malloc_oob_in_memset(void)
> +{
> + char *ptr;
> + size_t size = 666;
> +
> + pr_info("out-of-bounds in memset\n");
> + ptr = malloc(size);
> + if (!ptr) {
> + pr_err("Allocation failed\n");
> + return;
> + }
> +
> + memset(ptr, 0, size + 5);
> +
> + free(ptr);
> +}
> +
> +static noinline void malloc_uaf(void)
> +{
> + char *ptr;
> + size_t size = 10;
> +
> + pr_info("use-after-free\n");
> + ptr = malloc(size);
> + if (!ptr) {
> + pr_err("Allocation failed\n");
> + return;
> + }
> +
> + free(ptr);
> + *(ptr + 8) = 'x';
> +}
> +
> +static noinline void malloc_uaf_memset(void)
> +{
> + char *ptr;
> + size_t size = 33;
> +
> + pr_info("use-after-free in memset\n");
> + ptr = malloc(size);
> + if (!ptr) {
> + pr_err("Allocation failed\n");
> + return;
> + }
> +
> + free(ptr);
> + memset(ptr, 0, size);
> +}
> +
> +static noinline void malloc_uaf2(void)
> +{
> + char *ptr1, *ptr2;
> + size_t size = 43;
> +
> + pr_info("use-after-free after another malloc\n");
> + ptr1 = malloc(size);
> + if (!ptr1) {
> + pr_err("Allocation failed\n");
> + return;
> + }
> +
> + free(ptr1);
> + ptr2 = malloc(size);
> + if (!ptr2) {
> + pr_err("Allocation failed\n");
> + return;
> + }
> +
> + ptr1[40] = 'x';
> + if (ptr1 == ptr2)
> + pr_err("Could not detect use-after-free: ptr1 == ptr2\n");
> + free(ptr2);
> +}
> +
> +static char global_array[10];
> +
> +static noinline void kasan_global_oob(void)
> +{
> + volatile int i = 3;
> + char *p = &global_array[ARRAY_SIZE(global_array) + i];
> +
> + pr_info("out-of-bounds global variable\n");
> + *(volatile char *)p;
> +}
> +
> +static noinline void kasan_stack_oob(void)
> +{
> + char stack_array[10];
> + volatile int i = 0;
> + char *p = &stack_array[ARRAY_SIZE(stack_array) + i];
> +
> + pr_info("out-of-bounds on stack\n");
> + *(volatile char *)p;
> +}
> +
> +static noinline void kasan_alloca_oob_left(void)
> +{
> + volatile int i = 10;
> + char alloca_array[i];
> + char *p = alloca_array - 1;
> +
> + pr_info("out-of-bounds to left on alloca\n");
> + *(volatile char *)p;
> +}
> +
> +static noinline void kasan_alloca_oob_right(void)
> +{
> + volatile int i = 10;
> + char alloca_array[i];
> + char *p = alloca_array + i;
> +
> + pr_info("out-of-bounds to right on alloca\n");
> + *(volatile char *)p;
> +}
> +
> +static noinline void kasan_memchr(void)
> +{
> + char *ptr;
> + size_t size = 24;
> +
> + pr_info("out-of-bounds in memchr\n");
> + ptr = kzalloc(size, 0);
> + if (!ptr)
> + return;
> +
> + kasan_ptr_result = memchr(ptr, '1', size + 1);
> + free(ptr);
> +}
> +
> +static noinline void kasan_memcmp(void)
> +{
> + char *ptr;
> + size_t size = 24;
> + int arr[9];
> +
> + pr_info("out-of-bounds in memcmp\n");
> + ptr = kzalloc(size, 0);
> + if (!ptr)
> + return;
> +
> + memset(arr, 0, sizeof(arr));
> + kasan_int_result = memcmp(ptr, arr, size + 1);
> + free(ptr);
> +}
> +
> +static noinline void kasan_strings(void)
> +{
> + char *ptr;
> + size_t size = 24;
> +
> + pr_info("use-after-free in strchr\n");
> + ptr = malloc(size);
> + if (!ptr)
> + return;
> +
> + free(ptr);
> +
> + /*
> + * Try to cause only 1 invalid access (less spam in dmesg).
> + * For that we need ptr to point to zeroed byte.
> + * Skip metadata that could be stored in freed object so ptr
> + * will likely point to zeroed byte.
> + */
> + ptr += 16;
> + kasan_ptr_result = strchr(ptr, '1');
> +
> + pr_info("use-after-free in strrchr\n");
> + kasan_ptr_result = strrchr(ptr, '1');
> +
> + pr_info("use-after-free in strcmp\n");
> + kasan_int_result = strcmp(ptr, "2");
> +
> + pr_info("use-after-free in strncmp\n");
> + kasan_int_result = strncmp(ptr, "2", 1);
> +
> + pr_info("use-after-free in strlen\n");
> + kasan_int_result = strlen(ptr);
> +
> + pr_info("use-after-free in strnlen\n");
> + kasan_int_result = strnlen(ptr, 1);
> +}
> +
> +static noinline void kasan_bitops(void)
> +{
> + /*
> + * Allocate 1 more byte, which causes kzalloc to round up to 16-bytes;
> + * this way we do not actually corrupt other memory.
> + */
> + long *bits = xzalloc(sizeof(*bits) + 1);
> + if (!bits)
> + return;
> +
> + /*
> + * Below calls try to access bit within allocated memory; however, the
> + * below accesses are still out-of-bounds, since bitops are defined to
> + * operate on the whole long the bit is in.
> + */
> + pr_info("out-of-bounds in set_bit\n");
> + set_bit(BITS_PER_LONG, bits);
> +
> + pr_info("out-of-bounds in __set_bit\n");
> + __set_bit(BITS_PER_LONG, bits);
> +
> + pr_info("out-of-bounds in clear_bit\n");
> + clear_bit(BITS_PER_LONG, bits);
> +
> + pr_info("out-of-bounds in __clear_bit\n");
> + __clear_bit(BITS_PER_LONG, bits);
> +
> + pr_info("out-of-bounds in change_bit\n");
> + change_bit(BITS_PER_LONG, bits);
> +
> + pr_info("out-of-bounds in __change_bit\n");
> + __change_bit(BITS_PER_LONG, bits);
> +
> + /*
> + * Below calls try to access bit beyond allocated memory.
> + */
> + pr_info("out-of-bounds in test_and_set_bit\n");
> + test_and_set_bit(BITS_PER_LONG + BITS_PER_BYTE, bits);
> +
> + pr_info("out-of-bounds in __test_and_set_bit\n");
> + __test_and_set_bit(BITS_PER_LONG + BITS_PER_BYTE, bits);
> +
> + pr_info("out-of-bounds in test_and_clear_bit\n");
> + test_and_clear_bit(BITS_PER_LONG + BITS_PER_BYTE, bits);
> +
> + pr_info("out-of-bounds in __test_and_clear_bit\n");
> + __test_and_clear_bit(BITS_PER_LONG + BITS_PER_BYTE, bits);
> +
> + pr_info("out-of-bounds in test_and_change_bit\n");
> + test_and_change_bit(BITS_PER_LONG + BITS_PER_BYTE, bits);
> +
> + pr_info("out-of-bounds in __test_and_change_bit\n");
> + __test_and_change_bit(BITS_PER_LONG + BITS_PER_BYTE, bits);
> +
> + pr_info("out-of-bounds in test_bit\n");
> + kasan_int_result = test_bit(BITS_PER_LONG + BITS_PER_BYTE, bits);
> +
> +#if defined(clear_bit_unlock_is_negative_byte)
> + pr_info("out-of-bounds in clear_bit_unlock_is_negative_byte\n");
> + kasan_int_result = clear_bit_unlock_is_negative_byte(BITS_PER_LONG +
> + BITS_PER_BYTE, bits);
> +#endif
> + free(bits);
> +}
> +
> +static int do_kasan_test(int argc, char *argv[])
> +{
> + /*
> + * Temporarily enable multi-shot mode. Otherwise, we'd only get a
> + * report for the first case.
> + */
> + bool multishot = kasan_save_enable_multi_shot();
> +
> + malloc_oob_right();
> + malloc_oob_left();
> + malloc_oob_realloc_more();
> + malloc_oob_realloc_less();
> + malloc_oob_16();
> + malloc_oob_in_memset();
> + malloc_oob_memset_2();
> + malloc_oob_memset_4();
> + malloc_oob_memset_8();
> + malloc_oob_memset_16();
> + malloc_uaf();
> + malloc_uaf_memset();
> + malloc_uaf2();
> + kasan_stack_oob();
> + kasan_global_oob();
> + kasan_alloca_oob_left();
> + kasan_alloca_oob_right();
> + kasan_memchr();
> + kasan_memcmp();
> + kasan_strings();
> + kasan_bitops();
> +
> + kasan_restore_multi_shot(multishot);
> +
> + return 0;
> +}
> +
> +BAREBOX_CMD_START(kasan_tests)
> + .cmd = do_kasan_test,
> + BAREBOX_CMD_DESC("Run KAsan tests")
> + BAREBOX_CMD_COMPLETE(empty_complete)
> +BAREBOX_CMD_END
>
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] lib: kasan: remove reference of non-existent test_kasan.o
2020-09-28 14:59 ` Ahmad Fatoum
@ 2020-09-28 15:32 ` Sascha Hauer
2020-09-28 15:37 ` Ahmad Fatoum
0 siblings, 1 reply; 7+ messages in thread
From: Sascha Hauer @ 2020-09-28 15:32 UTC (permalink / raw)
To: Ahmad Fatoum; +Cc: barebox
On Mon, Sep 28, 2020 at 04:59:40PM +0200, Ahmad Fatoum wrote:
> On 9/28/20 4:58 PM, Sascha Hauer wrote:
> > On Mon, Sep 28, 2020 at 04:41:45PM +0200, Ahmad Fatoum wrote:
> >> We don't have anything that test_kasan.o can be generated out of,
> >> thus drop it to fix the build.
> >>
> >> It would still be nice to have this as a command, but that
> >> should be a separate patch.
> >>
> >> Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
> >> ---
> >> lib/kasan/Makefile | 2 +-
> >> 1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > I prefer to add the code that I have forgotten to git add ;)
>
> Wouldn't locating it in commands/ be better?
It uses internal KASan functions. Putting it into commands would mean
that we have to include "../lib/kasan/kasan.h". That's possible of
course, but I thought it looks better that way.
Sascha
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] lib: kasan: remove reference of non-existent test_kasan.o
2020-09-28 15:32 ` Sascha Hauer
@ 2020-09-28 15:37 ` Ahmad Fatoum
0 siblings, 0 replies; 7+ messages in thread
From: Ahmad Fatoum @ 2020-09-28 15:37 UTC (permalink / raw)
To: Sascha Hauer; +Cc: barebox
On 9/28/20 5:32 PM, Sascha Hauer wrote:
> On Mon, Sep 28, 2020 at 04:59:40PM +0200, Ahmad Fatoum wrote:
>> On 9/28/20 4:58 PM, Sascha Hauer wrote:
>>> On Mon, Sep 28, 2020 at 04:41:45PM +0200, Ahmad Fatoum wrote:
>>>> We don't have anything that test_kasan.o can be generated out of,
>>>> thus drop it to fix the build.
>>>>
>>>> It would still be nice to have this as a command, but that
>>>> should be a separate patch.
>>>>
>>>> Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
>>>> ---
>>>> lib/kasan/Makefile | 2 +-
>>>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>> I prefer to add the code that I have forgotten to git add ;)
>>
>> Wouldn't locating it in commands/ be better?
>
> It uses internal KASan functions. Putting it into commands would mean
> that we have to include "../lib/kasan/kasan.h". That's possible of
> course, but I thought it looks better that way.
Ok.
>
> Sascha
>
>
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] lib: kasan: migrate Kconfig option to Debugging menu
2020-09-28 14:41 ` [PATCH 2/2] lib: kasan: migrate Kconfig option to Debugging menu Ahmad Fatoum
@ 2020-09-29 6:37 ` Sascha Hauer
0 siblings, 0 replies; 7+ messages in thread
From: Sascha Hauer @ 2020-09-29 6:37 UTC (permalink / raw)
To: Ahmad Fatoum; +Cc: barebox
On Mon, Sep 28, 2020 at 04:41:46PM +0200, Ahmad Fatoum wrote:
> UBSAN and ASAN as well as other debugging aids are all in the
> Debugging menu. Relocate KASAN to be there as well.
>
> Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
> ---
> common/Kconfig | 1 +
> lib/Kconfig | 2 --
> 2 files changed, 1 insertion(+), 2 deletions(-)
Applied, thanks
Sascha
>
> diff --git a/common/Kconfig b/common/Kconfig
> index 8b8b30db0fc7..9419977276b2 100644
> --- a/common/Kconfig
> +++ b/common/Kconfig
> @@ -1379,6 +1379,7 @@ config PBL_BREAK
> on early pbl init. This option should be used only with JTAG debugger!
>
> source "lib/Kconfig.ubsan"
> +source "lib/kasan/Kconfig"
>
> config ASAN
> bool "ASAN: runtime memory debugger"
> diff --git a/lib/Kconfig b/lib/Kconfig
> index 6d909c1ac8f0..90552f3c2762 100644
> --- a/lib/Kconfig
> +++ b/lib/Kconfig
> @@ -154,8 +154,6 @@ source "lib/logo/Kconfig"
>
> source "lib/bootstrap/Kconfig"
>
> -source "lib/kasan/Kconfig"
> -
> config PRINTF_UUID
> bool
>
> --
> 2.28.0
>
>
> _______________________________________________
> barebox mailing list
> barebox@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox
>
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2020-09-29 6:37 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-28 14:41 [PATCH 1/2] lib: kasan: remove reference of non-existent test_kasan.o Ahmad Fatoum
2020-09-28 14:41 ` [PATCH 2/2] lib: kasan: migrate Kconfig option to Debugging menu Ahmad Fatoum
2020-09-29 6:37 ` Sascha Hauer
2020-09-28 14:58 ` [PATCH 1/2] lib: kasan: remove reference of non-existent test_kasan.o Sascha Hauer
2020-09-28 14:59 ` Ahmad Fatoum
2020-09-28 15:32 ` Sascha Hauer
2020-09-28 15:37 ` Ahmad Fatoum
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox