diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/Kconfig | 30 | ||||
-rw-r--r-- | common/Makefile | 1 | ||||
-rw-r--r-- | common/blspec.c | 16 | ||||
-rw-r--r-- | common/bootm.c | 60 | ||||
-rw-r--r-- | common/complete.c | 6 | ||||
-rw-r--r-- | common/console_countdown.c | 2 | ||||
-rw-r--r-- | common/efi/efi.c | 2 | ||||
-rw-r--r-- | common/fastboot.c | 2 | ||||
-rw-r--r-- | common/globalvar.c | 13 | ||||
-rw-r--r-- | common/image-fit.c | 91 | ||||
-rw-r--r-- | common/imd.c | 1 | ||||
-rw-r--r-- | common/kallsyms.c | 4 | ||||
-rw-r--r-- | common/ratp/ratp.c | 5 | ||||
-rw-r--r-- | common/restart.c | 37 | ||||
-rw-r--r-- | common/startup.c | 15 | ||||
-rw-r--r-- | common/tlsf.c | 29 |
16 files changed, 249 insertions, 65 deletions
diff --git a/common/Kconfig b/common/Kconfig index 658437f01c..9e6918189b 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -411,6 +411,7 @@ choice select COMMAND_SUPPORT select PARAMETER select STDDEV + select CMD_SETENV help simple shell. No if/then, no return values from commands, no loops @@ -699,7 +700,6 @@ config IMD config IMD_TARGET bool "build bareboximd target tool" depends on IMD - depends on !SANDBOX config KERNEL_INSTALL_TARGET bool @@ -1197,19 +1197,12 @@ config DEBUG_IMX7D_UART Say Y here if you want barebox low-level debugging support on i.MX7D. -config DEBUG_IMX8MP_UART - bool "i.MX8MP Debug UART" - depends on ARCH_IMX8MP - help - Say Y here if you want barebox low-level debugging support - on i.MX8MP. - -config DEBUG_IMX8MQ_UART - bool "i.MX8MQ Debug UART" - depends on ARCH_IMX8MQ +config DEBUG_IMX8M_UART + bool "i.MX8M Debug UART" + depends on ARCH_IMX8M help Say Y here if you want barebox low-level debugging support - on i.MX8MQ. + on i.MX8M*. config DEBUG_VF610_UART bool "VF610 Debug UART" @@ -1301,8 +1294,7 @@ config DEBUG_IMX_UART_PORT DEBUG_IMX6Q_UART || \ DEBUG_IMX6SL_UART || \ DEBUG_IMX7D_UART || \ - DEBUG_IMX8MP_UART || \ - DEBUG_IMX8MQ_UART || \ + DEBUG_IMX8M_UART || \ DEBUG_VF610_UART default 1 depends on ARCH_IMX @@ -1383,11 +1375,11 @@ config PBL_BREAK source "lib/Kconfig.ubsan" -config KASAN - bool "KASAN: runtime memory debugger" - depends on HAVE_ARCH_KASAN +config ASAN + bool "ASAN: runtime memory debugger" + depends on HAVE_ARCH_ASAN help - Enables KASAN (KernelAddressSANitizer) - runtime memory debugger, + Enables ASAN (AddressSANitizer) - runtime memory debugger, designed to find out-of-bounds accesses and use-after-free bugs. config COMPILE_TEST @@ -1412,5 +1404,5 @@ config DDR_SPD bool select CRC_ITU_T -config HAVE_ARCH_KASAN +config HAVE_ARCH_ASAN bool diff --git a/common/Makefile b/common/Makefile index 99f1977b4b..c3ae3ca1b9 100644 --- a/common/Makefile +++ b/common/Makefile @@ -40,6 +40,7 @@ obj-$(CONFIG_GREGORIAN_CALENDER) += date.o obj-$(CONFIG_KALLSYMS) += kallsyms.o obj-$(CONFIG_MALLOC_DLMALLOC) += dlmalloc.o obj-$(CONFIG_MALLOC_TLSF) += tlsf_malloc.o tlsf.o calloc.o +KASAN_SANITIZE_tlsf.o := n obj-$(CONFIG_MALLOC_DUMMY) += dummy_malloc.o calloc.o obj-$(CONFIG_MEMINFO) += meminfo.o obj-$(CONFIG_MENU) += menu.o diff --git a/common/blspec.c b/common/blspec.c index 9e1036c834..9499d32477 100644 --- a/common/blspec.c +++ b/common/blspec.c @@ -109,8 +109,11 @@ static void blspec_apply_oftree_overlays(const char *overlays, sep = freep = xstrdup(overlays); - while ((overlay = strsep(&sep, " "))) + while ((overlay = strsep(&sep, " "))) { + if (!*overlay) + continue; blspec_apply_oftree_overlay(overlay, abspath, dryrun); + } free(freep); } @@ -130,19 +133,18 @@ static int blspec_boot(struct bootentry *be, int verbose, int dryrun) const char *overlays; const char *appendroot; struct bootm_data data = { - .initrd_address = UIMAGE_INVALID_ADDRESS, - .os_address = UIMAGE_SOME_ADDRESS, - .verbose = verbose, .dryrun = dryrun, }; globalvar_set_match("linux.bootargs.dyn.", ""); - globalvar_set_match("bootm.image", ""); - globalvar_set_match("bootm.oftree", ""); - globalvar_set_match("bootm.initrd", ""); + globalvar_set("bootm.image", ""); + globalvar_set("bootm.oftree", ""); + globalvar_set("bootm.initrd", ""); bootm_data_init_defaults(&data); + data.verbose = verbose || data.verbose; + devicetree = blspec_entry_var_get(entry, "devicetree"); initrd = blspec_entry_var_get(entry, "initrd"); options = blspec_entry_var_get(entry, "options"); diff --git a/common/bootm.c b/common/bootm.c index bea73fac36..60b8bf10a8 100644 --- a/common/bootm.c +++ b/common/bootm.c @@ -58,12 +58,14 @@ void bootm_data_init_defaults(struct bootm_data *data) { data->initrd_address = UIMAGE_INVALID_ADDRESS; data->os_address = UIMAGE_SOME_ADDRESS; + data->os_entry = UIMAGE_SOME_ADDRESS; data->oftree_file = getenv_nonempty("global.bootm.oftree"); data->tee_file = getenv_nonempty("global.bootm.tee"); data->os_file = getenv_nonempty("global.bootm.image"); getenv_ul("global.bootm.image.loadaddr", &data->os_address); getenv_ul("global.bootm.initrd.loadaddr", &data->initrd_address); data->initrd_file = getenv_nonempty("global.bootm.initrd"); + data->root_dev = getenv_nonempty("global.bootm.root_dev"); data->verify = bootm_get_verify_mode(); data->appendroot = bootm_appendroot; data->provide_machine_id = bootm_provide_machine_id; @@ -231,7 +233,11 @@ int bootm_load_initrd(struct image_data *data, unsigned long load_address) ret = fit_open_image(data->os_fit, data->fit_config, "ramdisk", &initrd, &initrd_size); - + if (ret) { + pr_err("Cannot open ramdisk image in FIT image: %s\n", + strerror(-ret)); + return ret; + } data->initrd_res = request_sdram_region("initrd", load_address, initrd_size); @@ -638,6 +644,7 @@ int bootm_boot(struct bootm_data *bootm_data) if (IS_ENABLED(CONFIG_FITIMAGE) && os_type == filetype_oftree) { struct fit_handle *fit; + static const char *kernel_img = "kernel"; fit = fit_open(data->os_file, data->verbose, data->verify); if (IS_ERR(fit)) { @@ -658,10 +665,33 @@ int bootm_boot(struct bootm_data *bootm_data) goto err_out; } - ret = fit_open_image(data->os_fit, data->fit_config, "kernel", + ret = fit_open_image(data->os_fit, data->fit_config, kernel_img, &data->fit_kernel, &data->fit_kernel_size); if (ret) goto err_out; + if (data->os_address == UIMAGE_SOME_ADDRESS) { + ret = fit_get_image_address(data->os_fit, + data->fit_config, + kernel_img, + "load", &data->os_address); + if (!ret) + printf("Load address from FIT '%s': 0x%lx\n", + kernel_img, data->os_address); + /* Note: Error case uses default value. */ + } + if (data->os_entry == UIMAGE_SOME_ADDRESS) { + unsigned long entry; + ret = fit_get_image_address(data->os_fit, + data->fit_config, + kernel_img, + "entry", &entry); + if (!ret) { + data->os_entry = entry - data->os_address; + printf("Entry address from FIT '%s': 0x%lx\n", + kernel_img, entry); + } + /* Note: Error case uses default value. */ + } } if (os_type == filetype_uimage) { @@ -686,7 +716,25 @@ int bootm_boot(struct bootm_data *bootm_data) if (bootm_data->appendroot) { char *rootarg; - rootarg = path_get_linux_rootarg(data->os_file); + if (bootm_data->root_dev) { + const char *root_dev_name = devpath_to_name(bootm_data->root_dev); + const struct cdev *root_cdev = cdev_by_name(root_dev_name); + + if (root_cdev && root_cdev->partuuid[0] != 0) { + rootarg = basprintf("root=PARTUUID=%s", root_cdev->partuuid); + } else { + rootarg = ERR_PTR(-EINVAL); + + if (!root_cdev) + pr_err("no cdev found for %s, cannot set root= option\n", + root_dev_name); + else if (!root_cdev->partuuid[0]) + pr_err("%s doesn't have a PARTUUID, cannot set root= option\n", + root_dev_name); + } + } else { + rootarg = path_get_linux_rootarg(data->os_file); + } if (!IS_ERR(rootarg)) { printf("Adding \"%s\" to Kernel commandline\n", rootarg); globalvar_add_simple("linux.bootargs.bootm.appendroot", @@ -719,6 +767,8 @@ int bootm_boot(struct bootm_data *bootm_data) if (data->os_address == UIMAGE_SOME_ADDRESS) data->os_address = UIMAGE_INVALID_ADDRESS; + if (data->os_entry == UIMAGE_SOME_ADDRESS) + data->os_entry = 0; handler = bootm_find_handler(os_type, data); if (!handler) { @@ -775,6 +825,7 @@ static int bootm_init(void) globalvar_add_simple("bootm.image", NULL); globalvar_add_simple("bootm.image.loadaddr", NULL); globalvar_add_simple("bootm.oftree", NULL); + globalvar_add_simple("bootm.root_dev", NULL); globalvar_add_simple("bootm.tee", NULL); globalvar_add_simple_bool("bootm.appendroot", &bootm_appendroot); globalvar_add_simple_bool("bootm.provide_machine_id", &bootm_provide_machine_id); @@ -804,5 +855,6 @@ BAREBOX_MAGICVAR_NAMED(global_bootm_oftree, global.bootm.oftree, "bootm default BAREBOX_MAGICVAR_NAMED(global_bootm_tee, global.bootm.tee, "bootm default tee image"); BAREBOX_MAGICVAR_NAMED(global_bootm_verify, global.bootm.verify, "bootm default verify level"); BAREBOX_MAGICVAR_NAMED(global_bootm_verbose, global.bootm.verbose, "bootm default verbosity level (0=quiet)"); -BAREBOX_MAGICVAR_NAMED(global_bootm_appendroot, global.bootm.appendroot, "Add root= option to Kernel to mount rootfs from the device the Kernel comes from"); +BAREBOX_MAGICVAR_NAMED(global_bootm_appendroot, global.bootm.appendroot, "Add root= option to Kernel to mount rootfs from the device the Kernel comes from (default, device can be overridden via global.bootm.root_dev)"); +BAREBOX_MAGICVAR_NAMED(global_bootm_root_dev, global.bootm.root_dev, "bootm default root device (overrides default device in global.bootm.appendroot)"); BAREBOX_MAGICVAR_NAMED(global_bootm_provide_machine_id, global.bootm.provide_machine_id, "If true, add systemd.machine_id= with value of global.machine_id to Kernel"); diff --git a/common/complete.c b/common/complete.c index 919e5abc6a..36e10405c8 100644 --- a/common/complete.c +++ b/common/complete.c @@ -336,6 +336,12 @@ static int env_param_complete(struct string_list *sl, char *instr, int eval) return 0; } +int env_param_noeval_complete(struct string_list *sl, char *instr) +{ + return env_param_complete(sl, instr, 0); +} +EXPORT_SYMBOL(env_param_noeval_complete); + static int tab_pressed = 0; void complete_reset(void) diff --git a/common/console_countdown.c b/common/console_countdown.c index 74dc382795..b92948f503 100644 --- a/common/console_countdown.c +++ b/common/console_countdown.c @@ -64,7 +64,7 @@ int console_countdown(int timeout_s, unsigned flags, const char *keys, goto out; if (flags & CONSOLE_COUNTDOWN_ANYKEY) goto out; - if (flags & CONSOLE_COUNTDOWN_RETURN && key == '\n') + if (flags & CONSOLE_COUNTDOWN_RETURN && (key == '\n' || key == '\r')) goto out; if (flags & CONSOLE_COUNTDOWN_CTRLC && key == 3) goto out; diff --git a/common/efi/efi.c b/common/efi/efi.c index 6f55e3970e..01003dc00f 100644 --- a/common/efi/efi.c +++ b/common/efi/efi.c @@ -292,7 +292,7 @@ static void __noreturn efi_poweroff_system(struct poweroff_handler *handler) static int restart_register_feature(void) { - restart_handler_register_fn(efi_restart_system); + restart_handler_register_fn("efi", efi_restart_system); poweroff_handler_register_fn(efi_poweroff_system); return 0; diff --git a/common/fastboot.c b/common/fastboot.c index 3628d4dfb5..bcfadfad3d 100644 --- a/common/fastboot.c +++ b/common/fastboot.c @@ -408,7 +408,7 @@ static void __maybe_unused cb_boot(struct fastboot *fb, const char *opt) fastboot_tx_print(fb, FASTBOOT_MSG_INFO, "Booting kernel..\n"); globalvar_set_match("linux.bootargs.dyn.", ""); - globalvar_set_match("bootm.image", ""); + globalvar_set("bootm.image", ""); data.os_file = fb->tempname; diff --git a/common/globalvar.c b/common/globalvar.c index e9379085f2..5bde86aad0 100644 --- a/common/globalvar.c +++ b/common/globalvar.c @@ -449,6 +449,11 @@ void globalvar_set_match(const char *match, const char *val) } } +void globalvar_set(const char *name, const char *val) +{ + dev_set_param(&global_device, name, val); +} + static int globalvar_simple_set(struct device_d *dev, struct param_d *p, const char *val) { struct device_d *rdev; @@ -564,7 +569,9 @@ int globalvar_add_simple_int(const char *name, int *value, return 0; } -int globalvar_add_simple_bool(const char *name, int *value) +int globalvar_add_bool(const char *name, + int (*set)(struct param_d *, void *), + int *value, void *priv) { struct param_d *p; int ret; @@ -573,8 +580,8 @@ int globalvar_add_simple_bool(const char *name, int *value) if (ret) return ret; - p = dev_add_param_bool(&global_device, name, NULL, NULL, - value, NULL); + p = dev_add_param_bool(&global_device, name, set, NULL, + value, priv); if (IS_ERR(p)) return PTR_ERR(p); diff --git a/common/image-fit.c b/common/image-fit.c index 2681d62a9a..658f09b04d 100644 --- a/common/image-fit.c +++ b/common/image-fit.c @@ -517,6 +517,77 @@ int fit_has_image(struct fit_handle *handle, void *configuration, return 1; } +static int fit_get_address(struct device_node *image, const char *property, + unsigned long *addr) +{ + const __be32 *cell; + int len = 0; + + cell = of_get_property(image, property, &len); + if (!cell) + return -EINVAL; + if (len > sizeof(*addr)) + return -ENOTSUPP; + + *addr = (unsigned long)of_read_number(cell, len / sizeof(*cell)); + return 0; +} + +static int +fit_get_image(struct fit_handle *handle, void *configuration, + const char **unit, struct device_node **image) +{ + struct device_node *conf_node = configuration; + + if (conf_node) { + if (of_property_read_string(conf_node, *unit, unit)) { + pr_err("No image named '%s'\n", *unit); + return -ENOENT; + } + } + + *image = of_get_child_by_name(handle->images, *unit); + if (!*image) + return -ENOENT; + + return 0; +} + +/** + * fit_get_image_address - Get an address from an image in a FIT image + * @handle: The FIT image handle + * @name: The name of the image to open + * @property: The name of the address to get (for example "load" or "entry") + * @address: The address given by the image + * + * Try to parse the @property in the image @name as an address. @configuration + * holds the cookie returned from fit_open_configuration() if the image is + * opened as part of a configuration, or NULL if the image is opened without a + * configuration. If it exists the value will be returned in @address. Otherwise + * @address won't be changed. + * + * Return: 0 for success, negative error code otherwise + */ +int fit_get_image_address(struct fit_handle *handle, void *configuration, + const char *name, const char *property, + unsigned long *address) +{ + struct device_node *image; + const char *unit = name; + int ret; + + if (!address || !property || !name) + return -EINVAL; + + ret = fit_get_image(handle, configuration, &unit, &image); + if (ret) + return ret; + + ret = fit_get_address(image, property, address); + + return ret; +} + /** * fit_open_image - Open an image in a FIT image * @handle: The FIT image handle @@ -539,24 +610,14 @@ int fit_open_image(struct fit_handle *handle, void *configuration, unsigned long *outsize) { struct device_node *image; - const char *unit, *type = NULL, *desc= "(no description)"; + const char *unit = name, *type = NULL, *desc= "(no description)"; const void *data; int data_len; int ret = 0; - struct device_node *conf_node = configuration; - - if (conf_node) { - if (of_property_read_string(conf_node, name, &unit)) { - pr_err("No image named '%s'\n", name); - return -ENOENT; - } - } else { - unit = name; - } - image = of_get_child_by_name(handle->images, unit); - if (!image) - return -ENOENT; + ret = fit_get_image(handle, configuration, &unit, &image); + if (ret) + return ret; of_property_read_string(image, "description", &desc); pr_info("image '%s': '%s'\n", unit, desc); @@ -573,7 +634,7 @@ int fit_open_image(struct fit_handle *handle, void *configuration, return -EINVAL; } - if (conf_node) + if (configuration) ret = fit_verify_hash(handle, image, data, data_len); else ret = fit_image_verify_signature(handle, image, data, data_len); diff --git a/common/imd.c b/common/imd.c index 96496514a5..0644e6d3bf 100644 --- a/common/imd.c +++ b/common/imd.c @@ -312,6 +312,7 @@ static int imd_calculate_crc32(void *input, const struct imd_header *imd_start, const struct imd_header *imd; int length; int end_ofs = (char *)imd_start - (char *)input + sizeof(char) * 8; + *imd_crc = NULL; /* search the checksum imd token */ imd_for_each(imd_start, imd) { diff --git a/common/kallsyms.c b/common/kallsyms.c index e15dec5dfc..2c16ab2884 100644 --- a/common/kallsyms.c +++ b/common/kallsyms.c @@ -15,8 +15,8 @@ extern const unsigned long kallsyms_markers[] __attribute__((weak)); static inline int is_kernel_text(unsigned long addr) { - if ((addr >= (unsigned long)_stext && addr <= (unsigned long)_etext)) - return 1; + if (addr >= (unsigned long)_stext && addr <= (unsigned long)_end) + return 1; return 0; } diff --git a/common/ratp/ratp.c b/common/ratp/ratp.c index 84910cacb7..424c9406d2 100644 --- a/common/ratp/ratp.c +++ b/common/ratp/ratp.c @@ -15,11 +15,9 @@ #include <common.h> #include <command.h> -#include <kfifo.h> #include <malloc.h> #include <init.h> #include <ratp.h> -#include <command.h> #include <byteorder.h> #include <environment.h> #include <kfifo.h> @@ -28,6 +26,7 @@ #include <linux/sizes.h> #include <ratp_bb.h> #include <fs.h> +#include <console_countdown.h> LIST_HEAD(ratp_command_list); EXPORT_SYMBOL(ratp_command_list); @@ -502,6 +501,8 @@ int barebox_ratp(struct console_device *cdev) ctx->poller_registered = true; + console_countdown_abort(); + console_set_active(&ctx->ratp_console, CONSOLE_STDOUT | CONSOLE_STDERR | CONSOLE_STDIN); diff --git a/common/restart.c b/common/restart.c index b19ae54657..2bf7b166b0 100644 --- a/common/restart.c +++ b/common/restart.c @@ -19,6 +19,7 @@ #include <of.h> static LIST_HEAD(restart_handler_list); +static unsigned resetidx; /** * restart_handler_register() - register a handler for restarting the system @@ -31,7 +32,7 @@ static LIST_HEAD(restart_handler_list); int restart_handler_register(struct restart_handler *rst) { if (!rst->name) - rst->name = RESTART_DEFAULT_NAME; + rst->name = basprintf("reset%u", resetidx); if (!rst->priority) rst->priority = RESTART_DEFAULT_PRIORITY; @@ -40,11 +41,13 @@ int restart_handler_register(struct restart_handler *rst) pr_debug("registering restart handler \"%s\" with priority %d\n", rst->name, rst->priority); + resetidx++; return 0; } /** * restart_handler_register_fn() - register a handler function + * @name: restart method name or NULL if name should be auto-generated * @restart_fn: The restart function * * convenience wrapper for restart_handler_register() to register a handler @@ -52,13 +55,15 @@ int restart_handler_register(struct restart_handler *rst) * * return: 0 for success or negative error code */ -int restart_handler_register_fn(void (*restart_fn)(struct restart_handler *)) +int restart_handler_register_fn(const char *name, + void (*restart_fn)(struct restart_handler *)) { struct restart_handler *rst; int ret; rst = xzalloc(sizeof(*rst)); + rst->name = xstrdup(name); rst->restart = restart_fn; ret = restart_handler_register(rst); @@ -70,20 +75,33 @@ int restart_handler_register_fn(void (*restart_fn)(struct restart_handler *)) } /** - * restart_machine() - reset the whole system + * restart_handler_get_by_name() - reset the whole system */ -void __noreturn restart_machine(void) +struct restart_handler *restart_handler_get_by_name(const char *name) { struct restart_handler *rst = NULL, *tmp; unsigned int priority = 0; list_for_each_entry(tmp, &restart_handler_list, list) { + if (name && tmp->name && strcmp(name, tmp->name)) + continue; if (tmp->priority > priority) { priority = tmp->priority; rst = tmp; } } + return rst; +} + +/** + * restart_machine() - reset the whole system + */ +void __noreturn restart_machine(void) +{ + struct restart_handler *rst; + + rst = restart_handler_get_by_name(NULL); if (rst) { pr_debug("%s: using restart handler %s\n", __func__, rst->name); console_flush(); @@ -107,3 +125,14 @@ unsigned int of_get_restart_priority(struct device_node *node) return priority; } + +/* + * restart_handlers_print - print informations about all restart handlers + */ +void restart_handlers_print(void) +{ + struct restart_handler *tmp; + + list_for_each_entry(tmp, &restart_handler_list, list) + printf("%-20s %6d\n", tmp->name, tmp->priority); +} diff --git a/common/startup.c b/common/startup.c index 075863d22e..ea7ce6b8da 100644 --- a/common/startup.c +++ b/common/startup.c @@ -369,6 +369,19 @@ static int run_init(void) return 0; } +typedef void (*ctor_fn_t)(void); + +/* Call all constructor functions linked into the kernel. */ +static void do_ctors(void) +{ +#ifdef CONFIG_CONSTRUCTORS + ctor_fn_t *fn = (ctor_fn_t *) __ctors_start; + + for (; fn < (ctor_fn_t *) __ctors_end; fn++) + (*fn)(); +#endif +} + int (*barebox_main)(void); void __noreturn start_barebox(void) @@ -379,6 +392,8 @@ void __noreturn start_barebox(void) if (!IS_ENABLED(CONFIG_SHELL_NONE) && IS_ENABLED(CONFIG_COMMAND_SUPPORT)) barebox_main = run_init; + do_ctors(); + for (initcall = __barebox_initcalls_start; initcall < __barebox_initcalls_end; initcall++) { pr_debug("initcall-> %pS\n", *initcall); diff --git a/common/tlsf.c b/common/tlsf.c index 86cc684ab6..4247a9d3c7 100644 --- a/common/tlsf.c +++ b/common/tlsf.c @@ -3,9 +3,14 @@ #include <string.h> #include <tlsf.h> #include "tlsfbits.h" +#include <linux/kasan.h> #define CHAR_BIT 8 +#ifndef CONFIG_KASAN +#define __memcpy memcpy +#endif + /* ** Constants. */ @@ -529,7 +534,7 @@ static void block_trim_free(control_t* control, block_header_t* block, size_t si } /* Trim any trailing block space off the end of a used block, return to pool. */ -static void block_trim_used(control_t* control, block_header_t* block, size_t size) +static void block_trim_used(control_t* control, block_header_t* block, size_t size, size_t used) { tlsf_assert(!block_is_free(block) && "block must be used"); if (block_can_split(block, size)) @@ -541,6 +546,10 @@ static void block_trim_used(control_t* control, block_header_t* block, size_t si remaining_block = block_merge_next(control, remaining_block); block_insert(control, remaining_block); } + + kasan_poison_shadow(&block->size, size + 2 * sizeof(size_t), + KASAN_KMALLOC_REDZONE); + kasan_unpoison_shadow(block_to_ptr(block), used); } static block_header_t* block_trim_free_leading(control_t* control, block_header_t* block, size_t size) @@ -589,7 +598,8 @@ static block_header_t* block_locate_free(control_t* control, size_t size) return block; } -static void* block_prepare_used(control_t* control, block_header_t* block, size_t size) +static void* block_prepare_used(control_t* control, block_header_t* block, + size_t size, size_t used) { void* p = 0; if (block) @@ -598,6 +608,10 @@ static void* block_prepare_used(control_t* control, block_header_t* block, size_ block_trim_free(control, block, size); block_mark_as_used(block); p = block_to_ptr(block); + + kasan_poison_shadow(&block->size, size + 2 * sizeof(size_t), + KASAN_KMALLOC_REDZONE); + kasan_unpoison_shadow(p, used); } return p; } @@ -907,6 +921,7 @@ tlsf_t tlsf_create_with_pool(void* mem, size_t bytes) { tlsf_t tlsf = tlsf_create(mem); tlsf_add_pool(tlsf, (char*)mem + tlsf_size(), bytes - tlsf_size()); + kasan_poison_shadow(mem, bytes, KASAN_TAG_INVALID); return tlsf; } @@ -926,7 +941,8 @@ void* tlsf_malloc(tlsf_t tlsf, size_t size) control_t* control = tlsf_cast(control_t*, tlsf); const size_t adjust = adjust_request_size(size, ALIGN_SIZE); block_header_t* block = block_locate_free(control, adjust); - return block_prepare_used(control, block, adjust); + + return block_prepare_used(control, block, adjust, size); } void* tlsf_memalign(tlsf_t tlsf, size_t align, size_t size) @@ -983,7 +999,7 @@ void* tlsf_memalign(tlsf_t tlsf, size_t align, size_t size) } } - return block_prepare_used(control, block, adjust); + return block_prepare_used(control, block, adjust, size); } void tlsf_free(tlsf_t tlsf, void* ptr) @@ -994,6 +1010,7 @@ void tlsf_free(tlsf_t tlsf, void* ptr) control_t* control = tlsf_cast(control_t*, tlsf); block_header_t* block = block_from_ptr(ptr); tlsf_assert(!block_is_free(block) && "block already marked as free"); + kasan_poison_shadow(ptr, block_size(block), 0xff); block_mark_as_free(block); block = block_merge_prev(control, block); block = block_merge_next(control, block); @@ -1050,7 +1067,7 @@ void* tlsf_realloc(tlsf_t tlsf, void* ptr, size_t size) if (p) { const size_t minsize = tlsf_min(cursize, size); - memcpy(p, ptr, minsize); + __memcpy(p, ptr, minsize); tlsf_free(tlsf, ptr); } } @@ -1064,7 +1081,7 @@ void* tlsf_realloc(tlsf_t tlsf, void* ptr, size_t size) } /* Trim the resulting block and return the original pointer. */ - block_trim_used(control, block, adjust); + block_trim_used(control, block, adjust, size); p = ptr; } } |