Linux Archive

Linux Archive (http://www.linux-archive.org/)
-   Ubuntu Kernel Team (http://www.linux-archive.org/ubuntu-kernel-team/)
-   -   net: don't allow CAP_NET_ADMIN to load non-netdev kernel modules CVE-2011-1019 (http://www.linux-archive.org/ubuntu-kernel-team/547905-net-dont-allow-cap_net_admin-load-non-netdev-kernel-modules-cve-2011-1019-a.html)

07-04-2011 10:08 AM

net: don't allow CAP_NET_ADMIN to load non-netdev kernel modules CVE-2011-1019
 
From: Vasiliy Kulikov <segoon@openwall.com>

BugLink: http://bugs.launchpad.net/bugs/804366

commit 8909c9ad8ff03611c9c96c9a92656213e4bb495b upstream.

Since a8f80e8ff94ecba629542d9b4b5f5a8ee3eb565c any process with
CAP_NET_ADMIN may load any module from /lib/modules/. This doesn't mean
that CAP_NET_ADMIN is a superset of CAP_SYS_MODULE as modules are
limited to /lib/modules/**. However, CAP_NET_ADMIN capability shouldn't
allow anybody load any module not related to networking.

This patch restricts an ability of autoloading modules to netdev modules
with explicit aliases. This fixes CVE-2011-1019.

Arnd Bergmann suggested to leave untouched the old pre-v2.6.32 behavior
of loading netdev modules by name (without any prefix) for processes
with CAP_SYS_MODULE to maintain the compatibility with network scripts
that use autoloading netdev modules by aliases like "eth0", "wlan0".

Currently there are only three users of the feature in the upstream
kernel: ipip, ip_gre and sit.

root@albatros:~# capsh --drop=$(seq -s, 0 11),$(seq -s, 13 34) --
root@albatros:~# grep Cap /proc/$$/status
CapInh: 0000000000000000
CapPrm: fffffff800001000
CapEff: fffffff800001000
CapBnd: fffffff800001000
root@albatros:~# modprobe xfs
FATAL: Error inserting xfs
(/lib/modules/2.6.38-rc6-00001-g2bf4ca3/kernel/fs/xfs/xfs.ko): Operation not permitted
root@albatros:~# lsmod | grep xfs
root@albatros:~# ifconfig xfs
xfs: error fetching interface information: Device not found
root@albatros:~# lsmod | grep xfs
root@albatros:~# lsmod | grep sit
root@albatros:~# ifconfig sit
sit: error fetching interface information: Device not found
root@albatros:~# lsmod | grep sit
root@albatros:~# ifconfig sit0
sit0 Link encap:IPv6-in-IPv4
NOARP MTU:1480 Metric:1

root@albatros:~# lsmod | grep sit
sit 10457 0
tunnel4 2957 1 sit

For CAP_SYS_MODULE module loading is still relaxed:

root@albatros:~# grep Cap /proc/$$/status
CapInh: 0000000000000000
CapPrm: ffffffffffffffff
CapEff: ffffffffffffffff
CapBnd: ffffffffffffffff
root@albatros:~# ifconfig xfs
xfs: error fetching interface information: Device not found
root@albatros:~# lsmod | grep xfs
xfs 745319 0

Reference: https://lkml.org/lkml/2011/2/24/203

CVE-2011-1019

Signed-off-by: Vasiliy Kulikov <segoon@openwall.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Acked-by: David S. Miller <davem@davemloft.net>
Acked-by: Kees Cook <kees.cook@canonical.com>
Signed-off-by: James Morris <jmorris@namei.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Signed-off-by: Andi Kleen <ak@linux.intel.com>
Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
Signed-off-by: Paolo Pisati <paolo.pisati@canonical.com>
---
include/linux/netdevice.h | 4 ++++
net/core/dev.c | 13 ++++++++++---
net/ipv4/ip_gre.c | 1 +
net/ipv4/ipip.c | 1 +
net/ipv6/sit.c | 2 +-
5 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 142bf18..e857c94 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -2344,6 +2344,10 @@ do {
})
#endif

+#define MODULE_ALIAS_NETDEV(device)
+ MODULE_ALIAS("netdev-" device)
+
+
#endif /* __KERNEL__ */

#endif /* _LINUX_NETDEVICE_H */
diff --git a/net/core/dev.c b/net/core/dev.c
index 4c8f36d..d11a74d 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1121,13 +1121,20 @@ EXPORT_SYMBOL(netdev_bonding_change);
void dev_load(struct net *net, const char *name)
{
struct net_device *dev;
+ int no_module;

rcu_read_lock();
dev = dev_get_by_name_rcu(net, name);
rcu_read_unlock();
-
- if (!dev && capable(CAP_NET_ADMIN))
- request_module("%s", name);
+ 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
", name);
+ }
}
EXPORT_SYMBOL(dev_load);

diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 32618e1..cd527c4 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -1701,3 +1701,4 @@ module_exit(ipgre_fini);
MODULE_LICENSE("GPL");
MODULE_ALIAS_RTNL_LINK("gre");
MODULE_ALIAS_RTNL_LINK("gretap");
+MODULE_ALIAS_NETDEV("gre0");
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index 7fd6367..5d8e362 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -850,3 +850,4 @@ static void __exit ipip_fini(void)
module_init(ipip_init);
module_exit(ipip_fini);
MODULE_LICENSE("GPL");
+MODULE_ALIAS_NETDEV("tunl0");
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index e51e650..2020bea 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -1239,4 +1239,4 @@ static int __init sit_init(void)
module_init(sit_init);
module_exit(sit_cleanup);
MODULE_LICENSE("GPL");
-MODULE_ALIAS("sit0");
+MODULE_ALIAS_NETDEV("sit0");
--
1.7.4.1


--
kernel-team mailing list
kernel-team@lists.ubuntu.com
https://lists.ubuntu.com/mailman/listinfo/kernel-team


All times are GMT. The time now is 07:40 AM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.