ipv6: do not clear pinet6 field
We have seen multiple NULL dereferences in __inet6_lookup_established()
After analysis, I found that inet6_sk() could be NULL while the
check for sk_family == AF_INET6 was true.
Bug was added in linux-2.6.29 when RCU lookups were introduced in UDP
and TCP stacks.
Once an IPv6 socket, using SLAB_DESTROY_BY_RCU is inserted in a hash
table, we no longer can clear pinet6 field.
This patch extends logic used in commit fcbdf09d96
("net: fix nulls list corruptions in sk_prot_alloc")
TCP/UDP/UDPLite IPv6 protocols provide their own .clear_sk() method
to make sure we do not clear pinet6 field.
At socket clone phase, we do not really care, as cloning the parent (non
NULL) pinet6 is not adding a fatal race.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
233c7df082
commit
f77d602124
6 changed files with 39 additions and 14 deletions
|
@ -866,6 +866,18 @@ struct inet_hashinfo;
|
|||
struct raw_hashinfo;
|
||||
struct module;
|
||||
|
||||
/*
|
||||
* caches using SLAB_DESTROY_BY_RCU should let .next pointer from nulls nodes
|
||||
* un-modified. Special care is taken when initializing object to zero.
|
||||
*/
|
||||
static inline void sk_prot_clear_nulls(struct sock *sk, int size)
|
||||
{
|
||||
if (offsetof(struct sock, sk_node.next) != 0)
|
||||
memset(sk, 0, offsetof(struct sock, sk_node.next));
|
||||
memset(&sk->sk_node.pprev, 0,
|
||||
size - offsetof(struct sock, sk_node.pprev));
|
||||
}
|
||||
|
||||
/* Networking protocol blocks we attach to sockets.
|
||||
* socket layer -> transport layer interface
|
||||
* transport -> network interface is defined by struct inet_proto
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue