netdev
[Top] [All Lists]

[PATCH PKT_SCHED 6/22]: Add rtattr_strlcpy, use it where appropriate

To: jamal <hadi@xxxxxxxxxx>
Subject: [PATCH PKT_SCHED 6/22]: Add rtattr_strlcpy, use it where appropriate
From: Patrick McHardy <kaber@xxxxxxxxx>
Date: Mon, 10 Jan 2005 20:37:52 +0100
Cc: Maillist netdev <netdev@xxxxxxxxxxx>
Sender: netdev-bounce@xxxxxxxxxxx
User-agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.7.3) Gecko/20041008 Debian/1.7.3-5

# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2005/01/09 22:53:27+01:00 kaber@xxxxxxxxxxxx 
#   [RTNETLINK]: Add rtattr_strlcpy, use it where appropriate
#   
#   Add rtattr_strlcpy to handle unterminated strings. The destination
#   is nulled out entirely to avoid possible leaks when dumping. The
#   return value can be checked for >= size to detect truncated strings.
#   Currently strings equal to the size of the destination are accepted
#   everywhere even if not null-terminated. Sometimes they are silently
#   truncated, sometimes the unterminated string is used.
#   
#   Signed-off-by: Patrick McHardy <kaber@xxxxxxxxx>
# 
# net/sched/sch_api.c
#   2005/01/09 22:53:18+01:00 kaber@xxxxxxxxxxxx +3 -2
#   [RTNETLINK]: Add rtattr_strlcpy, use it where appropriate
#   
#   Add rtattr_strlcpy to handle unterminated strings. The destination
#   is nulled out entirely to avoid possible leaks when dumping. The
#   return value can be checked for >= size to detect truncated strings.
#   Currently strings equal to the size of the destination are accepted
#   everywhere even if not null-terminated. Sometimes they are silently
#   truncated, sometimes the unterminated string is used.
#   
#   Signed-off-by: Patrick McHardy <kaber@xxxxxxxxx>
# 
# net/sched/cls_api.c
#   2005/01/09 22:53:18+01:00 kaber@xxxxxxxxxxxx +3 -2
#   [RTNETLINK]: Add rtattr_strlcpy, use it where appropriate
#   
#   Add rtattr_strlcpy to handle unterminated strings. The destination
#   is nulled out entirely to avoid possible leaks when dumping. The
#   return value can be checked for >= size to detect truncated strings.
#   Currently strings equal to the size of the destination are accepted
#   everywhere even if not null-terminated. Sometimes they are silently
#   truncated, sometimes the unterminated string is used.
#   
#   Signed-off-by: Patrick McHardy <kaber@xxxxxxxxx>
# 
# net/sched/act_api.c
#   2005/01/09 22:53:18+01:00 kaber@xxxxxxxxxxxx +7 -18
#   [RTNETLINK]: Add rtattr_strlcpy, use it where appropriate
#   
#   Add rtattr_strlcpy to handle unterminated strings. The destination
#   is nulled out entirely to avoid possible leaks when dumping. The
#   return value can be checked for >= size to detect truncated strings.
#   Currently strings equal to the size of the destination are accepted
#   everywhere even if not null-terminated. Sometimes they are silently
#   truncated, sometimes the unterminated string is used.
#   
#   Signed-off-by: Patrick McHardy <kaber@xxxxxxxxx>
# 
# net/ipv4/fib_rules.c
#   2005/01/09 22:53:18+01:00 kaber@xxxxxxxxxxxx +1 -2
#   [RTNETLINK]: Add rtattr_strlcpy, use it where appropriate
#   
#   Add rtattr_strlcpy to handle unterminated strings. The destination
#   is nulled out entirely to avoid possible leaks when dumping. The
#   return value can be checked for >= size to detect truncated strings.
#   Currently strings equal to the size of the destination are accepted
#   everywhere even if not null-terminated. Sometimes they are silently
#   truncated, sometimes the unterminated string is used.
#   
#   Signed-off-by: Patrick McHardy <kaber@xxxxxxxxx>
# 
# net/ipv4/devinet.c
#   2005/01/09 22:53:18+01:00 kaber@xxxxxxxxxxxx +1 -1
#   [RTNETLINK]: Add rtattr_strlcpy, use it where appropriate
#   
#   Add rtattr_strlcpy to handle unterminated strings. The destination
#   is nulled out entirely to avoid possible leaks when dumping. The
#   return value can be checked for >= size to detect truncated strings.
#   Currently strings equal to the size of the destination are accepted
#   everywhere even if not null-terminated. Sometimes they are silently
#   truncated, sometimes the unterminated string is used.
#   
#   Signed-off-by: Patrick McHardy <kaber@xxxxxxxxx>
# 
# net/decnet/dn_rules.c
#   2005/01/09 22:53:18+01:00 kaber@xxxxxxxxxxxx +1 -2
#   [RTNETLINK]: Add rtattr_strlcpy, use it where appropriate
#   
#   Add rtattr_strlcpy to handle unterminated strings. The destination
#   is nulled out entirely to avoid possible leaks when dumping. The
#   return value can be checked for >= size to detect truncated strings.
#   Currently strings equal to the size of the destination are accepted
#   everywhere even if not null-terminated. Sometimes they are silently
#   truncated, sometimes the unterminated string is used.
#   
#   Signed-off-by: Patrick McHardy <kaber@xxxxxxxxx>
# 
# net/decnet/dn_dev.c
#   2005/01/09 22:53:18+01:00 kaber@xxxxxxxxxxxx +1 -1
#   [RTNETLINK]: Add rtattr_strlcpy, use it where appropriate
#   
#   Add rtattr_strlcpy to handle unterminated strings. The destination
#   is nulled out entirely to avoid possible leaks when dumping. The
#   return value can be checked for >= size to detect truncated strings.
#   Currently strings equal to the size of the destination are accepted
#   everywhere even if not null-terminated. Sometimes they are silently
#   truncated, sometimes the unterminated string is used.
#   
#   Signed-off-by: Patrick McHardy <kaber@xxxxxxxxx>
# 
# net/core/rtnetlink.c
#   2005/01/09 22:53:18+01:00 kaber@xxxxxxxxxxxx +20 -14
#   [RTNETLINK]: Add rtattr_strlcpy, use it where appropriate
#   
#   Add rtattr_strlcpy to handle unterminated strings. The destination
#   is nulled out entirely to avoid possible leaks when dumping. The
#   return value can be checked for >= size to detect truncated strings.
#   Currently strings equal to the size of the destination are accepted
#   everywhere even if not null-terminated. Sometimes they are silently
#   truncated, sometimes the unterminated string is used.
#   
#   Signed-off-by: Patrick McHardy <kaber@xxxxxxxxx>
# 
# include/net/pkt_cls.h
#   2005/01/09 22:53:18+01:00 kaber@xxxxxxxxxxxx +1 -7
#   [RTNETLINK]: Add rtattr_strlcpy, use it where appropriate
#   
#   Add rtattr_strlcpy to handle unterminated strings. The destination
#   is nulled out entirely to avoid possible leaks when dumping. The
#   return value can be checked for >= size to detect truncated strings.
#   Currently strings equal to the size of the destination are accepted
#   everywhere even if not null-terminated. Sometimes they are silently
#   truncated, sometimes the unterminated string is used.
#   
#   Signed-off-by: Patrick McHardy <kaber@xxxxxxxxx>
# 
# include/linux/rtnetlink.h
#   2005/01/09 22:53:18+01:00 kaber@xxxxxxxxxxxx +1 -0
#   [RTNETLINK]: Add rtattr_strlcpy, use it where appropriate
#   
#   Add rtattr_strlcpy to handle unterminated strings. The destination
#   is nulled out entirely to avoid possible leaks when dumping. The
#   return value can be checked for >= size to detect truncated strings.
#   Currently strings equal to the size of the destination are accepted
#   everywhere even if not null-terminated. Sometimes they are silently
#   truncated, sometimes the unterminated string is used.
#   
#   Signed-off-by: Patrick McHardy <kaber@xxxxxxxxx>
# 
diff -Nru a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
--- a/include/linux/rtnetlink.h 2005-01-10 06:22:06 +01:00
+++ b/include/linux/rtnetlink.h 2005-01-10 06:22:06 +01:00
@@ -748,6 +748,7 @@
 
 #include <linux/config.h>
 
+extern size_t rtattr_strlcpy(char *dest, const struct rtattr *rta, size_t 
size);
 static __inline__ int rtattr_strcmp(const struct rtattr *rta, const char *str)
 {
        int len = strlen(str) + 1;
diff -Nru a/include/net/pkt_cls.h b/include/net/pkt_cls.h
--- a/include/net/pkt_cls.h     2005-01-10 06:22:06 +01:00
+++ b/include/net/pkt_cls.h     2005-01-10 06:22:06 +01:00
@@ -148,14 +148,8 @@
 static inline int
 tcf_change_indev(struct tcf_proto *tp, char *indev, struct rtattr *indev_tlv)
 {
-       if (RTA_PAYLOAD(indev_tlv) >= IFNAMSIZ) {
-               printk("cls: bad indev name %s\n", (char *) 
RTA_DATA(indev_tlv));
+       if (rtattr_strlcpy(indev, indev_tlv, IFNAMSIZ) >= IFNAMSIZ)
                return -EINVAL;
-       }
-
-       memset(indev, 0, IFNAMSIZ);
-       sprintf(indev, "%s", (char *) RTA_DATA(indev_tlv));
-
        return 0;
 }
 
diff -Nru a/net/core/rtnetlink.c b/net/core/rtnetlink.c
--- a/net/core/rtnetlink.c      2005-01-10 06:22:06 +01:00
+++ b/net/core/rtnetlink.c      2005-01-10 06:22:06 +01:00
@@ -119,6 +119,21 @@
        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;
@@ -272,13 +287,9 @@
        else if (ida[IFLA_IFNAME - 1]) {
                char ifname[IFNAMSIZ];
 
-               if (RTA_PAYLOAD(ida[IFLA_IFNAME - 1]) > 
RTA_ALIGN(sizeof(ifname)))
+               if (rtattr_strlcpy(ifname, ida[IFLA_IFNAME - 1],
+                                  IFNAMSIZ) >= IFNAMSIZ)
                        return -EINVAL;
-
-               memset(ifname, 0, sizeof(ifname));
-               memcpy(ifname, RTA_DATA(ida[IFLA_IFNAME - 1]),
-                       RTA_PAYLOAD(ida[IFLA_IFNAME - 1]));
-               ifname[IFNAMSIZ - 1] = '\0';
                dev = dev_get_by_name(ifname);
        } else
                return -EINVAL;
@@ -376,16 +387,10 @@
        if (ifm->ifi_index >= 0 && ida[IFLA_IFNAME - 1]) {
                char ifname[IFNAMSIZ];
 
-               if (RTA_PAYLOAD(ida[IFLA_IFNAME - 1]) > 
RTA_ALIGN(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;
        }
@@ -690,6 +695,7 @@
 }
 
 EXPORT_SYMBOL(__rta_fill);
+EXPORT_SYMBOL(rtattr_strlcpy);
 EXPORT_SYMBOL(rtattr_parse);
 EXPORT_SYMBOL(rtnetlink_dump_ifinfo);
 EXPORT_SYMBOL(rtnetlink_links);
diff -Nru a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c
--- a/net/decnet/dn_dev.c       2005-01-10 06:22:06 +01:00
+++ b/net/decnet/dn_dev.c       2005-01-10 06:22:06 +01:00
@@ -705,7 +705,7 @@
        ifa->ifa_scope = ifm->ifa_scope;
        ifa->ifa_dev = dn_db;
        if (rta[IFA_LABEL-1])
-               memcpy(ifa->ifa_label, RTA_DATA(rta[IFA_LABEL-1]), IFNAMSIZ);
+               rtattr_strlcpy(ifa->ifa_label, rta[IFA_LABEL-1], IFNAMSIZ);
        else
                memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
 
diff -Nru a/net/decnet/dn_rules.c b/net/decnet/dn_rules.c
--- a/net/decnet/dn_rules.c     2005-01-10 06:22:06 +01:00
+++ b/net/decnet/dn_rules.c     2005-01-10 06:22:06 +01:00
@@ -170,8 +170,7 @@
        new_r->r_table = table_id;
        if (rta[RTA_IIF-1]) {
                struct net_device *dev;
-               memcpy(new_r->r_ifname, RTA_DATA(rta[RTA_IIF-1]), IFNAMSIZ);
-               new_r->r_ifname[IFNAMSIZ-1] = 0;
+               rtattr_strlcpy(new_r->r_ifname, rta[RTA_IIF-1], IFNAMSIZ);
                new_r->r_ifindex = -1;
                dev = dev_get_by_name(new_r->r_ifname);
                if (dev) {
diff -Nru a/net/ipv4/devinet.c b/net/ipv4/devinet.c
--- a/net/ipv4/devinet.c        2005-01-10 06:22:06 +01:00
+++ b/net/ipv4/devinet.c        2005-01-10 06:22:06 +01:00
@@ -456,7 +456,7 @@
        in_dev_hold(in_dev);
        ifa->ifa_dev   = in_dev;
        if (rta[IFA_LABEL - 1])
-               memcpy(ifa->ifa_label, RTA_DATA(rta[IFA_LABEL - 1]), IFNAMSIZ);
+               rtattr_strlcpy(ifa->ifa_label, rta[IFA_LABEL - 1], IFNAMSIZ);
        else
                memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
 
diff -Nru a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c
--- a/net/ipv4/fib_rules.c      2005-01-10 06:22:06 +01:00
+++ b/net/ipv4/fib_rules.c      2005-01-10 06:22:06 +01:00
@@ -209,8 +209,7 @@
        new_r->r_table = table_id;
        if (rta[RTA_IIF-1]) {
                struct net_device *dev;
-               memcpy(new_r->r_ifname, RTA_DATA(rta[RTA_IIF-1]), IFNAMSIZ);
-               new_r->r_ifname[IFNAMSIZ-1] = 0;
+               rtattr_strlcpy(new_r->r_ifname, rta[RTA_IIF-1], IFNAMSIZ);
                new_r->r_ifindex = -1;
                dev = __dev_get_by_name(new_r->r_ifname);
                if (dev)
diff -Nru a/net/sched/act_api.c b/net/sched/act_api.c
--- a/net/sched/act_api.c       2005-01-10 06:22:06 +01:00
+++ b/net/sched/act_api.c       2005-01-10 06:22:06 +01:00
@@ -272,7 +272,7 @@
 {
        struct tc_action *a;
        struct tc_action_ops *a_o;
-       char act_name[4 + IFNAMSIZ + 1];
+       char act_name[IFNAMSIZ];
        struct rtattr *tb[TCA_ACT_MAX+1];
        struct rtattr *kind;
 
@@ -284,12 +284,9 @@
                        goto err_out;
                kind = tb[TCA_ACT_KIND-1];
                if (kind != NULL) {
-                       sprintf(act_name, "%s", (char*)RTA_DATA(kind));
-                       if (RTA_PAYLOAD(kind) >= IFNAMSIZ) {
-                               printk("Action %s bad\n",
-                                       (char*)RTA_DATA(kind));
+                       if (rtattr_strlcpy(act_name, kind,
+                                          IFNAMSIZ) >= IFNAMSIZ)
                                goto err_out;
-                       }
                } else {
                        printk("Action bad kind\n");
                        goto err_out;
@@ -492,7 +489,7 @@
                             struct nlmsghdr *n, u32 pid)
 {
        struct tc_action_ops *a_o;
-       char act_name[4 + IFNAMSIZ + 1];
+       char act_name[IFNAMSIZ];
        struct rtattr *tb[TCA_ACT_MAX+1];
        struct rtattr *kind;
        int index;
@@ -502,12 +499,8 @@
                goto err_out;
        kind = tb[TCA_ACT_KIND-1];
        if (kind != NULL) {
-               sprintf(act_name, "%s", (char*)RTA_DATA(kind));
-               if (RTA_PAYLOAD(kind) >= IFNAMSIZ) {
-                       printk("tcf_action_get_1: action %s bad\n",
-                              (char*)RTA_DATA(kind));
+               if (rtattr_strlcpy(act_name, kind, IFNAMSIZ) >= IFNAMSIZ)
                        goto err_out;
-               }
        } else {
                printk("tcf_action_get_1: action bad kind\n");
                goto err_out;
@@ -562,16 +555,12 @@
 
 static struct tc_action_ops *get_ao(struct rtattr *kind, struct tc_action *a)
 {
-       char act_name[4 + IFNAMSIZ + 1];
+       char act_name[IFNAMSIZ];
        struct tc_action_ops *a_o;
 
        if (kind != NULL) {
-               sprintf(act_name, "%s", (char*)RTA_DATA(kind));
-               if (RTA_PAYLOAD(kind) >= IFNAMSIZ) {
-                       printk("get_ao: action %s bad\n",
-                              (char*)RTA_DATA(kind));
+               if (rtattr_strlcpy(act_name, kind, IFNAMSIZ) >= IFNAMSIZ)
                        return NULL;
-               }
        } else {
                printk("get_ao: action bad kind\n");
                return NULL;
diff -Nru a/net/sched/cls_api.c b/net/sched/cls_api.c
--- a/net/sched/cls_api.c       2005-01-10 06:22:06 +01:00
+++ b/net/sched/cls_api.c       2005-01-10 06:22:06 +01:00
@@ -215,9 +215,10 @@
 #ifdef CONFIG_KMOD
                if (tp_ops==NULL && tca[TCA_KIND-1] != NULL) {
                        struct rtattr *kind = tca[TCA_KIND-1];
+                       char name[IFNAMSIZ];
 
-                       if (RTA_PAYLOAD(kind) <= IFNAMSIZ) {
-                               request_module("cls_%s", (char*)RTA_DATA(kind));
+                       if (rtattr_strlcpy(name, kind, IFNAMSIZ) < IFNAMSIZ) {
+                               request_module("cls_%s", name);
                                tp_ops = tcf_proto_lookup_ops(kind);
                        }
                }
diff -Nru a/net/sched/sch_api.c b/net/sched/sch_api.c
--- a/net/sched/sch_api.c       2005-01-10 06:22:06 +01:00
+++ b/net/sched/sch_api.c       2005-01-10 06:22:06 +01:00
@@ -407,8 +407,9 @@
        ops = qdisc_lookup_ops(kind);
 #ifdef CONFIG_KMOD
        if (ops==NULL && tca[TCA_KIND-1] != NULL) {
-               if (RTA_PAYLOAD(kind) <= IFNAMSIZ) {
-                       request_module("sch_%s", (char*)RTA_DATA(kind));
+               char name[IFNAMSIZ];
+               if (rtattr_strlcpy(name, kind, IFNAMSIZ) < IFNAMSIZ) {
+                       request_module("sch_%s", name);
                        ops = qdisc_lookup_ops(kind);
                }
        }
<Prev in Thread] Current Thread [Next in Thread>
  • [PATCH PKT_SCHED 6/22]: Add rtattr_strlcpy, use it where appropriate, Patrick McHardy <=