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 | |
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')
-rw-r--r-- | net/bridge/br_netlink.c | 3 | ||||
-rw-r--r-- | net/can/gw.c | 6 | ||||
-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 | ||||
-rw-r--r-- | net/dcb/dcbnl.c | 3 | ||||
-rw-r--r-- | net/decnet/dn_dev.c | 6 | ||||
-rw-r--r-- | net/decnet/dn_fib.c | 6 | ||||
-rw-r--r-- | net/ipv4/devinet.c | 6 | ||||
-rw-r--r-- | net/ipv4/fib_frontend.c | 6 | ||||
-rw-r--r-- | net/ipv6/addrconf.c | 6 | ||||
-rw-r--r-- | net/ipv6/addrlabel.c | 3 | ||||
-rw-r--r-- | net/ipv6/route.c | 6 | ||||
-rw-r--r-- | net/phonet/pn_netlink.c | 6 | ||||
-rw-r--r-- | net/sched/act_api.c | 3 | ||||
-rw-r--r-- | net/sched/cls_api.c | 2 | ||||
-rw-r--r-- | net/sched/sch_api.c | 9 |
17 files changed, 102 insertions, 1 deletions
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index 65429b99a2a3..49e14937019d 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c | |||
@@ -240,6 +240,9 @@ int br_setlink(struct net_device *dev, struct nlmsghdr *nlh) | |||
240 | struct nlattr *tb[IFLA_BRPORT_MAX]; | 240 | struct nlattr *tb[IFLA_BRPORT_MAX]; |
241 | int err; | 241 | int err; |
242 | 242 | ||
243 | if (!capable(CAP_NET_ADMIN)) | ||
244 | return -EPERM; | ||
245 | |||
243 | ifm = nlmsg_data(nlh); | 246 | ifm = nlmsg_data(nlh); |
244 | 247 | ||
245 | protinfo = nlmsg_find_attr(nlh, sizeof(*ifm), IFLA_PROTINFO); | 248 | protinfo = nlmsg_find_attr(nlh, sizeof(*ifm), IFLA_PROTINFO); |
diff --git a/net/can/gw.c b/net/can/gw.c index 1f5c9785a262..574dda78eb0f 100644 --- a/net/can/gw.c +++ b/net/can/gw.c | |||
@@ -751,6 +751,9 @@ static int cgw_create_job(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
751 | struct cgw_job *gwj; | 751 | struct cgw_job *gwj; |
752 | int err = 0; | 752 | int err = 0; |
753 | 753 | ||
754 | if (!capable(CAP_NET_ADMIN)) | ||
755 | return -EPERM; | ||
756 | |||
754 | if (nlmsg_len(nlh) < sizeof(*r)) | 757 | if (nlmsg_len(nlh) < sizeof(*r)) |
755 | return -EINVAL; | 758 | return -EINVAL; |
756 | 759 | ||
@@ -839,6 +842,9 @@ static int cgw_remove_job(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
839 | struct can_can_gw ccgw; | 842 | struct can_can_gw ccgw; |
840 | int err = 0; | 843 | int err = 0; |
841 | 844 | ||
845 | if (!capable(CAP_NET_ADMIN)) | ||
846 | return -EPERM; | ||
847 | |||
842 | if (nlmsg_len(nlh) < sizeof(*r)) | 848 | if (nlmsg_len(nlh) < sizeof(*r)) |
843 | return -EINVAL; | 849 | return -EINVAL; |
844 | 850 | ||
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) { |
diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c index 70989e672304..b07c75d37e91 100644 --- a/net/dcb/dcbnl.c +++ b/net/dcb/dcbnl.c | |||
@@ -1662,6 +1662,9 @@ static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
1662 | struct nlmsghdr *reply_nlh = NULL; | 1662 | struct nlmsghdr *reply_nlh = NULL; |
1663 | const struct reply_func *fn; | 1663 | const struct reply_func *fn; |
1664 | 1664 | ||
1665 | if ((nlh->nlmsg_type == RTM_SETDCB) && !capable(CAP_NET_ADMIN)) | ||
1666 | return -EPERM; | ||
1667 | |||
1665 | if (!net_eq(net, &init_net)) | 1668 | if (!net_eq(net, &init_net)) |
1666 | return -EINVAL; | 1669 | return -EINVAL; |
1667 | 1670 | ||
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c index 7b7e561412d3..e47ba9fc4a0e 100644 --- a/net/decnet/dn_dev.c +++ b/net/decnet/dn_dev.c | |||
@@ -573,6 +573,9 @@ static int dn_nl_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
573 | struct dn_ifaddr __rcu **ifap; | 573 | struct dn_ifaddr __rcu **ifap; |
574 | int err = -EINVAL; | 574 | int err = -EINVAL; |
575 | 575 | ||
576 | if (!capable(CAP_NET_ADMIN)) | ||
577 | return -EPERM; | ||
578 | |||
576 | if (!net_eq(net, &init_net)) | 579 | if (!net_eq(net, &init_net)) |
577 | goto errout; | 580 | goto errout; |
578 | 581 | ||
@@ -614,6 +617,9 @@ static int dn_nl_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
614 | struct dn_ifaddr *ifa; | 617 | struct dn_ifaddr *ifa; |
615 | int err; | 618 | int err; |
616 | 619 | ||
620 | if (!capable(CAP_NET_ADMIN)) | ||
621 | return -EPERM; | ||
622 | |||
617 | if (!net_eq(net, &init_net)) | 623 | if (!net_eq(net, &init_net)) |
618 | return -EINVAL; | 624 | return -EINVAL; |
619 | 625 | ||
diff --git a/net/decnet/dn_fib.c b/net/decnet/dn_fib.c index 102d6106a942..e36614eccc04 100644 --- a/net/decnet/dn_fib.c +++ b/net/decnet/dn_fib.c | |||
@@ -520,6 +520,9 @@ static int dn_fib_rtm_delroute(struct sk_buff *skb, struct nlmsghdr *nlh, void * | |||
520 | struct rtattr **rta = arg; | 520 | struct rtattr **rta = arg; |
521 | struct rtmsg *r = NLMSG_DATA(nlh); | 521 | struct rtmsg *r = NLMSG_DATA(nlh); |
522 | 522 | ||
523 | if (!capable(CAP_NET_ADMIN)) | ||
524 | return -EPERM; | ||
525 | |||
523 | if (!net_eq(net, &init_net)) | 526 | if (!net_eq(net, &init_net)) |
524 | return -EINVAL; | 527 | return -EINVAL; |
525 | 528 | ||
@@ -540,6 +543,9 @@ static int dn_fib_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh, void * | |||
540 | struct rtattr **rta = arg; | 543 | struct rtattr **rta = arg; |
541 | struct rtmsg *r = NLMSG_DATA(nlh); | 544 | struct rtmsg *r = NLMSG_DATA(nlh); |
542 | 545 | ||
546 | if (!capable(CAP_NET_ADMIN)) | ||
547 | return -EPERM; | ||
548 | |||
543 | if (!net_eq(net, &init_net)) | 549 | if (!net_eq(net, &init_net)) |
544 | return -EINVAL; | 550 | return -EINVAL; |
545 | 551 | ||
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 6e06e924ed99..417093538916 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c | |||
@@ -539,6 +539,9 @@ static int inet_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg | |||
539 | 539 | ||
540 | ASSERT_RTNL(); | 540 | ASSERT_RTNL(); |
541 | 541 | ||
542 | if (!capable(CAP_NET_ADMIN)) | ||
543 | return -EPERM; | ||
544 | |||
542 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv4_policy); | 545 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv4_policy); |
543 | if (err < 0) | 546 | if (err < 0) |
544 | goto errout; | 547 | goto errout; |
@@ -646,6 +649,9 @@ static int inet_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg | |||
646 | 649 | ||
647 | ASSERT_RTNL(); | 650 | ASSERT_RTNL(); |
648 | 651 | ||
652 | if (!capable(CAP_NET_ADMIN)) | ||
653 | return -EPERM; | ||
654 | |||
649 | ifa = rtm_to_ifaddr(net, nlh); | 655 | ifa = rtm_to_ifaddr(net, nlh); |
650 | if (IS_ERR(ifa)) | 656 | if (IS_ERR(ifa)) |
651 | return PTR_ERR(ifa); | 657 | return PTR_ERR(ifa); |
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 825c608826de..bce4541c6784 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c | |||
@@ -613,6 +613,9 @@ static int inet_rtm_delroute(struct sk_buff *skb, struct nlmsghdr *nlh, void *ar | |||
613 | struct fib_table *tb; | 613 | struct fib_table *tb; |
614 | int err; | 614 | int err; |
615 | 615 | ||
616 | if (!capable(CAP_NET_ADMIN)) | ||
617 | return -EPERM; | ||
618 | |||
616 | err = rtm_to_fib_config(net, skb, nlh, &cfg); | 619 | err = rtm_to_fib_config(net, skb, nlh, &cfg); |
617 | if (err < 0) | 620 | if (err < 0) |
618 | goto errout; | 621 | goto errout; |
@@ -635,6 +638,9 @@ static int inet_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh, void *ar | |||
635 | struct fib_table *tb; | 638 | struct fib_table *tb; |
636 | int err; | 639 | int err; |
637 | 640 | ||
641 | if (!capable(CAP_NET_ADMIN)) | ||
642 | return -EPERM; | ||
643 | |||
638 | err = rtm_to_fib_config(net, skb, nlh, &cfg); | 644 | err = rtm_to_fib_config(net, skb, nlh, &cfg); |
639 | if (err < 0) | 645 | if (err < 0) |
640 | goto errout; | 646 | goto errout; |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index b24b4de5cd26..e21bdb92565d 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -3514,6 +3514,9 @@ inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
3514 | struct in6_addr *pfx; | 3514 | struct in6_addr *pfx; |
3515 | int err; | 3515 | int err; |
3516 | 3516 | ||
3517 | if (!capable(CAP_NET_ADMIN)) | ||
3518 | return -EPERM; | ||
3519 | |||
3517 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy); | 3520 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy); |
3518 | if (err < 0) | 3521 | if (err < 0) |
3519 | return err; | 3522 | return err; |
@@ -3584,6 +3587,9 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
3584 | u8 ifa_flags; | 3587 | u8 ifa_flags; |
3585 | int err; | 3588 | int err; |
3586 | 3589 | ||
3590 | if (!capable(CAP_NET_ADMIN)) | ||
3591 | return -EPERM; | ||
3592 | |||
3587 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy); | 3593 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy); |
3588 | if (err < 0) | 3594 | if (err < 0) |
3589 | return err; | 3595 | return err; |
diff --git a/net/ipv6/addrlabel.c b/net/ipv6/addrlabel.c index ff76eecfd622..b106f80be0c5 100644 --- a/net/ipv6/addrlabel.c +++ b/net/ipv6/addrlabel.c | |||
@@ -425,6 +425,9 @@ static int ip6addrlbl_newdel(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
425 | u32 label; | 425 | u32 label; |
426 | int err = 0; | 426 | int err = 0; |
427 | 427 | ||
428 | if (!capable(CAP_NET_ADMIN)) | ||
429 | return -EPERM; | ||
430 | |||
428 | err = nlmsg_parse(nlh, sizeof(*ifal), tb, IFAL_MAX, ifal_policy); | 431 | err = nlmsg_parse(nlh, sizeof(*ifal), tb, IFAL_MAX, ifal_policy); |
429 | if (err < 0) | 432 | if (err < 0) |
430 | return err; | 433 | return err; |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 021a48e8a5e2..c6215e2b9d7f 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -2446,6 +2446,9 @@ static int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *a | |||
2446 | struct fib6_config cfg; | 2446 | struct fib6_config cfg; |
2447 | int err; | 2447 | int err; |
2448 | 2448 | ||
2449 | if (!capable(CAP_NET_ADMIN)) | ||
2450 | return -EPERM; | ||
2451 | |||
2449 | err = rtm_to_fib6_config(skb, nlh, &cfg); | 2452 | err = rtm_to_fib6_config(skb, nlh, &cfg); |
2450 | if (err < 0) | 2453 | if (err < 0) |
2451 | return err; | 2454 | return err; |
@@ -2461,6 +2464,9 @@ static int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *a | |||
2461 | struct fib6_config cfg; | 2464 | struct fib6_config cfg; |
2462 | int err; | 2465 | int err; |
2463 | 2466 | ||
2467 | if (!capable(CAP_NET_ADMIN)) | ||
2468 | return -EPERM; | ||
2469 | |||
2464 | err = rtm_to_fib6_config(skb, nlh, &cfg); | 2470 | err = rtm_to_fib6_config(skb, nlh, &cfg); |
2465 | if (err < 0) | 2471 | if (err < 0) |
2466 | return err; | 2472 | return err; |
diff --git a/net/phonet/pn_netlink.c b/net/phonet/pn_netlink.c index 83a8389619aa..0193630d3061 100644 --- a/net/phonet/pn_netlink.c +++ b/net/phonet/pn_netlink.c | |||
@@ -70,6 +70,9 @@ static int addr_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *attr) | |||
70 | int err; | 70 | int err; |
71 | u8 pnaddr; | 71 | u8 pnaddr; |
72 | 72 | ||
73 | if (!capable(CAP_NET_ADMIN)) | ||
74 | return -EPERM; | ||
75 | |||
73 | if (!capable(CAP_SYS_ADMIN)) | 76 | if (!capable(CAP_SYS_ADMIN)) |
74 | return -EPERM; | 77 | return -EPERM; |
75 | 78 | ||
@@ -230,6 +233,9 @@ static int route_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *attr) | |||
230 | int err; | 233 | int err; |
231 | u8 dst; | 234 | u8 dst; |
232 | 235 | ||
236 | if (!capable(CAP_NET_ADMIN)) | ||
237 | return -EPERM; | ||
238 | |||
233 | if (!capable(CAP_SYS_ADMIN)) | 239 | if (!capable(CAP_SYS_ADMIN)) |
234 | return -EPERM; | 240 | return -EPERM; |
235 | 241 | ||
diff --git a/net/sched/act_api.c b/net/sched/act_api.c index 102761d294cb..65d240cbf74b 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c | |||
@@ -987,6 +987,9 @@ static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n, void *arg) | |||
987 | u32 portid = skb ? NETLINK_CB(skb).portid : 0; | 987 | u32 portid = skb ? NETLINK_CB(skb).portid : 0; |
988 | int ret = 0, ovr = 0; | 988 | int ret = 0, ovr = 0; |
989 | 989 | ||
990 | if ((n->nlmsg_type != RTM_GETACTION) && !capable(CAP_NET_ADMIN)) | ||
991 | return -EPERM; | ||
992 | |||
990 | ret = nlmsg_parse(n, sizeof(struct tcamsg), tca, TCA_ACT_MAX, NULL); | 993 | ret = nlmsg_parse(n, sizeof(struct tcamsg), tca, TCA_ACT_MAX, NULL); |
991 | if (ret < 0) | 994 | if (ret < 0) |
992 | return ret; | 995 | return ret; |
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index 7ae02892437c..ff55ed6c49b2 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c | |||
@@ -139,6 +139,8 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg) | |||
139 | int err; | 139 | int err; |
140 | int tp_created = 0; | 140 | int tp_created = 0; |
141 | 141 | ||
142 | if ((n->nlmsg_type != RTM_GETTFILTER) && !capable(CAP_NET_ADMIN)) | ||
143 | return -EPERM; | ||
142 | replay: | 144 | replay: |
143 | t = nlmsg_data(n); | 145 | t = nlmsg_data(n); |
144 | protocol = TC_H_MIN(t->tcm_info); | 146 | protocol = TC_H_MIN(t->tcm_info); |
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index 13cc744a2498..4799c4840c1a 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c | |||
@@ -980,6 +980,9 @@ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg) | |||
980 | struct Qdisc *p = NULL; | 980 | struct Qdisc *p = NULL; |
981 | int err; | 981 | int err; |
982 | 982 | ||
983 | if ((n->nlmsg_type != RTM_GETQDISC) && !capable(CAP_NET_ADMIN)) | ||
984 | return -EPERM; | ||
985 | |||
983 | dev = __dev_get_by_index(net, tcm->tcm_ifindex); | 986 | dev = __dev_get_by_index(net, tcm->tcm_ifindex); |
984 | if (!dev) | 987 | if (!dev) |
985 | return -ENODEV; | 988 | return -ENODEV; |
@@ -1043,6 +1046,9 @@ static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg) | |||
1043 | struct Qdisc *q, *p; | 1046 | struct Qdisc *q, *p; |
1044 | int err; | 1047 | int err; |
1045 | 1048 | ||
1049 | if (!capable(CAP_NET_ADMIN)) | ||
1050 | return -EPERM; | ||
1051 | |||
1046 | replay: | 1052 | replay: |
1047 | /* Reinit, just in case something touches this. */ | 1053 | /* Reinit, just in case something touches this. */ |
1048 | tcm = nlmsg_data(n); | 1054 | tcm = nlmsg_data(n); |
@@ -1379,6 +1385,9 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg) | |||
1379 | u32 qid = TC_H_MAJ(clid); | 1385 | u32 qid = TC_H_MAJ(clid); |
1380 | int err; | 1386 | int err; |
1381 | 1387 | ||
1388 | if ((n->nlmsg_type != RTM_GETTCLASS) && !capable(CAP_NET_ADMIN)) | ||
1389 | return -EPERM; | ||
1390 | |||
1382 | dev = __dev_get_by_index(net, tcm->tcm_ifindex); | 1391 | dev = __dev_get_by_index(net, tcm->tcm_ifindex); |
1383 | if (!dev) | 1392 | if (!dev) |
1384 | return -ENODEV; | 1393 | return -ENODEV; |