diff options
author | Vlad Yasevich <vladislav.yasevich@hp.com> | 2007-12-07 01:50:27 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-12-07 04:07:45 -0500 |
commit | f26f7c480555812ca7c4037e0a50fa54afe2cb4a (patch) | |
tree | 1418b99033d50241b8f866124b0974e7adb16449 | |
parent | 56c99d0415e8b778c200f115b198c126243ec351 (diff) |
[SCTP]: Add bind hash locking to the migrate code
SCTP accept code tries to add a newliy created socket
to a bind bucket without holding a lock. On a really
busy system, that can causes slab corruptions.
Add a lock around this code.
Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/sctp/socket.c | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index ff8bc95670ed..9f5d7930f54d 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -6325,6 +6325,7 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk, | |||
6325 | struct sctp_endpoint *newep = newsp->ep; | 6325 | struct sctp_endpoint *newep = newsp->ep; |
6326 | struct sk_buff *skb, *tmp; | 6326 | struct sk_buff *skb, *tmp; |
6327 | struct sctp_ulpevent *event; | 6327 | struct sctp_ulpevent *event; |
6328 | struct sctp_bind_hashbucket *head; | ||
6328 | int flags = 0; | 6329 | int flags = 0; |
6329 | 6330 | ||
6330 | /* Migrate socket buffer sizes and all the socket level options to the | 6331 | /* Migrate socket buffer sizes and all the socket level options to the |
@@ -6342,10 +6343,15 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk, | |||
6342 | newsp->hmac = NULL; | 6343 | newsp->hmac = NULL; |
6343 | 6344 | ||
6344 | /* Hook this new socket in to the bind_hash list. */ | 6345 | /* Hook this new socket in to the bind_hash list. */ |
6346 | head = &sctp_port_hashtable[sctp_phashfn(inet_sk(oldsk)->num)]; | ||
6347 | sctp_local_bh_disable(); | ||
6348 | sctp_spin_lock(&head->lock); | ||
6345 | pp = sctp_sk(oldsk)->bind_hash; | 6349 | pp = sctp_sk(oldsk)->bind_hash; |
6346 | sk_add_bind_node(newsk, &pp->owner); | 6350 | sk_add_bind_node(newsk, &pp->owner); |
6347 | sctp_sk(newsk)->bind_hash = pp; | 6351 | sctp_sk(newsk)->bind_hash = pp; |
6348 | inet_sk(newsk)->num = inet_sk(oldsk)->num; | 6352 | inet_sk(newsk)->num = inet_sk(oldsk)->num; |
6353 | sctp_spin_unlock(&head->lock); | ||
6354 | sctp_local_bh_enable(); | ||
6349 | 6355 | ||
6350 | /* Copy the bind_addr list from the original endpoint to the new | 6356 | /* Copy the bind_addr list from the original endpoint to the new |
6351 | * endpoint so that we can handle restarts properly | 6357 | * endpoint so that we can handle restarts properly |