projects
/
deliverable
/
linux.git
/ commitdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
| commitdiff |
tree
raw
|
patch
|
inline
| side by side (parent:
b7b5f48
)
[UDP]: Do not allow specific bind when wildcard bind exists.
author
David S. Miller
<davem@sunset.davemloft.net>
Mon, 30 Apr 2007 21:51:58 +0000
(14:51 -0700)
committer
David S. Miller
<davem@sunset.davemloft.net>
Mon, 30 Apr 2007 21:51:58 +0000
(14:51 -0700)
When allocating local ports, do not allow a bind to a port
with a specific local address when a bind to that port with
a wildcard local address already exists.
Noticed by Linus.
Signed-off-by: David S. Miller <davem@davemloft.net>
net/ipv4/udp.c
patch
|
blob
|
blame
|
history
diff --git
a/net/ipv4/udp.c
b/net/ipv4/udp.c
index db313d96488489de2e8c0d2100176e0ab893e171..113e0c4c8a928157d51f17abcd47804106ebdeca 100644
(file)
--- a/
net/ipv4/udp.c
+++ b/
net/ipv4/udp.c
@@
-203,6
+203,13
@@
int __udp_lib_get_port(struct sock *sk, unsigned short snum,
result = sysctl_local_port_range[0]
+ ((result - sysctl_local_port_range[0]) &
(UDP_HTABLE_SIZE - 1));
result = sysctl_local_port_range[0]
+ ((result - sysctl_local_port_range[0]) &
(UDP_HTABLE_SIZE - 1));
+ hash = hash_port_and_addr(result, 0);
+ if (__udp_lib_port_inuse(hash, result,
+ 0, udptable))
+ continue;
+ if (!inet_sk(sk)->rcv_saddr)
+ break;
+
hash = hash_port_and_addr(result,
inet_sk(sk)->rcv_saddr);
if (! __udp_lib_port_inuse(hash, result,
hash = hash_port_and_addr(result,
inet_sk(sk)->rcv_saddr);
if (! __udp_lib_port_inuse(hash, result,
@@
-214,18
+221,36
@@
int __udp_lib_get_port(struct sock *sk, unsigned short snum,
gotit:
*port_rover = snum = result;
} else {
gotit:
*port_rover = snum = result;
} else {
- hash = hash_port_and_addr(snum,
inet_sk(sk)->rcv_saddr
);
+ hash = hash_port_and_addr(snum,
0
);
head = &udptable[hash & (UDP_HTABLE_SIZE - 1)];
sk_for_each(sk2, node, head)
head = &udptable[hash & (UDP_HTABLE_SIZE - 1)];
sk_for_each(sk2, node, head)
- if (sk2->sk_hash == hash
&&
- sk2 != sk
&&
- inet_sk(sk2)->num == snum
&&
- (!sk2->sk_reuse
|| !sk->sk_reuse)
&&
- (!sk2->sk_bound_dev_if || !sk->sk_bound_dev_if
-
||
sk2->sk_bound_dev_if == sk->sk_bound_dev_if) &&
- (*saddr_comp)(sk, sk2)
)
+ if (sk2->sk_hash == hash &&
+ sk2 != sk &&
+ inet_sk(sk2)->num == snum &&
+ (!sk2->sk_reuse
|| !sk->sk_reuse)
&&
+ (!sk2->sk_bound_dev_if || !sk->sk_bound_dev_if
||
+ sk2->sk_bound_dev_if == sk->sk_bound_dev_if) &&
+ (*saddr_comp)(sk, sk2))
goto fail;
goto fail;
+
+ if (inet_sk(sk)->rcv_saddr) {
+ hash = hash_port_and_addr(snum,
+ inet_sk(sk)->rcv_saddr);
+ head = &udptable[hash & (UDP_HTABLE_SIZE - 1)];
+
+ sk_for_each(sk2, node, head)
+ if (sk2->sk_hash == hash &&
+ sk2 != sk &&
+ inet_sk(sk2)->num == snum &&
+ (!sk2->sk_reuse || !sk->sk_reuse) &&
+ (!sk2->sk_bound_dev_if ||
+ !sk->sk_bound_dev_if ||
+ sk2->sk_bound_dev_if ==
+ sk->sk_bound_dev_if) &&
+ (*saddr_comp)(sk, sk2))
+ goto fail;
+ }
}
inet_sk(sk)->num = snum;
sk->sk_hash = hash;
}
inet_sk(sk)->num = snum;
sk->sk_hash = hash;
This page took
0.028103 seconds
and
5
git commands to generate.