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 <quic_apuliyad@quicinc.com>
This commit is contained in:
Akash Puliyadi Jegannathan 2024-05-30 14:27:14 +05:30 committed by Sridhar Gujje
parent 6ddbe8dd37
commit f6a5a3a9a7

View File

@ -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;