net: ipc_router: Fix socket reference in IPC Router

The socket associated with an IPC Router port can be released before
the port is released. This leads to an use after free bug in cases
where the socket is closed while a packet is in flight.

Fix the use after free scenario by holding a sock reference during
creation of the port and releasing that in release port function.

CRs-Fixed: 811335
Change-Id: I638cc59e3b4e2347107e5ac19f233b0f7b9dd7b0
Signed-off-by: Atish Kumar Patra <apatra@codeaurora.org>
This commit is contained in:
Atish Kumar Patra 2015-03-22 18:40:01 -06:00
parent 646b269a5c
commit 3da72c23d7
2 changed files with 14 additions and 6 deletions

View File

@ -64,6 +64,8 @@ if (msm_ipc_router_debug_mask & RTR_DBG) \
#define IPC_ROUTER_LOG_EVENT_RX_ERR 0x04
#define IPC_ROUTER_DUMMY_DEST_NODE 0xFFFFFFFF
#define ipc_port_sk(port) ((struct sock *)(port))
static LIST_HEAD(control_ports);
static DECLARE_RWSEM(control_ports_lock_lha5);
@ -1214,6 +1216,8 @@ struct msm_ipc_port *msm_ipc_router_create_raw_port(void *endpoint,
port_ptr->priv = priv;
msm_ipc_router_add_local_port(port_ptr);
if (endpoint)
sock_hold(ipc_port_sk(endpoint));
return port_ptr;
}
@ -1260,6 +1264,8 @@ void ipc_router_release_port(struct kref *ref)
}
mutex_unlock(&port_ptr->port_rx_q_lock_lhc3);
wakeup_source_trash(&port_ptr->port_rx_ws);
if (port_ptr->endpoint)
sock_put(ipc_port_sk(port_ptr->endpoint));
kfree(port_ptr);
}

View File

@ -205,19 +205,21 @@ static int msm_ipc_router_create(struct net *net,
return -ENOMEM;
}
sock->ops = &msm_ipc_proto_ops;
sock_init_data(sock, sk);
sk->sk_data_ready = NULL;
sk->sk_rcvtimeo = DEFAULT_RCV_TIMEO;
sk->sk_sndtimeo = DEFAULT_SND_TIMEO;
port_ptr = msm_ipc_router_create_raw_port(sk, NULL, NULL);
if (!port_ptr) {
IPC_RTR_ERR("%s: port_ptr alloc failed\n", __func__);
sk_free(sk);
sock_put(sk);
sock->sk = NULL;
return -ENOMEM;
}
port_ptr->check_send_permissions = msm_ipc_check_send_permissions;
sock->ops = &msm_ipc_proto_ops;
sock_init_data(sock, sk);
sk->sk_rcvtimeo = DEFAULT_RCV_TIMEO;
sk->sk_sndtimeo = DEFAULT_SND_TIMEO;
msm_ipc_sk(sk)->port = port_ptr;
msm_ipc_sk(sk)->default_node_vote_info = NULL;