[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v3 1/3] hw/arm/boot: Abort if set_kernel_args() fails
From: |
Philippe Mathieu-Daudé |
Subject: |
[PATCH v3 1/3] hw/arm/boot: Abort if set_kernel_args() fails |
Date: |
Thu, 20 May 2021 07:15:40 +0200 |
If a address_space_write() call fails while calling
set_kernel_args(), the guest kernel will boot using
crap data. Avoid that by aborting if this ever occurs.
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
hw/arm/boot.c | 53 ++++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 42 insertions(+), 11 deletions(-)
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index d7b059225e6..0c1346d5842 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -291,15 +291,20 @@ static inline bool have_dtb(const struct arm_boot_info
*info)
#define WRITE_WORD(p, value) do { \
address_space_stl_notdirty(as, p, value, \
- MEMTXATTRS_UNSPECIFIED, NULL); \
+ MEMTXATTRS_UNSPECIFIED, &result); \
+ if (result != MEMTX_OK) { \
+ goto fail; \
+ } \
p += 4; \
} while (0)
-static void set_kernel_args(const struct arm_boot_info *info, AddressSpace *as)
+/* Returns: 0 on success, -1 on error */
+static int set_kernel_args(const struct arm_boot_info *info, AddressSpace *as)
{
int initrd_size = info->initrd_size;
hwaddr base = info->loader_start;
hwaddr p;
+ MemTxResult result;
p = base + KERNEL_ARGS_ADDR;
/* ATAG_CORE */
@@ -326,8 +331,11 @@ static void set_kernel_args(const struct arm_boot_info
*info, AddressSpace *as)
int cmdline_size;
cmdline_size = strlen(info->kernel_cmdline);
- address_space_write(as, p + 8, MEMTXATTRS_UNSPECIFIED,
- info->kernel_cmdline, cmdline_size + 1);
+ result = address_space_write(as, p + 8, MEMTXATTRS_UNSPECIFIED,
+ info->kernel_cmdline, cmdline_size + 1);
+ if (result != MEMTX_OK) {
+ goto fail;
+ }
cmdline_size = (cmdline_size >> 2) + 1;
WRITE_WORD(p, cmdline_size + 2);
WRITE_WORD(p, 0x54410009);
@@ -341,22 +349,31 @@ static void set_kernel_args(const struct arm_boot_info
*info, AddressSpace *as)
atag_board_len = (info->atag_board(info, atag_board_buf) + 3) & ~3;
WRITE_WORD(p, (atag_board_len + 8) >> 2);
WRITE_WORD(p, 0x414f4d50);
- address_space_write(as, p, MEMTXATTRS_UNSPECIFIED,
- atag_board_buf, atag_board_len);
+ result = address_space_write(as, p, MEMTXATTRS_UNSPECIFIED,
+ atag_board_buf, atag_board_len);
+ if (result != MEMTX_OK) {
+ goto fail;
+ }
p += atag_board_len;
}
/* ATAG_END */
WRITE_WORD(p, 0);
WRITE_WORD(p, 0);
+
+ return 0;
+fail:
+ return -1;
}
-static void set_kernel_args_old(const struct arm_boot_info *info,
- AddressSpace *as)
+/* Returns: 0 on success, -1 on error */
+static int set_kernel_args_old(const struct arm_boot_info *info,
+ AddressSpace *as)
{
hwaddr p;
const char *s;
int initrd_size = info->initrd_size;
hwaddr base = info->loader_start;
+ MemTxResult result;
/* see linux/include/asm-arm/setup.h */
p = base + KERNEL_ARGS_ADDR;
@@ -419,10 +436,18 @@ static void set_kernel_args_old(const struct
arm_boot_info *info,
}
s = info->kernel_cmdline;
if (s) {
- address_space_write(as, p, MEMTXATTRS_UNSPECIFIED, s, strlen(s) + 1);
+ result = address_space_write(as, p, MEMTXATTRS_UNSPECIFIED,
+ s, strlen(s) + 1);
+ if (result != MEMTX_OK) {
+ goto fail;
+ }
} else {
WRITE_WORD(p, 0);
}
+
+ return 0;
+fail:
+ return -1;
}
static int fdt_add_memory_node(void *fdt, uint32_t acells, hwaddr mem_base,
@@ -786,10 +811,16 @@ static void do_cpu_reset(void *opaque)
cpu_set_pc(cs, info->loader_start);
if (!have_dtb(info)) {
+ int err;
+
if (old_param) {
- set_kernel_args_old(info, as);
+ err = set_kernel_args_old(info, as);
} else {
- set_kernel_args(info, as);
+ err = set_kernel_args(info, as);
+ }
+ if (err) {
+ error_report("could not set kernel arguments");
+ exit(1);
}
}
} else {
--
2.26.3