X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;ds=sidebyside;f=net%2Fcore%2Frtnetlink.c;h=331ee518b630a3d0a7defb0a565de585d9d2afae;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=2a8e28941f5647ea18294c68924e69e7e7785818;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 2a8e28941..331ee518b 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -57,6 +57,11 @@ void rtnl_lock(void) { rtnl_shlock(); } + +int rtnl_lock_interruptible(void) +{ + return down_interruptible(&rtnl_sem); +} void rtnl_unlock(void) { @@ -119,6 +124,21 @@ void __rta_fill(struct sk_buff *skb, int attrtype, int attrlen, const void *data memcpy(RTA_DATA(rta), data, attrlen); } +size_t rtattr_strlcpy(char *dest, const struct rtattr *rta, size_t size) +{ + size_t ret = RTA_PAYLOAD(rta); + char *src = RTA_DATA(rta); + + if (ret > 0 && src[ret - 1] == '\0') + ret--; + if (size > 0) { + size_t len = (ret >= size) ? size - 1 : ret; + memset(dest, 0, size); + memcpy(dest, src, len); + } + return ret; +} + int rtnetlink_send(struct sk_buff *skb, u32 pid, unsigned group, int echo) { int err = 0; @@ -241,7 +261,7 @@ rtattr_failure: return -1; } -int rtnetlink_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) +static int rtnetlink_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) { int idx; int s_idx = cb->args[0]; @@ -270,7 +290,18 @@ static int do_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) struct net_device *dev; int err, send_addr_notify = 0; - dev = dev_get_by_index(ifm->ifi_index); + if (ifm->ifi_index >= 0) + dev = dev_get_by_index(ifm->ifi_index); + else if (ida[IFLA_IFNAME - 1]) { + char ifname[IFNAMSIZ]; + + if (rtattr_strlcpy(ifname, ida[IFLA_IFNAME - 1], + IFNAMSIZ) >= IFNAMSIZ) + return -EINVAL; + dev = dev_get_by_name(ifname); + } else + return -EINVAL; + if (!dev) return -ENODEV; @@ -361,19 +392,13 @@ static int do_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) dev->weight = *((u32 *) RTA_DATA(ida[IFLA_WEIGHT - 1])); } - if (ida[IFLA_IFNAME - 1]) { + if (ifm->ifi_index >= 0 && ida[IFLA_IFNAME - 1]) { char ifname[IFNAMSIZ]; - if (ida[IFLA_IFNAME - 1]->rta_len > RTA_LENGTH(sizeof(ifname))) + if (rtattr_strlcpy(ifname, ida[IFLA_IFNAME - 1], + IFNAMSIZ) >= IFNAMSIZ) goto out; - - memset(ifname, 0, sizeof(ifname)); - memcpy(ifname, RTA_DATA(ida[IFLA_IFNAME - 1]), - RTA_PAYLOAD(ida[IFLA_IFNAME - 1])); - ifname[IFNAMSIZ - 1] = '\0'; - err = dev_change_name(dev, ifname); - if (err) goto out; } @@ -681,11 +706,12 @@ void __init rtnetlink_init(void) } EXPORT_SYMBOL(__rta_fill); +EXPORT_SYMBOL(rtattr_strlcpy); EXPORT_SYMBOL(rtattr_parse); -EXPORT_SYMBOL(rtnetlink_dump_ifinfo); EXPORT_SYMBOL(rtnetlink_links); EXPORT_SYMBOL(rtnetlink_put_metrics); EXPORT_SYMBOL(rtnl); EXPORT_SYMBOL(rtnl_lock); +EXPORT_SYMBOL(rtnl_lock_interruptible); EXPORT_SYMBOL(rtnl_sem); EXPORT_SYMBOL(rtnl_unlock);