summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Roth <martinroth@chromium.org>2016-08-12 11:56:50 -0600
committerchrome-bot <chrome-bot@chromium.org>2016-08-23 15:37:13 -0700
commit681284ca22897088613247406ae4ee9e0e19f38c (patch)
tree7428b677e3c6306b816c42558eb82722daac185f
parentaee8407f4e62efefb944f9050de7ae80032b4651 (diff)
downloadchrome-ec-681284ca22897088613247406ae4ee9e0e19f38c.tar.gz
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 <martinroth@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/371400 Reviewed-by: Randall Spangler <rspangler@chromium.org> Reviewed-by: Mulin Chao <mlchao@nuvoton.com>
-rw-r--r--chip/npcx/i2c.c21
1 files changed, 19 insertions, 2 deletions
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;