From 9172b6920cac2c4dabf19e529dbfed91b15685c5 Mon Sep 17 00:00:00 2001 From: Jacob Garber Date: Wed, 26 Jun 2019 16:18:16 -0600 Subject: src: Remove variable length arrays Variable length arrays were a feature added in C99 that allows the length of an array to be determined at runtime. Eg. int sum(size_t n) { int arr[n]; ... } This adds a small amount of runtime overhead, but is also very dangerous, since it allows use of an unlimited amount of stack memory, potentially leading to stack overflow. This is only worsened in coreboot, which often has very little stack space to begin with. Citing concerns like this, all instances of VLA's were recently removed from the Linux kernel. In the immortal words of Linus Torvalds [0], AND USING VLA'S IS ACTIVELY STUPID! It generates much more code, and much _slower_ code (and more fragile code), than just using a fixed key size would have done. [...] Anyway, some of these are definitely easy to just fix, and using VLA's is actively bad not just for security worries, but simply because VLA's are a really horribly bad idea in general in the kernel. This patch follows suit and zaps all VLA's in coreboot. Some of the existing VLA's are accidental ones, and all but one can be replaced with small fixed-size buffers. The single tricky exception is in the SPI controller interface, which will require a rewrite of old drivers to remove [1]. [0] https://lkml.org/lkml/2018/3/7/621 [1] https://ticket.coreboot.org/issues/217 Change-Id: I7d9d1ddadbf1cee5f695165bbe3f0effb7bd32b9 Signed-off-by: Jacob Garber Reviewed-on: https://review.coreboot.org/c/coreboot/+/33821 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi --- src/soc/intel/baytrail/spi.c | 9 +++++---- src/soc/intel/braswell/spi.c | 9 +++++---- src/soc/intel/broadwell/spi.c | 9 +++++---- src/soc/intel/fsp_baytrail/spi.c | 9 +++++---- src/soc/intel/skylake/acpi.c | 36 +++++++++++++++--------------------- 5 files changed, 35 insertions(+), 37 deletions(-) (limited to 'src/soc') diff --git a/src/soc/intel/baytrail/spi.c b/src/soc/intel/baytrail/spi.c index d5b962ffe7..26b717c65e 100644 --- a/src/soc/intel/baytrail/spi.c +++ b/src/soc/intel/baytrail/spi.c @@ -248,6 +248,8 @@ static ich9_spi_regs *spi_regs(void) return (void *)sbase; } +#define MENU_BYTES member_size(struct ich9_spi_regs, opmenu) + void spi_init(void) { ich9_spi_regs *ich9_spi = spi_regs(); @@ -332,7 +334,7 @@ static void spi_setup_type(spi_transaction *trans) static int spi_setup_opcode(spi_transaction *trans) { uint16_t optypes; - uint8_t opmenu[cntlr.menubytes]; + uint8_t opmenu[MENU_BYTES]; trans->opcode = trans->out[0]; spi_use_out(trans, 1); @@ -353,13 +355,12 @@ static int spi_setup_opcode(spi_transaction *trans) return 0; read_reg(cntlr.opmenu, opmenu, sizeof(opmenu)); - for (opcode_index = 0; opcode_index < cntlr.menubytes; - opcode_index++) { + for (opcode_index = 0; opcode_index < ARRAY_SIZE(opmenu); opcode_index++) { if (opmenu[opcode_index] == trans->opcode) break; } - if (opcode_index == cntlr.menubytes) { + if (opcode_index == ARRAY_SIZE(opmenu)) { printk(BIOS_DEBUG, "ICH SPI: Opcode %x not found\n", trans->opcode); return -1; diff --git a/src/soc/intel/braswell/spi.c b/src/soc/intel/braswell/spi.c index b968283fe7..00ec48f978 100644 --- a/src/soc/intel/braswell/spi.c +++ b/src/soc/intel/braswell/spi.c @@ -221,6 +221,8 @@ static ich9_spi_regs *spi_regs(void) return (void *)sbase; } +#define MENU_BYTES member_size(struct ich9_spi_regs, opmenu) + void spi_init(void) { ich9_spi_regs *ich9_spi; @@ -310,7 +312,7 @@ static void spi_setup_type(spi_transaction *trans) static int spi_setup_opcode(spi_transaction *trans) { uint16_t optypes; - uint8_t opmenu[cntlr.menubytes]; + uint8_t opmenu[MENU_BYTES]; trans->opcode = trans->out[0]; spi_use_out(trans, 1); @@ -332,13 +334,12 @@ static int spi_setup_opcode(spi_transaction *trans) return 0; read_reg(cntlr.opmenu, opmenu, sizeof(opmenu)); - for (opcode_index = 0; opcode_index < cntlr.menubytes; - opcode_index++) { + for (opcode_index = 0; opcode_index < ARRAY_SIZE(opmenu); opcode_index++) { if (opmenu[opcode_index] == trans->opcode) break; } - if (opcode_index == cntlr.menubytes) { + if (opcode_index == ARRAY_SIZE(opmenu)) { printk(BIOS_DEBUG, "ICH SPI: Opcode %x not found\n", trans->opcode); return -1; diff --git a/src/soc/intel/broadwell/spi.c b/src/soc/intel/broadwell/spi.c index 01d2830481..ac893ea33d 100644 --- a/src/soc/intel/broadwell/spi.c +++ b/src/soc/intel/broadwell/spi.c @@ -231,6 +231,8 @@ static void ich_set_bbar(uint32_t minaddr) writel_(ichspi_bbar, cntlr.bbar); } +#define MENU_BYTES member_size(struct ich9_spi_regs, opmenu) + void spi_init(void) { uint8_t *rcrb; /* Root Complex Register Block */ @@ -332,7 +334,7 @@ static void spi_setup_type(spi_transaction *trans) static int spi_setup_opcode(spi_transaction *trans) { uint16_t optypes; - uint8_t opmenu[cntlr.menubytes]; + uint8_t opmenu[MENU_BYTES]; trans->opcode = trans->out[0]; spi_use_out(trans, 1); @@ -354,13 +356,12 @@ static int spi_setup_opcode(spi_transaction *trans) return 0; read_reg(cntlr.opmenu, opmenu, sizeof(opmenu)); - for (opcode_index = 0; opcode_index < cntlr.menubytes; - opcode_index++) { + for (opcode_index = 0; opcode_index < ARRAY_SIZE(opmenu); opcode_index++) { if (opmenu[opcode_index] == trans->opcode) break; } - if (opcode_index == cntlr.menubytes) { + if (opcode_index == ARRAY_SIZE(opmenu)) { printk(BIOS_DEBUG, "ICH SPI: Opcode %x not found\n", trans->opcode); return -1; diff --git a/src/soc/intel/fsp_baytrail/spi.c b/src/soc/intel/fsp_baytrail/spi.c index 9375d19547..0b52ea9611 100644 --- a/src/soc/intel/fsp_baytrail/spi.c +++ b/src/soc/intel/fsp_baytrail/spi.c @@ -237,6 +237,8 @@ static ich9_spi_regs *spi_regs(void) return (void *)sbase; } +#define MENU_BYTES member_size(struct ich9_spi_regs, opmenu) + void spi_init(void) { ich_spi_controller *cntlr = car_get_var_ptr(&g_cntlr); @@ -314,7 +316,7 @@ static int spi_setup_opcode(spi_transaction *trans) { ich_spi_controller *cntlr = car_get_var_ptr(&g_cntlr); uint16_t optypes; - uint8_t opmenu[cntlr->menubytes]; + uint8_t opmenu[MENU_BYTES]; trans->opcode = trans->out[0]; spi_use_out(trans, 1); @@ -335,13 +337,12 @@ static int spi_setup_opcode(spi_transaction *trans) return 0; read_reg(cntlr->opmenu, opmenu, sizeof(opmenu)); - for (opcode_index = 0; opcode_index < cntlr->menubytes; - opcode_index++) { + for (opcode_index = 0; opcode_index < ARRAY_SIZE(opmenu); opcode_index++) { if (opmenu[opcode_index] == trans->opcode) break; } - if (opcode_index == cntlr->menubytes) { + if (opcode_index == ARRAY_SIZE(opmenu)) { printk(BIOS_DEBUG, "ICH SPI: Opcode %x not found\n", trans->opcode); return -1; diff --git a/src/soc/intel/skylake/acpi.c b/src/soc/intel/skylake/acpi.c index 869ca7f1ee..aa51cbe7a5 100644 --- a/src/soc/intel/skylake/acpi.c +++ b/src/soc/intel/skylake/acpi.c @@ -350,25 +350,26 @@ void acpi_fill_fadt(acpi_fadt_t *fadt) fadt->x_gpe1_blk.addrh = 0x0; } -static void generate_c_state_entries(int s0ix_enable, int max_cstate) +static void write_c_state_entries(acpi_cstate_t *map, const int *set, size_t max_c_state) { - - acpi_cstate_t map[max_cstate]; - int *set; - int i; - - if (s0ix_enable) - set = cstate_set_s0ix; - else - set = cstate_set_non_s0ix; - - for (i = 0; i < max_cstate; i++) { + for (size_t i = 0; i < max_c_state; i++) { memcpy(&map[i], &cstate_map[set[i]], sizeof(acpi_cstate_t)); map[i].ctype = i + 1; } /* Generate C-state tables */ - acpigen_write_CST_package(map, ARRAY_SIZE(map)); + acpigen_write_CST_package(map, max_c_state); +} + +static void generate_c_state_entries(int s0ix_enable) +{ + if (s0ix_enable) { + acpi_cstate_t map[ARRAY_SIZE(cstate_set_s0ix)]; + write_c_state_entries(map, cstate_set_s0ix, ARRAY_SIZE(map)); + } else { + acpi_cstate_t map[ARRAY_SIZE(cstate_set_non_s0ix)]; + write_c_state_entries(map, cstate_set_non_s0ix, ARRAY_SIZE(map)); + } } static int calculate_power(int tdp, int p1_ratio, int ratio) @@ -506,12 +507,6 @@ void generate_cpu_entries(struct device *device) int numcpus = totalcores/cores_per_package; config_t *config = config_of_path(SA_DEVFN_ROOT); int is_s0ix_enable = config->s0ix_enable; - int max_c_state; - - if (is_s0ix_enable) - max_c_state = ARRAY_SIZE(cstate_set_s0ix); - else - max_c_state = ARRAY_SIZE(cstate_set_non_s0ix); printk(BIOS_DEBUG, "Found %d CPU(s) with %d core(s) each.\n", numcpus, cores_per_package); @@ -534,8 +529,7 @@ void generate_cpu_entries(struct device *device) cpu_id*cores_per_package+core_id, pcontrol_blk, plen); /* Generate C-state tables */ - generate_c_state_entries(is_s0ix_enable, - max_c_state); + generate_c_state_entries(is_s0ix_enable); if (config->eist_enable) { /* Generate P-state tables */ -- cgit v1.2.3