From c66b721a502cbbc15be8bd7c79c305fa40f1e6ce Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 17 Nov 2006 12:29:21 -0200 Subject: [DECNET]: Use kmemdup Code diff stats: [acme@newtoy net-2.6.20]$ codiff /tmp/decnet.ko.before /tmp/decnet.ko.after /pub/scm/linux/kernel/git/acme/net-2.6.20/net/decnet/dn_dev.c: dn_dev_sysctl_register | -51 1 function changed, 51 bytes removed [acme@newtoy net-2.6.20]$ Signed-off-by: Arnaldo Carvalho de Melo --- net/decnet/dn_dev.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'net/decnet/dn_dev.c') diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c index 01861feb608..5b451e196fb 100644 --- a/net/decnet/dn_dev.c +++ b/net/decnet/dn_dev.c @@ -255,12 +255,10 @@ static void dn_dev_sysctl_register(struct net_device *dev, struct dn_dev_parms * struct dn_dev_sysctl_table *t; int i; - t = kmalloc(sizeof(*t), GFP_KERNEL); + t = kmemdup(&dn_dev_sysctl, sizeof(*t), GFP_KERNEL); if (t == NULL) return; - memcpy(t, &dn_dev_sysctl, sizeof(*t)); - for(i = 0; i < ARRAY_SIZE(t->dn_dev_vars) - 1; i++) { long offset = (long)t->dn_dev_vars[i].data; t->dn_dev_vars[i].data = ((char *)parms) + offset; -- cgit v1.2.3 From a6f01cace3a6532c6f22d8e2fdefed3632ea61b2 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Fri, 24 Nov 2006 17:14:07 -0800 Subject: [DECNET] address: Calculate accurate message size for netlink notifications Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- net/decnet/dn_dev.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'net/decnet/dn_dev.c') diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c index 5b451e196fb..2459a8d236a 100644 --- a/net/decnet/dn_dev.c +++ b/net/decnet/dn_dev.c @@ -38,7 +38,6 @@ #include #include #include -#include #include #include #include @@ -47,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -711,6 +711,14 @@ static int dn_dev_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *a return rv; } +static inline size_t dn_ifaddr_nlmsg_size(void) +{ + return NLMSG_ALIGN(sizeof(struct ifaddrmsg)) + + nla_total_size(IFNAMSIZ) /* IFA_LABEL */ + + nla_total_size(2) /* IFA_ADDRESS */ + + nla_total_size(2); /* IFA_LOCAL */ +} + static int dn_dev_fill_ifaddr(struct sk_buff *skb, struct dn_ifaddr *ifa, u32 pid, u32 seq, int event, unsigned int flags) { @@ -744,18 +752,15 @@ rtattr_failure: static void rtmsg_ifa(int event, struct dn_ifaddr *ifa) { struct sk_buff *skb; - int payload = sizeof(struct ifaddrmsg) + 128; int err = -ENOBUFS; - skb = alloc_skb(nlmsg_total_size(payload), GFP_KERNEL); + skb = alloc_skb(dn_ifaddr_nlmsg_size(), GFP_KERNEL); if (skb == NULL) goto errout; err = dn_dev_fill_ifaddr(skb, ifa, 0, 0, event, 0); - if (err < 0) { - kfree_skb(skb); - goto errout; - } + /* failure implies BUG in dn_ifaddr_nlmsg_size() */ + BUG_ON(err < 0); err = rtnl_notify(skb, 0, RTNLGRP_DECnet_IFADDR, NULL, GFP_KERNEL); errout: -- cgit v1.2.3 From b020b942cdc238e9761cb38598eda6691c366d68 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Fri, 24 Nov 2006 17:14:31 -0800 Subject: [DECNET] address: Rename rtmsg_ifa() to dn_ifaddr_notify() The name rtmsg_ifa is heavly overused and confusing. Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- net/decnet/dn_dev.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'net/decnet/dn_dev.c') diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c index 2459a8d236a..309b2c7a4c6 100644 --- a/net/decnet/dn_dev.c +++ b/net/decnet/dn_dev.c @@ -73,7 +73,7 @@ static BLOCKING_NOTIFIER_HEAD(dnaddr_chain); static struct dn_dev *dn_dev_create(struct net_device *dev, int *err); static void dn_dev_delete(struct net_device *dev); -static void rtmsg_ifa(int event, struct dn_ifaddr *ifa); +static void dn_ifaddr_notify(int event, struct dn_ifaddr *ifa); static int dn_eth_up(struct net_device *); static void dn_eth_down(struct net_device *); @@ -440,7 +440,7 @@ static void dn_dev_del_ifa(struct dn_dev *dn_db, struct dn_ifaddr **ifap, int de } } - rtmsg_ifa(RTM_DELADDR, ifa1); + dn_ifaddr_notify(RTM_DELADDR, ifa1); blocking_notifier_call_chain(&dnaddr_chain, NETDEV_DOWN, ifa1); if (destroy) { dn_dev_free_ifa(ifa1); @@ -475,7 +475,7 @@ static int dn_dev_insert_ifa(struct dn_dev *dn_db, struct dn_ifaddr *ifa) ifa->ifa_next = dn_db->ifa_list; dn_db->ifa_list = ifa; - rtmsg_ifa(RTM_NEWADDR, ifa); + dn_ifaddr_notify(RTM_NEWADDR, ifa); blocking_notifier_call_chain(&dnaddr_chain, NETDEV_UP, ifa); return 0; @@ -749,7 +749,7 @@ rtattr_failure: return -1; } -static void rtmsg_ifa(int event, struct dn_ifaddr *ifa) +static void dn_ifaddr_notify(int event, struct dn_ifaddr *ifa) { struct sk_buff *skb; int err = -ENOBUFS; -- cgit v1.2.3 From 4a89c2562cb81c24c515b9de041aced4d21cb6d1 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Fri, 24 Nov 2006 17:14:51 -0800 Subject: [DECNET] address: Convert to new netlink interface Extends the netlink interface to support the __le16 type and converts address addition, deletion and, dumping to use the new netlink interface. Fixes multiple occasions of possible illegal memory references due to not validated netlink attributes. Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- net/decnet/dn_dev.c | 142 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 85 insertions(+), 57 deletions(-) (limited to 'net/decnet/dn_dev.c') diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c index 309b2c7a4c6..0b9d4c95515 100644 --- a/net/decnet/dn_dev.c +++ b/net/decnet/dn_dev.c @@ -645,41 +645,62 @@ static struct dn_dev *dn_dev_by_index(int ifindex) return dn_dev; } -static int dn_dev_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) +static struct nla_policy dn_ifa_policy[IFA_MAX+1] __read_mostly = { + [IFA_ADDRESS] = { .type = NLA_U16 }, + [IFA_LOCAL] = { .type = NLA_U16 }, + [IFA_LABEL] = { .type = NLA_STRING, + .len = IFNAMSIZ - 1 }, +}; + +static int dn_nl_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) { - struct rtattr **rta = arg; + struct nlattr *tb[IFA_MAX+1]; struct dn_dev *dn_db; - struct ifaddrmsg *ifm = NLMSG_DATA(nlh); + struct ifaddrmsg *ifm; struct dn_ifaddr *ifa, **ifap; + int err = -EADDRNOTAVAIL; + + err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, dn_ifa_policy); + if (err < 0) + goto errout; + ifm = nlmsg_data(nlh); if ((dn_db = dn_dev_by_index(ifm->ifa_index)) == NULL) - return -EADDRNOTAVAIL; + goto errout; + + for (ifap = &dn_db->ifa_list; (ifa = *ifap); ifap = &ifa->ifa_next) { + if (tb[IFA_LOCAL] && + nla_memcmp(tb[IFA_LOCAL], &ifa->ifa_local, 2)) + continue; - for(ifap = &dn_db->ifa_list; (ifa=*ifap) != NULL; ifap = &ifa->ifa_next) { - void *tmp = rta[IFA_LOCAL-1]; - if ((tmp && memcmp(RTA_DATA(tmp), &ifa->ifa_local, 2)) || - (rta[IFA_LABEL-1] && rtattr_strcmp(rta[IFA_LABEL-1], ifa->ifa_label))) + if (tb[IFA_LABEL] && nla_strcmp(tb[IFA_LABEL], ifa->ifa_label)) continue; dn_dev_del_ifa(dn_db, ifap, 1); return 0; } - return -EADDRNOTAVAIL; +errout: + return err; } -static int dn_dev_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) +static int dn_nl_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) { - struct rtattr **rta = arg; + struct nlattr *tb[IFA_MAX+1]; struct net_device *dev; struct dn_dev *dn_db; - struct ifaddrmsg *ifm = NLMSG_DATA(nlh); + struct ifaddrmsg *ifm; struct dn_ifaddr *ifa; - int rv; + int err; + + err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, dn_ifa_policy); + if (err < 0) + return err; - if (rta[IFA_LOCAL-1] == NULL) + if (tb[IFA_LOCAL] == NULL) return -EINVAL; + ifm = nlmsg_data(nlh); if ((dev = __dev_get_by_index(ifm->ifa_index)) == NULL) return -ENODEV; @@ -693,22 +714,25 @@ static int dn_dev_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *a if ((ifa = dn_dev_alloc_ifa()) == NULL) return -ENOBUFS; - if (!rta[IFA_ADDRESS - 1]) - rta[IFA_ADDRESS - 1] = rta[IFA_LOCAL - 1]; - memcpy(&ifa->ifa_local, RTA_DATA(rta[IFA_LOCAL-1]), 2); - memcpy(&ifa->ifa_address, RTA_DATA(rta[IFA_ADDRESS-1]), 2); + if (tb[IFA_ADDRESS] == NULL) + tb[IFA_ADDRESS] = tb[IFA_LOCAL]; + + ifa->ifa_local = nla_get_le16(tb[IFA_LOCAL]); + ifa->ifa_address = nla_get_le16(tb[IFA_ADDRESS]); ifa->ifa_flags = ifm->ifa_flags; ifa->ifa_scope = ifm->ifa_scope; ifa->ifa_dev = dn_db; - if (rta[IFA_LABEL-1]) - rtattr_strlcpy(ifa->ifa_label, rta[IFA_LABEL-1], IFNAMSIZ); + + if (tb[IFA_LABEL]) + nla_strlcpy(ifa->ifa_label, tb[IFA_LABEL], IFNAMSIZ); else memcpy(ifa->ifa_label, dev->name, IFNAMSIZ); - rv = dn_dev_insert_ifa(dn_db, ifa); - if (rv) + err = dn_dev_insert_ifa(dn_db, ifa); + if (err) dn_dev_free_ifa(ifa); - return rv; + + return err; } static inline size_t dn_ifaddr_nlmsg_size(void) @@ -719,34 +743,34 @@ static inline size_t dn_ifaddr_nlmsg_size(void) + nla_total_size(2); /* IFA_LOCAL */ } -static int dn_dev_fill_ifaddr(struct sk_buff *skb, struct dn_ifaddr *ifa, - u32 pid, u32 seq, int event, unsigned int flags) +static int dn_nl_fill_ifaddr(struct sk_buff *skb, struct dn_ifaddr *ifa, + u32 pid, u32 seq, int event, unsigned int flags) { struct ifaddrmsg *ifm; struct nlmsghdr *nlh; - unsigned char *b = skb->tail; - nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*ifm), flags); - ifm = NLMSG_DATA(nlh); + nlh = nlmsg_put(skb, pid, seq, event, sizeof(*ifm), flags); + if (nlh == NULL) + return -ENOBUFS; + ifm = nlmsg_data(nlh); ifm->ifa_family = AF_DECnet; ifm->ifa_prefixlen = 16; ifm->ifa_flags = ifa->ifa_flags | IFA_F_PERMANENT; ifm->ifa_scope = ifa->ifa_scope; ifm->ifa_index = ifa->ifa_dev->dev->ifindex; + if (ifa->ifa_address) - RTA_PUT(skb, IFA_ADDRESS, 2, &ifa->ifa_address); + NLA_PUT_LE16(skb, IFA_ADDRESS, ifa->ifa_address); if (ifa->ifa_local) - RTA_PUT(skb, IFA_LOCAL, 2, &ifa->ifa_local); + NLA_PUT_LE16(skb, IFA_LOCAL, ifa->ifa_local); if (ifa->ifa_label[0]) - RTA_PUT(skb, IFA_LABEL, IFNAMSIZ, &ifa->ifa_label); - nlh->nlmsg_len = skb->tail - b; - return skb->len; + NLA_PUT_STRING(skb, IFA_LABEL, ifa->ifa_label); -nlmsg_failure: -rtattr_failure: - skb_trim(skb, b - skb->data); - return -1; + return nlmsg_end(skb, nlh); + +nla_put_failure: + return nlmsg_cancel(skb, nlh); } static void dn_ifaddr_notify(int event, struct dn_ifaddr *ifa) @@ -758,7 +782,7 @@ static void dn_ifaddr_notify(int event, struct dn_ifaddr *ifa) if (skb == NULL) goto errout; - err = dn_dev_fill_ifaddr(skb, ifa, 0, 0, event, 0); + err = dn_nl_fill_ifaddr(skb, ifa, 0, 0, event, 0); /* failure implies BUG in dn_ifaddr_nlmsg_size() */ BUG_ON(err < 0); @@ -768,39 +792,43 @@ errout: rtnl_set_sk_err(RTNLGRP_DECnet_IFADDR, err); } -static int dn_dev_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) +static int dn_nl_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) { - int idx, dn_idx; - int s_idx, s_dn_idx; + int idx, dn_idx = 0, skip_ndevs, skip_naddr; struct net_device *dev; struct dn_dev *dn_db; struct dn_ifaddr *ifa; - s_idx = cb->args[0]; - s_dn_idx = dn_idx = cb->args[1]; + skip_ndevs = cb->args[0]; + skip_naddr = cb->args[1]; + read_lock(&dev_base_lock); - for(dev = dev_base, idx = 0; dev; dev = dev->next, idx++) { - if (idx < s_idx) + for (dev = dev_base, idx = 0; dev; dev = dev->next, idx++) { + if (idx < skip_ndevs) continue; - if (idx > s_idx) - s_dn_idx = 0; + else if (idx > skip_ndevs) { + /* Only skip over addresses for first dev dumped + * in this iteration (idx == skip_ndevs) */ + skip_naddr = 0; + } + if ((dn_db = dev->dn_ptr) == NULL) continue; - for(ifa = dn_db->ifa_list, dn_idx = 0; ifa; ifa = ifa->ifa_next, dn_idx++) { - if (dn_idx < s_dn_idx) + for (ifa = dn_db->ifa_list, dn_idx = 0; ifa; + ifa = ifa->ifa_next, dn_idx++) { + if (dn_idx < skip_naddr) continue; - if (dn_dev_fill_ifaddr(skb, ifa, - NETLINK_CB(cb->skb).pid, - cb->nlh->nlmsg_seq, - RTM_NEWADDR, - NLM_F_MULTI) <= 0) + if (dn_nl_fill_ifaddr(skb, ifa, NETLINK_CB(cb->skb).pid, + cb->nlh->nlmsg_seq, RTM_NEWADDR, + NLM_F_MULTI) < 0) goto done; } } done: read_unlock(&dev_base_lock); + cb->args[0] = idx; cb->args[1] = dn_idx; @@ -1417,9 +1445,9 @@ static struct file_operations dn_dev_seq_fops = { static struct rtnetlink_link dnet_rtnetlink_table[RTM_NR_MSGTYPES] = { - [RTM_NEWADDR - RTM_BASE] = { .doit = dn_dev_rtm_newaddr, }, - [RTM_DELADDR - RTM_BASE] = { .doit = dn_dev_rtm_deladdr, }, - [RTM_GETADDR - RTM_BASE] = { .dumpit = dn_dev_dump_ifaddr, }, + [RTM_NEWADDR - RTM_BASE] = { .doit = dn_nl_newaddr, }, + [RTM_DELADDR - RTM_BASE] = { .doit = dn_nl_deladdr, }, + [RTM_GETADDR - RTM_BASE] = { .dumpit = dn_nl_dump_ifaddr, }, #ifdef CONFIG_DECNET_ROUTER [RTM_NEWROUTE - RTM_BASE] = { .doit = dn_fib_rtm_newroute, }, [RTM_DELROUTE - RTM_BASE] = { .doit = dn_fib_rtm_delroute, }, -- cgit v1.2.3 From 1f29bcd739972f71f2fd5d5d265daf3e1208fa5e Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Sun, 10 Dec 2006 02:19:10 -0800 Subject: [PATCH] sysctl: remove unused "context" param Signed-off-by: Alexey Dobriyan Cc: Andi Kleen Cc: "David S. Miller" Cc: David Howells Cc: Ralf Baechle Cc: "Eric W. Biederman" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- net/decnet/dn_dev.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'net/decnet/dn_dev.c') diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c index 0b9d4c95515..fc6f3c023a5 100644 --- a/net/decnet/dn_dev.c +++ b/net/decnet/dn_dev.c @@ -167,8 +167,7 @@ static int dn_forwarding_proc(ctl_table *, int, struct file *, void __user *, size_t *, loff_t *); static int dn_forwarding_sysctl(ctl_table *table, int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp, - void __user *newval, size_t newlen, - void **context); + void __user *newval, size_t newlen); static struct dn_dev_sysctl_table { struct ctl_table_header *sysctl_header; @@ -347,8 +346,7 @@ static int dn_forwarding_proc(ctl_table *table, int write, static int dn_forwarding_sysctl(ctl_table *table, int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp, - void __user *newval, size_t newlen, - void **context) + void __user *newval, size_t newlen) { #ifdef CONFIG_DECNET_ROUTER struct net_device *dev = table->extra1; -- cgit v1.2.3