diff options
Diffstat (limited to 'net/sctp/socket.c')
-rw-r--r-- | net/sctp/socket.c | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 90863307bcd9..b1a17758003a 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -1229,7 +1229,7 @@ SCTP_STATIC void sctp_close(struct sock *sk, long timeout) | |||
1229 | 1229 | ||
1230 | ep = sctp_sk(sk)->ep; | 1230 | ep = sctp_sk(sk)->ep; |
1231 | 1231 | ||
1232 | /* Walk all associations on a socket, not on an endpoint. */ | 1232 | /* Walk all associations on an endpoint. */ |
1233 | list_for_each_safe(pos, temp, &ep->asocs) { | 1233 | list_for_each_safe(pos, temp, &ep->asocs) { |
1234 | asoc = list_entry(pos, struct sctp_association, asocs); | 1234 | asoc = list_entry(pos, struct sctp_association, asocs); |
1235 | 1235 | ||
@@ -5318,6 +5318,7 @@ static int sctp_wait_for_sndbuf(struct sctp_association *asoc, long *timeo_p, | |||
5318 | */ | 5318 | */ |
5319 | sctp_release_sock(sk); | 5319 | sctp_release_sock(sk); |
5320 | current_timeo = schedule_timeout(current_timeo); | 5320 | current_timeo = schedule_timeout(current_timeo); |
5321 | BUG_ON(sk != asoc->base.sk); | ||
5321 | sctp_lock_sock(sk); | 5322 | sctp_lock_sock(sk); |
5322 | 5323 | ||
5323 | *timeo_p = current_timeo; | 5324 | *timeo_p = current_timeo; |
@@ -5605,12 +5606,14 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk, | |||
5605 | */ | 5606 | */ |
5606 | newsp->type = type; | 5607 | newsp->type = type; |
5607 | 5608 | ||
5608 | spin_lock_bh(&oldsk->sk_lock.slock); | 5609 | /* Mark the new socket "in-use" by the user so that any packets |
5609 | /* Migrate the backlog from oldsk to newsk. */ | 5610 | * that may arrive on the association after we've moved it are |
5610 | sctp_backlog_migrate(assoc, oldsk, newsk); | 5611 | * queued to the backlog. This prevents a potential race between |
5611 | /* Migrate the association to the new socket. */ | 5612 | * backlog processing on the old socket and new-packet processing |
5613 | * on the new socket. | ||
5614 | */ | ||
5615 | sctp_lock_sock(newsk); | ||
5612 | sctp_assoc_migrate(assoc, newsk); | 5616 | sctp_assoc_migrate(assoc, newsk); |
5613 | spin_unlock_bh(&oldsk->sk_lock.slock); | ||
5614 | 5617 | ||
5615 | /* If the association on the newsk is already closed before accept() | 5618 | /* If the association on the newsk is already closed before accept() |
5616 | * is called, set RCV_SHUTDOWN flag. | 5619 | * is called, set RCV_SHUTDOWN flag. |
@@ -5619,6 +5622,7 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk, | |||
5619 | newsk->sk_shutdown |= RCV_SHUTDOWN; | 5622 | newsk->sk_shutdown |= RCV_SHUTDOWN; |
5620 | 5623 | ||
5621 | newsk->sk_state = SCTP_SS_ESTABLISHED; | 5624 | newsk->sk_state = SCTP_SS_ESTABLISHED; |
5625 | sctp_release_sock(newsk); | ||
5622 | } | 5626 | } |
5623 | 5627 | ||
5624 | /* This proto struct describes the ULP interface for SCTP. */ | 5628 | /* This proto struct describes the ULP interface for SCTP. */ |