From b854272b3c732316676e9128f7b9e6f1e1ff88b0 Mon Sep 17 00:00:00 2001 From: "Denis V. Lunev" Date: Sat, 1 Dec 2007 00:21:31 +1100 Subject: [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 Signed-off-by: Eric W. Biederman Signed-off-by: David S. Miller Signed-off-by: Herbert Xu --- net/decnet/dn_dev.c | 14 +++++++++++++- net/decnet/dn_fib.c | 8 ++++++++ net/decnet/dn_route.c | 8 ++++++++ net/decnet/dn_table.c | 4 ++++ 4 files changed, 33 insertions(+), 1 deletion(-) (limited to 'net/decnet') diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c index 3bc82dc83b3..94256845a05 100644 --- a/net/decnet/dn_dev.c +++ b/net/decnet/dn_dev.c @@ -647,11 +647,15 @@ static const struct nla_policy dn_ifa_policy[IFA_MAX+1] = { static int dn_nl_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) { + struct net *net = skb->sk->sk_net; struct nlattr *tb[IFA_MAX+1]; struct dn_dev *dn_db; struct ifaddrmsg *ifm; struct dn_ifaddr *ifa, **ifap; - int err; + int err = -EINVAL; + + if (net != &init_net) + goto errout; err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, dn_ifa_policy); if (err < 0) @@ -681,6 +685,7 @@ errout: static int dn_nl_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) { + struct net *net = skb->sk->sk_net; struct nlattr *tb[IFA_MAX+1]; struct net_device *dev; struct dn_dev *dn_db; @@ -688,6 +693,9 @@ static int dn_nl_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) struct dn_ifaddr *ifa; int err; + if (net != &init_net) + return -EINVAL; + err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, dn_ifa_policy); if (err < 0) return err; @@ -793,11 +801,15 @@ errout: static int dn_nl_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) { + struct net *net = skb->sk->sk_net; int idx, dn_idx = 0, skip_ndevs, skip_naddr; struct net_device *dev; struct dn_dev *dn_db; struct dn_ifaddr *ifa; + if (net != &init_net) + return 0; + skip_ndevs = cb->args[0]; skip_naddr = cb->args[1]; diff --git a/net/decnet/dn_fib.c b/net/decnet/dn_fib.c index 3760a20d10d..5413e1b75b5 100644 --- a/net/decnet/dn_fib.c +++ b/net/decnet/dn_fib.c @@ -506,10 +506,14 @@ static int dn_fib_check_attr(struct rtmsg *r, struct rtattr **rta) static int dn_fib_rtm_delroute(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) { + struct net *net = skb->sk->sk_net; struct dn_fib_table *tb; struct rtattr **rta = arg; struct rtmsg *r = NLMSG_DATA(nlh); + if (net != &init_net) + return -EINVAL; + if (dn_fib_check_attr(r, rta)) return -EINVAL; @@ -522,10 +526,14 @@ static int dn_fib_rtm_delroute(struct sk_buff *skb, struct nlmsghdr *nlh, void * static int dn_fib_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) { + struct net *net = skb->sk->sk_net; struct dn_fib_table *tb; struct rtattr **rta = arg; struct rtmsg *r = NLMSG_DATA(nlh); + if (net != &init_net) + return -EINVAL; + if (dn_fib_check_attr(r, rta)) return -EINVAL; diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index 2a5bb0714c7..28aeba15cf1 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c @@ -1511,6 +1511,7 @@ rtattr_failure: */ static int dn_cache_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, void *arg) { + struct net *net = in_skb->sk->sk_net; struct rtattr **rta = arg; struct rtmsg *rtm = NLMSG_DATA(nlh); struct dn_route *rt = NULL; @@ -1519,6 +1520,9 @@ static int dn_cache_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, void struct sk_buff *skb; struct flowi fl; + if (net != &init_net) + return -EINVAL; + memset(&fl, 0, sizeof(fl)); fl.proto = DNPROTO_NSP; @@ -1596,10 +1600,14 @@ out_free: */ int dn_cache_dump(struct sk_buff *skb, struct netlink_callback *cb) { + struct net *net = skb->sk->sk_net; struct dn_route *rt; int h, s_h; int idx, s_idx; + if (net != &init_net) + return 0; + if (NLMSG_PAYLOAD(cb->nlh, 0) < sizeof(struct rtmsg)) return -EINVAL; if (!(((struct rtmsg *)NLMSG_DATA(cb->nlh))->rtm_flags&RTM_F_CLONED)) diff --git a/net/decnet/dn_table.c b/net/decnet/dn_table.c index fda0772fa21..a3bdb8dd1fb 100644 --- a/net/decnet/dn_table.c +++ b/net/decnet/dn_table.c @@ -463,12 +463,16 @@ static int dn_fib_table_dump(struct dn_fib_table *tb, struct sk_buff *skb, int dn_fib_dump(struct sk_buff *skb, struct netlink_callback *cb) { + struct net *net = skb->sk->sk_net; unsigned int h, s_h; unsigned int e = 0, s_e; struct dn_fib_table *tb; struct hlist_node *node; int dumped = 0; + if (net != &init_net) + return 0; + if (NLMSG_PAYLOAD(cb->nlh, 0) >= sizeof(struct rtmsg) && ((struct rtmsg *)NLMSG_DATA(cb->nlh))->rtm_flags&RTM_F_CLONED) return dn_cache_dump(skb, cb); -- cgit v1.2.3-18-g5258