diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2012-11-15 22:03:00 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-11-18 20:32:44 -0500 |
commit | dfc47ef8639facd77210e74be831943c2fdd9c74 (patch) | |
tree | 5c7e9f93a999bf1d38b216af346ce2159e5f18ec /net/core | |
parent | 464dc801c76aa0db88e16e8f5f47c6879858b9b2 (diff) |
net: Push capable(CAP_NET_ADMIN) into the rtnl methods
- In rtnetlink_rcv_msg convert the capable(CAP_NET_ADMIN) check
to ns_capable(net->user-ns, CAP_NET_ADMIN). Allowing unprivileged
users to make netlink calls to modify their local network
namespace.
- In the rtnetlink doit methods add capable(CAP_NET_ADMIN) so
that calls that are not safe for unprivileged users are still
protected.
Later patches will remove the extra capable calls from methods
that are safe for unprivilged users.
Acked-by: Serge Hallyn <serge.hallyn@canonical.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/fib_rules.c | 6 | ||||
-rw-r--r-- | net/core/neighbour.c | 9 | ||||
-rw-r--r-- | net/core/rtnetlink.c | 17 |
3 files changed, 31 insertions, 1 deletions
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c index 58a4ba27dfe3..bf5b5b8af56e 100644 --- a/net/core/fib_rules.c +++ b/net/core/fib_rules.c | |||
@@ -275,6 +275,9 @@ static int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | |||
275 | struct nlattr *tb[FRA_MAX+1]; | 275 | struct nlattr *tb[FRA_MAX+1]; |
276 | int err = -EINVAL, unresolved = 0; | 276 | int err = -EINVAL, unresolved = 0; |
277 | 277 | ||
278 | if (!capable(CAP_NET_ADMIN)) | ||
279 | return -EPERM; | ||
280 | |||
278 | if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*frh))) | 281 | if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*frh))) |
279 | goto errout; | 282 | goto errout; |
280 | 283 | ||
@@ -424,6 +427,9 @@ static int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | |||
424 | struct nlattr *tb[FRA_MAX+1]; | 427 | struct nlattr *tb[FRA_MAX+1]; |
425 | int err = -EINVAL; | 428 | int err = -EINVAL; |
426 | 429 | ||
430 | if (!capable(CAP_NET_ADMIN)) | ||
431 | return -EPERM; | ||
432 | |||
427 | if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*frh))) | 433 | if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*frh))) |
428 | goto errout; | 434 | goto errout; |
429 | 435 | ||
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index f1c0c2e9cad5..7adcdaf91c4d 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
@@ -1620,6 +1620,9 @@ static int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
1620 | struct net_device *dev = NULL; | 1620 | struct net_device *dev = NULL; |
1621 | int err = -EINVAL; | 1621 | int err = -EINVAL; |
1622 | 1622 | ||
1623 | if (!capable(CAP_NET_ADMIN)) | ||
1624 | return -EPERM; | ||
1625 | |||
1623 | ASSERT_RTNL(); | 1626 | ASSERT_RTNL(); |
1624 | if (nlmsg_len(nlh) < sizeof(*ndm)) | 1627 | if (nlmsg_len(nlh) < sizeof(*ndm)) |
1625 | goto out; | 1628 | goto out; |
@@ -1684,6 +1687,9 @@ static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
1684 | struct net_device *dev = NULL; | 1687 | struct net_device *dev = NULL; |
1685 | int err; | 1688 | int err; |
1686 | 1689 | ||
1690 | if (!capable(CAP_NET_ADMIN)) | ||
1691 | return -EPERM; | ||
1692 | |||
1687 | ASSERT_RTNL(); | 1693 | ASSERT_RTNL(); |
1688 | err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, NULL); | 1694 | err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, NULL); |
1689 | if (err < 0) | 1695 | if (err < 0) |
@@ -1962,6 +1968,9 @@ static int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
1962 | struct nlattr *tb[NDTA_MAX+1]; | 1968 | struct nlattr *tb[NDTA_MAX+1]; |
1963 | int err; | 1969 | int err; |
1964 | 1970 | ||
1971 | if (!capable(CAP_NET_ADMIN)) | ||
1972 | return -EPERM; | ||
1973 | |||
1965 | err = nlmsg_parse(nlh, sizeof(*ndtmsg), tb, NDTA_MAX, | 1974 | err = nlmsg_parse(nlh, sizeof(*ndtmsg), tb, NDTA_MAX, |
1966 | nl_neightbl_policy); | 1975 | nl_neightbl_policy); |
1967 | if (err < 0) | 1976 | if (err < 0) |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index a810f6a61372..a40c10b96f47 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -1547,6 +1547,9 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
1547 | struct nlattr *tb[IFLA_MAX+1]; | 1547 | struct nlattr *tb[IFLA_MAX+1]; |
1548 | char ifname[IFNAMSIZ]; | 1548 | char ifname[IFNAMSIZ]; |
1549 | 1549 | ||
1550 | if (!capable(CAP_NET_ADMIN)) | ||
1551 | return -EPERM; | ||
1552 | |||
1550 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy); | 1553 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy); |
1551 | if (err < 0) | 1554 | if (err < 0) |
1552 | goto errout; | 1555 | goto errout; |
@@ -1590,6 +1593,9 @@ static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
1590 | int err; | 1593 | int err; |
1591 | LIST_HEAD(list_kill); | 1594 | LIST_HEAD(list_kill); |
1592 | 1595 | ||
1596 | if (!capable(CAP_NET_ADMIN)) | ||
1597 | return -EPERM; | ||
1598 | |||
1593 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy); | 1599 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy); |
1594 | if (err < 0) | 1600 | if (err < 0) |
1595 | return err; | 1601 | return err; |
@@ -1720,6 +1726,9 @@ static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
1720 | struct nlattr *linkinfo[IFLA_INFO_MAX+1]; | 1726 | struct nlattr *linkinfo[IFLA_INFO_MAX+1]; |
1721 | int err; | 1727 | int err; |
1722 | 1728 | ||
1729 | if (!capable(CAP_NET_ADMIN)) | ||
1730 | return -EPERM; | ||
1731 | |||
1723 | #ifdef CONFIG_MODULES | 1732 | #ifdef CONFIG_MODULES |
1724 | replay: | 1733 | replay: |
1725 | #endif | 1734 | #endif |
@@ -2057,6 +2066,9 @@ static int rtnl_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
2057 | u8 *addr; | 2066 | u8 *addr; |
2058 | int err; | 2067 | int err; |
2059 | 2068 | ||
2069 | if (!capable(CAP_NET_ADMIN)) | ||
2070 | return -EPERM; | ||
2071 | |||
2060 | err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, NULL); | 2072 | err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, NULL); |
2061 | if (err < 0) | 2073 | if (err < 0) |
2062 | return err; | 2074 | return err; |
@@ -2123,6 +2135,9 @@ static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
2123 | int err = -EINVAL; | 2135 | int err = -EINVAL; |
2124 | __u8 *addr; | 2136 | __u8 *addr; |
2125 | 2137 | ||
2138 | if (!capable(CAP_NET_ADMIN)) | ||
2139 | return -EPERM; | ||
2140 | |||
2126 | if (nlmsg_len(nlh) < sizeof(*ndm)) | 2141 | if (nlmsg_len(nlh) < sizeof(*ndm)) |
2127 | return -EINVAL; | 2142 | return -EINVAL; |
2128 | 2143 | ||
@@ -2488,7 +2503,7 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
2488 | sz_idx = type>>2; | 2503 | sz_idx = type>>2; |
2489 | kind = type&3; | 2504 | kind = type&3; |
2490 | 2505 | ||
2491 | if (kind != 2 && !capable(CAP_NET_ADMIN)) | 2506 | if (kind != 2 && !ns_capable(net->user_ns, CAP_NET_ADMIN)) |
2492 | return -EPERM; | 2507 | return -EPERM; |
2493 | 2508 | ||
2494 | if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) { | 2509 | if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) { |