diff options
Diffstat (limited to 'net/core/sock.c')
-rw-r--r-- | net/core/sock.c | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/net/core/sock.c b/net/core/sock.c index fcd397a762ff..c5812bbc2cc9 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -340,8 +340,12 @@ int sk_receive_skb(struct sock *sk, struct sk_buff *skb, const int nested) | |||
340 | rc = sk_backlog_rcv(sk, skb); | 340 | rc = sk_backlog_rcv(sk, skb); |
341 | 341 | ||
342 | mutex_release(&sk->sk_lock.dep_map, 1, _RET_IP_); | 342 | mutex_release(&sk->sk_lock.dep_map, 1, _RET_IP_); |
343 | } else | 343 | } else if (sk_add_backlog(sk, skb)) { |
344 | sk_add_backlog(sk, skb); | 344 | bh_unlock_sock(sk); |
345 | atomic_inc(&sk->sk_drops); | ||
346 | goto discard_and_relse; | ||
347 | } | ||
348 | |||
345 | bh_unlock_sock(sk); | 349 | bh_unlock_sock(sk); |
346 | out: | 350 | out: |
347 | sock_put(sk); | 351 | sock_put(sk); |
@@ -1139,6 +1143,7 @@ struct sock *sk_clone(const struct sock *sk, const gfp_t priority) | |||
1139 | sock_lock_init(newsk); | 1143 | sock_lock_init(newsk); |
1140 | bh_lock_sock(newsk); | 1144 | bh_lock_sock(newsk); |
1141 | newsk->sk_backlog.head = newsk->sk_backlog.tail = NULL; | 1145 | newsk->sk_backlog.head = newsk->sk_backlog.tail = NULL; |
1146 | newsk->sk_backlog.len = 0; | ||
1142 | 1147 | ||
1143 | atomic_set(&newsk->sk_rmem_alloc, 0); | 1148 | atomic_set(&newsk->sk_rmem_alloc, 0); |
1144 | /* | 1149 | /* |
@@ -1542,6 +1547,12 @@ static void __release_sock(struct sock *sk) | |||
1542 | 1547 | ||
1543 | bh_lock_sock(sk); | 1548 | bh_lock_sock(sk); |
1544 | } while ((skb = sk->sk_backlog.head) != NULL); | 1549 | } while ((skb = sk->sk_backlog.head) != NULL); |
1550 | |||
1551 | /* | ||
1552 | * Doing the zeroing here guarantee we can not loop forever | ||
1553 | * while a wild producer attempts to flood us. | ||
1554 | */ | ||
1555 | sk->sk_backlog.len = 0; | ||
1545 | } | 1556 | } |
1546 | 1557 | ||
1547 | /** | 1558 | /** |
@@ -1874,6 +1885,7 @@ void sock_init_data(struct socket *sock, struct sock *sk) | |||
1874 | sk->sk_allocation = GFP_KERNEL; | 1885 | sk->sk_allocation = GFP_KERNEL; |
1875 | sk->sk_rcvbuf = sysctl_rmem_default; | 1886 | sk->sk_rcvbuf = sysctl_rmem_default; |
1876 | sk->sk_sndbuf = sysctl_wmem_default; | 1887 | sk->sk_sndbuf = sysctl_wmem_default; |
1888 | sk->sk_backlog.limit = sk->sk_rcvbuf << 1; | ||
1877 | sk->sk_state = TCP_CLOSE; | 1889 | sk->sk_state = TCP_CLOSE; |
1878 | sk_set_socket(sk, sock); | 1890 | sk_set_socket(sk, sock); |
1879 | 1891 | ||
@@ -2276,7 +2288,8 @@ out_free_request_sock_slab: | |||
2276 | prot->rsk_prot->slab = NULL; | 2288 | prot->rsk_prot->slab = NULL; |
2277 | } | 2289 | } |
2278 | out_free_request_sock_slab_name: | 2290 | out_free_request_sock_slab_name: |
2279 | kfree(prot->rsk_prot->slab_name); | 2291 | if (prot->rsk_prot) |
2292 | kfree(prot->rsk_prot->slab_name); | ||
2280 | out_free_sock_slab: | 2293 | out_free_sock_slab: |
2281 | kmem_cache_destroy(prot->slab); | 2294 | kmem_cache_destroy(prot->slab); |
2282 | prot->slab = NULL; | 2295 | prot->slab = NULL; |