summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacob Garber <jgarber1@ualberta.ca>2019-06-13 15:34:55 -0600
committerMartin Roth <martinroth@google.com>2019-07-17 16:06:46 +0000
commit715d60abce937a7891516cdbeae9eef70ef05cb2 (patch)
treea873855dc5f913293dec87921619ce66a8cd0606
parent1557a67c83b469e183b30f26d8e2f4c8ebb7d030 (diff)
downloadcoreboot-715d60abce937a7891516cdbeae9eef70ef05cb2.tar.xz
sb/amd/sr5650: Add fine-grained bounds checking
The code currently checks that 4 <= dev_index <= 10, which after subtraction by 4 can index into an array of length at most 7. This is fine for the largest cpl array (which does have length 7), but is too large for some of the others, which are smaller. This adds bounds checks for each array access to ensure they are all within bounds. Change-Id: I1610d35ca6cbb6cfb42c251e75b0e8b22b64252b Signed-off-by: Jacob Garber <jgarber1@ualberta.ca> Found-by: Coverity CID 1229676 Reviewed-on: https://review.coreboot.org/c/coreboot/+/33458 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: HAOUAS Elyes <ehaouas@noos.fr> Reviewed-by: Angel Pons <th3fanbus@gmail.com>
-rw-r--r--src/southbridge/amd/sr5650/pcie.c32
1 files changed, 22 insertions, 10 deletions
diff --git a/src/southbridge/amd/sr5650/pcie.c b/src/southbridge/amd/sr5650/pcie.c
index 6c42fdde4d..5c3aee7995 100644
--- a/src/southbridge/amd/sr5650/pcie.c
+++ b/src/southbridge/amd/sr5650/pcie.c
@@ -360,41 +360,53 @@ const u8 pGpp111111[] = {0x0E, 0x0E, 0x0E, 0x0E, 0, 0x0E, 0x0E};
static void gpp3a_cpl_buf_alloc(struct device *nb_dev, struct device *dev)
{
u8 dev_index;
- u8 *slave_cpl;
u8 value;
struct southbridge_amd_sr5650_config *cfg =
(struct southbridge_amd_sr5650_config *)nb_dev->chip_info;
dev_index = dev->path.pci.devfn >> 3;
- if (dev_index < 4 || dev_index > 0xa) {
+
+ if (dev_index < 4)
return;
- }
+
+ dev_index -= 4;
switch (cfg->gpp3a_configuration) {
case 0x1: /* 4:2:0:0:0:0 */
- slave_cpl = (u8 *)&pGpp420000;
+ if (dev_index >= ARRAY_SIZE(pGpp420000))
+ return;
+ value = pGpp420000[dev_index];
break;
case 0x2: /* 4:1:1:0:0:0 */
- slave_cpl = (u8 *)&pGpp411000;
+ if (dev_index >= ARRAY_SIZE(pGpp411000))
+ return;
+ value = pGpp411000[dev_index];
break;
case 0xC: /* 2:2:2:0:0:0 */
- slave_cpl = (u8 *)&pGpp222000;
+ if (dev_index >= ARRAY_SIZE(pGpp222000))
+ return;
+ value = pGpp222000[dev_index];
break;
case 0xA: /* 2:2:1:1:0:0 */
- slave_cpl = (u8 *)&pGpp221100;
+ if (dev_index >= ARRAY_SIZE(pGpp221100))
+ return;
+ value = pGpp221100[dev_index];
break;
case 0x4: /* 2:1:1:1:1:0 */
- slave_cpl = (u8 *)&pGpp211110;
+ if (dev_index >= ARRAY_SIZE(pGpp211110))
+ return;
+ value = pGpp211110[dev_index];
break;
case 0xB: /* 1:1:1:1:1:1 */
- slave_cpl = (u8 *)&pGpp111111;
+ if (dev_index >= ARRAY_SIZE(pGpp111111))
+ return;
+ value = pGpp111111[dev_index];
break;
default: /* shouldn't be here. */
printk(BIOS_WARNING, "buggy gpp3a_configuration\n");
return;
}
- value = slave_cpl[dev_index - 4];
if (value != 0) {
set_pcie_enable_bits(dev, 0x10, 0x3f << 8, value << 8);
set_pcie_enable_bits(dev, 0x20, 1 << 11, 1 << 11);