From f6a5a3a9a7c41530370515a76b99b24a2f1b00fe Mon Sep 17 00:00:00 2001 From: Akash Puliyadi Jegannathan Date: Thu, 30 May 2024 14:27:14 +0530 Subject: [PATCH] msm: camera: sensor: TOCTOU error handling in eeprom I2C cmd can be modified due to access to shared memory. This change scopes the data locally so as to avoid vulnerability of count being modified by external means while executing due to being in shared memory. CRs-Fixed: 3777534 Change-Id: I4637f49db67d1bd1d5ca418435e3627b5652f604 Signed-off-by: Akash Puliyadi Jegannathan --- .../cam_eeprom/cam_eeprom_core.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/cam_sensor_module/cam_eeprom/cam_eeprom_core.c b/drivers/cam_sensor_module/cam_eeprom/cam_eeprom_core.c index 80115c2552..56ce2a7aa3 100644 --- a/drivers/cam_sensor_module/cam_eeprom/cam_eeprom_core.c +++ b/drivers/cam_sensor_module/cam_eeprom/cam_eeprom_core.c @@ -425,6 +425,7 @@ static int32_t cam_eeprom_parse_memory_map( int32_t rc = 0; int32_t cnt = 0; int32_t processed_size = 0; + int32_t payload_count; uint8_t generic_op_code; struct cam_eeprom_memory_map_t *map = data->map; struct common_header *cmm_hdr = @@ -454,24 +455,25 @@ static int32_t cam_eeprom_parse_memory_map( switch (cmm_hdr->cmd_type) { case CAMERA_SENSOR_CMD_TYPE_I2C_RNDM_WR: i2c_random_wr = (struct cam_cmd_i2c_random_wr *)cmd_buf; + payload_count = i2c_random_wr->header.count; - if (i2c_random_wr->header.count == 0 || - i2c_random_wr->header.count >= MSM_EEPROM_MAX_MEM_MAP_CNT || + if (payload_count == 0 || + payload_count >= MSM_EEPROM_MAX_MEM_MAP_CNT || (size_t)*num_map >= ((MSM_EEPROM_MAX_MEM_MAP_CNT * MSM_EEPROM_MEMORY_MAP_MAX_SIZE) - - i2c_random_wr->header.count)) { + payload_count)) { CAM_ERR(CAM_EEPROM, "OOB Error"); return -EINVAL; } cmd_length_in_bytes = sizeof(struct cam_cmd_i2c_random_wr) + - ((i2c_random_wr->header.count - 1) * + ((payload_count - 1) * sizeof(struct i2c_random_wr_payload)); if (cmd_length_in_bytes > remain_buf_len) { CAM_ERR(CAM_EEPROM, "Not enough buffer remaining"); return -EINVAL; } - for (cnt = 0; cnt < (i2c_random_wr->header.count); + for (cnt = 0; cnt < (payload_count); cnt++) { map[*num_map + cnt].page.addr = i2c_random_wr->random_wr_payload[cnt].reg_addr; @@ -484,15 +486,16 @@ static int32_t cam_eeprom_parse_memory_map( map[*num_map + cnt].page.valid_size = 1; } - *num_map += (i2c_random_wr->header.count - 1); + *num_map += (payload_count - 1); processed_size += cmd_length_in_bytes; break; case CAMERA_SENSOR_CMD_TYPE_I2C_CONT_RD: i2c_cont_rd = (struct cam_cmd_i2c_continuous_rd *)cmd_buf; cmd_length_in_bytes = sizeof(struct cam_cmd_i2c_continuous_rd); + payload_count = i2c_cont_rd->header.count; - if (i2c_cont_rd->header.count >= U32_MAX - data->num_data) { + if (payload_count >= U32_MAX - data->num_data) { CAM_ERR(CAM_EEPROM, "int overflow on eeprom memory block"); return -EINVAL; @@ -501,7 +504,7 @@ static int32_t cam_eeprom_parse_memory_map( map[*num_map].mem.addr_type = i2c_cont_rd->header.addr_type; map[*num_map].mem.data_type = i2c_cont_rd->header.data_type; map[*num_map].mem.valid_size = - i2c_cont_rd->header.count; + payload_count; processed_size += cmd_length_in_bytes; data->num_data += map[*num_map].mem.valid_size;