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

Commit 49662914 authored by Timothy Sham's avatar Timothy Sham
Browse files

soc: msm: add size check to fix out of bounds on ANC



Before calling audio ANC ioctl functions, compare the
allocated buffer size to the size of the header and ANC cmd header
to ensure the buffer is big enough.

Change-Id: I8fcd0a830853d802bbb11fc243a4d392fbe384f3
Signed-off-by: default avatarTimothy Sham <tsham@codeaurora.org>
parent 5cb5749c
Loading
Loading
Loading
Loading
+12 −8
Original line number Diff line number Diff line
@@ -53,6 +53,9 @@ static size_t get_user_anc_cmd_size(int32_t anc_cmd)
	case ANC_CMD_ALGO_MODULE:
		size = sizeof(struct audio_anc_algo_module_info);
		break;
	case ANC_CMD_ALGO_CALIBRATION:
		size = sizeof(struct audio_anc_algo_calibration_info);
		break;
	default:
		pr_err("%s:Invalid anc cmd %d!",
			__func__, anc_cmd);
@@ -77,6 +80,7 @@ static int call_set_anc(int32_t anc_cmd,
	case ANC_CMD_RPM:
	case ANC_CMD_BYPASS_MODE:
	case ANC_CMD_ALGO_MODULE:
	case ANC_CMD_ALGO_CALIBRATION:
		ret = msm_anc_dev_set_info(data, anc_cmd);
		break;
	default:
@@ -176,6 +180,12 @@ static long audio_anc_shared_ioctl(struct file *file, unsigned int cmd,
			sizeof(union audio_anc_data));
		ret = -EINVAL;
		goto done;
	} else if ((data->hdr.anc_cmd_size + sizeof(data->hdr)) > size) {
		pr_err("%s: anc_cmd size %d + anc cmd hdr size %zd is is greater than user buffer siz %d!\n",
			__func__, data->hdr.anc_cmd_size, sizeof(data->hdr),
			size);
		ret = -EFAULT;
		goto done;
	}

	switch (cmd) {
@@ -194,15 +204,9 @@ static long audio_anc_shared_ioctl(struct file *file, unsigned int cmd,
			goto done;
		if (data == NULL)
			goto done;
		if ((sizeof(data->hdr) + data->hdr.anc_cmd_size) > size) {
			pr_err("%s: header size %zd plus ype size %d larger than data buffer size %d\n",
				__func__, sizeof(data->hdr),
				data->hdr.anc_cmd_size, size);
			ret = -EFAULT;
			goto done;
		} else if (copy_to_user((void *)arg, data,
		if (copy_to_user(arg, data,
			sizeof(data->hdr) + data->hdr.anc_cmd_size)) {
			pr_err("%s: Could not copy cal type to user\n",
			pr_err("%s: Could not copy anc data to user\n",
				__func__);
			ret = -EFAULT;
			goto done;
+7 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
#define ANC_CMD_RPM    2
#define ANC_CMD_BYPASS_MODE    3
#define ANC_CMD_ALGO_MODULE    4
#define ANC_CMD_ALGO_CALIBRATION    5

/* room for ANC_CMD define extend */
#define ANC_CMD_MAX   0xFF
@@ -39,10 +40,16 @@ struct audio_anc_algo_module_info {
	int32_t module_id;
};

struct audio_anc_algo_calibration_info {
	int32_t payload_size;
	/* num bytes of payload specificed in payload_size followed */
};

union  audio_anc_data {
	struct audio_anc_rpm_info rpm_info;
	struct audio_anc_bypass_mode bypass_mode_info;
	struct audio_anc_algo_module_info algo_info;
	struct audio_anc_algo_calibration_info algo_cali_info;
};

struct audio_anc_packet {