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

Commit 840766fa authored by Srinivasarao Pathipati's avatar Srinivasarao Pathipati
Browse files

virt: haven: rm_core: Validate notifications using payload size only



Preparation for cleaning up the resource manager core.
Notification size validation needs to only be performed on the payload
size. The RM RPC header will always be present, else the RM driver would
not have been able to determine that the message is a notification.
Thus, considering the RPC header is not required.

Change-Id: Id6a561a77d693e4f8f307d9d0d96b8d173940c60
Signed-off-by: default avatarElliot Berman <quic_eberman@quicinc.com>
Signed-off-by: default avatarSrinivasarao Pathipati <quic_c_spathi@quicinc.com>
parent d5088814
Loading
Loading
Loading
Loading
+25 −19
Original line number Diff line number Diff line
@@ -170,6 +170,7 @@ static int hh_rm_process_notif(void *recv_buff, size_t recv_buff_size)
	struct hh_rm_rpc_hdr *hdr = recv_buff;
	u32 notification = hdr->msg_id;
	void *payload = NULL;
	size_t payload_size;
	int ret = 0;

	pr_debug("Notification received from RM-VM: %x\n", notification);
@@ -197,87 +198,92 @@ static int hh_rm_process_notif(void *recv_buff, size_t recv_buff_size)
		payload = connection->recv_buff;
		recv_buff_size = connection->recv_buff_size;
	}
	payload_size = recv_buff_size - sizeof(*hdr);

	switch (notification) {
	case HH_RM_NOTIF_VM_STATUS:
		if (recv_buff_size != sizeof(*hdr) +
		if (payload_size !=
			sizeof(struct hh_rm_notif_vm_status_payload)) {
			pr_err("%s: Invalid size for VM_STATUS notif: %u\n",
				__func__, recv_buff_size - sizeof(*hdr));
				__func__, payload_size);
			ret = -EINVAL;
			goto err;
		}
		break;
	case HH_RM_NOTIF_VM_IRQ_LENT:
		if (recv_buff_size != sizeof(*hdr) +
		if (payload_size !=
			sizeof(struct hh_rm_notif_vm_irq_lent_payload)) {
			pr_err("%s: Invalid size for VM_IRQ_LENT notif: %u\n",
				__func__, recv_buff_size - sizeof(*hdr));
				__func__, payload_size);
			ret = -EINVAL;
			goto err;
		}
		break;
	case HH_RM_NOTIF_VM_IRQ_RELEASED:
		if (recv_buff_size != sizeof(*hdr) +
		if (payload_size !=
			sizeof(struct hh_rm_notif_vm_irq_released_payload)) {
			pr_err("%s: Invalid size for VM_IRQ_REL notif: %u\n",
				__func__, recv_buff_size - sizeof(*hdr));
				__func__, payload_size);
			ret = -EINVAL;
			goto err;
		}
		break;
	case HH_RM_NOTIF_VM_IRQ_ACCEPTED:
		if (recv_buff_size != sizeof(*hdr) +
		if (payload_size !=
			sizeof(struct hh_rm_notif_vm_irq_accepted_payload)) {
			pr_err("%s: Invalid size for VM_IRQ_ACCEPTED notif: %u\n",
				__func__, recv_buff_size - sizeof(*hdr));
				__func__, payload_size);
			ret = -EINVAL;
			goto err;
		}
		break;
	case HH_RM_NOTIF_MEM_SHARED:
		if (recv_buff_size < sizeof(*hdr) +
		if (payload_size <
			sizeof(struct hh_rm_notif_mem_shared_payload)) {
			pr_err("%s: Invalid size for MEM_SHARED notif: %u\n",
				__func__, recv_buff_size - sizeof(*hdr));
				__func__, payload_size);
			ret = -EINVAL;
			goto err;
		}
		break;
	case HH_RM_NOTIF_MEM_RELEASED:
		if (recv_buff_size != sizeof(*hdr) +
		if (payload_size !=
			sizeof(struct hh_rm_notif_mem_released_payload)) {
			pr_err("%s: Invalid size for MEM_RELEASED notif: %u\n",
				__func__, recv_buff_size - sizeof(*hdr));
				__func__, payload_size);
			ret = -EINVAL;
			goto err;
		}
		break;
	case HH_RM_NOTIF_MEM_ACCEPTED:
		if (recv_buff_size != sizeof(*hdr) +
		if (payload_size !=
			sizeof(struct hh_rm_notif_mem_accepted_payload)) {
			pr_err("%s: Invalid size for MEM_ACCEPTED notif: %u\n",
				__func__, recv_buff_size - sizeof(*hdr));
				__func__, payload_size);
			ret = -EINVAL;
			goto err;
		}
		break;
	case HH_RM_NOTIF_VM_CONSOLE_CHARS:
		if (recv_buff_size < sizeof(*hdr) +
		if (payload_size >=
			sizeof(struct hh_rm_notif_vm_console_chars)) {
			struct hh_rm_notif_vm_console_chars *console_chars;
			u16 num_bytes;

			console_chars = recv_buff + sizeof(*hdr);
			console_chars = payload;
			num_bytes = console_chars->num_bytes;

			if (sizeof(*hdr) + sizeof(*console_chars) + num_bytes !=
				recv_buff_size) {
			if (sizeof(*console_chars) + num_bytes !=
				payload_size) {
				pr_err("%s: Invalid size for VM_CONSOLE_CHARS notify %u\n",
				       __func__, recv_buff_size - sizeof(*hdr));
				       __func__, payload_size);
				ret = -EINVAL;
				goto err;
			}
		} else {
			pr_err("%s: Invalid size for VM_CONSOLE_CHARS notify %u\n",
				__func__, payload_size);
			goto err;
		}
		break;
	default: