aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorDenis V. Lunev <den@openvz.org>2007-11-30 08:21:31 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 17:54:24 -0500
commitb854272b3c732316676e9128f7b9e6f1e1ff88b0 (patch)
treec90c74b9ec068453881f1173da4c57d6bb00a7d9 /net/ipv6
parentad5d20a63940fcfb40af76ba06148f36d5d0b433 (diff)
[NET]: Modify all rtnetlink methods to only work in the initial namespace (v2)
Before I can enable rtnetlink to work in all network namespaces I need to be certain that something won't break. So this patch deliberately disables all of the rtnletlink methods in everything except the initial network namespace. After the methods have been audited this extra check can be disabled. Changes from v1: - added IPv6 addrlabel protection Signed-off-by: Denis V. Lunev <den@openvz.org> Signed-off-by: Eric W. Biederman <ebiederm@xmission.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/addrconf.c31
-rw-r--r--net/ipv6/addrlabel.c12
-rw-r--r--net/ipv6/ip6_fib.c4
-rw-r--r--net/ipv6/route.c12
4 files changed, 59 insertions, 0 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index a70cecf8fc8..26de8ee5095 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -2971,11 +2971,15 @@ static const struct nla_policy ifa_ipv6_policy[IFA_MAX+1] = {
2971static int 2971static int
2972inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) 2972inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
2973{ 2973{
2974 struct net *net = skb->sk->sk_net;
2974 struct ifaddrmsg *ifm; 2975 struct ifaddrmsg *ifm;
2975 struct nlattr *tb[IFA_MAX+1]; 2976 struct nlattr *tb[IFA_MAX+1];
2976 struct in6_addr *pfx; 2977 struct in6_addr *pfx;
2977 int err; 2978 int err;
2978 2979
2980 if (net != &init_net)
2981 return -EINVAL;
2982
2979 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy); 2983 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy);
2980 if (err < 0) 2984 if (err < 0)
2981 return err; 2985 return err;
@@ -3028,6 +3032,7 @@ static int inet6_addr_modify(struct inet6_ifaddr *ifp, u8 ifa_flags,
3028static int 3032static int
3029inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) 3033inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
3030{ 3034{
3035 struct net *net = skb->sk->sk_net;
3031 struct ifaddrmsg *ifm; 3036 struct ifaddrmsg *ifm;
3032 struct nlattr *tb[IFA_MAX+1]; 3037 struct nlattr *tb[IFA_MAX+1];
3033 struct in6_addr *pfx; 3038 struct in6_addr *pfx;
@@ -3037,6 +3042,9 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
3037 u8 ifa_flags; 3042 u8 ifa_flags;
3038 int err; 3043 int err;
3039 3044
3045 if (net != &init_net)
3046 return -EINVAL;
3047
3040 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy); 3048 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy);
3041 if (err < 0) 3049 if (err < 0)
3042 return err; 3050 return err;
@@ -3310,26 +3318,42 @@ done:
3310 3318
3311static int inet6_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) 3319static int inet6_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
3312{ 3320{
3321 struct net *net = skb->sk->sk_net;
3313 enum addr_type_t type = UNICAST_ADDR; 3322 enum addr_type_t type = UNICAST_ADDR;
3323
3324 if (net != &init_net)
3325 return 0;
3326
3314 return inet6_dump_addr(skb, cb, type); 3327 return inet6_dump_addr(skb, cb, type);
3315} 3328}
3316 3329
3317static int inet6_dump_ifmcaddr(struct sk_buff *skb, struct netlink_callback *cb) 3330static int inet6_dump_ifmcaddr(struct sk_buff *skb, struct netlink_callback *cb)
3318{ 3331{
3332 struct net *net = skb->sk->sk_net;
3319 enum addr_type_t type = MULTICAST_ADDR; 3333 enum addr_type_t type = MULTICAST_ADDR;
3334
3335 if (net != &init_net)
3336 return 0;
3337
3320 return inet6_dump_addr(skb, cb, type); 3338 return inet6_dump_addr(skb, cb, type);
3321} 3339}
3322 3340
3323 3341
3324static int inet6_dump_ifacaddr(struct sk_buff *skb, struct netlink_callback *cb) 3342static int inet6_dump_ifacaddr(struct sk_buff *skb, struct netlink_callback *cb)
3325{ 3343{
3344 struct net *net = skb->sk->sk_net;
3326 enum addr_type_t type = ANYCAST_ADDR; 3345 enum addr_type_t type = ANYCAST_ADDR;
3346
3347 if (net != &init_net)
3348 return 0;
3349
3327 return inet6_dump_addr(skb, cb, type); 3350 return inet6_dump_addr(skb, cb, type);
3328} 3351}
3329 3352
3330static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr* nlh, 3353static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr* nlh,
3331 void *arg) 3354 void *arg)
3332{ 3355{
3356 struct net *net = in_skb->sk->sk_net;
3333 struct ifaddrmsg *ifm; 3357 struct ifaddrmsg *ifm;
3334 struct nlattr *tb[IFA_MAX+1]; 3358 struct nlattr *tb[IFA_MAX+1];
3335 struct in6_addr *addr = NULL; 3359 struct in6_addr *addr = NULL;
@@ -3338,6 +3362,9 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr* nlh,
3338 struct sk_buff *skb; 3362 struct sk_buff *skb;
3339 int err; 3363 int err;
3340 3364
3365 if (net != &init_net)
3366 return -EINVAL;
3367
3341 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy); 3368 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy);
3342 if (err < 0) 3369 if (err < 0)
3343 goto errout; 3370 goto errout;
@@ -3555,11 +3582,15 @@ nla_put_failure:
3555 3582
3556static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) 3583static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
3557{ 3584{
3585 struct net *net = skb->sk->sk_net;
3558 int idx, err; 3586 int idx, err;
3559 int s_idx = cb->args[0]; 3587 int s_idx = cb->args[0];
3560 struct net_device *dev; 3588 struct net_device *dev;
3561 struct inet6_dev *idev; 3589 struct inet6_dev *idev;
3562 3590
3591 if (net != &init_net)
3592 return 0;
3593
3563 read_lock(&dev_base_lock); 3594 read_lock(&dev_base_lock);
3564 idx = 0; 3595 idx = 0;
3565 for_each_netdev(&init_net, dev) { 3596 for_each_netdev(&init_net, dev) {
diff --git a/net/ipv6/addrlabel.c b/net/ipv6/addrlabel.c
index 204d4d66834..b9b5d570714 100644
--- a/net/ipv6/addrlabel.c
+++ b/net/ipv6/addrlabel.c
@@ -361,12 +361,16 @@ static const struct nla_policy ifal_policy[IFAL_MAX+1] = {
361static int ip6addrlbl_newdel(struct sk_buff *skb, struct nlmsghdr *nlh, 361static int ip6addrlbl_newdel(struct sk_buff *skb, struct nlmsghdr *nlh,
362 void *arg) 362 void *arg)
363{ 363{
364 struct net *net = skb->sk->sk_net;
364 struct ifaddrlblmsg *ifal; 365 struct ifaddrlblmsg *ifal;
365 struct nlattr *tb[IFAL_MAX+1]; 366 struct nlattr *tb[IFAL_MAX+1];
366 struct in6_addr *pfx; 367 struct in6_addr *pfx;
367 u32 label; 368 u32 label;
368 int err = 0; 369 int err = 0;
369 370
371 if (net != &init_net)
372 return 0;
373
370 err = nlmsg_parse(nlh, sizeof(*ifal), tb, IFAL_MAX, ifal_policy); 374 err = nlmsg_parse(nlh, sizeof(*ifal), tb, IFAL_MAX, ifal_policy);
371 if (err < 0) 375 if (err < 0)
372 return err; 376 return err;
@@ -445,11 +449,15 @@ static int ip6addrlbl_fill(struct sk_buff *skb,
445 449
446static int ip6addrlbl_dump(struct sk_buff *skb, struct netlink_callback *cb) 450static int ip6addrlbl_dump(struct sk_buff *skb, struct netlink_callback *cb)
447{ 451{
452 struct net *net = skb->sk->sk_net;
448 struct ip6addrlbl_entry *p; 453 struct ip6addrlbl_entry *p;
449 struct hlist_node *pos; 454 struct hlist_node *pos;
450 int idx = 0, s_idx = cb->args[0]; 455 int idx = 0, s_idx = cb->args[0];
451 int err; 456 int err;
452 457
458 if (net != &init_net)
459 return 0;
460
453 rcu_read_lock(); 461 rcu_read_lock();
454 hlist_for_each_entry_rcu(p, pos, &ip6addrlbl_table.head, list) { 462 hlist_for_each_entry_rcu(p, pos, &ip6addrlbl_table.head, list) {
455 if (idx >= s_idx) { 463 if (idx >= s_idx) {
@@ -479,6 +487,7 @@ static inline int ip6addrlbl_msgsize(void)
479static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr* nlh, 487static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr* nlh,
480 void *arg) 488 void *arg)
481{ 489{
490 struct net *net = in_skb->sk->sk_net;
482 struct ifaddrlblmsg *ifal; 491 struct ifaddrlblmsg *ifal;
483 struct nlattr *tb[IFAL_MAX+1]; 492 struct nlattr *tb[IFAL_MAX+1];
484 struct in6_addr *addr; 493 struct in6_addr *addr;
@@ -487,6 +496,9 @@ static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr* nlh,
487 struct ip6addrlbl_entry *p; 496 struct ip6addrlbl_entry *p;
488 struct sk_buff *skb; 497 struct sk_buff *skb;
489 498
499 if (net != &init_net)
500 return 0;
501
490 err = nlmsg_parse(nlh, sizeof(*ifal), tb, IFAL_MAX, ifal_policy); 502 err = nlmsg_parse(nlh, sizeof(*ifal), tb, IFAL_MAX, ifal_policy);
491 if (err < 0) 503 if (err < 0)
492 return err; 504 return err;
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 946cf389ab9..31b60a02512 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -361,6 +361,7 @@ end:
361 361
362static int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb) 362static int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
363{ 363{
364 struct net *net = skb->sk->sk_net;
364 unsigned int h, s_h; 365 unsigned int h, s_h;
365 unsigned int e = 0, s_e; 366 unsigned int e = 0, s_e;
366 struct rt6_rtnl_dump_arg arg; 367 struct rt6_rtnl_dump_arg arg;
@@ -369,6 +370,9 @@ static int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
369 struct hlist_node *node; 370 struct hlist_node *node;
370 int res = 0; 371 int res = 0;
371 372
373 if (net != &init_net)
374 return 0;
375
372 s_h = cb->args[0]; 376 s_h = cb->args[0];
373 s_e = cb->args[1]; 377 s_e = cb->args[1];
374 378
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 4ef2cfaa346..5e1c5796761 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -2003,9 +2003,13 @@ errout:
2003 2003
2004static int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) 2004static int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
2005{ 2005{
2006 struct net *net = skb->sk->sk_net;
2006 struct fib6_config cfg; 2007 struct fib6_config cfg;
2007 int err; 2008 int err;
2008 2009
2010 if (net != &init_net)
2011 return -EINVAL;
2012
2009 err = rtm_to_fib6_config(skb, nlh, &cfg); 2013 err = rtm_to_fib6_config(skb, nlh, &cfg);
2010 if (err < 0) 2014 if (err < 0)
2011 return err; 2015 return err;
@@ -2015,9 +2019,13 @@ static int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *a
2015 2019
2016static int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) 2020static int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
2017{ 2021{
2022 struct net *net = skb->sk->sk_net;
2018 struct fib6_config cfg; 2023 struct fib6_config cfg;
2019 int err; 2024 int err;
2020 2025
2026 if (net != &init_net)
2027 return -EINVAL;
2028
2021 err = rtm_to_fib6_config(skb, nlh, &cfg); 2029 err = rtm_to_fib6_config(skb, nlh, &cfg);
2022 if (err < 0) 2030 if (err < 0)
2023 return err; 2031 return err;
@@ -2152,6 +2160,7 @@ int rt6_dump_route(struct rt6_info *rt, void *p_arg)
2152 2160
2153static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg) 2161static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg)
2154{ 2162{
2163 struct net *net = in_skb->sk->sk_net;
2155 struct nlattr *tb[RTA_MAX+1]; 2164 struct nlattr *tb[RTA_MAX+1];
2156 struct rt6_info *rt; 2165 struct rt6_info *rt;
2157 struct sk_buff *skb; 2166 struct sk_buff *skb;
@@ -2159,6 +2168,9 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
2159 struct flowi fl; 2168 struct flowi fl;
2160 int err, iif = 0; 2169 int err, iif = 0;
2161 2170
2171 if (net != &init_net)
2172 return -EINVAL;
2173
2162 err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_ipv6_policy); 2174 err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_ipv6_policy);
2163 if (err < 0) 2175 if (err < 0)
2164 goto errout; 2176 goto errout;