Commit 5ad63005 authored by Johannes Berg's avatar Johannes Berg Committed by David S. Miller

genetlink: disallow subscribing to unknown mcast groups

Jeff Layton reported that he could trigger the multicast unbind warning
in generic netlink using trinity. I originally thought it was a race
condition between unregistering the generic netlink family and closing
the socket, but there's a far simpler explanation: genetlink currently
allows subscribing to groups that don't (yet) exist, and the warning is
triggered when unsubscribing again while the group still doesn't exist.

Originally, I had a warning in the subscribe case and accepted it out of
userspace API concerns, but the warning was of course wrong and removed
later.

However, I now think that allowing userspace to subscribe to groups that
don't exist is wrong and could possibly become a security problem:
Consider a (new) genetlink family implementing a permission check in
the mcast_bind() function similar to the like the audit code does today;
it would be possible to bypass the permission check by guessing the ID
and subscribing to the group it exists. This is only possible in case a
family like that would be dynamically loaded, but it doesn't seem like a
huge stretch, for example wireless may be loaded when you plug in a USB
device.

To avoid this reject such subscription attempts.

If this ends up causing userspace issues we may need to add a workaround
in af_netlink to deny such requests but not return an error.
Reported-by: default avatarJeff Layton <jeff.layton@primarydata.com>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f555f3d7
...@@ -985,7 +985,7 @@ static struct genl_multicast_group genl_ctrl_groups[] = { ...@@ -985,7 +985,7 @@ static struct genl_multicast_group genl_ctrl_groups[] = {
static int genl_bind(struct net *net, int group) static int genl_bind(struct net *net, int group)
{ {
int i, err = 0; int i, err = -ENOENT;
down_read(&cb_lock); down_read(&cb_lock);
for (i = 0; i < GENL_FAM_TAB_SIZE; i++) { for (i = 0; i < GENL_FAM_TAB_SIZE; i++) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment