Capabilities for loading network modules
Linux capabilities are still a work in progress. They have been in the kernel for a long time—since the 2.1 days in 1998—but for various reasons, it has taken more than a decade for distributions to really start using the feature. While capabilities ostensibly provide a way to give limited privileges to processes, rather than the all-or-none setuid model, the feature has been beset with incompleteness, limitations, complexity concerns, and other problems. Now that Fedora, Openwall, and other distributions are working on actually using capabilities to reduce the privileges extended to system binaries we are seeing some of those problems shake out.
A patch that was merged for 2.6.32 is one such example. The idea behind it was that the CAP_NET_ADMIN capability should be enough to allow loading network modules, rather than requiring CAP_SYS_MODULE. The CAP_SYS_MODULE capability allows loading modules from anywhere, rather than restricting the module search path to /lib/modules/.... So, by switching to use CAP_NET_ADMIN, network utilities, like ifconfig, could be restricted to only load system modules, rather than arbitrary code.
There is one problem with that scheme, though, as Vasiliy Kulikov pointed out, because it allows processes with CAP_NET_ADMIN to load any module from /lib/modules, not just those that are networking related. Or, as he puts it:
root@albatros:~# grep Cap /proc/$$/status CapInh: 0000000000000000 CapPrm: fffffffc00001000 CapEff: fffffffc00001000 CapBnd: fffffffc00001000 root@albatros:~# lsmod | grep xfs root@albatros:~# ifconfig xfs xfs: error fetching interface information: Device not found root@albatros:~# lsmod | grep xfs xfs 767011 0 exportfs 4226 2 xfs,nfsd
That example deserves a bit of explanation. The first command establishes that the capabilities of the shell are just CAP_NET_ADMIN (capability number 12 of the 34 currently defined capabilities). Kulikov then goes on to show that the xfs module is not loaded until he loads it via ifconfig. That is clearly not the expected behavior. In fact it is now CVE-2011-1019 (which is just reserved at the time of this writing). For those that want to try this out at home, Kulikov gives the proper incantation in his v2 patch:
# capsh --drop=$(seq -s, 0 11),$(seq -s, 13 34) --
Note that on not-quite-bleeding-edge kernels (e.g. Fedora 14's kernel), the 34 should be changed to 33 to account for the lack of a CAP_SYSLOG, which was just recently added. Running that command will give you a shell with just CAP_NET_ADMIN.
Kulikov's first patch proposal simply changed the request_module() call in the core networking dev_load() function to only load modules that start with "netdev-", with udev expected to set up the appropriate aliases. There are three modules that already have aliases (ip_gre.c, ipip.c, and sit.c) in the code, so the patch changes those to prefix "netdev-". But David Miller was not happy with changing those names, as it will break existing code.
There was also a bit of a digression regarding attackers recompiling modules with a "netdev-" alias, but unless that attacker can install the code in /lib/modules, it isn't a real problem. In this case, the threat model is a subverted binary that has CAP_NET_ADMIN, which is not a capability that would allow it to write to /lib/modules. But Miller's complaint is more substantial, as anything that used to do "ifconfig sit0", for example, will no longer work.
After some discussion of various ways to handle that problem, Arnd Bergmann noted that the backward compatibility problem is only for systems that are not splitting up capabilities (i.e. they just use root or setuid with the full capability set). For those, the CAP_SYS_MODULE capability can be required, while the programs that only have CAP_NET_ADMIN will be new, and thus can use the new "netdev-" names. The code will look something like:
no_module = !dev; if (no_module && capable(CAP_NET_ADMIN)) no_module = request_module("netdev-%s", name); if (no_module && capable(CAP_SYS_MODULE)) { if (!request_module("%s", name)) pr_err("Loading kernel module for a network device " "with CAP_SYS_MODULE (deprecated). Use CAP_NET_ADMIN and alias netdev-%s " "instead\n", name);
That solution seemed to be acceptable to Miller and others, so we may well see it in the mainline soon. One thing to note, though, is that capabilities are part of the kernel ABI, so changes to their behavior will be difficult to sell, in general. This change is fixing a security problem—and is hopefully not a behavior that any user-space application is relying on—so it is likely to find a reasonably smooth path into the kernel. Other changes that come up as more systems start to actually use the various capability bits may be more difficult to do, though we have already seen some problems with the current definitions of various capabilities.
Index entries for this article | |
---|---|
Kernel | Capabilities |
Kernel | Security/Security technologies |
Security | Linux kernel/Linux/POSIX capabilities |
Posted Mar 3, 2011 5:39 UTC (Thu)
by josh (subscriber, #17465)
[Link] (1 responses)
Posted Mar 10, 2011 10:33 UTC (Thu)
by segoon (guest, #61133)
[Link]
Posted Mar 4, 2011 10:38 UTC (Fri)
by rvfh (guest, #31018)
[Link] (1 responses)
Posted Mar 4, 2011 19:16 UTC (Fri)
by misiu_mp (guest, #41936)
[Link]
Posted Mar 4, 2011 15:34 UTC (Fri)
by jeremiah (subscriber, #1221)
[Link]
Posted Mar 5, 2011 15:51 UTC (Sat)
by BenHutchings (subscriber, #37955)
[Link] (2 responses)
That's not the problem - the networking core and these modules will be changed at the same time to use the 'netdev-' prefix. The problem is with module aliases which some distributions (and individual sysadmins) configured as a way of auto-loading net drivers before the introduction of udev, and which they may still rely on some cases. These of course will not have the 'netdev-' prefix.
Posted Mar 5, 2011 16:17 UTC (Sat)
by jake (editor, #205)
[Link] (1 responses)
> That's not the problem - the networking core and these modules will be
That line from the article was referring to David's complaint about the original patch (which would have removed the 'sit0' alias without providing any backward compatibility). The way forward suggested by Arnd takes care of that problem, if I am following along correctly (which is sometimes in question, see the thread :) -- or am I still confused?
jake
Posted Mar 5, 2011 17:00 UTC (Sat)
by BenHutchings (subscriber, #37955)
[Link]
Posted Mar 7, 2011 22:28 UTC (Mon)
by rwmj (subscriber, #5474)
[Link] (2 responses)
Posted Mar 7, 2011 23:02 UTC (Mon)
by jake (editor, #205)
[Link] (1 responses)
No, the idea is that there may be kernel modules with vulnerabilities that aren't normally loaded, which might make an admin somewhat lax about updating them. If an attacker can load arbitrary modules (even just those in the approved /lib/modules location), it increases the attack surface of the running kernel.
jake
Posted Mar 8, 2011 7:38 UTC (Tue)
by rwmj (subscriber, #5474)
[Link]
Capabilities for loading network modules
Capabilities for loading network modules
Capabilities for loading network modules
Capabilities for loading network modules
Capabilities for loading network modules
Capabilities for loading network modules
But Miller's complaint is more substantial, as anything that used to do "ifconfig sit0", for example, will no longer work.
Capabilities for loading network modules
> > "ifconfig sit0", for example, will no longer work.
> changed at the same time to use the 'netdev-' prefix. The problem is with
> module aliases which some distributions (and individual sysadmins)
> configured as a way of auto-loading net drivers before the introduction of
> udev, and which they may still rely on some cases. These of course will
> not have the 'netdev-' prefix.
Capabilities for loading network modules
No-one proposed removing those static aliases. The first actual patch was posted after I made a (hopefully comprehensive) list of the static aliases, and it updated all those aliases.
That line from the article was referring to David's complaint about the original patch (which would have removed the 'sit0' alias without providing any backward compatibility). The way forward suggested by Arnd takes care of that problem, if I am following along correctly (which is sometimes in question, see the thread :) -- or am I still confused?
But Miller's complaint is more substantial, as anything that used to do
"ifconfig sit0", for example, will no longer work.
That's not the problem - the networking core and these modules will be
changed at the same time to use the 'netdev-' prefix. The problem is with
module aliases which some distributions (and individual sysadmins)
configured as a way of auto-loading net drivers before the introduction of
udev, and which they may still rely on some cases. These of course will
not have the 'netdev-' prefix.
Capabilities for loading network modules
Capabilities for loading network modules
> loading random modules?
Capabilities for loading network modules