diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2022-08-11 13:43:03 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2022-08-11 13:43:03 +0200 |
commit | ad4fa274907bbc78ebabb015b4351d5f9226f081 (patch) | |
tree | 3eb033a3d6bedb50459ea0181e5180e1531d00e8 /common | |
parent | 3fcf4400a7b051bdbe9fc175b88336519099ff22 (diff) | |
parent | 3a0f44a7839d475c58720c4091d5e008215cd166 (diff) | |
download | barebox-ad4fa274907bbc78ebabb015b4351d5f9226f081.tar.gz barebox-ad4fa274907bbc78ebabb015b4351d5f9226f081.tar.xz |
Merge branch 'for-next/misc'
Diffstat (limited to 'common')
-rw-r--r-- | common/Kconfig | 17 | ||||
-rw-r--r-- | common/blspec.c | 167 | ||||
-rw-r--r-- | common/boot.c | 11 | ||||
-rw-r--r-- | common/booti.c | 7 | ||||
-rw-r--r-- | common/bootm.c | 7 | ||||
-rw-r--r-- | common/image-fit.c | 34 |
6 files changed, 150 insertions, 93 deletions
diff --git a/common/Kconfig b/common/Kconfig index 60f52a10e1..43dd92b08a 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -639,6 +639,21 @@ config BOOTM_FITIMAGE_SIGNATURE Additionally the barebox device tree needs a /signature node with the public key with which the image has been signed. +config BOOTM_FITIMAGE_PUBKEY_ENV + bool "Specify path to public key in environment" + depends on BOOTM_FITIMAGE_SIGNATURE + help + If this option is enabled the path to the public key for verifying + FIT images signature is taken from environment which allows for + better integration with build systems. + + The environment variable has the same name as the corresponding + Kconfig variable: + + CONFIG_BOOTM_FITIMAGE_PUBKEY + +if BOOTM_FITIMAGE_SIGNATURE && !BOOTM_FITIMAGE_PUBKEY_ENV + config BOOTM_FITIMAGE_PUBKEY string "Path to dtsi containing pubkey" default "../fit/pubkey.dtsi" @@ -648,6 +663,8 @@ config BOOTM_FITIMAGE_PUBKEY snippet can then be included in a device tree with "#include CONFIG_BOOTM_FITIMAGE_PUBKEY". +endif + config BOOTM_FORCE_SIGNED_IMAGES bool prompt "Force booting of signed images" diff --git a/common/blspec.c b/common/blspec.c index 158fd1e9a2..9bb25ee721 100644 --- a/common/blspec.c +++ b/common/blspec.c @@ -15,6 +15,7 @@ #include <libbb.h> #include <init.h> #include <bootm.h> +#include <glob.h> #include <net.h> #include <fs.h> #include <of.h> @@ -513,6 +514,55 @@ static bool entry_is_match_machine_id(struct blspec_entry *entry) return ret; } +int blspec_scan_file(struct bootentries *bootentries, const char *root, + const char *configname) +{ + char *devname = NULL, *hwdevname = NULL; + struct blspec_entry *entry; + + if (blspec_have_entry(bootentries, configname)) + return -EEXIST; + + entry = blspec_entry_open(bootentries, configname); + if (IS_ERR(entry)) + return PTR_ERR(entry); + + root = root ?: get_mounted_path(configname); + entry->rootpath = xstrdup(root); + entry->configpath = xstrdup(configname); + entry->cdev = get_cdev_by_mountpath(root); + + if (!entry_is_of_compatible(entry)) { + blspec_entry_free(&entry->entry); + return -ENODEV; + } + + if (!entry_is_match_machine_id(entry)) { + blspec_entry_free(&entry->entry); + return -ENODEV; + } + + if (entry->cdev && entry->cdev->dev) { + devname = xstrdup(dev_name(entry->cdev->dev)); + if (entry->cdev->dev->parent) + hwdevname = xstrdup(dev_name(entry->cdev->dev->parent)); + } + + entry->entry.title = xasprintf("%s (%s)", blspec_entry_var_get(entry, "title"), + configname); + entry->entry.description = basprintf("blspec entry, device: %s hwdevice: %s", + devname ? devname : "none", + hwdevname ? hwdevname : "none"); + free(devname); + free(hwdevname); + + entry->entry.me.type = MENU_ENTRY_NORMAL; + entry->entry.release = blspec_entry_free; + + bootentries_add_entry(bootentries, &entry->entry); + return 1; +} + /* * blspec_scan_directory - scan over a directory * @@ -522,115 +572,40 @@ static bool entry_is_match_machine_id(struct blspec_entry *entry) */ int blspec_scan_directory(struct bootentries *bootentries, const char *root) { - struct blspec_entry *entry; - DIR *dir; - struct dirent *d; + glob_t globb; char *abspath; int ret, found = 0; const char *dirname = "loader/entries"; - char *nfspath = NULL; - - nfspath = parse_nfs_url(root); - if (!IS_ERR(nfspath)) - root = nfspath; + int i; pr_debug("%s: %s %s\n", __func__, root, dirname); - abspath = basprintf("%s/%s", root, dirname); + abspath = basprintf("%s/%s/*.conf", root, dirname); - dir = opendir(abspath); - if (!dir) { + ret = glob(abspath, 0, NULL, &globb); + if (ret) { pr_debug("%s: %s: %s\n", __func__, abspath, strerror(errno)); ret = -errno; goto err_out; } - while ((d = readdir(dir))) { - char *configname; + for (i = 0; i < globb.gl_pathc; i++) { + const char *configname = globb.gl_pathv[i]; struct stat s; - char *dot; - char *devname = NULL, *hwdevname = NULL; - - if (*d->d_name == '.') - continue; - - configname = basprintf("%s/%s", abspath, d->d_name); - - dot = strrchr(configname, '.'); - if (!dot) { - free(configname); - continue; - } - - if (strcmp(dot, ".conf")) { - free(configname); - continue; - } ret = stat(configname, &s); - if (ret) { - free(configname); - continue; - } - - if (!S_ISREG(s.st_mode)) { - free(configname); - continue; - } - - if (blspec_have_entry(bootentries, configname)) { - free(configname); - continue; - } - - entry = blspec_entry_open(bootentries, configname); - if (IS_ERR(entry)) { - free(configname); - continue; - } - - entry->rootpath = xstrdup(root); - entry->configpath = configname; - entry->cdev = get_cdev_by_mountpath(root); - - if (!entry_is_of_compatible(entry)) { - blspec_entry_free(&entry->entry); - continue; - } - - if (!entry_is_match_machine_id(entry)) { - blspec_entry_free(&entry->entry); + if (ret || !S_ISREG(s.st_mode)) continue; - } - - found++; - - if (entry->cdev && entry->cdev->dev) { - devname = xstrdup(dev_name(entry->cdev->dev)); - if (entry->cdev->dev->parent) - hwdevname = xstrdup(dev_name(entry->cdev->dev->parent)); - } - - entry->entry.title = xasprintf("%s (%s)", blspec_entry_var_get(entry, "title"), - configname); - entry->entry.description = basprintf("blspec entry, device: %s hwdevice: %s", - devname ? devname : "none", - hwdevname ? hwdevname : "none"); - free(devname); - free(hwdevname); - - entry->entry.me.type = MENU_ENTRY_NORMAL; - entry->entry.release = blspec_entry_free; - bootentries_add_entry(bootentries, &entry->entry); + ret = blspec_scan_file(bootentries, root, configname); + if (ret > 0) + found += ret; } ret = found; - closedir(dir); + globfree(&globb); err_out: - if (!IS_ERR(nfspath)) - free(nfspath); free(abspath); return ret; @@ -839,6 +814,7 @@ int blspec_scan_devicename(struct bootentries *bootentries, const char *devname) static int blspec_bootentry_provider(struct bootentries *bootentries, const char *name) { + struct stat s; int ret, found = 0; ret = blspec_scan_devicename(bootentries, name); @@ -846,9 +822,24 @@ static int blspec_bootentry_provider(struct bootentries *bootentries, found += ret; if (*name == '/' || !strncmp(name, "nfs://", 6)) { - ret = blspec_scan_directory(bootentries, name); + char *nfspath = parse_nfs_url(name); + + if (!IS_ERR(nfspath)) + name = nfspath; + + ret = stat(name, &s); + if (ret) + return found; + + if (S_ISDIR(s.st_mode)) + ret = blspec_scan_directory(bootentries, name); + else if (S_ISREG(s.st_mode) && strends(name, ".conf")) + ret = blspec_scan_file(bootentries, NULL, name); if (ret > 0) found += ret; + + if (!IS_ERR(nfspath)) + free(nfspath); } return found; diff --git a/common/boot.c b/common/boot.c index 8220b8d3fb..9c6fc30442 100644 --- a/common/boot.c +++ b/common/boot.c @@ -272,6 +272,7 @@ int bootentry_register_provider(int (*fn)(struct bootentries *bootentries, const * name can be: * - a name of a boot script under /env/boot * - a full path of a boot script + * - a full path of a bootloader spec entry * - a device name * - a cdev name * - a full path of a directory containing bootloader spec entries @@ -313,10 +314,12 @@ int bootentry_create_from_name(struct bootentries *bootentries, /* * bootsources_menu - show a menu from an array of names */ -void bootsources_menu(struct bootentries *bootentries, int timeout) +void bootsources_menu(struct bootentries *bootentries, + unsigned default_entry, int timeout) { struct bootentry *entry; struct menu_entry *back_entry; + int i = 1; if (!IS_ENABLED(CONFIG_MENU)) { pr_warn("no menu support available\n"); @@ -328,6 +331,9 @@ void bootsources_menu(struct bootentries *bootentries, int timeout) entry->me.display = xstrdup(entry->title); entry->me.action = bootsource_action; menu_add_entry(bootentries->menu, &entry->me); + + if (i++ == default_entry) + bootentries->menu->selected = &entry->me; } back_entry = xzalloc(sizeof(*back_entry)); @@ -336,6 +342,9 @@ void bootsources_menu(struct bootentries *bootentries, int timeout) back_entry->non_re_ent = 1; menu_add_entry(bootentries->menu, back_entry); + if (i == default_entry) + bootentries->menu->selected = back_entry; + if (timeout >= 0) bootentries->menu->auto_select = timeout; diff --git a/common/booti.c b/common/booti.c index dde1605fe1..302d7440ab 100644 --- a/common/booti.c +++ b/common/booti.c @@ -1,6 +1,8 @@ // SPDX-License-Identifier: GPL-2.0-only // SPDX-FileCopyrightText: 2018 Sascha Hauer <s.hauer@pengutronix.de> +#define pr_fmt(fmt) "booti: " fmt + #include <common.h> #include <memory.h> #include <bootm.h> @@ -40,6 +42,11 @@ void *booti_load_image(struct image_data *data, phys_addr_t *oftree) image_size = le64_to_cpup(kernel_header + 16); kernel = get_kernel_address(data->os_address, text_offset); + + print_hex_dump_bytes("header ", DUMP_PREFIX_OFFSET, + kernel_header, 80); + pr_debug("Kernel to be loaded to %lx+%lx\n", kernel, image_size); + if (kernel == UIMAGE_INVALID_ADDRESS) return ERR_PTR(-ENOENT); diff --git a/common/bootm.c b/common/bootm.c index 712e6ebe49..c0f7bca6ce 100644 --- a/common/bootm.c +++ b/common/bootm.c @@ -461,7 +461,7 @@ int bootm_load_devicetree(struct image_data *data, void *fdt, of_print_cmdline(data->of_root_node); if (bootm_verbose(data) > 1) - of_print_nodes(data->of_root_node, 0); + of_print_nodes(data->of_root_node, 0, ~0); return 0; } @@ -725,7 +725,10 @@ int bootm_boot(struct bootm_data *bootm_data) } else { rootarg = path_get_linux_rootarg(data->os_file); } - if (!IS_ERR(rootarg)) { + + if (IS_ERR(rootarg)) { + pr_err("Failed to append kernel cmdline parameter 'root='\n"); + } else { pr_info("Adding \"%s\" to Kernel commandline\n", rootarg); globalvar_add_simple("linux.bootargs.bootm.appendroot", rootarg); diff --git a/common/image-fit.c b/common/image-fit.c index a410632d70..3e6e7fbd6d 100644 --- a/common/image-fit.c +++ b/common/image-fit.c @@ -21,6 +21,7 @@ #include <linux/err.h> #include <stringlist.h> #include <rsa.h> +#include <uncompress.h> #include <image-fit.h> #define FDT_MAX_DEPTH 32 @@ -559,6 +560,11 @@ int fit_get_image_address(struct fit_handle *handle, void *configuration, return ret; } +static void fit_uncompress_error_fn(char *x) +{ + pr_err("%s\n", x); +} + /** * fit_open_image - Open an image in a FIT image * @handle: The FIT image handle @@ -581,7 +587,8 @@ int fit_open_image(struct fit_handle *handle, void *configuration, unsigned long *outsize) { struct device_node *image; - const char *unit = name, *type = NULL, *desc= "(no description)"; + const char *unit = name, *type = NULL, *compression = NULL, + *desc= "(no description)"; const void *data; int data_len; int ret = 0; @@ -613,6 +620,29 @@ int fit_open_image(struct fit_handle *handle, void *configuration, if (ret < 0) return ret; + of_property_read_string(image, "compression", &compression); + if (compression && strcmp(compression, "none") != 0) { + void *uc_data; + + if (!IS_ENABLED(CONFIG_UNCOMPRESS)) { + pr_err("image has compression = \"%s\", but support not compiled in\n", + compression); + return -ENOSYS; + } + + data_len = uncompress_buf_to_buf(data, data_len, &uc_data, + fit_uncompress_error_fn); + if (data_len < 0) { + pr_err("data couldn't be decompressed\n"); + return data_len; + } + + data = uc_data; + + /* associate buffer with FIT, so it's not leaked */ + __of_new_property(image, "uncompressed-data", uc_data, data_len); + } + *outdata = data; *outsize = data_len; @@ -641,7 +671,7 @@ static int fit_config_verify_signature(struct fit_handle *handle, struct device_ for_each_child_of_node(conf_node, sig_node) { if (handle->verbose) - of_print_nodes(sig_node, 0); + of_print_nodes(sig_node, 0, ~0); ret = fit_verify_signature(sig_node, handle->fit); if (ret < 0) return ret; |