From 681284ca22897088613247406ae4ee9e0e19f38c Mon Sep 17 00:00:00 2001 From: Martin Roth Date: Fri, 12 Aug 2016 11:56:50 -0600 Subject: npcx/i2c.c: Verify that controller value is not negative before using it The function i2c_port_to_controller() returns a negative value if the port value was out of range. This wasn't being checked before the controller value was getting used which could lead to using an invalid value as a pointer to a structure. This returns an error where it makes sense, and just ignores the incorrect value otherwise. TEST=Build BUG=None BRANCH=None Change-Id: Ie8967bc4db87d3dd1863a2e36e35ac87e6161132 Signed-off-by: Martin Roth Reviewed-on: https://chromium-review.googlesource.com/371400 Reviewed-by: Randall Spangler Reviewed-by: Mulin Chao --- chip/npcx/i2c.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'chip') diff --git a/chip/npcx/i2c.c b/chip/npcx/i2c.c index eedefce008..b4b879cfa8 100644 --- a/chip/npcx/i2c.c +++ b/chip/npcx/i2c.c @@ -592,6 +592,11 @@ DECLARE_IRQ(NPCX_IRQ_SMB4, i2c3_interrupt, 3); void i2c_set_timeout(int port, uint32_t timeout) { int ctrl = i2c_port_to_controller(port); + + /* Return if i2c_port_to_controller() returned an error */ + if (ctrl < 0) + return; + /* Param is port, but timeout is stored by-controller. */ i2c_stsobjs[ctrl].timeout_us = timeout ? timeout : I2C_TIMEOUT_DEFAULT_US; @@ -600,8 +605,14 @@ void i2c_set_timeout(int port, uint32_t timeout) int chip_i2c_xfer(int port, int slave_addr, const uint8_t *out, int out_size, uint8_t *in, int in_size, int flags) { + volatile struct i2c_status *p_status; int ctrl = i2c_port_to_controller(port); - volatile struct i2c_status *p_status = i2c_stsobjs + ctrl; + + /* Return error if i2c_port_to_controller() returned an error */ + if (ctrl < 0) + return EC_ERROR_INVAL; + + p_status = i2c_stsobjs + ctrl; interrupt_disable(); /* make sure bus is not occupied by the other task */ @@ -823,9 +834,15 @@ static void i2c_init(void) * initialize smb status and register */ for (i = 0; i < i2c_ports_used; i++) { + volatile struct i2c_status *p_status; int port = i2c_ports[i].port; int ctrl = i2c_port_to_controller(port); - volatile struct i2c_status *p_status = i2c_stsobjs + ctrl; + + /* ignore the port if i2c_port_to_controller() failed */ + if (ctrl < 0) + continue; + + p_status = i2c_stsobjs + ctrl; /* status init */ p_status->oper_state = SMB_IDLE; -- cgit v1.2.1