On Mon, May 23, 2022 at 08:27:55AM +0200, Ahmad Fatoum wrote: > Surprisingly, the TLSF allocator is prone to overflow. Add some tests > that trigger this behavior. These tests run to success with dlmalloc, > but some of them fail under tlsf when compiled for 32-bit: > > test_malloc:40: unexpectedly succeeded to malloc(SIZE_MAX) > test_malloc:61: unexpectedly succeeded to (tmp = realloc(p, 0xf0000000)) > test_malloc:63: unexpectedly succeeded to tmp = realloc(p, SIZE_MAX) > ERROR: malloc: failed 3 out of 12 tests > > Signed-off-by: Ahmad Fatoum <a.fatoum@xxxxxxxxxxxxxx> > --- > test/self/Kconfig | 5 +++ > test/self/Makefile | 1 + > test/self/malloc.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 97 insertions(+) > create mode 100644 test/self/malloc.c Applied, thanks Sascha > > diff --git a/test/self/Kconfig b/test/self/Kconfig > index 3340a9146ee2..cf11efe54486 100644 > --- a/test/self/Kconfig > +++ b/test/self/Kconfig > @@ -32,6 +32,11 @@ config SELFTEST_ENABLE_ALL > help > Selects all self-tests compatible with current configuration > > +config SELFTEST_MALLOC > + bool "malloc() selftest" > + help > + Tests barebox memory allocator > + > config SELFTEST_PRINTF > bool "printf selftest" > help > diff --git a/test/self/Makefile b/test/self/Makefile > index 05a2a6a236ec..65d01596b806 100644 > --- a/test/self/Makefile > +++ b/test/self/Makefile > @@ -1,6 +1,7 @@ > # SPDX-License-Identifier: GPL-2.0 > > obj-$(CONFIG_SELFTEST) += core.o > +obj-$(CONFIG_SELFTEST_MALLOC) += malloc.o > obj-$(CONFIG_SELFTEST_PRINTF) += printf.o > obj-$(CONFIG_SELFTEST_PROGRESS_NOTIFIER) += progress-notifier.o > obj-$(CONFIG_SELFTEST_OF_MANIPULATION) += of_manipulation.o of_manipulation.dtb.o > diff --git a/test/self/malloc.c b/test/self/malloc.c > new file mode 100644 > index 000000000000..c25b416b9751 > --- /dev/null > +++ b/test/self/malloc.c > @@ -0,0 +1,91 @@ > +// SPDX-License-Identifier: GPL-2.0-only > + > +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt > + > +#include <common.h> > +#include <bselftest.h> > +#include <malloc.h> > +#include <memory.h> > +#include <linux/sizes.h> > + > +BSELFTEST_GLOBALS(); > + > +static void __expect(bool cond, bool expect, > + const char *condstr, const char *func, int line) > +{ > + total_tests++; > + if (cond != expect) { > + failed_tests++; > + printf("%s:%d: %s to %s\n", func, line, > + expect ? "failed" : "unexpectedly succeeded", > + condstr); > + } > +} > + > +#define expect_alloc_ok(cond) \ > + __expect((cond), true, #cond, __func__, __LINE__) > + > +#define expect_alloc_fail(cond) \ > + __expect((cond), false, #cond, __func__, __LINE__) > + > +static void test_malloc(void) > +{ > + size_t mem_malloc_size = mem_malloc_end() - mem_malloc_start(); > + u8 *p, *tmp; > + > + pr_debug("mem_malloc_size = %zu\n", mem_malloc_size); > + > + /* System libc when built for sandbox may have overcommit, so > + * doing very big allocations without actual use may succeed > + * unlike in-barebox allocators, so skip these tests in that > + * case > + */ > + if (IS_ENABLED(CONFIG_MALLOC_LIBC)) { > + pr_info("built with host libc allocator: Skipping tests that may trigger overcommit\n"); > + mem_malloc_size = 0; > + } > + > + expect_alloc_ok(p = malloc(1)); > + free(p); > + > + if (mem_malloc_size) { > + expect_alloc_fail(malloc(SIZE_MAX)); > + > + if (0xf0000000 > mem_malloc_size) { > + expect_alloc_fail((tmp = malloc(0xf0000000))); > + free(tmp); > + } > + } else { > + skipped_tests += 2; > + } > + > + p = realloc(NULL, 1); > + expect_alloc_ok(p = realloc(NULL, 1)); > + > + *p = 0x42; > + > + expect_alloc_ok(tmp = realloc(p, 2)); > + > + p = tmp; > + __expect(*p == 0x42, true, "reread after realloc", __func__, __LINE__); > + > + if (mem_malloc_size) { > + expect_alloc_fail(tmp = realloc(p, mem_malloc_size)); > + > + if (0xf0000000 > mem_malloc_size) > + expect_alloc_fail((tmp = realloc(p, 0xf0000000))); > + > + expect_alloc_fail(tmp = realloc(p, SIZE_MAX)); > + > + } else { > + skipped_tests += 3; > + } > + > + free(p); > + > + expect_alloc_ok(p = malloc(0)); > + expect_alloc_ok(tmp = malloc(0)); > + > + __expect(p != tmp, true, "allocate distinct 0-size buffers", __func__, __LINE__); > +} > +bselftest(core, test_malloc); > -- > 2.30.2 > > > -- 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@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/barebox