summaryrefslogtreecommitdiff
path: root/drivers/fastboot
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/fastboot')
-rw-r--r--drivers/fastboot/Kconfig19
-rw-r--r--drivers/fastboot/fb_command.c108
-rw-r--r--drivers/fastboot/fb_common.c11
-rw-r--r--drivers/fastboot/fb_getvar.c49
4 files changed, 79 insertions, 108 deletions
diff --git a/drivers/fastboot/Kconfig b/drivers/fastboot/Kconfig
index b97c67bf609..eefa34779c4 100644
--- a/drivers/fastboot/Kconfig
+++ b/drivers/fastboot/Kconfig
@@ -80,12 +80,13 @@ config FASTBOOT_FLASH
this to enable the "fastboot flash" command.
config FASTBOOT_UUU_SUPPORT
- bool "Enable FASTBOOT i.MX UUU special command"
+ bool "Enable UUU support"
help
- The fastboot protocol includes "UCmd" and "ACmd" command.
- Be aware that you provide full access to any U-Boot command,
- including working with memory and may open a huge backdoor,
- when enabling this option.
+ This extends the fastboot protocol with the "UCmd" and "ACmd"
+ commands, which are used by NXP's "universal update utility" (UUU).
+ These commands allow running any shell command. Do not enable this
+ feature if you are using verified boot, as it will allow an attacker
+ to bypass any restrictions you have in place.
choice
prompt "Flash provider for FASTBOOT"
@@ -218,6 +219,14 @@ config FASTBOOT_CMD_OEM_BOOTBUS
Add support for the "oem bootbus" command from a client. This set
the mmc boot configuration for the selecting eMMC device.
+config FASTBOOT_OEM_RUN
+ bool "Enable the 'oem run' command"
+ help
+ This extends the fastboot protocol with an "oem run" command. This
+ command allows running arbitrary U-Boot shell commands. Do not enable
+ this feature if you are using verified boot, as it will allow an
+ attacker to bypass any restrictions you have in place.
+
endif # FASTBOOT
endmenu
diff --git a/drivers/fastboot/fb_command.c b/drivers/fastboot/fb_command.c
index bdfdf262c8a..67a94798287 100644
--- a/drivers/fastboot/fb_command.c
+++ b/drivers/fastboot/fb_command.c
@@ -31,27 +31,16 @@ static u32 fastboot_bytes_expected;
static void okay(char *, char *);
static void getvar(char *, char *);
static void download(char *, char *);
-#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
static void flash(char *, char *);
static void erase(char *, char *);
-#endif
static void reboot_bootloader(char *, char *);
static void reboot_fastbootd(char *, char *);
static void reboot_recovery(char *, char *);
-#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_FORMAT)
static void oem_format(char *, char *);
-#endif
-#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_PARTCONF)
static void oem_partconf(char *, char *);
-#endif
-#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_BOOTBUS)
static void oem_bootbus(char *, char *);
-#endif
-
-#if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT)
static void run_ucmd(char *, char *);
static void run_acmd(char *, char *);
-#endif
static const struct {
const char *command;
@@ -65,16 +54,14 @@ static const struct {
.command = "download",
.dispatch = download
},
-#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
[FASTBOOT_COMMAND_FLASH] = {
.command = "flash",
- .dispatch = flash
+ .dispatch = CONFIG_IS_ENABLED(FASTBOOT_FLASH, (flash), (NULL))
},
[FASTBOOT_COMMAND_ERASE] = {
.command = "erase",
- .dispatch = erase
+ .dispatch = CONFIG_IS_ENABLED(FASTBOOT_FLASH, (erase), (NULL))
},
-#endif
[FASTBOOT_COMMAND_BOOT] = {
.command = "boot",
.dispatch = okay
@@ -103,34 +90,30 @@ static const struct {
.command = "set_active",
.dispatch = okay
},
-#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_FORMAT)
[FASTBOOT_COMMAND_OEM_FORMAT] = {
.command = "oem format",
- .dispatch = oem_format,
+ .dispatch = CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_FORMAT, (oem_format), (NULL))
},
-#endif
-#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_PARTCONF)
[FASTBOOT_COMMAND_OEM_PARTCONF] = {
.command = "oem partconf",
- .dispatch = oem_partconf,
+ .dispatch = CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_PARTCONF, (oem_partconf), (NULL))
},
-#endif
-#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_BOOTBUS)
[FASTBOOT_COMMAND_OEM_BOOTBUS] = {
.command = "oem bootbus",
- .dispatch = oem_bootbus,
+ .dispatch = CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_BOOTBUS, (oem_bootbus), (NULL))
+ },
+ [FASTBOOT_COMMAND_OEM_RUN] = {
+ .command = "oem run",
+ .dispatch = CONFIG_IS_ENABLED(FASTBOOT_OEM_RUN, (run_ucmd), (NULL))
},
-#endif
-#if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT)
[FASTBOOT_COMMAND_UCMD] = {
.command = "UCmd",
- .dispatch = run_ucmd,
+ .dispatch = CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT, (run_ucmd), (NULL))
},
[FASTBOOT_COMMAND_ACMD] = {
.command = "ACmd",
- .dispatch = run_acmd,
+ .dispatch = CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT, (run_acmd), (NULL))
},
-#endif
};
/**
@@ -156,7 +139,9 @@ int fastboot_handle_command(char *cmd_string, char *response)
response);
return i;
} else {
- break;
+ pr_err("command %s not supported.\n", cmd_string);
+ fastboot_fail("Unsupported command", response);
+ return -1;
}
}
}
@@ -299,7 +284,6 @@ void fastboot_data_complete(char *response)
fastboot_bytes_received = 0;
}
-#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
/**
* flash() - write the downloaded image to the indicated partition.
*
@@ -309,16 +293,15 @@ void fastboot_data_complete(char *response)
* Writes the previously downloaded image to the partition indicated by
* cmd_parameter. Writes to response.
*/
-static void flash(char *cmd_parameter, char *response)
+static void __maybe_unused flash(char *cmd_parameter, char *response)
{
-#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
- fastboot_mmc_flash_write(cmd_parameter, fastboot_buf_addr, image_size,
- response);
-#endif
-#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND)
- fastboot_nand_flash_write(cmd_parameter, fastboot_buf_addr, image_size,
- response);
-#endif
+ if (CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC))
+ fastboot_mmc_flash_write(cmd_parameter, fastboot_buf_addr,
+ image_size, response);
+
+ if (CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND))
+ fastboot_nand_flash_write(cmd_parameter, fastboot_buf_addr,
+ image_size, response);
}
/**
@@ -330,25 +313,22 @@ static void flash(char *cmd_parameter, char *response)
* Erases the partition indicated by cmd_parameter (clear to 0x00s). Writes
* to response.
*/
-static void erase(char *cmd_parameter, char *response)
+static void __maybe_unused erase(char *cmd_parameter, char *response)
{
-#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
- fastboot_mmc_erase(cmd_parameter, response);
-#endif
-#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND)
- fastboot_nand_erase(cmd_parameter, response);
-#endif
+ if (CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC))
+ fastboot_mmc_erase(cmd_parameter, response);
+
+ if (CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND))
+ fastboot_nand_erase(cmd_parameter, response);
}
-#endif
-#if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT)
/**
* run_ucmd() - Execute the UCmd command
*
* @cmd_parameter: Pointer to command parameter
* @response: Pointer to fastboot response buffer
*/
-static void run_ucmd(char *cmd_parameter, char *response)
+static void __maybe_unused run_ucmd(char *cmd_parameter, char *response)
{
if (!cmd_parameter) {
pr_err("missing slot suffix\n");
@@ -375,7 +355,7 @@ void fastboot_acmd_complete(void)
* @cmd_parameter: Pointer to command parameter
* @response: Pointer to fastboot response buffer
*/
-static void run_acmd(char *cmd_parameter, char *response)
+static void __maybe_unused run_acmd(char *cmd_parameter, char *response)
{
if (!cmd_parameter) {
pr_err("missing slot suffix\n");
@@ -392,7 +372,6 @@ static void run_acmd(char *cmd_parameter, char *response)
strcpy(g_a_cmd_buff, cmd_parameter);
fastboot_okay(NULL, response);
}
-#endif
/**
* reboot_bootloader() - Sets reboot bootloader flag.
@@ -436,40 +415,40 @@ static void reboot_recovery(char *cmd_parameter, char *response)
fastboot_okay(NULL, response);
}
-#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_FORMAT)
/**
* oem_format() - Execute the OEM format command
*
* @cmd_parameter: Pointer to command parameter
* @response: Pointer to fastboot response buffer
*/
-static void oem_format(char *cmd_parameter, char *response)
+static void __maybe_unused oem_format(char *cmd_parameter, char *response)
{
char cmdbuf[32];
+ const int mmc_dev = config_opt_enabled(CONFIG_FASTBOOT_FLASH_MMC,
+ CONFIG_FASTBOOT_FLASH_MMC_DEV, -1);
if (!env_get("partitions")) {
fastboot_fail("partitions not set", response);
} else {
- sprintf(cmdbuf, "gpt write mmc %x $partitions",
- CONFIG_FASTBOOT_FLASH_MMC_DEV);
+ sprintf(cmdbuf, "gpt write mmc %x $partitions", mmc_dev);
if (run_command(cmdbuf, 0))
fastboot_fail("", response);
else
fastboot_okay(NULL, response);
}
}
-#endif
-#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_PARTCONF)
/**
* oem_partconf() - Execute the OEM partconf command
*
* @cmd_parameter: Pointer to command parameter
* @response: Pointer to fastboot response buffer
*/
-static void oem_partconf(char *cmd_parameter, char *response)
+static void __maybe_unused oem_partconf(char *cmd_parameter, char *response)
{
char cmdbuf[32];
+ const int mmc_dev = config_opt_enabled(CONFIG_FASTBOOT_FLASH_MMC,
+ CONFIG_FASTBOOT_FLASH_MMC_DEV, -1);
if (!cmd_parameter) {
fastboot_fail("Expected command parameter", response);
@@ -477,26 +456,25 @@ static void oem_partconf(char *cmd_parameter, char *response)
}
/* execute 'mmc partconfg' command with cmd_parameter arguments*/
- snprintf(cmdbuf, sizeof(cmdbuf), "mmc partconf %x %s 0",
- CONFIG_FASTBOOT_FLASH_MMC_DEV, cmd_parameter);
+ snprintf(cmdbuf, sizeof(cmdbuf), "mmc partconf %x %s 0", mmc_dev, cmd_parameter);
printf("Execute: %s\n", cmdbuf);
if (run_command(cmdbuf, 0))
fastboot_fail("Cannot set oem partconf", response);
else
fastboot_okay(NULL, response);
}
-#endif
-#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_BOOTBUS)
/**
* oem_bootbus() - Execute the OEM bootbus command
*
* @cmd_parameter: Pointer to command parameter
* @response: Pointer to fastboot response buffer
*/
-static void oem_bootbus(char *cmd_parameter, char *response)
+static void __maybe_unused oem_bootbus(char *cmd_parameter, char *response)
{
char cmdbuf[32];
+ const int mmc_dev = config_opt_enabled(CONFIG_FASTBOOT_FLASH_MMC,
+ CONFIG_FASTBOOT_FLASH_MMC_DEV, -1);
if (!cmd_parameter) {
fastboot_fail("Expected command parameter", response);
@@ -504,12 +482,10 @@ static void oem_bootbus(char *cmd_parameter, char *response)
}
/* execute 'mmc bootbus' command with cmd_parameter arguments*/
- snprintf(cmdbuf, sizeof(cmdbuf), "mmc bootbus %x %s",
- CONFIG_FASTBOOT_FLASH_MMC_DEV, cmd_parameter);
+ snprintf(cmdbuf, sizeof(cmdbuf), "mmc bootbus %x %s", mmc_dev, cmd_parameter);
printf("Execute: %s\n", cmdbuf);
if (run_command(cmdbuf, 0))
fastboot_fail("Cannot set oem bootbus", response);
else
fastboot_okay(NULL, response);
}
-#endif
diff --git a/drivers/fastboot/fb_common.c b/drivers/fastboot/fb_common.c
index ef399d0c4ab..7563650d07d 100644
--- a/drivers/fastboot/fb_common.c
+++ b/drivers/fastboot/fb_common.c
@@ -91,20 +91,21 @@ void fastboot_okay(const char *reason, char *response)
*/
int __weak fastboot_set_reboot_flag(enum fastboot_reboot_reason reason)
{
-#ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
static const char * const boot_cmds[] = {
[FASTBOOT_REBOOT_REASON_BOOTLOADER] = "bootonce-bootloader",
[FASTBOOT_REBOOT_REASON_FASTBOOTD] = "boot-fastboot",
[FASTBOOT_REBOOT_REASON_RECOVERY] = "boot-recovery"
};
+ const int mmc_dev = config_opt_enabled(CONFIG_FASTBOOT_FLASH_MMC,
+ CONFIG_FASTBOOT_FLASH_MMC_DEV, -1);
+
+ if (!CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC))
+ return -EINVAL;
if (reason >= FASTBOOT_REBOOT_REASONS_COUNT)
return -EINVAL;
- return bcb_write_reboot_reason(CONFIG_FASTBOOT_FLASH_MMC_DEV, "misc", boot_cmds[reason]);
-#else
- return -EINVAL;
-#endif
+ return bcb_write_reboot_reason(mmc_dev, "misc", boot_cmds[reason]);
}
/**
diff --git a/drivers/fastboot/fb_getvar.c b/drivers/fastboot/fb_getvar.c
index 018989dd166..2fbd285db38 100644
--- a/drivers/fastboot/fb_getvar.c
+++ b/drivers/fastboot/fb_getvar.c
@@ -21,15 +21,9 @@ static void getvar_version_baseband(char *var_parameter, char *response);
static void getvar_product(char *var_parameter, char *response);
static void getvar_platform(char *var_parameter, char *response);
static void getvar_current_slot(char *var_parameter, char *response);
-#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
static void getvar_has_slot(char *var_parameter, char *response);
-#endif
-#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
static void getvar_partition_type(char *part_name, char *response);
-#endif
-#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
static void getvar_partition_size(char *part_name, char *response);
-#endif
static void getvar_is_userspace(char *var_parameter, char *response);
static const struct {
@@ -84,7 +78,6 @@ static const struct {
}
};
-#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
/**
* Get partition number and size for any storage type.
*
@@ -102,28 +95,26 @@ static int getvar_get_part_info(const char *part_name, char *response,
size_t *size)
{
int r;
-# if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
struct blk_desc *dev_desc;
- struct disk_partition part_info;
-
- r = fastboot_mmc_get_part_info(part_name, &dev_desc, &part_info,
- response);
- if (r >= 0 && size)
- *size = part_info.size * part_info.blksz;
-# elif CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND)
+ struct disk_partition disk_part;
struct part_info *part_info;
- r = fastboot_nand_get_part_info(part_name, &part_info, response);
- if (r >= 0 && size)
- *size = part_info->size;
-# else
- fastboot_fail("this storage is not supported in bootloader", response);
- r = -ENODEV;
-# endif
+ if (CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)) {
+ r = fastboot_mmc_get_part_info(part_name, &dev_desc, &disk_part,
+ response);
+ if (r >= 0 && size)
+ *size = disk_part.size * disk_part.blksz;
+ } else if (CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND)) {
+ r = fastboot_nand_get_part_info(part_name, &part_info, response);
+ if (r >= 0 && size)
+ *size = part_info->size;
+ } else {
+ fastboot_fail("this storage is not supported in bootloader", response);
+ r = -ENODEV;
+ }
return r;
}
-#endif
static void getvar_version(char *var_parameter, char *response)
{
@@ -181,8 +172,7 @@ static void getvar_current_slot(char *var_parameter, char *response)
fastboot_okay("a", response);
}
-#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
-static void getvar_has_slot(char *part_name, char *response)
+static void __maybe_unused getvar_has_slot(char *part_name, char *response)
{
char part_name_wslot[PART_NAME_LEN];
size_t len;
@@ -213,10 +203,8 @@ static void getvar_has_slot(char *part_name, char *response)
fail:
fastboot_fail("invalid partition name", response);
}
-#endif
-#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
-static void getvar_partition_type(char *part_name, char *response)
+static void __maybe_unused getvar_partition_type(char *part_name, char *response)
{
int r;
struct blk_desc *dev_desc;
@@ -232,10 +220,8 @@ static void getvar_partition_type(char *part_name, char *response)
fastboot_okay(fs_get_type_name(), response);
}
}
-#endif
-#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
-static void getvar_partition_size(char *part_name, char *response)
+static void __maybe_unused getvar_partition_size(char *part_name, char *response)
{
int r;
size_t size;
@@ -244,7 +230,6 @@ static void getvar_partition_size(char *part_name, char *response)
if (r >= 0)
fastboot_response("OKAY", response, "0x%016zx", size);
}
-#endif
static void getvar_is_userspace(char *var_parameter, char *response)
{