[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 06/33] hw/riscv/virt.c: Assemble plic_hart_config string with g_st
From: |
Alistair Francis |
Subject: |
[PULL 06/33] hw/riscv/virt.c: Assemble plic_hart_config string with g_strjoinv() |
Date: |
Wed, 1 Sep 2021 12:09:31 +1000 |
From: Peter Maydell <peter.maydell@linaro.org>
In the riscv virt machine init function, We assemble a string
plic_hart_config which is a comma-separated list of N copies of the
VIRT_PLIC_HART_CONFIG string. The code that does this has a
misunderstanding of the strncat() length argument. If the source
string is too large strncat() will write a maximum of length+1 bytes
(length bytes from the source string plus a trailing NUL), but the
code here assumes that it will write only length bytes at most.
This isn't an actual bug because the code has correctly precalculated
the amount of memory it needs to allocate so that it will never be
too small (i.e. we could have used plain old strcat()), but it does
mean that the code looks like it has a guard against accidental
overrun when it doesn't.
Rewrite the string handling here to use the glib g_strjoinv()
function, which means we don't need to do careful accountancy of
string lengths, and makes it clearer that what we're doing is
"create a comma-separated string".
Fixes: Coverity 1460752
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-id: 20210812144647.10516-1-peter.maydell@linaro.org
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
hw/riscv/virt.c | 33 ++++++++++++++++++++-------------
1 file changed, 20 insertions(+), 13 deletions(-)
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index aa279c1bb6..5624adda58 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -540,6 +540,24 @@ static FWCfgState *create_fw_cfg(const MachineState *mc)
return fw_cfg;
}
+/*
+ * Return the per-socket PLIC hart topology configuration string
+ * (caller must free with g_free())
+ */
+static char *plic_hart_config_string(int hart_count)
+{
+ g_autofree const char **vals = g_new(const char *, hart_count + 1);
+ int i;
+
+ for (i = 0; i < hart_count; i++) {
+ vals[i] = VIRT_PLIC_HART_CONFIG;
+ }
+ vals[i] = NULL;
+
+ /* g_strjoinv() obliges us to cast away const here */
+ return g_strjoinv(",", (char **)vals);
+}
+
static void virt_machine_init(MachineState *machine)
{
const MemMapEntry *memmap = virt_memmap;
@@ -548,13 +566,12 @@ static void virt_machine_init(MachineState *machine)
MemoryRegion *main_mem = g_new(MemoryRegion, 1);
MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
char *plic_hart_config, *soc_name;
- size_t plic_hart_config_len;
target_ulong start_addr = memmap[VIRT_DRAM].base;
target_ulong firmware_end_addr, kernel_start_addr;
uint32_t fdt_load_addr;
uint64_t kernel_entry;
DeviceState *mmio_plic, *virtio_plic, *pcie_plic;
- int i, j, base_hartid, hart_count;
+ int i, base_hartid, hart_count;
/* Check socket count limit */
if (VIRT_SOCKETS_MAX < riscv_socket_count(machine)) {
@@ -603,17 +620,7 @@ static void virt_machine_init(MachineState *machine)
SIFIVE_CLINT_TIMEBASE_FREQ, true);
/* Per-socket PLIC hart topology configuration string */
- plic_hart_config_len =
- (strlen(VIRT_PLIC_HART_CONFIG) + 1) * hart_count;
- plic_hart_config = g_malloc0(plic_hart_config_len);
- for (j = 0; j < hart_count; j++) {
- if (j != 0) {
- strncat(plic_hart_config, ",", plic_hart_config_len);
- }
- strncat(plic_hart_config, VIRT_PLIC_HART_CONFIG,
- plic_hart_config_len);
- plic_hart_config_len -= (strlen(VIRT_PLIC_HART_CONFIG) + 1);
- }
+ plic_hart_config = plic_hart_config_string(hart_count);
/* Per-socket PLIC */
s->plic[i] = sifive_plic_create(
--
2.31.1
- [PULL 00/33] riscv-to-apply queue, Alistair Francis, 2021/08/31
- [PULL 01/33] hw/char: Add config for shakti uart, Alistair Francis, 2021/08/31
- [PULL 02/33] hw/riscv: virt: Move flash node to root, Alistair Francis, 2021/08/31
- [PULL 03/33] target/riscv: Correct a comment in riscv_csrrw(), Alistair Francis, 2021/08/31
- [PULL 04/33] target/riscv: Don't wrongly override isa version, Alistair Francis, 2021/08/31
- [PULL 05/33] target/riscv: Add User CSRs read-only check, Alistair Francis, 2021/08/31
- [PULL 07/33] hw/intc/sifive_clint: Fix muldiv64 overflow in sifive_clint_write_timecmp(), Alistair Francis, 2021/08/31
- [PULL 06/33] hw/riscv/virt.c: Assemble plic_hart_config string with g_strjoinv(),
Alistair Francis <=
- [PULL 08/33] hw/core/register: Add more 64-bit utilities, Alistair Francis, 2021/08/31
- [PULL 09/33] hw/registerfields: Use 64-bit bitfield for FIELD_DP64, Alistair Francis, 2021/08/31
- [PULL 10/33] target/riscv: Use tcg_constant_*, Alistair Francis, 2021/08/31
- [PULL 11/33] tests/tcg/riscv64: Add test for division, Alistair Francis, 2021/08/31
- [PULL 12/33] target/riscv: Clean up division helpers, Alistair Francis, 2021/08/31
- [PULL 15/33] target/riscv: Add DisasExtend to gen_arith*, Alistair Francis, 2021/08/31
- [PULL 13/33] target/riscv: Add DisasContext to gen_get_gpr, gen_set_gpr, Alistair Francis, 2021/08/31
- [PULL 16/33] target/riscv: Remove gen_arith_div*, Alistair Francis, 2021/08/31
- [PULL 17/33] target/riscv: Use gen_arith for mulh and mulhu, Alistair Francis, 2021/08/31
- [PULL 14/33] target/riscv: Introduce DisasExtend and new helpers, Alistair Francis, 2021/08/31