aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2012-11-15 22:03:00 -0500
committerDavid S. Miller <davem@davemloft.net>2012-11-18 20:32:44 -0500
commitdfc47ef8639facd77210e74be831943c2fdd9c74 (patch)
tree5c7e9f93a999bf1d38b216af346ce2159e5f18ec /net
parent464dc801c76aa0db88e16e8f5f47c6879858b9b2 (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.c3
-rw-r--r--net/can/gw.c6
-rw-r--r--net/core/fib_rules.c6
-rw-r--r--net/core/neighbour.c9
-rw-r--r--net/core/rtnetlink.c17
-rw-r--r--net/dcb/dcbnl.c3
-rw-r--r--net/decnet/dn_dev.c6
-rw-r--r--net/decnet/dn_fib.c6
-rw-r--r--net/ipv4/devinet.c6
-rw-r--r--net/ipv4/fib_frontend.c6
-rw-r--r--net/ipv6/addrconf.c6
-rw-r--r--net/ipv6/addrlabel.c3
-rw-r--r--net/ipv6/route.c6
-rw-r--r--net/phonet/pn_netlink.c6
-rw-r--r--net/sched/act_api.c3
-rw-r--r--net/sched/cls_api.c2
-rw-r--r--net/sched/sch_api.c9
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
1724replay: 1733replay:
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;
142replay: 144replay:
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
1046replay: 1052replay:
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;