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

Commit 62a91ba9 authored by Jim Rasche's avatar Jim Rasche Committed by Stephen Boyd
Browse files

msm:camera: Fix multiple bounds check



Added bounds check to user input num_streams at several location,
without checking a position outside array could be dereferenced

Change-Id: I6e82d8b51e4ec6772316c7daef243240c029db96
Signed-off-by: default avatarJim Rasche <jrasche@codeaurora.org>
parent 4cffcf0e
Loading
Loading
Loading
Loading
+46 −0
Original line number Diff line number Diff line
@@ -300,7 +300,16 @@ int msm_isp_axi_check_stream_state(
	struct msm_vfe_axi_stream *stream_info;
	enum msm_vfe_axi_state valid_state =
		(stream_cfg_cmd->cmd == START_STREAM) ? INACTIVE : ACTIVE;

	if (stream_cfg_cmd->num_streams > MAX_NUM_STREAM) {
		return -EINVAL;
	}

	for (i = 0; i < stream_cfg_cmd->num_streams; i++) {
		if (HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])
		> MAX_NUM_STREAM) {
			return -EINVAL;
		}
		stream_info = &axi_data->stream_info[
			HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])];
		spin_lock_irqsave(&stream_info->lock, flags);
@@ -852,7 +861,16 @@ static void msm_isp_update_camif_output_count(
	int i;
	struct msm_vfe_axi_stream *stream_info;
	struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;

	if (stream_cfg_cmd->num_streams > MAX_NUM_STREAM) {
		return;
	}

	for (i = 0; i < stream_cfg_cmd->num_streams; i++) {
		if (HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])
		> MAX_NUM_STREAM) {
			return;
		}
		stream_info =
			&axi_data->stream_info[
			HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])];
@@ -1032,7 +1050,16 @@ static int msm_isp_start_axi_stream(struct vfe_device *vfe_dev,
	uint32_t wm_reload_mask = 0x0;
	struct msm_vfe_axi_stream *stream_info;
	struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;

	if (stream_cfg_cmd->num_streams > MAX_NUM_STREAM) {
		return -EINVAL;
	}

	for (i = 0; i < stream_cfg_cmd->num_streams; i++) {
		if (HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])
		> MAX_NUM_STREAM) {
			return -EINVAL;
		}
		stream_info = &axi_data->stream_info[
			HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])];
		src_state = axi_data->src_info[
@@ -1085,7 +1112,16 @@ static int msm_isp_stop_axi_stream(struct vfe_device *vfe_dev,
	uint8_t wait_for_complete = 0;
	struct msm_vfe_axi_stream *stream_info;
	struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;

	if (stream_cfg_cmd->num_streams > MAX_NUM_STREAM) {
		return -EINVAL;
	}

	for (i = 0; i < stream_cfg_cmd->num_streams; i++) {
		if (HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])
		> MAX_NUM_STREAM) {
			return -EINVAL;
		}
		stream_info = &axi_data->stream_info[
			HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])];

@@ -1175,8 +1211,18 @@ int msm_isp_update_axi_stream(struct vfe_device *vfe_dev, void *arg)
		return -EBUSY;
	}

	/*num_stream is uint32 and update_info[] bound by MAX_NUM_STREAM*/
	if (update_cmd->num_streams > MAX_NUM_STREAM) {
		return -EINVAL;
	}

	for (i = 0; i < update_cmd->num_streams; i++) {
		update_info = &update_cmd->update_info[i];
		/*check array reference bounds*/
		if (HANDLE_TO_IDX(update_info->stream_handle)
		 > MAX_NUM_STREAM) {
			return -EINVAL;
		}
		stream_info = &axi_data->stream_info[
				HANDLE_TO_IDX(update_info->stream_handle)];
		if (stream_info->state != ACTIVE &&