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

Commit a1e1d014 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: camera2: cpp: Fix out-of-bounds frame or command buffer access"

parents 9d0c2b46 fab64410
Loading
Loading
Loading
Loading
+64 −18
Original line number Diff line number Diff line
@@ -2542,8 +2542,28 @@ static int msm_cpp_cfg_frame(struct cpp_device *cpp_dev,
		return -EINVAL;
	}

	if (stripe_base == UINT_MAX || new_frame->num_strips >
		(UINT_MAX - 1 - stripe_base) / stripe_size) {
	/* Stripe index starts at zero */
	if ((!new_frame->num_strips) ||
		(new_frame->first_stripe_index >= new_frame->num_strips) ||
		(new_frame->last_stripe_index  >= new_frame->num_strips) ||
		(new_frame->first_stripe_index >
			new_frame->last_stripe_index)) {
		pr_err("Invalid frame message, #stripes=%d, stripe indices=[%d,%d]\n",
			new_frame->num_strips,
			new_frame->first_stripe_index,
			new_frame->last_stripe_index);
		return -EINVAL;
	}

	if (!stripe_size) {
		pr_err("Invalid frame message, invalid stripe_size (%d)!\n",
			stripe_size);
		return -EINVAL;
	}

	if ((stripe_base == UINT_MAX) ||
		(new_frame->num_strips >
			(UINT_MAX - 1 - stripe_base) / stripe_size)) {
		pr_err("Invalid frame message, num_strips %d is large\n",
			new_frame->num_strips);
		return -EINVAL;
@@ -2785,9 +2805,10 @@ static int msm_cpp_cfg(struct cpp_device *cpp_dev,
	struct msm_cpp_frame_info_t *frame = NULL;
	struct msm_cpp_frame_info_t k_frame_info;
	int32_t rc = 0;
	int32_t i = 0;
	int32_t num_buff = sizeof(k_frame_info.output_buffer_info)/
	uint32_t i = 0;
	uint32_t num_buff = sizeof(k_frame_info.output_buffer_info) /
				sizeof(struct msm_cpp_buffer_info_t);

	if (copy_from_user(&k_frame_info,
			(void __user *)ioctl_ptr->ioctl_ptr,
			sizeof(k_frame_info)))
@@ -2953,8 +2974,9 @@ static int msm_cpp_validate_input(unsigned int cmd, void *arg,
		}

		*ioctl_ptr = arg;
		if ((*ioctl_ptr == NULL) ||
			((*ioctl_ptr)->ioctl_ptr == NULL)) {
		if (((*ioctl_ptr) == NULL) ||
			((*ioctl_ptr)->ioctl_ptr == NULL) ||
			((*ioctl_ptr)->len == 0)) {
			pr_err("Error invalid ioctl argument cmd %u", cmd);
			return -EINVAL;
		}
@@ -3503,13 +3525,18 @@ STREAM_BUFF_END:
		if (cpp_dev->iommu_state == CPP_IOMMU_STATE_DETACHED) {
			struct msm_camera_smmu_attach_type cpp_attach_info;

			if (ioctl_ptr->len !=
				sizeof(struct msm_camera_smmu_attach_type)) {
				rc = -EINVAL;
				break;
			}

			memset(&cpp_attach_info, 0, sizeof(cpp_attach_info));
			rc = msm_cpp_copy_from_ioctl_ptr(&cpp_attach_info,
				ioctl_ptr);
			if (rc < 0) {
				pr_err("CPP_IOMMU_ATTACH copy from user fail");
				ERR_COPY_FROM_USER();
				return -EINVAL;
				break;
			}

			cpp_dev->security_mode = cpp_attach_info.attach;
@@ -3538,16 +3565,20 @@ STREAM_BUFF_END:
	case VIDIOC_MSM_CPP_IOMMU_DETACH: {
		if ((cpp_dev->iommu_state == CPP_IOMMU_STATE_ATTACHED) &&
			(cpp_dev->stream_cnt == 0)) {

			struct msm_camera_smmu_attach_type cpp_attach_info;

			if (ioctl_ptr->len !=
				sizeof(struct msm_camera_smmu_attach_type)) {
				rc = -EINVAL;
				break;
			}

			memset(&cpp_attach_info, 0, sizeof(cpp_attach_info));
			rc = msm_cpp_copy_from_ioctl_ptr(&cpp_attach_info,
				ioctl_ptr);
			if (rc < 0) {
				pr_err("CPP_IOMMU_DETTACH copy from user fail");
				ERR_COPY_FROM_USER();
				return -EINVAL;
				break;
			}

			cpp_dev->security_mode = cpp_attach_info.attach;
@@ -3568,6 +3599,7 @@ STREAM_BUFF_END:
		} else {
			pr_err("%s:%d IOMMMU attach triggered in invalid state\n",
				__func__, __LINE__);
			rc = -EINVAL;
		}
		break;
	}
@@ -3883,6 +3915,7 @@ static long msm_cpp_subdev_fops_compat_ioctl(struct file *file,
	struct msm_cpp_stream_buff_info_t k_cpp_buff_info;
	struct msm_cpp_frame_info32_t k32_frame_info;
	struct msm_cpp_frame_info_t k64_frame_info;
	struct msm_camera_smmu_attach_type kb_cpp_smmu_attach_info;
	uint32_t identity_k = 0;
	bool is_copytouser_req = true;
	void __user *up = (void __user *)arg;
@@ -4187,11 +4220,23 @@ static long msm_cpp_subdev_fops_compat_ioctl(struct file *file,
		break;
	}
	case VIDIOC_MSM_CPP_IOMMU_ATTACH32:
		cmd = VIDIOC_MSM_CPP_IOMMU_ATTACH;
		break;
	case VIDIOC_MSM_CPP_IOMMU_DETACH32:
		cmd = VIDIOC_MSM_CPP_IOMMU_DETACH;
	{
		if ((kp_ioctl.len != sizeof(struct msm_camera_smmu_attach_type))
			|| (copy_from_user(&kb_cpp_smmu_attach_info,
				(void __user *)kp_ioctl.ioctl_ptr,
				sizeof(kb_cpp_smmu_attach_info)))) {
			mutex_unlock(&cpp_dev->mutex);
			return -EINVAL;
		}

		kp_ioctl.ioctl_ptr = (void *)&kb_cpp_smmu_attach_info;
		is_copytouser_req = false;
		cmd = (cmd == VIDIOC_MSM_CPP_IOMMU_ATTACH32) ?
			VIDIOC_MSM_CPP_IOMMU_ATTACH :
			VIDIOC_MSM_CPP_IOMMU_DETACH;
		break;
	}
	case MSM_SD_NOTIFY_FREEZE:
		break;
	case MSM_SD_UNNOTIFY_FREEZE:
@@ -4202,7 +4247,8 @@ static long msm_cpp_subdev_fops_compat_ioctl(struct file *file,
	default:
		pr_err_ratelimited("%s: unsupported compat type :%x LOAD %lu\n",
				__func__, cmd, VIDIOC_MSM_CPP_LOAD_FIRMWARE);
		break;
		mutex_unlock(&cpp_dev->mutex);
		return -EINVAL;
	}

	mutex_unlock(&cpp_dev->mutex);
@@ -4233,7 +4279,7 @@ static long msm_cpp_subdev_fops_compat_ioctl(struct file *file,
	default:
		pr_err_ratelimited("%s: unsupported compat type :%d\n",
				__func__, cmd);
		break;
		return -EINVAL;
	}

	if (is_copytouser_req) {