aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched
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/sched
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/sched')
-rw-r--r--net/sched/act_api.c10
-rw-r--r--net/sched/cls_api.c10
-rw-r--r--net/sched/sch_api.c21
3 files changed, 41 insertions, 0 deletions
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 72cdb0fade20..852829139c67 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -18,6 +18,8 @@
18#include <linux/skbuff.h> 18#include <linux/skbuff.h>
19#include <linux/init.h> 19#include <linux/init.h>
20#include <linux/kmod.h> 20#include <linux/kmod.h>
21#include <net/net_namespace.h>
22#include <net/sock.h>
21#include <net/sch_generic.h> 23#include <net/sch_generic.h>
22#include <net/act_api.h> 24#include <net/act_api.h>
23#include <net/netlink.h> 25#include <net/netlink.h>
@@ -924,10 +926,14 @@ done:
924 926
925static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n, void *arg) 927static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
926{ 928{
929 struct net *net = skb->sk->sk_net;
927 struct rtattr **tca = arg; 930 struct rtattr **tca = arg;
928 u32 pid = skb ? NETLINK_CB(skb).pid : 0; 931 u32 pid = skb ? NETLINK_CB(skb).pid : 0;
929 int ret = 0, ovr = 0; 932 int ret = 0, ovr = 0;
930 933
934 if (net != &init_net)
935 return -EINVAL;
936
931 if (tca[TCA_ACT_TAB-1] == NULL) { 937 if (tca[TCA_ACT_TAB-1] == NULL) {
932 printk("tc_ctl_action: received NO action attribs\n"); 938 printk("tc_ctl_action: received NO action attribs\n");
933 return -EINVAL; 939 return -EINVAL;
@@ -997,6 +1003,7 @@ find_dump_kind(struct nlmsghdr *n)
997static int 1003static int
998tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb) 1004tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
999{ 1005{
1006 struct net *net = skb->sk->sk_net;
1000 struct nlmsghdr *nlh; 1007 struct nlmsghdr *nlh;
1001 unsigned char *b = skb_tail_pointer(skb); 1008 unsigned char *b = skb_tail_pointer(skb);
1002 struct rtattr *x; 1009 struct rtattr *x;
@@ -1006,6 +1013,9 @@ tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
1006 struct tcamsg *t = (struct tcamsg *) NLMSG_DATA(cb->nlh); 1013 struct tcamsg *t = (struct tcamsg *) NLMSG_DATA(cb->nlh);
1007 struct rtattr *kind = find_dump_kind(cb->nlh); 1014 struct rtattr *kind = find_dump_kind(cb->nlh);
1008 1015
1016 if (net != &init_net)
1017 return 0;
1018
1009 if (kind == NULL) { 1019 if (kind == NULL) {
1010 printk("tc_dump_action: action bad kind\n"); 1020 printk("tc_dump_action: action bad kind\n");
1011 return 0; 1021 return 0;
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index bb98045d5508..fdab6a530bba 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -23,6 +23,8 @@
23#include <linux/init.h> 23#include <linux/init.h>
24#include <linux/kmod.h> 24#include <linux/kmod.h>
25#include <linux/netlink.h> 25#include <linux/netlink.h>
26#include <net/net_namespace.h>
27#include <net/sock.h>
26#include <net/netlink.h> 28#include <net/netlink.h>
27#include <net/pkt_sched.h> 29#include <net/pkt_sched.h>
28#include <net/pkt_cls.h> 30#include <net/pkt_cls.h>
@@ -119,6 +121,7 @@ static __inline__ u32 tcf_auto_prio(struct tcf_proto *tp)
119 121
120static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg) 122static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
121{ 123{
124 struct net *net = skb->sk->sk_net;
122 struct rtattr **tca; 125 struct rtattr **tca;
123 struct tcmsg *t; 126 struct tcmsg *t;
124 u32 protocol; 127 u32 protocol;
@@ -135,6 +138,9 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
135 unsigned long fh; 138 unsigned long fh;
136 int err; 139 int err;
137 140
141 if (net != &init_net)
142 return -EINVAL;
143
138replay: 144replay:
139 tca = arg; 145 tca = arg;
140 t = NLMSG_DATA(n); 146 t = NLMSG_DATA(n);
@@ -375,6 +381,7 @@ static int tcf_node_dump(struct tcf_proto *tp, unsigned long n, struct tcf_walke
375 381
376static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb) 382static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb)
377{ 383{
384 struct net *net = skb->sk->sk_net;
378 int t; 385 int t;
379 int s_t; 386 int s_t;
380 struct net_device *dev; 387 struct net_device *dev;
@@ -385,6 +392,9 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb)
385 const struct Qdisc_class_ops *cops; 392 const struct Qdisc_class_ops *cops;
386 struct tcf_dump_args arg; 393 struct tcf_dump_args arg;
387 394
395 if (net != &init_net)
396 return 0;
397
388 if (cb->nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*tcm))) 398 if (cb->nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*tcm)))
389 return skb->len; 399 return skb->len;
390 if ((dev = dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL) 400 if ((dev = dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL)
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 259321be1ad8..f30e3f7ad885 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -29,6 +29,7 @@
29#include <linux/hrtimer.h> 29#include <linux/hrtimer.h>
30 30
31#include <net/net_namespace.h> 31#include <net/net_namespace.h>
32#include <net/sock.h>
32#include <net/netlink.h> 33#include <net/netlink.h>
33#include <net/pkt_sched.h> 34#include <net/pkt_sched.h>
34 35
@@ -599,6 +600,7 @@ check_loop_fn(struct Qdisc *q, unsigned long cl, struct qdisc_walker *w)
599 600
600static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg) 601static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
601{ 602{
603 struct net *net = skb->sk->sk_net;
602 struct tcmsg *tcm = NLMSG_DATA(n); 604 struct tcmsg *tcm = NLMSG_DATA(n);
603 struct rtattr **tca = arg; 605 struct rtattr **tca = arg;
604 struct net_device *dev; 606 struct net_device *dev;
@@ -607,6 +609,9 @@ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
607 struct Qdisc *p = NULL; 609 struct Qdisc *p = NULL;
608 int err; 610 int err;
609 611
612 if (net != &init_net)
613 return -EINVAL;
614
610 if ((dev = __dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL) 615 if ((dev = __dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL)
611 return -ENODEV; 616 return -ENODEV;
612 617
@@ -660,6 +665,7 @@ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
660 665
661static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg) 666static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
662{ 667{
668 struct net *net = skb->sk->sk_net;
663 struct tcmsg *tcm; 669 struct tcmsg *tcm;
664 struct rtattr **tca; 670 struct rtattr **tca;
665 struct net_device *dev; 671 struct net_device *dev;
@@ -667,6 +673,9 @@ static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
667 struct Qdisc *q, *p; 673 struct Qdisc *q, *p;
668 int err; 674 int err;
669 675
676 if (net != &init_net)
677 return -EINVAL;
678
670replay: 679replay:
671 /* Reinit, just in case something touches this. */ 680 /* Reinit, just in case something touches this. */
672 tcm = NLMSG_DATA(n); 681 tcm = NLMSG_DATA(n);
@@ -872,11 +881,15 @@ err_out:
872 881
873static int tc_dump_qdisc(struct sk_buff *skb, struct netlink_callback *cb) 882static int tc_dump_qdisc(struct sk_buff *skb, struct netlink_callback *cb)
874{ 883{
884 struct net *net = skb->sk->sk_net;
875 int idx, q_idx; 885 int idx, q_idx;
876 int s_idx, s_q_idx; 886 int s_idx, s_q_idx;
877 struct net_device *dev; 887 struct net_device *dev;
878 struct Qdisc *q; 888 struct Qdisc *q;
879 889
890 if (net != &init_net)
891 return 0;
892
880 s_idx = cb->args[0]; 893 s_idx = cb->args[0];
881 s_q_idx = q_idx = cb->args[1]; 894 s_q_idx = q_idx = cb->args[1];
882 read_lock(&dev_base_lock); 895 read_lock(&dev_base_lock);
@@ -920,6 +933,7 @@ done:
920 933
921static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg) 934static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
922{ 935{
936 struct net *net = skb->sk->sk_net;
923 struct tcmsg *tcm = NLMSG_DATA(n); 937 struct tcmsg *tcm = NLMSG_DATA(n);
924 struct rtattr **tca = arg; 938 struct rtattr **tca = arg;
925 struct net_device *dev; 939 struct net_device *dev;
@@ -932,6 +946,9 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
932 u32 qid = TC_H_MAJ(clid); 946 u32 qid = TC_H_MAJ(clid);
933 int err; 947 int err;
934 948
949 if (net != &init_net)
950 return -EINVAL;
951
935 if ((dev = __dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL) 952 if ((dev = __dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL)
936 return -ENODEV; 953 return -ENODEV;
937 954
@@ -1106,6 +1123,7 @@ static int qdisc_class_dump(struct Qdisc *q, unsigned long cl, struct qdisc_walk
1106 1123
1107static int tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb) 1124static int tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb)
1108{ 1125{
1126 struct net *net = skb->sk->sk_net;
1109 int t; 1127 int t;
1110 int s_t; 1128 int s_t;
1111 struct net_device *dev; 1129 struct net_device *dev;
@@ -1113,6 +1131,9 @@ static int tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb)
1113 struct tcmsg *tcm = (struct tcmsg*)NLMSG_DATA(cb->nlh); 1131 struct tcmsg *tcm = (struct tcmsg*)NLMSG_DATA(cb->nlh);
1114 struct qdisc_dump_args arg; 1132 struct qdisc_dump_args arg;
1115 1133
1134 if (net != &init_net)
1135 return 0;
1136
1116 if (cb->nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*tcm))) 1137 if (cb->nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*tcm)))
1117 return 0; 1138 return 0;
1118 if ((dev = dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL) 1139 if ((dev = dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL)