msm: ipc: Fix SKB ownership for failure case
When a client writes to IPC Router and if the write fails, then in certain scenarios both the client and IPC Router take up the ownership of the SKB. These failure scenarios lead to a double-free and segmentation fault. Fix these scenarios by resolving the ownership issue. If the write to IPC Router is successful, then IPC Router will keep the ownership of the SKBs and free the packets. If the write fails, then the client will keep the ownership of the SKBs and free the packets. CRs-Fixed: 530180 Change-Id: Iaba47f5da377cdf0a6b16ae02d99eab91a9a6221 Signed-off-by: Zaheerulla Meer <zmeer@codeaurora.org>
This commit is contained in:
parent
f4899eaeb0
commit
2071905fcf
|
@ -458,7 +458,7 @@ static void *msm_ipc_router_skb_to_buf(struct sk_buff_head *skb_head,
|
|||
return buf;
|
||||
}
|
||||
|
||||
static void msm_ipc_router_free_skb(struct sk_buff_head *skb_head)
|
||||
void msm_ipc_router_free_skb(struct sk_buff_head *skb_head)
|
||||
{
|
||||
struct sk_buff *temp_skb;
|
||||
|
||||
|
@ -2299,6 +2299,7 @@ static int loopback_data(struct msm_ipc_port *src,
|
|||
if (!port_ptr) {
|
||||
pr_err("%s: Local port %d not present\n", __func__, port_id);
|
||||
up_read(&local_ports_lock_lha2);
|
||||
pkt->pkt_fragment_q = NULL;
|
||||
release_pkt(pkt);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
@ -2501,6 +2502,8 @@ int msm_ipc_router_send_to(struct msm_ipc_port *src,
|
|||
|
||||
ret = msm_ipc_router_write_pkt(src, rport_ptr, pkt);
|
||||
up_read(&routing_table_lock_lha3);
|
||||
if (ret < 0)
|
||||
pkt->pkt_fragment_q = NULL;
|
||||
release_pkt(pkt);
|
||||
|
||||
return ret;
|
||||
|
@ -2520,11 +2523,10 @@ int msm_ipc_router_send_msg(struct msm_ipc_port *src,
|
|||
}
|
||||
|
||||
ret = msm_ipc_router_send_to(src, out_skb_head, dest);
|
||||
if (ret == -EAGAIN)
|
||||
return ret;
|
||||
if (ret < 0) {
|
||||
pr_err("%s: msm_ipc_router_send_to failed - ret: %d\n",
|
||||
__func__, ret);
|
||||
if (ret != -EAGAIN)
|
||||
pr_err("%s: msm_ipc_router_send_to failed - ret: %d\n",
|
||||
__func__, ret);
|
||||
msm_ipc_router_free_skb(out_skb_head);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -257,4 +257,5 @@ static inline void *msm_ipc_load_default_node(void)
|
|||
static inline void msm_ipc_unload_default_node(void *pil) { }
|
||||
#endif
|
||||
|
||||
void msm_ipc_router_free_skb(struct sk_buff_head *skb_head);
|
||||
#endif
|
||||
|
|
|
@ -378,10 +378,14 @@ static int msm_ipc_router_sendmsg(struct kiocb *iocb, struct socket *sock,
|
|||
msm_ipc_router_ipc_log(IPC_SEND, ipc_buf, port_ptr);
|
||||
ret = msm_ipc_router_send_to(port_ptr, msg, &dest->address);
|
||||
if (ret != total_len) {
|
||||
if (ret < 0 && ret != -EAGAIN)
|
||||
pr_err("%s: Send_to failure %d\n", __func__, ret);
|
||||
else if (ret >= 0)
|
||||
if (ret < 0) {
|
||||
if (ret != -EAGAIN)
|
||||
pr_err("%s: Send_to failure %d\n",
|
||||
__func__, ret);
|
||||
msm_ipc_router_free_skb(msg);
|
||||
} else if (ret >= 0) {
|
||||
ret = -EFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
out_sendmsg:
|
||||
|
|
Loading…
Reference in New Issue