Security and correctness issues around captured FDT pointers
Anup Patel
apatel at ventanamicro.com
Mon Nov 13 09:29:45 PST 2023
On Mon, Nov 13, 2023 at 6:02 PM Bo Gan <ganboing at gmail.com> wrote:
>
> Hi OpenSBI community again,
>
> It's a little bit unclear to me from design point of view how are we going to
> protect the flattened device tree shared with lower privileged modes. I ask
> because in several places we have the following
>
> 1. generic/platform.c:
> > static void fw_platform_lookup_special(void *fdt, int root_offset)
> > {
> > ...
> > match = fdt_match_node(fdt, root_offset, plat->match_table);
> > if (!match)
> > continue;
> >
> > generic_plat = plat;
> > generic_plat_match = match;
>
> `generic_plat_match` captures a data blob inside fdt.
>
> 2. generic/starfive/jh7110.c
> > static int starfive_jh7110_final_init(bool cold_boot,
> > const struct fdt_match *match)
> > {
> > void *fdt = fdt_get_address();
> >
> > if (cold_boot) {
> > fdt_reset_driver_init(fdt, &fdt_reset_pmic);
> > return starfive_jh7110_inst_init(fdt);
> > }
> >
> > static int pm_reset_init(void *fdt, int nodeoff,
> > const struct fdt_match *match)
> > {
> > ...
> > rc = fdt_get_node_addr_size(fdt, nodeoff, 0, &addr, NULL);
> > if (rc)
> > return rc;
> >
> > pmic_inst.dev_addr = addr;
> > pmic_inst.compatible = match->compatible;
>
> `fdt_reset_pmic` will capture a compatible string in `pmic.compatible`
>
> For 1, it's probably safe unless we are using the same fdt from previous boot-
> loader and pass it to the next stage. (Could happen if using fw_jump and not
> defining FW_JUMP_FDT_ADDR). For 2, it's very likely unsafe. `fdt_get_address`
> will return `root.next_arg1`, which IS the fdt we pass to next stage. I don't
> think we can ever made the fdt to next stage as read-only, because they, such
> as U-boot or Linux kernel running in S-mode, usually will relocate it and reuse
> the memory for something else, or at least probably modify it in-place. When it
> happens, the harts, at runtime, regardless of cold/warm booted, will access the
> corrupted data. This can also be exploited by malicious actors.
Yes, #1 is mostly safe.
The #2 needs to be fixed in the generic/starfive/jh7110.c and all other places
where it exists.
>
> In my opinion, the only place we access fdt should be from code boot hart, and
> we should stop accessing it and zero-out pointers captured before it kicks warm
> boot harts. If the fdt data is still need afterwards, either parse it or make a
> copy (perhaps on the heap). fdt_get_address() can also be enhanced to prevent
> it from being called in the wrong places. Please let me know your thoughts, and
> I'm looking forward to your ideas. Thanks!
We should certainly stop accessing FDT after cold boot hard is done but I don't
think we should zero-out pointers as well.
Regards,
Anup
>
> Bo
>
>
>
> --
> opensbi mailing list
> opensbi at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/opensbi
More information about the opensbi
mailing list