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

Commit bd379d7c authored by Katish Paran's avatar Katish Paran
Browse files

diag : Safeguard for bound checks and integer underflow



At certain point in diag driver there can be integer underflow
and thus can lead to memory leak. Bound checks are placed to
ensure correct behaviour of condition statements.

Change-Id: I461aafe20d641766dddec86d86793b1aa2f2ab6b
CRs-fixed: 549470
Signed-off-by: default avatarKatish Paran <kparan@codeaurora.org>
parent 471e6a78
Loading
Loading
Loading
Loading
+10 −9
Original line number Diff line number Diff line
@@ -183,7 +183,7 @@ static ssize_t diag_dbgfs_read_status(struct file *file, char __user *ubuf,
		driver->real_time_mode);

#ifdef CONFIG_DIAG_OVER_USB
	ret += scnprintf(buf+ret, DEBUG_BUF_SIZE,
	ret += scnprintf(buf+ret, DEBUG_BUF_SIZE-ret,
		"usb_connected: %d\n",
		driver->usb_connected);
#endif
@@ -197,7 +197,8 @@ static ssize_t diag_dbgfs_read_dcistats(struct file *file,
				char __user *ubuf, size_t count, loff_t *ppos)
{
	char *buf = NULL;
	int bytes_remaining, bytes_written = 0, bytes_in_buf = 0, i = 0;
	unsigned int bytes_remaining, bytes_written = 0;
	unsigned int bytes_in_buf = 0, i = 0;
	struct diag_dci_data_info *temp_data = dci_data_smd;
	int buf_size = (DEBUG_BUF_SIZE < count) ? DEBUG_BUF_SIZE : count;

@@ -335,7 +336,7 @@ static ssize_t diag_dbgfs_read_workpending(struct file *file,
						diag_notify_update_smd_work)));

#ifdef CONFIG_DIAG_OVER_USB
	ret += scnprintf(buf+ret, DEBUG_BUF_SIZE,
	ret += scnprintf(buf+ret, DEBUG_BUF_SIZE-ret,
		"diag_proc_hdlc_work: %d\n"
		"diag_read_work: %d\n",
		work_pending(&(driver->diag_proc_hdlc_work)),
@@ -353,9 +354,9 @@ static ssize_t diag_dbgfs_read_table(struct file *file, char __user *ubuf,
	char *buf;
	int ret = 0;
	int i;
	int bytes_remaining;
	int bytes_in_buffer = 0;
	int bytes_written;
	unsigned int bytes_remaining;
	unsigned int bytes_in_buffer = 0;
	unsigned int bytes_written;
	int buf_size = (DEBUG_BUF_SIZE < count) ? DEBUG_BUF_SIZE : count;

	if (diag_dbgfs_table_index >= diag_max_reg) {
@@ -526,9 +527,9 @@ static ssize_t diag_dbgfs_read_bridge(struct file *file, char __user *ubuf,
	char *buf;
	int ret;
	int i;
	int bytes_remaining;
	int bytes_in_buffer = 0;
	int bytes_written;
	unsigned int bytes_remaining;
	unsigned int bytes_in_buffer = 0;
	unsigned int bytes_written;
	int buf_size = (DEBUG_BUF_SIZE < count) ? DEBUG_BUF_SIZE : count;
	int bytes_hsic_inited = 45;
	int bytes_hsic_not_inited = 410;
+16 −5
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ MODULE_DESCRIPTION("Diag Char Driver");
MODULE_LICENSE("GPL v2");
MODULE_VERSION("1.0");

#define MIN_SIZ_ALLOW 4
#define INIT	1
#define EXIT	-1
struct diagchar_dev *driver;
@@ -1450,6 +1451,10 @@ static ssize_t diagchar_write(struct file *file, const char __user *buf,
	index = 0;
	/* Get the packet type F3/log/event/Pkt response */
	err = copy_from_user((&pkt_type), buf, 4);
	if (err) {
		pr_alert("diag: copy failed for pkt_type\n");
		return -EAGAIN;
	}
	/* First 4 bytes indicate the type of payload - ignore these */
	if (count < 4) {
		pr_err("diag: Client sending short data\n");
@@ -1493,8 +1498,8 @@ static ssize_t diagchar_write(struct file *file, const char __user *buf,
		return err;
	}
	if (pkt_type == CALLBACK_DATA_TYPE) {
		if (payload_size > driver->itemsize) {
			pr_err("diag: Dropping packet, packet payload size crosses 4KB limit. Current payload size %d\n",
		if (payload_size > itemsize || payload_size <= MIN_SIZ_ALLOW) {
			pr_err("diag: Dropping packet, invalid packet size. Current payload size %d\n",
				payload_size);
			driver->dropped_count++;
			return -EBADMSG;
@@ -1624,10 +1629,16 @@ static ssize_t diagchar_write(struct file *file, const char __user *buf,
			return -EIO;
		}
		/* Check for proc_type */
		remote_proc =
			diag_get_remote(*(int *)driver->user_space_data_buf);

		remote_proc = diag_get_remote(*(int *)user_space_data);
		if (remote_proc) {
			if (payload_size <= MIN_SIZ_ALLOW) {
				pr_err("diag: Integer underflow in %s, payload size: %d",
							__func__, payload_size);
				diagmem_free(driver, user_space_data,
								POOL_TYPE_USER);
				user_space_data = NULL;
				return -EBADMSG;
			}
			token_offset = 4;
			payload_size -= 4;
			buf += 4;
+2 −2
Original line number Diff line number Diff line
@@ -177,8 +177,8 @@ int diag_hdlc_decode(struct diag_hdlc_decode_type *hdlc)
	int msg_start;

	if (hdlc && hdlc->src_ptr && hdlc->dest_ptr &&
	    (hdlc->src_size - hdlc->src_idx > 0) &&
	    (hdlc->dest_size - hdlc->dest_idx > 0)) {
	    (hdlc->src_size > hdlc->src_idx) &&
	    (hdlc->dest_size > hdlc->dest_idx)) {

		msg_start = (hdlc->src_idx == 0) ? 1 : 0;