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

Commit 82cbd083 authored by Priyanka Gujjula's avatar Priyanka Gujjula
Browse files

msm: vidc: Ensure size of the data available before typecasting



Ensure the available data size with in the packet before type
casting from smaller data type to larger data type in order
to avoid information leak or packet out of boundary access.

Change-Id: I8614a8b3f930c87af8aa49f77ea9d768a73ea203
Signed-off-by: default avatarPriyanka Gujjula <pgujjula@codeaurora.org>
parent 8517bb17
Loading
Loading
Loading
Loading
+21 −9
Original line number Diff line number Diff line
@@ -370,6 +370,12 @@ static int hfi_process_evt_release_buffer_ref(u32 device_id,
				"hal_process_session_init_done: bad_pkt_size\n");
		return -E2BIG;
	}
	if (pkt->size < sizeof(struct hfi_msg_event_notify_packet) - sizeof(u32)
		+ sizeof(struct hfi_msg_release_buffer_ref_event_packet)) {
		dprintk(VIDC_ERR, "%s: bad_pkt_size: %d\n",
			__func__, pkt->size);
		return -E2BIG;
	}

	data = (struct hfi_msg_release_buffer_ref_event_packet *)
				pkt->rg_ext_event_data;
@@ -1558,15 +1564,13 @@ static int hfi_process_session_etb_done(u32 device_id,
	struct hfi_msg_session_empty_buffer_done_packet *pkt = _pkt;
	struct msm_vidc_cb_data_done data_done = {0};
	struct hfi_picture_type *hfi_picture_type = NULL;
	u32 is_sync_frame;

	dprintk(VIDC_DBG, "RECEIVED: SESSION_ETB_DONE[%#x]\n", pkt->session_id);

	if (!pkt || pkt->size <
		sizeof(struct hfi_msg_session_empty_buffer_done_packet)) {
		dprintk(VIDC_ERR,
				"hal_process_session_etb_done: bad_pkt_size\n");
		return -E2BIG;
	}
		sizeof(struct hfi_msg_session_empty_buffer_done_packet))
		goto bad_packet_size;

	data_done.device_id = device_id;
	data_done.session_id = (void *)(uintptr_t)pkt->session_id;
@@ -1586,8 +1590,13 @@ static int hfi_process_session_etb_done(u32 device_id,
	data_done.input_done.extra_data_buffer = pkt->extra_data_buffer;
	data_done.input_done.status =
		hfi_map_err_status(pkt->error_type);
	hfi_picture_type = (struct hfi_picture_type *)&pkt->rgData[0];
	if (hfi_picture_type->is_sync_frame) {
	is_sync_frame = pkt->rgData[0];
	if (is_sync_frame == 1) {
		if (pkt->size <
			sizeof(struct hfi_msg_session_empty_buffer_done_packet)
			+ sizeof(struct hfi_picture_type))
			goto bad_packet_size;
		hfi_picture_type = (struct hfi_picture_type *)&pkt->rgData[1];
		if (hfi_picture_type->picture_type)
			data_done.input_done.flags =
				hfi_picture_type->picture_type;
@@ -1604,6 +1613,10 @@ static int hfi_process_session_etb_done(u32 device_id,
	info->response.data = data_done;

	return 0;
bad_packet_size:
	dprintk(VIDC_ERR, "%s: bad_pkt_size: %d\n",
		__func__, pkt ? pkt->size : 0);
	return -E2BIG;
}

static int hfi_process_session_ftb_done(
@@ -1838,8 +1851,7 @@ static int hfi_process_session_rel_buf_done(u32 device_id,
	cmd_done.size = sizeof(struct msm_vidc_cb_cmd_done);
	cmd_done.session_id = (void *)(uintptr_t)pkt->session_id;
	cmd_done.status = hfi_map_err_status(pkt->error_type);
	cmd_done.data.buffer_info =
			*(struct hal_buffer_info *)pkt->rg_buffer_info;
	cmd_done.data.buffer_info.buffer_addr = *pkt->rg_buffer_info;
	cmd_done.size = sizeof(struct hal_buffer_info);

	info->response_type = HAL_SESSION_RELEASE_BUFFER_DONE;
+2 −2
Original line number Diff line number Diff line
/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -601,7 +601,7 @@ struct hfi_msg_session_empty_buffer_done_packet {
	u32 extra_data_buffer;
	u32 flags;
	struct hfi_frame_cr_stats_type ubwc_cr_stats;
	u32 rgData[0];
	u32 rgData[1];
};

struct hfi_msg_session_fill_buffer_done_compressed_packet {
+0 −1
Original line number Diff line number Diff line
@@ -655,7 +655,6 @@ struct hfi_bit_depth {
};

struct hfi_picture_type {
	u32 is_sync_frame;
	u32 picture_type;
};

+21 −9
Original line number Diff line number Diff line
@@ -287,6 +287,12 @@ static int hfi_process_evt_release_buffer_ref(u32 device_id,
				"hal_process_session_init_done: bad_pkt_size\n");
		return -E2BIG;
	}
	if (pkt->size < sizeof(struct hfi_msg_event_notify_packet) - sizeof(u32)
		+ sizeof(struct hfi_msg_release_buffer_ref_event_packet)) {
		dprintk(VIDC_ERR,
			"hfi_msg_release_buffer_ref_event: bad_pkt_size\n");
		return -E2BIG;
	}

	data = (struct hfi_msg_release_buffer_ref_event_packet *)
				pkt->rg_ext_event_data;
@@ -1540,15 +1546,13 @@ static int hfi_process_session_etb_done(u32 device_id,
	struct hfi_msg_session_empty_buffer_done_packet *pkt = _pkt;
	struct msm_vidc_cb_data_done data_done = {0};
	struct hfi_picture_type *hfi_picture_type = NULL;
	u32 is_sync_frame;

	dprintk(VIDC_DBG, "RECEIVED: SESSION_ETB_DONE[%#x]\n", pkt->session_id);

	if (!pkt || pkt->size <
		sizeof(struct hfi_msg_session_empty_buffer_done_packet)) {
		dprintk(VIDC_ERR,
				"hal_process_session_etb_done: bad_pkt_size\n");
		return -E2BIG;
	}
		sizeof(struct hfi_msg_session_empty_buffer_done_packet))
		goto bad_packet_size;

	data_done.device_id = device_id;
	data_done.session_id = (void *)(uintptr_t)pkt->session_id;
@@ -1563,8 +1567,13 @@ static int hfi_process_session_etb_done(u32 device_id,
		(ion_phys_addr_t)pkt->extra_data_buffer;
	data_done.input_done.status =
		hfi_map_err_status(pkt->error_type);
	hfi_picture_type = (struct hfi_picture_type *)&pkt->rgData[0];
	if (hfi_picture_type->is_sync_frame) {
	is_sync_frame = pkt->rgData[0];
	if (is_sync_frame == 1) {
		if (pkt->size <
			sizeof(struct hfi_msg_session_empty_buffer_done_packet)
			+ sizeof(struct hfi_picture_type))
			goto bad_packet_size;
		hfi_picture_type = (struct hfi_picture_type *)&pkt->rgData[1];
		if (hfi_picture_type->picture_type)
			data_done.input_done.flags =
				hfi_picture_type->picture_type;
@@ -1583,6 +1592,10 @@ static int hfi_process_session_etb_done(u32 device_id,
	};

	return 0;
bad_packet_size:
	dprintk(VIDC_ERR, "%s: bad_pkt_size: %d\n",
		__func__, pkt ? pkt->size : 0);
	return -E2BIG;
}

static int hfi_process_session_ftb_done(
@@ -1823,8 +1836,7 @@ static int hfi_process_session_rel_buf_done(u32 device_id,
	cmd_done.session_id = (void *)(uintptr_t)pkt->session_id;
	cmd_done.status = hfi_map_err_status(pkt->error_type);
	if (pkt->rg_buffer_info) {
		cmd_done.data.buffer_info =
			*(struct hal_buffer_info *)pkt->rg_buffer_info;
		cmd_done.data.buffer_info.buffer_addr = *pkt->rg_buffer_info;
		cmd_done.size = sizeof(struct hal_buffer_info);
	} else {
		dprintk(VIDC_ERR, "invalid payload in rel_buff_done\n");
+2 −2
Original line number Diff line number Diff line
/* Copyright (c) 2012-2016, 2018 The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2016, 2018-2019 The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -662,7 +662,7 @@ struct hfi_msg_session_empty_buffer_done_packet {
	u32 input_tag;
	u32 packet_buffer;
	u32 extra_data_buffer;
	u32 rgData[0];
	u32 rgData[1];
};

struct hfi_msg_session_fill_buffer_done_compressed_packet {
Loading