diff options
author | Patrick McHardy <kaber@trash.net> | 2011-01-19 22:00:42 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-01-21 02:28:54 -0500 |
commit | ffa934f192c8381061242eb170419266ef229902 (patch) | |
tree | fb09699460d85166bfa64c524eb6eda01b899c4a /net/core/rtnetlink.c | |
parent | d52344a7ae8a3fb660636f7de4f1c542b0036cbb (diff) |
rtnetlink: fix link attribute validation with IFLA_GROUP
rtnl_group_changelink() is invoked by rtnl_newlink() before the link
attributes have been validated. Additionally the group changes are
performed even if NLM_F_CREATE is specified and a new link is
created, while more reasonable semantics would be to set the group
value on the newly created link.
Fix both problems by moving the rtnl_group_changelink() invocation
down to the handling of non-existant links without NLM_F_CREATE()
and add a dev_set_group() call to rtnl_create_link().
Signed-off-by: Patrick McHardy <kaber@trash.net>
Acked-by: Vlad Dogaru <ddvlad@rosedu.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core/rtnetlink.c')
-rw-r--r-- | net/core/rtnetlink.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index a0b2eeb3b610..310eb804e092 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -1548,6 +1548,8 @@ struct net_device *rtnl_create_link(struct net *src_net, struct net *net, | |||
1548 | set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE])); | 1548 | set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE])); |
1549 | if (tb[IFLA_LINKMODE]) | 1549 | if (tb[IFLA_LINKMODE]) |
1550 | dev->link_mode = nla_get_u8(tb[IFLA_LINKMODE]); | 1550 | dev->link_mode = nla_get_u8(tb[IFLA_LINKMODE]); |
1551 | if (tb[IFLA_GROUP]) | ||
1552 | dev_set_group(dev, nla_get_u32(tb[IFLA_GROUP])); | ||
1551 | 1553 | ||
1552 | return dev; | 1554 | return dev; |
1553 | 1555 | ||
@@ -1606,10 +1608,6 @@ replay: | |||
1606 | else { | 1608 | else { |
1607 | if (ifname[0]) | 1609 | if (ifname[0]) |
1608 | dev = __dev_get_by_name(net, ifname); | 1610 | dev = __dev_get_by_name(net, ifname); |
1609 | else if (tb[IFLA_GROUP]) | ||
1610 | return rtnl_group_changelink(net, | ||
1611 | nla_get_u32(tb[IFLA_GROUP]), | ||
1612 | ifm, tb); | ||
1613 | else | 1611 | else |
1614 | dev = NULL; | 1612 | dev = NULL; |
1615 | } | 1613 | } |
@@ -1676,8 +1674,13 @@ replay: | |||
1676 | return do_setlink(dev, ifm, tb, ifname, modified); | 1674 | return do_setlink(dev, ifm, tb, ifname, modified); |
1677 | } | 1675 | } |
1678 | 1676 | ||
1679 | if (!(nlh->nlmsg_flags & NLM_F_CREATE)) | 1677 | if (!(nlh->nlmsg_flags & NLM_F_CREATE)) { |
1678 | if (ifm->ifi_index == 0 && tb[IFLA_GROUP]) | ||
1679 | return rtnl_group_changelink(net, | ||
1680 | nla_get_u32(tb[IFLA_GROUP]), | ||
1681 | ifm, tb); | ||
1680 | return -ENODEV; | 1682 | return -ENODEV; |
1683 | } | ||
1681 | 1684 | ||
1682 | if (ifm->ifi_index) | 1685 | if (ifm->ifi_index) |
1683 | return -EOPNOTSUPP; | 1686 | return -EOPNOTSUPP; |