Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 04ad130e authored by Sreesudhan Ramakrish Ramkumar's avatar Sreesudhan Ramakrish Ramkumar
Browse files

msm: camera: isp: Validate input parameters in ioctl handler



Validate reg_offset, data_offset, hi_tbl_offset, lo_tbl_offset
and len parameters before consuming to avoid invalid register access
and invalid memory access.

Change-Id: Ib0c1fd2b640576cadfc50fbb6485be6160a51deb
Signed-off-by: default avatarSreesudhan Ramakrish Ramkumar <srramku@codeaurora.org>
parent 18c43109
Loading
Loading
Loading
Loading
+31 −17
Original line number Diff line number Diff line
@@ -913,28 +913,42 @@ static int msm_isp_send_hw_cmd(struct vfe_device *vfe_dev,
			cmd_len);
		return -EINVAL;
	}

	/* Validate input parameters */
	switch (reg_cfg_cmd->cmd_type) {
	case VFE_WRITE: {
		if (reg_cfg_cmd->u.rw_info.reg_offset <
			resource_size(vfe_dev->vfe_mem)) {
			uint32_t diff = 0;
			diff = resource_size(vfe_dev->vfe_mem) -
				reg_cfg_cmd->u.rw_info.reg_offset;
			if (diff < reg_cfg_cmd->u.rw_info.len) {
				pr_err("%s: VFE_WRITE: Invalid length\n",
					__func__);
	case VFE_WRITE:
	case VFE_READ: {
		if ((reg_cfg_cmd->u.rw_info.reg_offset >
			(UINT_MAX - reg_cfg_cmd->u.rw_info.len)) ||
			((reg_cfg_cmd->u.rw_info.reg_offset +
			reg_cfg_cmd->u.rw_info.len) >
			resource_size(vfe_dev->vfe_mem))) {
			pr_err("%s:%d reg_offset %d len %d res %d\n",
				__func__, __LINE__,
				reg_cfg_cmd->u.rw_info.reg_offset,
				reg_cfg_cmd->u.rw_info.len,
				(uint32_t)resource_size(vfe_dev->vfe_mem));
			return -EINVAL;
		}
		} else {
			pr_err("%s: VFE_WRITE: Invalid length\n", __func__);

		if ((reg_cfg_cmd->u.rw_info.cmd_data_offset >
			(UINT_MAX - reg_cfg_cmd->u.rw_info.len)) ||
			((reg_cfg_cmd->u.rw_info.cmd_data_offset +
			reg_cfg_cmd->u.rw_info.len) > cmd_len)) {
			pr_err("%s:%d cmd_data_offset %d len %d cmd_len %d\n",
				__func__, __LINE__,
				reg_cfg_cmd->u.rw_info.cmd_data_offset,
				reg_cfg_cmd->u.rw_info.len, cmd_len);
			return -EINVAL;
		}
		if (resource_size(vfe_dev->vfe_mem) <
			(reg_cfg_cmd->u.rw_info.reg_offset +
			reg_cfg_cmd->u.rw_info.len)) {
			pr_err("%s: VFE_WRITE: Invalid length\n", __func__);
			return -EINVAL;
		break;
	}
	default:
		break;
	}

	switch (reg_cfg_cmd->cmd_type) {
	case VFE_WRITE: {
		msm_camera_io_memcpy(vfe_dev->vfe_base +
			reg_cfg_cmd->u.rw_info.reg_offset,
			cfg_data + reg_cfg_cmd->u.rw_info.cmd_data_offset/4,