mirror of
https://github.com/torvalds/linux
synced 2024-11-05 18:23:50 +00:00
Merge branch 'sctp-accept-deadlock'
Karl Heiss says: ==================== sctp: Fix SCTP deadlock These patches fix a deadlock during accept() of an SCTP connection. The first patch fixes whitespace issues. The second patch actually fixes the deadlock race. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
51359bfc5b
1 changed files with 24 additions and 20 deletions
|
@ -244,12 +244,13 @@ void sctp_generate_t3_rtx_event(unsigned long peer)
|
|||
int error;
|
||||
struct sctp_transport *transport = (struct sctp_transport *) peer;
|
||||
struct sctp_association *asoc = transport->asoc;
|
||||
struct net *net = sock_net(asoc->base.sk);
|
||||
struct sock *sk = asoc->base.sk;
|
||||
struct net *net = sock_net(sk);
|
||||
|
||||
/* Check whether a task is in the sock. */
|
||||
|
||||
bh_lock_sock(asoc->base.sk);
|
||||
if (sock_owned_by_user(asoc->base.sk)) {
|
||||
bh_lock_sock(sk);
|
||||
if (sock_owned_by_user(sk)) {
|
||||
pr_debug("%s: sock is busy\n", __func__);
|
||||
|
||||
/* Try again later. */
|
||||
|
@ -272,10 +273,10 @@ void sctp_generate_t3_rtx_event(unsigned long peer)
|
|||
transport, GFP_ATOMIC);
|
||||
|
||||
if (error)
|
||||
asoc->base.sk->sk_err = -error;
|
||||
sk->sk_err = -error;
|
||||
|
||||
out_unlock:
|
||||
bh_unlock_sock(asoc->base.sk);
|
||||
bh_unlock_sock(sk);
|
||||
sctp_transport_put(transport);
|
||||
}
|
||||
|
||||
|
@ -285,11 +286,12 @@ void sctp_generate_t3_rtx_event(unsigned long peer)
|
|||
static void sctp_generate_timeout_event(struct sctp_association *asoc,
|
||||
sctp_event_timeout_t timeout_type)
|
||||
{
|
||||
struct net *net = sock_net(asoc->base.sk);
|
||||
struct sock *sk = asoc->base.sk;
|
||||
struct net *net = sock_net(sk);
|
||||
int error = 0;
|
||||
|
||||
bh_lock_sock(asoc->base.sk);
|
||||
if (sock_owned_by_user(asoc->base.sk)) {
|
||||
bh_lock_sock(sk);
|
||||
if (sock_owned_by_user(sk)) {
|
||||
pr_debug("%s: sock is busy: timer %d\n", __func__,
|
||||
timeout_type);
|
||||
|
||||
|
@ -312,10 +314,10 @@ static void sctp_generate_timeout_event(struct sctp_association *asoc,
|
|||
(void *)timeout_type, GFP_ATOMIC);
|
||||
|
||||
if (error)
|
||||
asoc->base.sk->sk_err = -error;
|
||||
sk->sk_err = -error;
|
||||
|
||||
out_unlock:
|
||||
bh_unlock_sock(asoc->base.sk);
|
||||
bh_unlock_sock(sk);
|
||||
sctp_association_put(asoc);
|
||||
}
|
||||
|
||||
|
@ -365,10 +367,11 @@ void sctp_generate_heartbeat_event(unsigned long data)
|
|||
int error = 0;
|
||||
struct sctp_transport *transport = (struct sctp_transport *) data;
|
||||
struct sctp_association *asoc = transport->asoc;
|
||||
struct net *net = sock_net(asoc->base.sk);
|
||||
struct sock *sk = asoc->base.sk;
|
||||
struct net *net = sock_net(sk);
|
||||
|
||||
bh_lock_sock(asoc->base.sk);
|
||||
if (sock_owned_by_user(asoc->base.sk)) {
|
||||
bh_lock_sock(sk);
|
||||
if (sock_owned_by_user(sk)) {
|
||||
pr_debug("%s: sock is busy\n", __func__);
|
||||
|
||||
/* Try again later. */
|
||||
|
@ -388,11 +391,11 @@ void sctp_generate_heartbeat_event(unsigned long data)
|
|||
asoc->state, asoc->ep, asoc,
|
||||
transport, GFP_ATOMIC);
|
||||
|
||||
if (error)
|
||||
asoc->base.sk->sk_err = -error;
|
||||
if (error)
|
||||
sk->sk_err = -error;
|
||||
|
||||
out_unlock:
|
||||
bh_unlock_sock(asoc->base.sk);
|
||||
bh_unlock_sock(sk);
|
||||
sctp_transport_put(transport);
|
||||
}
|
||||
|
||||
|
@ -403,10 +406,11 @@ void sctp_generate_proto_unreach_event(unsigned long data)
|
|||
{
|
||||
struct sctp_transport *transport = (struct sctp_transport *) data;
|
||||
struct sctp_association *asoc = transport->asoc;
|
||||
struct net *net = sock_net(asoc->base.sk);
|
||||
struct sock *sk = asoc->base.sk;
|
||||
struct net *net = sock_net(sk);
|
||||
|
||||
bh_lock_sock(asoc->base.sk);
|
||||
if (sock_owned_by_user(asoc->base.sk)) {
|
||||
bh_lock_sock(sk);
|
||||
if (sock_owned_by_user(sk)) {
|
||||
pr_debug("%s: sock is busy\n", __func__);
|
||||
|
||||
/* Try again later. */
|
||||
|
@ -427,7 +431,7 @@ void sctp_generate_proto_unreach_event(unsigned long data)
|
|||
asoc->state, asoc->ep, asoc, transport, GFP_ATOMIC);
|
||||
|
||||
out_unlock:
|
||||
bh_unlock_sock(asoc->base.sk);
|
||||
bh_unlock_sock(sk);
|
||||
sctp_association_put(asoc);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue