msm: ipc: Cache the length of a packet being looped back

When a message is looped back to the user-space, sometimes the
receiver acts quickly, reads the contents of the packet and frees
the buffer. This leads to a scenario where the sender is trying to
dereference the packet length info of a freed packet. Hence a garbage
packet length gets returned to the user-space.

Fix this race condition by storing the packet length of the packet
being looped back into a variable and return the value of that variable
when the loopback operation is complete.

Change-Id: I595a562bfa12151b2f9154df681ce23c965dfff5
Signed-off-by: Karthikeyan Ramasubramanian <kramasub@codeaurora.org>
diff --git a/arch/arm/mach-msm/ipc_router.c b/arch/arm/mach-msm/ipc_router.c
index 206dedf..d6f844e 100644
--- a/arch/arm/mach-msm/ipc_router.c
+++ b/arch/arm/mach-msm/ipc_router.c
@@ -1679,6 +1679,7 @@
 	struct rr_header *hdr;
 	struct msm_ipc_port *port_ptr;
 	struct rr_packet *pkt;
+	int ret_len;
 
 	if (!data) {
 		pr_err("%s: Invalid pkt pointer\n", __func__);
@@ -1724,11 +1725,12 @@
 	mutex_lock(&port_ptr->port_rx_q_lock);
 	wake_lock(&port_ptr->port_rx_wake_lock);
 	list_add_tail(&pkt->list, &port_ptr->port_rx_q);
+	ret_len = pkt->length;
 	wake_up(&port_ptr->port_rx_wait_q);
 	mutex_unlock(&port_ptr->port_rx_q_lock);
 	mutex_unlock(&local_ports_lock);
 
-	return pkt->length;
+	return ret_len;
 }
 
 static int msm_ipc_router_write_pkt(struct msm_ipc_port *src,