aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/inet_hashtables.c
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@linux-foundation.org>2007-10-10 20:30:46 -0400
committerDavid S. Miller <davem@davemloft.net>2007-10-10 20:30:46 -0400
commit227b60f5102cda4e4ab792b526a59c8cb20cd9f8 (patch)
tree2c9e372601ba794894833b0618bc531a9f5d57c4 /net/ipv4/inet_hashtables.c
parent06393009000779b00a558fd2f280882cc7dc2008 (diff)
[INET]: local port range robustness
Expansion of original idea from Denis V. Lunev <den@openvz.org> Add robustness and locking to the local_port_range sysctl. 1. Enforce that low < high when setting. 2. Use seqlock to ensure atomic update. The locking might seem like overkill, but there are cases where sysadmin might want to change value in the middle of a DoS attack. Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/inet_hashtables.c')
-rw-r--r--net/ipv4/inet_hashtables.c13
1 files changed, 6 insertions, 7 deletions
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
index fb662621c54..fac6398e436 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -279,19 +279,18 @@ int inet_hash_connect(struct inet_timewait_death_row *death_row,
279 int ret; 279 int ret;
280 280
281 if (!snum) { 281 if (!snum) {
282 int low = sysctl_local_port_range[0]; 282 int i, remaining, low, high, port;
283 int high = sysctl_local_port_range[1];
284 int range = high - low;
285 int i;
286 int port;
287 static u32 hint; 283 static u32 hint;
288 u32 offset = hint + inet_sk_port_offset(sk); 284 u32 offset = hint + inet_sk_port_offset(sk);
289 struct hlist_node *node; 285 struct hlist_node *node;
290 struct inet_timewait_sock *tw = NULL; 286 struct inet_timewait_sock *tw = NULL;
291 287
288 inet_get_local_port_range(&low, &high);
289 remaining = high - low;
290
292 local_bh_disable(); 291 local_bh_disable();
293 for (i = 1; i <= range; i++) { 292 for (i = 1; i <= remaining; i++) {
294 port = low + (i + offset) % range; 293 port = low + (i + offset) % remaining;
295 head = &hinfo->bhash[inet_bhashfn(port, hinfo->bhash_size)]; 294 head = &hinfo->bhash[inet_bhashfn(port, hinfo->bhash_size)];
296 spin_lock(&head->lock); 295 spin_lock(&head->lock);
297 296