diff options
author | Allan Stephens <allan.stephens@windriver.com> | 2008-05-12 18:42:28 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-05-12 18:42:28 -0400 |
commit | 7ef43ebaa538e0cc9063cbf84593a05091bcace2 (patch) | |
tree | d2bac748f6620cc2f217672105918b2116f6c958 /net/tipc/socket.c | |
parent | 4e3e6dcb43c3669a8817cb3d0f920f91661afd98 (diff) |
tipc: Fix race condition when creating socket or native port
This patch eliminates the (very remote) chance of a crash resulting
from a partially initialized socket or native port unexpectedly
receiving a message. Now, during the creation of a socket or native
port, the underlying generic port's lock is not released until all
initialization required to handle incoming messages has been done.
Signed-off-by: Allan Stephens <allan.stephens@windriver.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc/socket.c')
-rw-r--r-- | net/tipc/socket.c | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 230f9ca2ad6b..38f48795b40e 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -188,6 +188,7 @@ static int tipc_create(struct net *net, struct socket *sock, int protocol) | |||
188 | const struct proto_ops *ops; | 188 | const struct proto_ops *ops; |
189 | socket_state state; | 189 | socket_state state; |
190 | struct sock *sk; | 190 | struct sock *sk; |
191 | struct tipc_port *tp_ptr; | ||
191 | u32 portref; | 192 | u32 portref; |
192 | 193 | ||
193 | /* Validate arguments */ | 194 | /* Validate arguments */ |
@@ -225,7 +226,7 @@ static int tipc_create(struct net *net, struct socket *sock, int protocol) | |||
225 | /* Allocate TIPC port for socket to use */ | 226 | /* Allocate TIPC port for socket to use */ |
226 | 227 | ||
227 | portref = tipc_createport_raw(sk, &dispatch, &wakeupdispatch, | 228 | portref = tipc_createport_raw(sk, &dispatch, &wakeupdispatch, |
228 | TIPC_LOW_IMPORTANCE); | 229 | TIPC_LOW_IMPORTANCE, &tp_ptr); |
229 | if (unlikely(portref == 0)) { | 230 | if (unlikely(portref == 0)) { |
230 | sk_free(sk); | 231 | sk_free(sk); |
231 | return -ENOMEM; | 232 | return -ENOMEM; |
@@ -241,6 +242,8 @@ static int tipc_create(struct net *net, struct socket *sock, int protocol) | |||
241 | sk->sk_backlog_rcv = backlog_rcv; | 242 | sk->sk_backlog_rcv = backlog_rcv; |
242 | tipc_sk(sk)->p = tipc_get_port(portref); | 243 | tipc_sk(sk)->p = tipc_get_port(portref); |
243 | 244 | ||
245 | spin_unlock_bh(tp_ptr->lock); | ||
246 | |||
244 | if (sock->state == SS_READY) { | 247 | if (sock->state == SS_READY) { |
245 | tipc_set_portunreturnable(portref, 1); | 248 | tipc_set_portunreturnable(portref, 1); |
246 | if (sock->type == SOCK_DGRAM) | 249 | if (sock->type == SOCK_DGRAM) |