From: Patrick McHardy <kaber@trash.net>
To: jamal <hadi@cyberus.ca>
Cc: Maillist netdev <netdev@oss.sgi.com>
Subject: [PATCH PKT_SCHED 6/22]: Add rtattr_strlcpy, use it where appropriate
Date: Mon, 10 Jan 2005 20:37:52 +0100 [thread overview]
Message-ID: <41E2D990.6040406@trash.net> (raw)
[-- Attachment #1: Type: text/plain, Size: 1 bytes --]
[-- Attachment #2: 06.diff --]
[-- Type: text/x-patch, Size: 14751 bytes --]
# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
# 2005/01/09 22:53:27+01:00 kaber@coreworks.de
# [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@trash.net>
#
# net/sched/sch_api.c
# 2005/01/09 22:53:18+01:00 kaber@coreworks.de +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@trash.net>
#
# net/sched/cls_api.c
# 2005/01/09 22:53:18+01:00 kaber@coreworks.de +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@trash.net>
#
# net/sched/act_api.c
# 2005/01/09 22:53:18+01:00 kaber@coreworks.de +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@trash.net>
#
# net/ipv4/fib_rules.c
# 2005/01/09 22:53:18+01:00 kaber@coreworks.de +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@trash.net>
#
# net/ipv4/devinet.c
# 2005/01/09 22:53:18+01:00 kaber@coreworks.de +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@trash.net>
#
# net/decnet/dn_rules.c
# 2005/01/09 22:53:18+01:00 kaber@coreworks.de +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@trash.net>
#
# net/decnet/dn_dev.c
# 2005/01/09 22:53:18+01:00 kaber@coreworks.de +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@trash.net>
#
# net/core/rtnetlink.c
# 2005/01/09 22:53:18+01:00 kaber@coreworks.de +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@trash.net>
#
# include/net/pkt_cls.h
# 2005/01/09 22:53:18+01:00 kaber@coreworks.de +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@trash.net>
#
# include/linux/rtnetlink.h
# 2005/01/09 22:53:18+01:00 kaber@coreworks.de +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@trash.net>
#
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);
}
}
reply other threads:[~2005-01-10 19:37 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=41E2D990.6040406@trash.net \
--to=kaber@trash.net \
--cc=hadi@cyberus.ca \
--cc=netdev@oss.sgi.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.