diff options
author | Pablo Neira <pablo@netfilter.org> | 2015-01-29 10:51:53 +0100 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-01-30 17:43:47 -0800 |
commit | 8b7c36d810c61ab16997f4387fc16291410700f8 (patch) | |
tree | f8279a3912807e9cc53eea82eef57bd8b8c4375a /net/netlink/af_netlink.c | |
parent | 3cdaa5be9e81a914e633a6be7b7d2ef75b528562 (diff) | |
download | linux-8b7c36d810c61ab16997f4387fc16291410700f8.tar.gz linux-8b7c36d810c61ab16997f4387fc16291410700f8.tar.bz2 linux-8b7c36d810c61ab16997f4387fc16291410700f8.zip |
netlink: fix wrong subscription bitmask to group mapping in
The subscription bitmask passed via struct sockaddr_nl is converted to
the group number when calling the netlink_bind() and netlink_unbind()
callbacks.
The conversion is however incorrect since bitmask (1 << 0) needs to be
mapped to group number 1. Note that you cannot specify the group number 0
(usually known as _NONE) from setsockopt() using NETLINK_ADD_MEMBERSHIP
since this is rejected through -EINVAL.
This problem became noticeable since 97840cb ("netfilter: nfnetlink:
fix insufficient validation in nfnetlink_bind") when binding to bitmask
(1 << 0) in ctnetlink.
Reported-by: Andre Tomt <andre@tomt.net>
Reported-by: Ivan Delalande <colona@arista.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/netlink/af_netlink.c')
-rw-r--r-- | net/netlink/af_netlink.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 02fdde28dada..75532efa51cd 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -1438,7 +1438,7 @@ static void netlink_undo_bind(int group, long unsigned int groups, for (undo = 0; undo < group; undo++) if (test_bit(undo, &groups)) - nlk->netlink_unbind(sock_net(sk), undo); + nlk->netlink_unbind(sock_net(sk), undo + 1); } static int netlink_bind(struct socket *sock, struct sockaddr *addr, @@ -1476,7 +1476,7 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr, for (group = 0; group < nlk->ngroups; group++) { if (!test_bit(group, &groups)) continue; - err = nlk->netlink_bind(net, group); + err = nlk->netlink_bind(net, group + 1); if (!err) continue; netlink_undo_bind(group, groups, sk); |