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

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

Merge "msm: smd: Handle corrupted packet header gracefully"

parents 43c2bacd 61ead888
Loading
Loading
Loading
Loading
+35 −0
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@
#include <mach/msm_smd.h>
#include <mach/msm_iomap.h>
#include <mach/subsystem_notif.h>
#include <mach/subsystem_restart.h>
#include <mach/socinfo.h>
#include <mach/proc_comm.h>
#include <mach/msm_ipc_logging.h>
@@ -1214,6 +1215,7 @@ static void update_packet_state(struct smd_channel *ch)
{
	unsigned hdr[5];
	int r;
	const char *peripheral = NULL;

	/* can't do anything if we're in the middle of a packet */
	while (ch->current_packet == 0) {
@@ -1227,6 +1229,17 @@ static void update_packet_state(struct smd_channel *ch)
		BUG_ON(r != SMD_HEADER_SIZE);

		ch->current_packet = hdr[0];
		if (ch->current_packet > (uint32_t)INT_MAX) {
			pr_err("%s: Invalid packet size of %d bytes detected. Edge: %d, Channel : %s, RPTR: %d, WPTR: %d",
				__func__, ch->current_packet, ch->type,
				ch->name, ch->half_ch->get_tail(ch->recv),
				ch->half_ch->get_head(ch->recv));
			peripheral = smd_edge_to_pil_str(ch->type);
			if (peripheral) {
				if (subsystem_restart(peripheral) < 0)
					BUG();
			}
		}
	}
}

@@ -1704,6 +1717,12 @@ static int smd_packet_read(smd_channel_t *ch, void *data, int len, int user_buf)
	if (len < 0)
		return -EINVAL;

	if (ch->current_packet > (uint32_t)INT_MAX) {
		pr_err("%s: Invalid packet size for Edge %d and Channel %s",
			__func__, ch->type, ch->name);
		return -EFAULT;
	}

	if (len > ch->current_packet)
		len = ch->current_packet;

@@ -1728,6 +1747,12 @@ static int smd_packet_read_from_cb(smd_channel_t *ch, void *data, int len,
	if (len < 0)
		return -EINVAL;

	if (ch->current_packet > (uint32_t)INT_MAX) {
		pr_err("%s: Invalid packet size for Edge %d and Channel %s",
			__func__, ch->type, ch->name);
		return -EFAULT;
	}

	if (len > ch->current_packet)
		len = ch->current_packet;

@@ -2336,6 +2361,11 @@ int smd_read_avail(smd_channel_t *ch)
		return -ENODEV;
	}

	if (ch->current_packet > (uint32_t)INT_MAX) {
		pr_err("%s: Invalid packet size for Edge %d and Channel %s",
			__func__, ch->type, ch->name);
		return -EFAULT;
	}
	return ch->read_avail(ch);
}
EXPORT_SYMBOL(smd_read_avail);
@@ -2432,6 +2462,11 @@ int smd_cur_packet_size(smd_channel_t *ch)
		return -ENODEV;
	}

	if (ch->current_packet > (uint32_t)INT_MAX) {
		pr_err("%s: Invalid packet size for Edge %d and Channel %s",
			__func__, ch->type, ch->name);
		return -EFAULT;
	}
	return ch->current_packet;
}
EXPORT_SYMBOL(smd_cur_packet_size);