diff options
Diffstat (limited to 'net/tipc/socket.c')
| -rw-r--r-- | net/tipc/socket.c | 46 |
1 files changed, 31 insertions, 15 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 3b61851bb927..e741416d1d24 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
| @@ -354,7 +354,7 @@ static int release(struct socket *sock) | |||
| 354 | * Delete TIPC port; this ensures no more messages are queued | 354 | * Delete TIPC port; this ensures no more messages are queued |
| 355 | * (also disconnects an active connection & sends a 'FIN-' to peer) | 355 | * (also disconnects an active connection & sends a 'FIN-' to peer) |
| 356 | */ | 356 | */ |
| 357 | res = tipc_deleteport(tport->ref); | 357 | res = tipc_deleteport(tport); |
| 358 | 358 | ||
| 359 | /* Discard any remaining (connection-based) messages in receive queue */ | 359 | /* Discard any remaining (connection-based) messages in receive queue */ |
| 360 | __skb_queue_purge(&sk->sk_receive_queue); | 360 | __skb_queue_purge(&sk->sk_receive_queue); |
| @@ -386,30 +386,46 @@ static int release(struct socket *sock) | |||
| 386 | */ | 386 | */ |
| 387 | static int bind(struct socket *sock, struct sockaddr *uaddr, int uaddr_len) | 387 | static int bind(struct socket *sock, struct sockaddr *uaddr, int uaddr_len) |
| 388 | { | 388 | { |
| 389 | struct sock *sk = sock->sk; | ||
| 389 | struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr; | 390 | struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr; |
| 390 | u32 portref = tipc_sk_port(sock->sk)->ref; | 391 | struct tipc_port *tport = tipc_sk_port(sock->sk); |
| 392 | int res = -EINVAL; | ||
| 391 | 393 | ||
| 392 | if (unlikely(!uaddr_len)) | 394 | lock_sock(sk); |
| 393 | return tipc_withdraw(portref, 0, NULL); | 395 | if (unlikely(!uaddr_len)) { |
| 396 | res = tipc_withdraw(tport, 0, NULL); | ||
| 397 | goto exit; | ||
| 398 | } | ||
| 394 | 399 | ||
| 395 | if (uaddr_len < sizeof(struct sockaddr_tipc)) | 400 | if (uaddr_len < sizeof(struct sockaddr_tipc)) { |
| 396 | return -EINVAL; | 401 | res = -EINVAL; |
| 397 | if (addr->family != AF_TIPC) | 402 | goto exit; |
| 398 | return -EAFNOSUPPORT; | 403 | } |
| 404 | if (addr->family != AF_TIPC) { | ||
| 405 | res = -EAFNOSUPPORT; | ||
| 406 | goto exit; | ||
| 407 | } | ||
| 399 | 408 | ||
| 400 | if (addr->addrtype == TIPC_ADDR_NAME) | 409 | if (addr->addrtype == TIPC_ADDR_NAME) |
| 401 | addr->addr.nameseq.upper = addr->addr.nameseq.lower; | 410 | addr->addr.nameseq.upper = addr->addr.nameseq.lower; |
| 402 | else if (addr->addrtype != TIPC_ADDR_NAMESEQ) | 411 | else if (addr->addrtype != TIPC_ADDR_NAMESEQ) { |
| 403 | return -EAFNOSUPPORT; | 412 | res = -EAFNOSUPPORT; |
| 413 | goto exit; | ||
| 414 | } | ||
| 404 | 415 | ||
| 405 | if ((addr->addr.nameseq.type < TIPC_RESERVED_TYPES) && | 416 | if ((addr->addr.nameseq.type < TIPC_RESERVED_TYPES) && |
| 406 | (addr->addr.nameseq.type != TIPC_TOP_SRV) && | 417 | (addr->addr.nameseq.type != TIPC_TOP_SRV) && |
| 407 | (addr->addr.nameseq.type != TIPC_CFG_SRV)) | 418 | (addr->addr.nameseq.type != TIPC_CFG_SRV)) { |
| 408 | return -EACCES; | 419 | res = -EACCES; |
| 420 | goto exit; | ||
| 421 | } | ||
| 409 | 422 | ||
| 410 | return (addr->scope > 0) ? | 423 | res = (addr->scope > 0) ? |
| 411 | tipc_publish(portref, addr->scope, &addr->addr.nameseq) : | 424 | tipc_publish(tport, addr->scope, &addr->addr.nameseq) : |
| 412 | tipc_withdraw(portref, -addr->scope, &addr->addr.nameseq); | 425 | tipc_withdraw(tport, -addr->scope, &addr->addr.nameseq); |
| 426 | exit: | ||
| 427 | release_sock(sk); | ||
| 428 | return res; | ||
| 413 | } | 429 | } |
| 414 | 430 | ||
| 415 | /** | 431 | /** |
