mirror of https://github.com/wolfSSL/wolfBoot.git
t10xx: map the 10G memac cell-index instead of skipping it
NXP's qoriq-fman3 dtsi numbers the 10G memacs 0x8/0x9, and phydevs holds the 10G port at FM1_10GEC1. Bounding the raw cell-index against the table traded an out-of-bounds read for a silently dropped MAC fixup on exactly the DTBs that motivated the guard. Translate instead, and skip only indexes with no slot.pull/862/head
parent
88b637130c
commit
5f26943e6f
|
|
@ -3391,6 +3391,7 @@ int hal_dts_fixup(void* dts_addr)
|
|||
#ifndef BUILD_LOADER_STAGE1
|
||||
struct fdt_header *fdt = (struct fdt_header *)dts_addr;
|
||||
int off, i;
|
||||
uint32_t cell;
|
||||
uint32_t *reg;
|
||||
const char* prev_compat;
|
||||
|
||||
|
|
@ -3531,14 +3532,23 @@ int hal_dts_fixup(void* dts_addr)
|
|||
reg = (uint32_t*)fdt_getprop(fdt, off, "cell-index", NULL);
|
||||
if (reg == NULL)
|
||||
break;
|
||||
i = (int)fdt32_to_cpu(*reg);
|
||||
cell = fdt32_to_cpu(*reg);
|
||||
|
||||
/* Translate the DTS cell-index into a phydevs slot before
|
||||
* touching the table. NXP's qoriq-fman3 dtsi numbers the 1G
|
||||
* memacs 0..3 and the 10G memacs 0x8/0x9, while phydevs holds
|
||||
* the 1G ports at 0..3 and the single 10G port at FM1_10GEC1.
|
||||
* Anything with no slot is skipped rather than indexed. */
|
||||
if (cell <= FM1_DTSEC4)
|
||||
i = (int)cell;
|
||||
else if (cell == 8)
|
||||
i = FM1_10GEC1;
|
||||
else
|
||||
i = -1;
|
||||
|
||||
/* Bound the index before touching phydevs, mirroring the
|
||||
* qman-portal loop above: standard FMan DTBs give the 10G
|
||||
* MACs cell-index 8/9, outside the 5-entry table. */
|
||||
if (i < 0 || i >= (int)(sizeof(phydevs) / sizeof(phydevs[0]))) {
|
||||
wolfBoot_printf("FDT: Ethernet%d: invalid cell-index, skipping\n",
|
||||
i);
|
||||
wolfBoot_printf("FDT: Ethernet cell-index %u unsupported, "
|
||||
"skipping\n", (unsigned)cell);
|
||||
off = fdt_node_offset_by_compatible(fdt, off, "fsl,fman-memac");
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1047,6 +1047,7 @@ nxp_t10xx_fixup_extract.h: ../../hal/nxp_t10xx.c
|
|||
sed -n '/^struct qportal_info {/,/^};/p' $< >> $@
|
||||
sed -n '/#define SET_QP_INFO(/,/sdest = dest/p' $< >> $@
|
||||
sed -n '/^static const struct qportal_info qp_info\[QMAN_NUM_PORTALS\] = {/,/^};/p' $< >> $@
|
||||
grep -E '^#define FM1_(DTSEC[0-9]|10GEC1) ' $< >> $@
|
||||
sed -n '/^int hal_dts_fixup(/,/^}/p' $< >> $@
|
||||
|
||||
unit-t10xx-dts-memac: unit-t10xx-dts-memac.c nxp_t10xx_fixup_extract.h ../../src/fdt.c
|
||||
|
|
|
|||
|
|
@ -357,16 +357,37 @@ static void teardown(void)
|
|||
{
|
||||
}
|
||||
|
||||
/* A cell-index outside the 5-entry phydevs table must not produce a
|
||||
* local-mac-address. Pre-fix the loop read phydevs[8] out of bounds
|
||||
* and wrote the result into the device tree. */
|
||||
START_TEST(test_memac_oob_cell_index_skipped)
|
||||
/* NXP's qoriq-fman3 dtsi gives the first 10G memac cell-index 8, and
|
||||
* phydevs holds that port at FM1_10GEC1 (slot 4). It must be mapped
|
||||
* there, not skipped: skipping silently drops the 10G MAC fixup. Pre
|
||||
* fix the loop read phydevs[8] out of bounds instead. */
|
||||
START_TEST(test_memac_10g_cell_index_mapped)
|
||||
{
|
||||
struct dtb d;
|
||||
int off, len;
|
||||
const void *mac;
|
||||
|
||||
dtb_build_memac(&d, "memac0", 8);
|
||||
ck_assert_int_eq(hal_dts_fixup(d.buf), 0);
|
||||
|
||||
off = fdt_node_offset_by_compatible(d.buf, -1, "fsl,fman-memac");
|
||||
ck_assert_int_gt(off, 0);
|
||||
mac = fdt_getprop(d.buf, off, "local-mac-address", &len);
|
||||
ck_assert_ptr_nonnull(mac);
|
||||
ck_assert_int_eq(len, 6);
|
||||
ck_assert_int_eq(((const uint8_t *)mac)[5], 0x14); /* phydevs[4] */
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/* A cell-index with no phydevs slot at all (a second 10G port, or a
|
||||
* malformed DTB) must produce no local-mac-address. */
|
||||
START_TEST(test_memac_unmapped_cell_index_skipped)
|
||||
{
|
||||
struct dtb d;
|
||||
int off;
|
||||
const void *mac;
|
||||
|
||||
dtb_build_memac(&d, "memac0", 8);
|
||||
dtb_build_memac(&d, "memac0", 9);
|
||||
ck_assert_int_eq(hal_dts_fixup(d.buf), 0);
|
||||
|
||||
off = fdt_node_offset_by_compatible(d.buf, -1, "fsl,fman-memac");
|
||||
|
|
@ -395,15 +416,15 @@ START_TEST(test_memac_valid_cell_index_fixed)
|
|||
}
|
||||
END_TEST
|
||||
|
||||
/* An out-of-bounds node must be skipped, not break the loop: the
|
||||
* following valid node still gets its MAC. */
|
||||
/* An unmapped node must be skipped, not break the loop: the following
|
||||
* valid node still gets its MAC. */
|
||||
START_TEST(test_memac_mixed_oob_then_valid)
|
||||
{
|
||||
struct dtb d;
|
||||
int off0, off1, len;
|
||||
const void *mac;
|
||||
|
||||
dtb_build_memac2(&d, 8, 2);
|
||||
dtb_build_memac2(&d, 9, 2);
|
||||
ck_assert_int_eq(hal_dts_fixup(d.buf), 0);
|
||||
|
||||
off0 = fdt_node_offset_by_compatible(d.buf, -1, "fsl,fman-memac");
|
||||
|
|
@ -411,7 +432,7 @@ START_TEST(test_memac_mixed_oob_then_valid)
|
|||
ck_assert_int_gt(off0, 0);
|
||||
ck_assert_int_gt(off1, 0);
|
||||
|
||||
/* node 0 (index 8): skipped */
|
||||
/* node 0 (index 9): no phydevs slot, skipped */
|
||||
mac = fdt_getprop(d.buf, off0, "local-mac-address", NULL);
|
||||
ck_assert_ptr_null(mac);
|
||||
|
||||
|
|
@ -429,7 +450,8 @@ Suite *t10xx_dts_memac_suite(void)
|
|||
TCase *tc = tcase_create("memac");
|
||||
|
||||
tcase_add_checked_fixture(tc, setup, teardown);
|
||||
tcase_add_test(tc, test_memac_oob_cell_index_skipped);
|
||||
tcase_add_test(tc, test_memac_10g_cell_index_mapped);
|
||||
tcase_add_test(tc, test_memac_unmapped_cell_index_skipped);
|
||||
tcase_add_test(tc, test_memac_valid_cell_index_fixed);
|
||||
tcase_add_test(tc, test_memac_mixed_oob_then_valid);
|
||||
suite_add_tcase(s, tc);
|
||||
|
|
|
|||
Loading…
Reference in New Issue