summaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/Kconfig30
-rw-r--r--common/Makefile1
-rw-r--r--common/blspec.c16
-rw-r--r--common/bootm.c60
-rw-r--r--common/complete.c6
-rw-r--r--common/console_countdown.c2
-rw-r--r--common/efi/efi.c2
-rw-r--r--common/fastboot.c2
-rw-r--r--common/globalvar.c13
-rw-r--r--common/image-fit.c91
-rw-r--r--common/imd.c1
-rw-r--r--common/kallsyms.c4
-rw-r--r--common/ratp/ratp.c5
-rw-r--r--common/restart.c37
-rw-r--r--common/startup.c15
-rw-r--r--common/tlsf.c29
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;
}
}