diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/nfc/llcp/llcp.c | 15 | ||||
-rw-r--r-- | net/nfc/llcp/sock.c | 23 |
2 files changed, 26 insertions, 12 deletions
diff --git a/net/nfc/llcp/llcp.c b/net/nfc/llcp/llcp.c index 3ce646e35f6..8af896dc759 100644 --- a/net/nfc/llcp/llcp.c +++ b/net/nfc/llcp/llcp.c | |||
@@ -47,7 +47,7 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local) | |||
47 | 47 | ||
48 | /* Release all child sockets */ | 48 | /* Release all child sockets */ |
49 | list_for_each_entry_safe(s, n, &parent->list, list) { | 49 | list_for_each_entry_safe(s, n, &parent->list, list) { |
50 | list_del(&s->list); | 50 | list_del_init(&s->list); |
51 | sk = &s->sk; | 51 | sk = &s->sk; |
52 | 52 | ||
53 | lock_sock(sk); | 53 | lock_sock(sk); |
@@ -56,9 +56,12 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local) | |||
56 | nfc_put_device(s->dev); | 56 | nfc_put_device(s->dev); |
57 | 57 | ||
58 | sk->sk_state = LLCP_CLOSED; | 58 | sk->sk_state = LLCP_CLOSED; |
59 | sock_set_flag(sk, SOCK_DEAD); | ||
60 | 59 | ||
61 | release_sock(sk); | 60 | release_sock(sk); |
61 | |||
62 | sock_orphan(sk); | ||
63 | |||
64 | s->local = NULL; | ||
62 | } | 65 | } |
63 | 66 | ||
64 | parent_sk = &parent->sk; | 67 | parent_sk = &parent->sk; |
@@ -77,11 +80,12 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local) | |||
77 | nfc_llcp_accept_unlink(accept_sk); | 80 | nfc_llcp_accept_unlink(accept_sk); |
78 | 81 | ||
79 | accept_sk->sk_state = LLCP_CLOSED; | 82 | accept_sk->sk_state = LLCP_CLOSED; |
80 | sock_set_flag(accept_sk, SOCK_DEAD); | ||
81 | 83 | ||
82 | release_sock(accept_sk); | 84 | release_sock(accept_sk); |
83 | 85 | ||
84 | sock_orphan(accept_sk); | 86 | sock_orphan(accept_sk); |
87 | |||
88 | lsk->local = NULL; | ||
85 | } | 89 | } |
86 | } | 90 | } |
87 | 91 | ||
@@ -89,9 +93,12 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local) | |||
89 | nfc_put_device(parent->dev); | 93 | nfc_put_device(parent->dev); |
90 | 94 | ||
91 | parent_sk->sk_state = LLCP_CLOSED; | 95 | parent_sk->sk_state = LLCP_CLOSED; |
92 | sock_set_flag(parent_sk, SOCK_DEAD); | ||
93 | 96 | ||
94 | release_sock(parent_sk); | 97 | release_sock(parent_sk); |
98 | |||
99 | sock_orphan(parent_sk); | ||
100 | |||
101 | parent->local = NULL; | ||
95 | } | 102 | } |
96 | 103 | ||
97 | mutex_unlock(&local->socket_lock); | 104 | mutex_unlock(&local->socket_lock); |
diff --git a/net/nfc/llcp/sock.c b/net/nfc/llcp/sock.c index d3861773fab..35825e20163 100644 --- a/net/nfc/llcp/sock.c +++ b/net/nfc/llcp/sock.c | |||
@@ -315,6 +315,7 @@ static int llcp_sock_release(struct socket *sock) | |||
315 | struct sock *sk = sock->sk; | 315 | struct sock *sk = sock->sk; |
316 | struct nfc_llcp_local *local; | 316 | struct nfc_llcp_local *local; |
317 | struct nfc_llcp_sock *llcp_sock = nfc_llcp_sock(sk); | 317 | struct nfc_llcp_sock *llcp_sock = nfc_llcp_sock(sk); |
318 | int err = 0; | ||
318 | 319 | ||
319 | if (!sk) | 320 | if (!sk) |
320 | return 0; | 321 | return 0; |
@@ -322,15 +323,17 @@ static int llcp_sock_release(struct socket *sock) | |||
322 | pr_debug("%p\n", sk); | 323 | pr_debug("%p\n", sk); |
323 | 324 | ||
324 | local = llcp_sock->local; | 325 | local = llcp_sock->local; |
325 | if (local == NULL) | 326 | if (local == NULL) { |
326 | return -ENODEV; | 327 | err = -ENODEV; |
328 | goto out; | ||
329 | } | ||
327 | 330 | ||
328 | mutex_lock(&local->socket_lock); | 331 | mutex_lock(&local->socket_lock); |
329 | 332 | ||
330 | if (llcp_sock == local->sockets[llcp_sock->ssap]) | 333 | if (llcp_sock == local->sockets[llcp_sock->ssap]) |
331 | local->sockets[llcp_sock->ssap] = NULL; | 334 | local->sockets[llcp_sock->ssap] = NULL; |
332 | else | 335 | else |
333 | list_del(&llcp_sock->list); | 336 | list_del_init(&llcp_sock->list); |
334 | 337 | ||
335 | mutex_unlock(&local->socket_lock); | 338 | mutex_unlock(&local->socket_lock); |
336 | 339 | ||
@@ -354,9 +357,7 @@ static int llcp_sock_release(struct socket *sock) | |||
354 | 357 | ||
355 | release_sock(accept_sk); | 358 | release_sock(accept_sk); |
356 | 359 | ||
357 | sock_set_flag(sk, SOCK_DEAD); | ||
358 | sock_orphan(accept_sk); | 360 | sock_orphan(accept_sk); |
359 | sock_put(accept_sk); | ||
360 | } | 361 | } |
361 | } | 362 | } |
362 | 363 | ||
@@ -367,14 +368,13 @@ static int llcp_sock_release(struct socket *sock) | |||
367 | sk->sk_state == LLCP_LISTEN) | 368 | sk->sk_state == LLCP_LISTEN) |
368 | nfc_llcp_put_ssap(llcp_sock->local, llcp_sock->ssap); | 369 | nfc_llcp_put_ssap(llcp_sock->local, llcp_sock->ssap); |
369 | 370 | ||
370 | sock_set_flag(sk, SOCK_DEAD); | ||
371 | |||
372 | release_sock(sk); | 371 | release_sock(sk); |
373 | 372 | ||
373 | out: | ||
374 | sock_orphan(sk); | 374 | sock_orphan(sk); |
375 | sock_put(sk); | 375 | sock_put(sk); |
376 | 376 | ||
377 | return 0; | 377 | return err; |
378 | } | 378 | } |
379 | 379 | ||
380 | static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr, | 380 | static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr, |
@@ -645,6 +645,8 @@ struct sock *nfc_llcp_sock_alloc(struct socket *sock, int type, gfp_t gfp) | |||
645 | 645 | ||
646 | void nfc_llcp_sock_free(struct nfc_llcp_sock *sock) | 646 | void nfc_llcp_sock_free(struct nfc_llcp_sock *sock) |
647 | { | 647 | { |
648 | struct nfc_llcp_local *local = sock->local; | ||
649 | |||
648 | kfree(sock->service_name); | 650 | kfree(sock->service_name); |
649 | 651 | ||
650 | skb_queue_purge(&sock->tx_queue); | 652 | skb_queue_purge(&sock->tx_queue); |
@@ -653,6 +655,11 @@ void nfc_llcp_sock_free(struct nfc_llcp_sock *sock) | |||
653 | 655 | ||
654 | list_del_init(&sock->accept_queue); | 656 | list_del_init(&sock->accept_queue); |
655 | 657 | ||
658 | if (local != NULL && sock == local->sockets[sock->ssap]) | ||
659 | local->sockets[sock->ssap] = NULL; | ||
660 | else | ||
661 | list_del_init(&sock->list); | ||
662 | |||
656 | sock->parent = NULL; | 663 | sock->parent = NULL; |
657 | } | 664 | } |
658 | 665 | ||