[NETNS]: Double free in netlink_release.
Netlink protocol table is global for all namespaces. Some netlink protocols have been virtualized, i.e. they have per/namespace netlink socket. This difference can easily lead to double free if more than 1 namespace is started. Count the number of kernel netlink sockets to track that this table is not used any more. Signed-off-by: Denis V. Lunev <den@openvz.org> Tested-by: Alexey Dobriyan <adobriyan@openvz.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
7d460db953
commit
869e58f870
1 changed files with 7 additions and 3 deletions
|
@ -498,9 +498,12 @@ static int netlink_release(struct socket *sock)
|
||||||
|
|
||||||
netlink_table_grab();
|
netlink_table_grab();
|
||||||
if (netlink_is_kernel(sk)) {
|
if (netlink_is_kernel(sk)) {
|
||||||
kfree(nl_table[sk->sk_protocol].listeners);
|
BUG_ON(nl_table[sk->sk_protocol].registered == 0);
|
||||||
nl_table[sk->sk_protocol].module = NULL;
|
if (--nl_table[sk->sk_protocol].registered == 0) {
|
||||||
nl_table[sk->sk_protocol].registered = 0;
|
kfree(nl_table[sk->sk_protocol].listeners);
|
||||||
|
nl_table[sk->sk_protocol].module = NULL;
|
||||||
|
nl_table[sk->sk_protocol].registered = 0;
|
||||||
|
}
|
||||||
} else if (nlk->subscriptions)
|
} else if (nlk->subscriptions)
|
||||||
netlink_update_listeners(sk);
|
netlink_update_listeners(sk);
|
||||||
netlink_table_ungrab();
|
netlink_table_ungrab();
|
||||||
|
@ -1389,6 +1392,7 @@ netlink_kernel_create(struct net *net, int unit, unsigned int groups,
|
||||||
nl_table[unit].registered = 1;
|
nl_table[unit].registered = 1;
|
||||||
} else {
|
} else {
|
||||||
kfree(listeners);
|
kfree(listeners);
|
||||||
|
nl_table[unit].registered++;
|
||||||
}
|
}
|
||||||
netlink_table_ungrab();
|
netlink_table_ungrab();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue