[PATCH] env: fat: Avoid writing to read-only location
Andre Przywara
andre.przywara at arm.com
Thu Jan 30 14:36:46 CET 2025
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 at arm.com>
---
Hi,
found when naively testing Ilias' series on some Allwinner board.
I am sure there are better ways to implement this (probably as many as
there are developers), but this works for me.
This does away with the optimisation of doing the manipulation only
once, but I am not sure that's really worthwhile?
Cheers,
Andre
env/fat.c | 14 ++++++--------
1 file 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;
--
2.25.1
More information about the U-Boot
mailing list