aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndre Przywara <andre.przywara@arm.com>2025-01-30 13:36:46 +0000
committerTom Rini <trini@konsulko.com>2025-02-10 10:29:53 -0600
commit4ef949eedc2d7bb136ac7a33fb7a072c439e2171 (patch)
tree2205e831a8344ffc511bb6ab85c7129c125c5147
parent530fc5c9e5670be62b3183cd54b42e5169d19fdf (diff)
downloadu-boot-4ef949eedc2d7bb136ac7a33fb7a072c439e2171.tar.gz
env: fat: Avoid writing to read-only location
The env_fat_get_dev_part() function mostly returns a fixed string, set via some Kconfig variable. However when the first character is a colon, that means that the boot device number is determined at runtime, and patched in. This requires altering the string. So far this was done via some ugly and actually illegal direct write to the .rodata string storage. We got away with this because U-Boot maps everything as read/write/execute so far. A proposed patch set actually enforces read-only (and no-execute) permissions in the page tables, so this routine now causes an exception: ======================= Loading Environment from FAT... "Synchronous Abort" handler, esr 0x9600004f, far 0xfffb7d4c elr: 000000004a054228 lr : 000000004a05421c (reloc) elr: 00000000fff7c228 lr : 00000000fff7c21c ..... ======================= Rewrite the routine to do away with the dodgy string manipulation, instead allocate the string in the r/w .data section, where we can safely manipulate it. Signed-off-by: Andre Przywara <andre.przywara@arm.com> Acked-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
-rw-r--r--env/fat.c14
1 files changed, 6 insertions, 8 deletions
diff --git a/env/fat.c b/env/fat.c
index b04b1d9c315..1ad301eaaff 100644
--- a/env/fat.c
+++ b/env/fat.c
@@ -41,14 +41,12 @@ __weak const char *env_fat_get_intf(void)
__weak char *env_fat_get_dev_part(void)
{
#ifdef CONFIG_MMC
- static char *part_str;
-
- if (!part_str) {
- part_str = CONFIG_ENV_FAT_DEVICE_AND_PART;
- if (!strcmp(CONFIG_ENV_FAT_INTERFACE, "mmc") && part_str[0] == ':') {
- part_str = "0" CONFIG_ENV_FAT_DEVICE_AND_PART;
- part_str[0] += mmc_get_env_dev();
- }
+ /* reserve one more char for the manipulation below */
+ static char part_str[] = CONFIG_ENV_FAT_DEVICE_AND_PART "\0";
+
+ if (!strcmp(CONFIG_ENV_FAT_INTERFACE, "mmc") && part_str[0] == ':') {
+ part_str[0] = '0' + mmc_get_env_dev();
+ strcpy(&part_str[1], CONFIG_ENV_FAT_DEVICE_AND_PART);
}
return part_str;