netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC][PATCH v3 0/3] Fix inefficiences and rename nla_strlcpy
@ 2020-10-20 16:47 laniel_francis
  2020-10-20 16:47 ` [RFC][PATCH v3 1/3] Fix unefficient call to memset before memcpu in nla_strlcpy laniel_francis
                   ` (2 more replies)
  0 siblings, 3 replies; 17+ messages in thread
From: laniel_francis @ 2020-10-20 16:47 UTC (permalink / raw)
  To: linux-hardening, netdev; +Cc: davem, kuba, Francis Laniel

From: Francis Laniel <laniel_francis@privacyrequired.com>

Hi.


I hope your relatives and yourselves are fine.

This patch set answers to first three issues listed in:
https://github.com/KSPP/linux/issues/110

To sum up, the first patch fixes an inefficiency where some bytes in dst were
written twice, one with 0 the other with src content.
The second one modifies nla_strlcpy to return the same value as strscpy,
i.e. number of bytes written or -E2BIG if src was truncated.
The third rename nla_strlcpy to nla_strscpy.

The name nla_strscpy should be discussed and agreed to find a representative
name (nla_strscpy_pad, nla_strcpy, nla_strzcpy, etc.).

Unfortunately, I did not find how to create struct nlattr objects so I tested
my modifications on simple char* and withing GDB with tc to get to
tcf_proto_check_kind.
This is why I tagged this patch set as RFC.

If you see any way to improve the code or have any remark, feel free to comment.


Best regards.

Francis Laniel (3):
  Fix unefficient call to memset before memcpu in nla_strlcpy.
  Modify return value of nla_strlcpy to match that of strscpy.
  Rename nla_strlcpy to nla_strscpy.

 drivers/infiniband/core/nldev.c            | 10 +++---
 drivers/net/can/vxcan.c                    |  4 +--
 drivers/net/veth.c                         |  4 +--
 include/linux/genl_magic_struct.h          |  2 +-
 include/net/netlink.h                      |  4 +--
 include/net/pkt_cls.h                      |  2 +-
 kernel/taskstats.c                         |  2 +-
 lib/nlattr.c                               | 42 ++++++++++++++--------
 net/core/fib_rules.c                       |  4 +--
 net/core/rtnetlink.c                       | 12 +++----
 net/decnet/dn_dev.c                        |  2 +-
 net/ieee802154/nl-mac.c                    |  2 +-
 net/ipv4/devinet.c                         |  2 +-
 net/ipv4/fib_semantics.c                   |  2 +-
 net/ipv4/metrics.c                         |  2 +-
 net/netfilter/ipset/ip_set_hash_netiface.c |  4 +--
 net/netfilter/nf_tables_api.c              |  6 ++--
 net/netfilter/nfnetlink_acct.c             |  2 +-
 net/netfilter/nfnetlink_cthelper.c         |  4 +--
 net/netfilter/nft_ct.c                     |  2 +-
 net/netfilter/nft_log.c                    |  2 +-
 net/netlabel/netlabel_mgmt.c               |  2 +-
 net/nfc/netlink.c                          |  2 +-
 net/sched/act_api.c                        |  2 +-
 net/sched/act_ipt.c                        |  2 +-
 net/sched/act_simple.c                     |  4 +--
 net/sched/cls_api.c                        |  2 +-
 net/sched/sch_api.c                        |  2 +-
 net/tipc/netlink_compat.c                  |  2 +-
 29 files changed, 73 insertions(+), 61 deletions(-)

-- 
2.20.1


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [RFC][PATCH v3 1/3] Fix unefficient call to memset before memcpu in nla_strlcpy.
  2020-10-20 16:47 [RFC][PATCH v3 0/3] Fix inefficiences and rename nla_strlcpy laniel_francis
@ 2020-10-20 16:47 ` laniel_francis
  2020-10-21 23:46   ` Kees Cook
  2020-10-20 16:47 ` [RFC][PATCH v3 2/3] Modify return value of nla_strlcpy to match that of strscpy laniel_francis
  2020-10-20 16:47 ` [RFC][PATCH v3 3/3] Rename nla_strlcpy to nla_strscpy laniel_francis
  2 siblings, 1 reply; 17+ messages in thread
From: laniel_francis @ 2020-10-20 16:47 UTC (permalink / raw)
  To: linux-hardening, netdev; +Cc: davem, kuba, Francis Laniel

From: Francis Laniel <laniel_francis@privacyrequired.com>

Before this commit, nla_strlcpy first memseted dst to 0 then wrote src into it.
This is inefficient because bytes whom number is less than src length are written
twice.

This patch solves this issue by first writing src into dst then fill dst with
0's.
Note that, in the case where src length is higher than dst, only 0 is written.
Otherwise there are as many 0's written to fill dst.

For example, if src is "foo\0" and dst is 5 bytes long, the result will be:
1. "fooGG" after memcpy (G means garbage).
2. "foo\0\0" after memset.

Signed-off-by: Francis Laniel <laniel_francis@privacyrequired.com>
---
 lib/nlattr.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lib/nlattr.c b/lib/nlattr.c
index 74019c8ebf6b..07156e581997 100644
--- a/lib/nlattr.c
+++ b/lib/nlattr.c
@@ -731,8 +731,9 @@ size_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize)
 	if (dstsize > 0) {
 		size_t len = (srclen >= dstsize) ? dstsize - 1 : srclen;
 
-		memset(dst, 0, dstsize);
 		memcpy(dst, src, len);
+		/* Zero pad end of dst. */
+		memset(dst + len, 0, dstsize - len);
 	}
 
 	return srclen;
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [RFC][PATCH v3 2/3] Modify return value of nla_strlcpy to match that of strscpy.
  2020-10-20 16:47 [RFC][PATCH v3 0/3] Fix inefficiences and rename nla_strlcpy laniel_francis
  2020-10-20 16:47 ` [RFC][PATCH v3 1/3] Fix unefficient call to memset before memcpu in nla_strlcpy laniel_francis
@ 2020-10-20 16:47 ` laniel_francis
  2020-10-21 23:48   ` Kees Cook
  2020-10-20 16:47 ` [RFC][PATCH v3 3/3] Rename nla_strlcpy to nla_strscpy laniel_francis
  2 siblings, 1 reply; 17+ messages in thread
From: laniel_francis @ 2020-10-20 16:47 UTC (permalink / raw)
  To: linux-hardening, netdev; +Cc: davem, kuba, Francis Laniel

From: Francis Laniel <laniel_francis@privacyrequired.com>

nla_strlcpy now returns -E2BIG if src was truncated when written to dst.
It also returns this error value if dstsize is 0 or higher than INT_MAX.

For example, if src is "foo\0" and dst is 3 bytes long, the result will be:
1. "foG" after memcpy (G means garbage).
2. "fo\0" after memset.
3. -E2BIG is returned because src was not completely written into dst.

The callers of nla_strlcpy were modified to take into account this modification.

Signed-off-by: Francis Laniel <laniel_francis@privacyrequired.com>
---
 include/net/netlink.h |  2 +-
 include/net/pkt_cls.h |  2 +-
 lib/nlattr.c          | 39 +++++++++++++++++++++++++--------------
 net/sched/act_api.c   |  2 +-
 net/sched/cls_api.c   |  2 +-
 net/sched/sch_api.c   |  2 +-
 6 files changed, 30 insertions(+), 19 deletions(-)

diff --git a/include/net/netlink.h b/include/net/netlink.h
index 7356f41d23ba..446ca182e13d 100644
--- a/include/net/netlink.h
+++ b/include/net/netlink.h
@@ -506,7 +506,7 @@ int __nla_parse(struct nlattr **tb, int maxtype, const struct nlattr *head,
 		struct netlink_ext_ack *extack);
 int nla_policy_len(const struct nla_policy *, int);
 struct nlattr *nla_find(const struct nlattr *head, int len, int attrtype);
-size_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize);
+ssize_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize);
 char *nla_strdup(const struct nlattr *nla, gfp_t flags);
 int nla_memcpy(void *dest, const struct nlattr *src, int count);
 int nla_memcmp(const struct nlattr *nla, const void *data, size_t size);
diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
index d4d461236351..db9a828f4f4f 100644
--- a/include/net/pkt_cls.h
+++ b/include/net/pkt_cls.h
@@ -512,7 +512,7 @@ tcf_change_indev(struct net *net, struct nlattr *indev_tlv,
 	char indev[IFNAMSIZ];
 	struct net_device *dev;
 
-	if (nla_strlcpy(indev, indev_tlv, IFNAMSIZ) >= IFNAMSIZ) {
+	if (nla_strlcpy(indev, indev_tlv, IFNAMSIZ) < 0) {
 		NL_SET_ERR_MSG_ATTR(extack, indev_tlv,
 				    "Interface name too long");
 		return -EINVAL;
diff --git a/lib/nlattr.c b/lib/nlattr.c
index 07156e581997..447182543c03 100644
--- a/lib/nlattr.c
+++ b/lib/nlattr.c
@@ -710,33 +710,44 @@ EXPORT_SYMBOL(nla_find);
 
 /**
  * nla_strlcpy - Copy string attribute payload into a sized buffer
- * @dst: where to copy the string to
- * @nla: attribute to copy the string from
- * @dstsize: size of destination buffer
+ * @dst: Where to copy the string to.
+ * @nla: Attribute to copy the string from.
+ * @dstsize: Size of destination buffer.
  *
  * Copies at most dstsize - 1 bytes into the destination buffer.
- * The result is always a valid NUL-terminated string. Unlike
- * strlcpy the destination buffer is always padded out.
+ * Unlike strlcpy the destination buffer is always padded out.
  *
- * Returns the length of the source buffer.
+ * Return:
+ * * srclen - Returns @nla length (not including the trailing %NUL).
+ * * -E2BIG - If @dstsize is 0 or greater than U16_MAX or @nla length greater
+ *            than @dstsize.
  */
-size_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize)
+ssize_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize)
 {
 	size_t srclen = nla_len(nla);
 	char *src = nla_data(nla);
+	ssize_t ret;
+	size_t len;
+
+	if (dstsize == 0 || WARN_ON_ONCE(dstsize > U16_MAX))
+		return -E2BIG;
 
 	if (srclen > 0 && src[srclen - 1] == '\0')
 		srclen--;
 
-	if (dstsize > 0) {
-		size_t len = (srclen >= dstsize) ? dstsize - 1 : srclen;
-
-		memcpy(dst, src, len);
-		/* Zero pad end of dst. */
-		memset(dst + len, 0, dstsize - len);
+	if (srclen >= dstsize) {
+		len = dstsize - 1;
+		ret = -E2BIG;
+	} else {
+		len = srclen;
+		ret = len;
 	}
 
-	return srclen;
+	memcpy(dst, src, len);
+	/* Zero pad end of dst. */
+	memset(dst + len, 0, dstsize - len);
+
+	return ret;
 }
 EXPORT_SYMBOL(nla_strlcpy);
 
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index f66417d5d2c3..541574520c52 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -935,7 +935,7 @@ struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
 			NL_SET_ERR_MSG(extack, "TC action kind must be specified");
 			goto err_out;
 		}
-		if (nla_strlcpy(act_name, kind, IFNAMSIZ) >= IFNAMSIZ) {
+		if (nla_strlcpy(act_name, kind, IFNAMSIZ) < 0) {
 			NL_SET_ERR_MSG(extack, "TC action name too long");
 			goto err_out;
 		}
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 41a55c6cbeb8..c78241c853a5 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -223,7 +223,7 @@ static inline u32 tcf_auto_prio(struct tcf_proto *tp)
 static bool tcf_proto_check_kind(struct nlattr *kind, char *name)
 {
 	if (kind)
-		return nla_strlcpy(name, kind, IFNAMSIZ) >= IFNAMSIZ;
+		return nla_strlcpy(name, kind, IFNAMSIZ) < 0;
 	memset(name, 0, IFNAMSIZ);
 	return false;
 }
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 2a76a2f5ed88..f9b053b30a7b 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -1170,7 +1170,7 @@ static struct Qdisc *qdisc_create(struct net_device *dev,
 #ifdef CONFIG_MODULES
 	if (ops == NULL && kind != NULL) {
 		char name[IFNAMSIZ];
-		if (nla_strlcpy(name, kind, IFNAMSIZ) < IFNAMSIZ) {
+		if (nla_strlcpy(name, kind, IFNAMSIZ) > 0) {
 			/* We dropped the RTNL semaphore in order to
 			 * perform the module load.  So, even if we
 			 * succeeded in loading the module we have to
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [RFC][PATCH v3 3/3] Rename nla_strlcpy to nla_strscpy.
  2020-10-20 16:47 [RFC][PATCH v3 0/3] Fix inefficiences and rename nla_strlcpy laniel_francis
  2020-10-20 16:47 ` [RFC][PATCH v3 1/3] Fix unefficient call to memset before memcpu in nla_strlcpy laniel_francis
  2020-10-20 16:47 ` [RFC][PATCH v3 2/3] Modify return value of nla_strlcpy to match that of strscpy laniel_francis
@ 2020-10-20 16:47 ` laniel_francis
  2020-10-21 23:49   ` Kees Cook
  2 siblings, 1 reply; 17+ messages in thread
From: laniel_francis @ 2020-10-20 16:47 UTC (permalink / raw)
  To: linux-hardening, netdev; +Cc: davem, kuba, Francis Laniel

From: Francis Laniel <laniel_francis@privacyrequired.com>

Calls to nla_strlcpy are now replaced by calls to nla_strscpy which is the new
name of this function.

Signed-off-by: Francis Laniel <laniel_francis@privacyrequired.com>
---
 drivers/infiniband/core/nldev.c            | 10 +++++-----
 drivers/net/can/vxcan.c                    |  4 ++--
 drivers/net/veth.c                         |  4 ++--
 include/linux/genl_magic_struct.h          |  2 +-
 include/net/netlink.h                      |  4 ++--
 include/net/pkt_cls.h                      |  2 +-
 kernel/taskstats.c                         |  2 +-
 lib/nlattr.c                               |  6 +++---
 net/core/fib_rules.c                       |  4 ++--
 net/core/rtnetlink.c                       | 12 ++++++------
 net/decnet/dn_dev.c                        |  2 +-
 net/ieee802154/nl-mac.c                    |  2 +-
 net/ipv4/devinet.c                         |  2 +-
 net/ipv4/fib_semantics.c                   |  2 +-
 net/ipv4/metrics.c                         |  2 +-
 net/netfilter/ipset/ip_set_hash_netiface.c |  4 ++--
 net/netfilter/nf_tables_api.c              |  6 +++---
 net/netfilter/nfnetlink_acct.c             |  2 +-
 net/netfilter/nfnetlink_cthelper.c         |  4 ++--
 net/netfilter/nft_ct.c                     |  2 +-
 net/netfilter/nft_log.c                    |  2 +-
 net/netlabel/netlabel_mgmt.c               |  2 +-
 net/nfc/netlink.c                          |  2 +-
 net/sched/act_api.c                        |  2 +-
 net/sched/act_ipt.c                        |  2 +-
 net/sched/act_simple.c                     |  4 ++--
 net/sched/cls_api.c                        |  2 +-
 net/sched/sch_api.c                        |  2 +-
 net/tipc/netlink_compat.c                  |  2 +-
 29 files changed, 49 insertions(+), 49 deletions(-)

diff --git a/drivers/infiniband/core/nldev.c b/drivers/infiniband/core/nldev.c
index 12d29d54a081..08366e254b1d 100644
--- a/drivers/infiniband/core/nldev.c
+++ b/drivers/infiniband/core/nldev.c
@@ -932,7 +932,7 @@ static int nldev_set_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
 	if (tb[RDMA_NLDEV_ATTR_DEV_NAME]) {
 		char name[IB_DEVICE_NAME_MAX] = {};
 
-		nla_strlcpy(name, tb[RDMA_NLDEV_ATTR_DEV_NAME],
+		nla_strscpy(name, tb[RDMA_NLDEV_ATTR_DEV_NAME],
 			    IB_DEVICE_NAME_MAX);
 		if (strlen(name) == 0) {
 			err = -EINVAL;
@@ -1529,13 +1529,13 @@ static int nldev_newlink(struct sk_buff *skb, struct nlmsghdr *nlh,
 	    !tb[RDMA_NLDEV_ATTR_LINK_TYPE] || !tb[RDMA_NLDEV_ATTR_NDEV_NAME])
 		return -EINVAL;
 
-	nla_strlcpy(ibdev_name, tb[RDMA_NLDEV_ATTR_DEV_NAME],
+	nla_strscpy(ibdev_name, tb[RDMA_NLDEV_ATTR_DEV_NAME],
 		    sizeof(ibdev_name));
 	if (strchr(ibdev_name, '%') || strlen(ibdev_name) == 0)
 		return -EINVAL;
 
-	nla_strlcpy(type, tb[RDMA_NLDEV_ATTR_LINK_TYPE], sizeof(type));
-	nla_strlcpy(ndev_name, tb[RDMA_NLDEV_ATTR_NDEV_NAME],
+	nla_strscpy(type, tb[RDMA_NLDEV_ATTR_LINK_TYPE], sizeof(type));
+	nla_strscpy(ndev_name, tb[RDMA_NLDEV_ATTR_NDEV_NAME],
 		    sizeof(ndev_name));
 
 	ndev = dev_get_by_name(sock_net(skb->sk), ndev_name);
@@ -1602,7 +1602,7 @@ static int nldev_get_chardev(struct sk_buff *skb, struct nlmsghdr *nlh,
 	if (err || !tb[RDMA_NLDEV_ATTR_CHARDEV_TYPE])
 		return -EINVAL;
 
-	nla_strlcpy(client_name, tb[RDMA_NLDEV_ATTR_CHARDEV_TYPE],
+	nla_strscpy(client_name, tb[RDMA_NLDEV_ATTR_CHARDEV_TYPE],
 		    sizeof(client_name));
 
 	if (tb[RDMA_NLDEV_ATTR_DEV_INDEX]) {
diff --git a/drivers/net/can/vxcan.c b/drivers/net/can/vxcan.c
index d6ba9426be4d..fa47bab510bb 100644
--- a/drivers/net/can/vxcan.c
+++ b/drivers/net/can/vxcan.c
@@ -186,7 +186,7 @@ static int vxcan_newlink(struct net *net, struct net_device *dev,
 	}
 
 	if (ifmp && tbp[IFLA_IFNAME]) {
-		nla_strlcpy(ifname, tbp[IFLA_IFNAME], IFNAMSIZ);
+		nla_strscpy(ifname, tbp[IFLA_IFNAME], IFNAMSIZ);
 		name_assign_type = NET_NAME_USER;
 	} else {
 		snprintf(ifname, IFNAMSIZ, DRV_NAME "%%d");
@@ -223,7 +223,7 @@ static int vxcan_newlink(struct net *net, struct net_device *dev,
 
 	/* register first device */
 	if (tb[IFLA_IFNAME])
-		nla_strlcpy(dev->name, tb[IFLA_IFNAME], IFNAMSIZ);
+		nla_strscpy(dev->name, tb[IFLA_IFNAME], IFNAMSIZ);
 	else
 		snprintf(dev->name, IFNAMSIZ, DRV_NAME "%%d");
 
diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index 8c737668008a..359d3ab33c4d 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -1329,7 +1329,7 @@ static int veth_newlink(struct net *src_net, struct net_device *dev,
 	}
 
 	if (ifmp && tbp[IFLA_IFNAME]) {
-		nla_strlcpy(ifname, tbp[IFLA_IFNAME], IFNAMSIZ);
+		nla_strscpy(ifname, tbp[IFLA_IFNAME], IFNAMSIZ);
 		name_assign_type = NET_NAME_USER;
 	} else {
 		snprintf(ifname, IFNAMSIZ, DRV_NAME "%%d");
@@ -1379,7 +1379,7 @@ static int veth_newlink(struct net *src_net, struct net_device *dev,
 		eth_hw_addr_random(dev);
 
 	if (tb[IFLA_IFNAME])
-		nla_strlcpy(dev->name, tb[IFLA_IFNAME], IFNAMSIZ);
+		nla_strscpy(dev->name, tb[IFLA_IFNAME], IFNAMSIZ);
 	else
 		snprintf(dev->name, IFNAMSIZ, DRV_NAME "%%d");
 
diff --git a/include/linux/genl_magic_struct.h b/include/linux/genl_magic_struct.h
index eeae59d3ceb7..35d21fddaf2d 100644
--- a/include/linux/genl_magic_struct.h
+++ b/include/linux/genl_magic_struct.h
@@ -89,7 +89,7 @@ static inline int nla_put_u64_0pad(struct sk_buff *skb, int attrtype, u64 value)
 			nla_get_u64, nla_put_u64_0pad, false)
 #define __str_field(attr_nr, attr_flag, name, maxlen) \
 	__array(attr_nr, attr_flag, name, NLA_NUL_STRING, char, maxlen, \
-			nla_strlcpy, nla_put, false)
+			nla_strscpy, nla_put, false)
 #define __bin_field(attr_nr, attr_flag, name, maxlen) \
 	__array(attr_nr, attr_flag, name, NLA_BINARY, char, maxlen, \
 			nla_memcpy, nla_put, false)
diff --git a/include/net/netlink.h b/include/net/netlink.h
index 446ca182e13d..1ceec518ab49 100644
--- a/include/net/netlink.h
+++ b/include/net/netlink.h
@@ -142,7 +142,7 @@
  * Attribute Misc:
  *   nla_memcpy(dest, nla, count)	copy attribute into memory
  *   nla_memcmp(nla, data, size)	compare attribute with memory area
- *   nla_strlcpy(dst, nla, size)	copy attribute to a sized string
+ *   nla_strscpy(dst, nla, size)	copy attribute to a sized string
  *   nla_strcmp(nla, str)		compare attribute with string
  *
  * Attribute Parsing:
@@ -506,7 +506,7 @@ int __nla_parse(struct nlattr **tb, int maxtype, const struct nlattr *head,
 		struct netlink_ext_ack *extack);
 int nla_policy_len(const struct nla_policy *, int);
 struct nlattr *nla_find(const struct nlattr *head, int len, int attrtype);
-ssize_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize);
+ssize_t nla_strscpy(char *dst, const struct nlattr *nla, size_t dstsize);
 char *nla_strdup(const struct nlattr *nla, gfp_t flags);
 int nla_memcpy(void *dest, const struct nlattr *src, int count);
 int nla_memcmp(const struct nlattr *nla, const void *data, size_t size);
diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
index db9a828f4f4f..133f9ad4d4f9 100644
--- a/include/net/pkt_cls.h
+++ b/include/net/pkt_cls.h
@@ -512,7 +512,7 @@ tcf_change_indev(struct net *net, struct nlattr *indev_tlv,
 	char indev[IFNAMSIZ];
 	struct net_device *dev;
 
-	if (nla_strlcpy(indev, indev_tlv, IFNAMSIZ) < 0) {
+	if (nla_strscpy(indev, indev_tlv, IFNAMSIZ) < 0) {
 		NL_SET_ERR_MSG_ATTR(extack, indev_tlv,
 				    "Interface name too long");
 		return -EINVAL;
diff --git a/kernel/taskstats.c b/kernel/taskstats.c
index a2802b6ff4bb..2b4898b4752e 100644
--- a/kernel/taskstats.c
+++ b/kernel/taskstats.c
@@ -346,7 +346,7 @@ static int parse(struct nlattr *na, struct cpumask *mask)
 	data = kmalloc(len, GFP_KERNEL);
 	if (!data)
 		return -ENOMEM;
-	nla_strlcpy(data, na, len);
+	nla_strscpy(data, na, len);
 	ret = cpulist_parse(data, mask);
 	kfree(data);
 	return ret;
diff --git a/lib/nlattr.c b/lib/nlattr.c
index 447182543c03..09aa181569e0 100644
--- a/lib/nlattr.c
+++ b/lib/nlattr.c
@@ -709,7 +709,7 @@ struct nlattr *nla_find(const struct nlattr *head, int len, int attrtype)
 EXPORT_SYMBOL(nla_find);
 
 /**
- * nla_strlcpy - Copy string attribute payload into a sized buffer
+ * nla_strscpy - Copy string attribute payload into a sized buffer
  * @dst: Where to copy the string to.
  * @nla: Attribute to copy the string from.
  * @dstsize: Size of destination buffer.
@@ -722,7 +722,7 @@ EXPORT_SYMBOL(nla_find);
  * * -E2BIG - If @dstsize is 0 or greater than U16_MAX or @nla length greater
  *            than @dstsize.
  */
-ssize_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize)
+ssize_t nla_strscpy(char *dst, const struct nlattr *nla, size_t dstsize)
 {
 	size_t srclen = nla_len(nla);
 	char *src = nla_data(nla);
@@ -749,7 +749,7 @@ ssize_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize)
 
 	return ret;
 }
-EXPORT_SYMBOL(nla_strlcpy);
+EXPORT_SYMBOL(nla_strscpy);
 
 /**
  * nla_strdup - Copy string attribute payload into a newly allocated buffer
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c
index 7bcfb16854cb..cd80ffed6d26 100644
--- a/net/core/fib_rules.c
+++ b/net/core/fib_rules.c
@@ -563,7 +563,7 @@ static int fib_nl2rule(struct sk_buff *skb, struct nlmsghdr *nlh,
 		struct net_device *dev;
 
 		nlrule->iifindex = -1;
-		nla_strlcpy(nlrule->iifname, tb[FRA_IIFNAME], IFNAMSIZ);
+		nla_strscpy(nlrule->iifname, tb[FRA_IIFNAME], IFNAMSIZ);
 		dev = __dev_get_by_name(net, nlrule->iifname);
 		if (dev)
 			nlrule->iifindex = dev->ifindex;
@@ -573,7 +573,7 @@ static int fib_nl2rule(struct sk_buff *skb, struct nlmsghdr *nlh,
 		struct net_device *dev;
 
 		nlrule->oifindex = -1;
-		nla_strlcpy(nlrule->oifname, tb[FRA_OIFNAME], IFNAMSIZ);
+		nla_strscpy(nlrule->oifname, tb[FRA_OIFNAME], IFNAMSIZ);
 		dev = __dev_get_by_name(net, nlrule->oifname);
 		if (dev)
 			nlrule->oifindex = dev->ifindex;
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 68e0682450c6..e0059256fe93 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -1939,7 +1939,7 @@ static const struct rtnl_link_ops *linkinfo_to_kind_ops(const struct nlattr *nla
 	if (linfo[IFLA_INFO_KIND]) {
 		char kind[MODULE_NAME_LEN];
 
-		nla_strlcpy(kind, linfo[IFLA_INFO_KIND], sizeof(kind));
+		nla_strscpy(kind, linfo[IFLA_INFO_KIND], sizeof(kind));
 		ops = rtnl_link_ops_get(kind);
 	}
 
@@ -2953,9 +2953,9 @@ static struct net_device *rtnl_dev_get(struct net *net,
 	if (!ifname) {
 		ifname = buffer;
 		if (ifname_attr)
-			nla_strlcpy(ifname, ifname_attr, IFNAMSIZ);
+			nla_strscpy(ifname, ifname_attr, IFNAMSIZ);
 		else if (altifname_attr)
-			nla_strlcpy(ifname, altifname_attr, ALTIFNAMSIZ);
+			nla_strscpy(ifname, altifname_attr, ALTIFNAMSIZ);
 		else
 			return NULL;
 	}
@@ -2983,7 +2983,7 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh,
 		goto errout;
 
 	if (tb[IFLA_IFNAME])
-		nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
+		nla_strscpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
 	else
 		ifname[0] = '\0';
 
@@ -3264,7 +3264,7 @@ static int __rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh,
 		return err;
 
 	if (tb[IFLA_IFNAME])
-		nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
+		nla_strscpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
 	else
 		ifname[0] = '\0';
 
@@ -3296,7 +3296,7 @@ static int __rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh,
 		memset(linkinfo, 0, sizeof(linkinfo));
 
 	if (linkinfo[IFLA_INFO_KIND]) {
-		nla_strlcpy(kind, linkinfo[IFLA_INFO_KIND], sizeof(kind));
+		nla_strscpy(kind, linkinfo[IFLA_INFO_KIND], sizeof(kind));
 		ops = rtnl_link_ops_get(kind);
 	} else {
 		kind[0] = '\0';
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c
index 15d42353f1a3..d1c50a48614b 100644
--- a/net/decnet/dn_dev.c
+++ b/net/decnet/dn_dev.c
@@ -658,7 +658,7 @@ static int dn_nl_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh,
 	ifa->ifa_dev = dn_db;
 
 	if (tb[IFA_LABEL])
-		nla_strlcpy(ifa->ifa_label, tb[IFA_LABEL], IFNAMSIZ);
+		nla_strscpy(ifa->ifa_label, tb[IFA_LABEL], IFNAMSIZ);
 	else
 		memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
 
diff --git a/net/ieee802154/nl-mac.c b/net/ieee802154/nl-mac.c
index 6d091e419d3e..9c640d670ffe 100644
--- a/net/ieee802154/nl-mac.c
+++ b/net/ieee802154/nl-mac.c
@@ -149,7 +149,7 @@ static struct net_device *ieee802154_nl_get_dev(struct genl_info *info)
 	if (info->attrs[IEEE802154_ATTR_DEV_NAME]) {
 		char name[IFNAMSIZ + 1];
 
-		nla_strlcpy(name, info->attrs[IEEE802154_ATTR_DEV_NAME],
+		nla_strscpy(name, info->attrs[IEEE802154_ATTR_DEV_NAME],
 			    sizeof(name));
 		dev = dev_get_by_name(&init_net, name);
 	} else if (info->attrs[IEEE802154_ATTR_DEV_INDEX]) {
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 123a6d39438f..a50951a90f63 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -881,7 +881,7 @@ static struct in_ifaddr *rtm_to_ifaddr(struct net *net, struct nlmsghdr *nlh,
 		ifa->ifa_broadcast = nla_get_in_addr(tb[IFA_BROADCAST]);
 
 	if (tb[IFA_LABEL])
-		nla_strlcpy(ifa->ifa_label, tb[IFA_LABEL], IFNAMSIZ);
+		nla_strscpy(ifa->ifa_label, tb[IFA_LABEL], IFNAMSIZ);
 	else
 		memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
 
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index 1f75dc686b6b..4b505074b24f 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -973,7 +973,7 @@ bool fib_metrics_match(struct fib_config *cfg, struct fib_info *fi)
 			char tmp[TCP_CA_NAME_MAX];
 			bool ecn_ca = false;
 
-			nla_strlcpy(tmp, nla, sizeof(tmp));
+			nla_strscpy(tmp, nla, sizeof(tmp));
 			val = tcp_ca_get_key_by_name(fi->fib_net, tmp, &ecn_ca);
 		} else {
 			if (nla_len(nla) != sizeof(u32))
diff --git a/net/ipv4/metrics.c b/net/ipv4/metrics.c
index 3205d5f7c8c9..25ea6ac44db9 100644
--- a/net/ipv4/metrics.c
+++ b/net/ipv4/metrics.c
@@ -31,7 +31,7 @@ static int ip_metrics_convert(struct net *net, struct nlattr *fc_mx,
 		if (type == RTAX_CC_ALGO) {
 			char tmp[TCP_CA_NAME_MAX];
 
-			nla_strlcpy(tmp, nla, sizeof(tmp));
+			nla_strscpy(tmp, nla, sizeof(tmp));
 			val = tcp_ca_get_key_by_name(net, tmp, &ecn_ca);
 			if (val == TCP_CA_UNSPEC) {
 				NL_SET_ERR_MSG(extack, "Unknown tcp congestion algorithm");
diff --git a/net/netfilter/ipset/ip_set_hash_netiface.c b/net/netfilter/ipset/ip_set_hash_netiface.c
index be5e95a0d876..b96fd0c55eaa 100644
--- a/net/netfilter/ipset/ip_set_hash_netiface.c
+++ b/net/netfilter/ipset/ip_set_hash_netiface.c
@@ -225,7 +225,7 @@ hash_netiface4_uadt(struct ip_set *set, struct nlattr *tb[],
 		if (e.cidr > HOST_MASK)
 			return -IPSET_ERR_INVALID_CIDR;
 	}
-	nla_strlcpy(e.iface, tb[IPSET_ATTR_IFACE], IFNAMSIZ);
+	nla_strscpy(e.iface, tb[IPSET_ATTR_IFACE], IFNAMSIZ);
 
 	if (tb[IPSET_ATTR_CADT_FLAGS]) {
 		u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
@@ -442,7 +442,7 @@ hash_netiface6_uadt(struct ip_set *set, struct nlattr *tb[],
 
 	ip6_netmask(&e.ip, e.cidr);
 
-	nla_strlcpy(e.iface, tb[IPSET_ATTR_IFACE], IFNAMSIZ);
+	nla_strscpy(e.iface, tb[IPSET_ATTR_IFACE], IFNAMSIZ);
 
 	if (tb[IPSET_ATTR_CADT_FLAGS]) {
 		u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 9957e0ed8658..90c39e694e87 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -1281,7 +1281,7 @@ static struct nft_chain *nft_chain_lookup(struct net *net,
 	if (nla == NULL)
 		return ERR_PTR(-EINVAL);
 
-	nla_strlcpy(search, nla, sizeof(search));
+	nla_strscpy(search, nla, sizeof(search));
 
 	WARN_ON(!rcu_read_lock_held() &&
 		!lockdep_commit_lock_is_held(net));
@@ -1721,7 +1721,7 @@ static struct nft_hook *nft_netdev_hook_alloc(struct net *net,
 		goto err_hook_alloc;
 	}
 
-	nla_strlcpy(ifname, attr, IFNAMSIZ);
+	nla_strscpy(ifname, attr, IFNAMSIZ);
 	dev = __dev_get_by_name(net, ifname);
 	if (!dev) {
 		err = -ENOENT;
@@ -5734,7 +5734,7 @@ struct nft_object *nft_obj_lookup(const struct net *net,
 	struct rhlist_head *tmp, *list;
 	struct nft_object *obj;
 
-	nla_strlcpy(search, nla, sizeof(search));
+	nla_strscpy(search, nla, sizeof(search));
 	k.name = search;
 
 	WARN_ON_ONCE(!rcu_read_lock_held() &&
diff --git a/net/netfilter/nfnetlink_acct.c b/net/netfilter/nfnetlink_acct.c
index 5bfec829c12f..5e511df8d709 100644
--- a/net/netfilter/nfnetlink_acct.c
+++ b/net/netfilter/nfnetlink_acct.c
@@ -112,7 +112,7 @@ static int nfnl_acct_new(struct net *net, struct sock *nfnl,
 		nfacct->flags = flags;
 	}
 
-	nla_strlcpy(nfacct->name, tb[NFACCT_NAME], NFACCT_NAME_MAX);
+	nla_strscpy(nfacct->name, tb[NFACCT_NAME], NFACCT_NAME_MAX);
 
 	if (tb[NFACCT_BYTES]) {
 		atomic64_set(&nfacct->bytes,
diff --git a/net/netfilter/nfnetlink_cthelper.c b/net/netfilter/nfnetlink_cthelper.c
index 5b0d0a77379c..0f94fce1d3ed 100644
--- a/net/netfilter/nfnetlink_cthelper.c
+++ b/net/netfilter/nfnetlink_cthelper.c
@@ -146,7 +146,7 @@ nfnl_cthelper_expect_policy(struct nf_conntrack_expect_policy *expect_policy,
 	    !tb[NFCTH_POLICY_EXPECT_TIMEOUT])
 		return -EINVAL;
 
-	nla_strlcpy(expect_policy->name,
+	nla_strscpy(expect_policy->name,
 		    tb[NFCTH_POLICY_NAME], NF_CT_HELPER_NAME_LEN);
 	expect_policy->max_expected =
 		ntohl(nla_get_be32(tb[NFCTH_POLICY_EXPECT_MAX]));
@@ -233,7 +233,7 @@ nfnl_cthelper_create(const struct nlattr * const tb[],
 	if (ret < 0)
 		goto err1;
 
-	nla_strlcpy(helper->name,
+	nla_strscpy(helper->name,
 		    tb[NFCTH_NAME], NF_CT_HELPER_NAME_LEN);
 	size = ntohl(nla_get_be32(tb[NFCTH_PRIV_DATA_LEN]));
 	if (size > sizeof_field(struct nf_conn_help, data)) {
diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c
index 322bd674963e..a8c4d442231c 100644
--- a/net/netfilter/nft_ct.c
+++ b/net/netfilter/nft_ct.c
@@ -990,7 +990,7 @@ static int nft_ct_helper_obj_init(const struct nft_ctx *ctx,
 	if (!priv->l4proto)
 		return -ENOENT;
 
-	nla_strlcpy(name, tb[NFTA_CT_HELPER_NAME], sizeof(name));
+	nla_strscpy(name, tb[NFTA_CT_HELPER_NAME], sizeof(name));
 
 	if (tb[NFTA_CT_HELPER_L3PROTO])
 		family = ntohs(nla_get_be16(tb[NFTA_CT_HELPER_L3PROTO]));
diff --git a/net/netfilter/nft_log.c b/net/netfilter/nft_log.c
index 57899454a530..a06a46b039c5 100644
--- a/net/netfilter/nft_log.c
+++ b/net/netfilter/nft_log.c
@@ -152,7 +152,7 @@ static int nft_log_init(const struct nft_ctx *ctx,
 		priv->prefix = kmalloc(nla_len(nla) + 1, GFP_KERNEL);
 		if (priv->prefix == NULL)
 			return -ENOMEM;
-		nla_strlcpy(priv->prefix, nla, nla_len(nla) + 1);
+		nla_strscpy(priv->prefix, nla, nla_len(nla) + 1);
 	} else {
 		priv->prefix = (char *)nft_log_null_prefix;
 	}
diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c
index eb1d66d20afb..df1b41ed73fd 100644
--- a/net/netlabel/netlabel_mgmt.c
+++ b/net/netlabel/netlabel_mgmt.c
@@ -95,7 +95,7 @@ static int netlbl_mgmt_add_common(struct genl_info *info,
 			ret_val = -ENOMEM;
 			goto add_free_entry;
 		}
-		nla_strlcpy(entry->domain,
+		nla_strscpy(entry->domain,
 			    info->attrs[NLBL_MGMT_A_DOMAIN], tmp_size);
 	}
 
diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c
index e894254c17d4..438ff1f30a33 100644
--- a/net/nfc/netlink.c
+++ b/net/nfc/netlink.c
@@ -1226,7 +1226,7 @@ static int nfc_genl_fw_download(struct sk_buff *skb, struct genl_info *info)
 	if (!dev)
 		return -ENODEV;
 
-	nla_strlcpy(firmware_name, info->attrs[NFC_ATTR_FIRMWARE_NAME],
+	nla_strscpy(firmware_name, info->attrs[NFC_ATTR_FIRMWARE_NAME],
 		    sizeof(firmware_name));
 
 	rc = nfc_fw_download(dev, firmware_name);
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 541574520c52..eac24a73115f 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -935,7 +935,7 @@ struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
 			NL_SET_ERR_MSG(extack, "TC action kind must be specified");
 			goto err_out;
 		}
-		if (nla_strlcpy(act_name, kind, IFNAMSIZ) < 0) {
+		if (nla_strscpy(act_name, kind, IFNAMSIZ) < 0) {
 			NL_SET_ERR_MSG(extack, "TC action name too long");
 			goto err_out;
 		}
diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c
index 8dc3bec0d325..ac7297f42355 100644
--- a/net/sched/act_ipt.c
+++ b/net/sched/act_ipt.c
@@ -166,7 +166,7 @@ static int __tcf_ipt_init(struct net *net, unsigned int id, struct nlattr *nla,
 	if (unlikely(!tname))
 		goto err1;
 	if (tb[TCA_IPT_TABLE] == NULL ||
-	    nla_strlcpy(tname, tb[TCA_IPT_TABLE], IFNAMSIZ) >= IFNAMSIZ)
+	    nla_strscpy(tname, tb[TCA_IPT_TABLE], IFNAMSIZ) >= IFNAMSIZ)
 		strcpy(tname, "mangle");
 
 	t = kmemdup(td, td->u.target_size, GFP_KERNEL);
diff --git a/net/sched/act_simple.c b/net/sched/act_simple.c
index a4f3d0f0daa9..726cc956d06f 100644
--- a/net/sched/act_simple.c
+++ b/net/sched/act_simple.c
@@ -52,7 +52,7 @@ static int alloc_defdata(struct tcf_defact *d, const struct nlattr *defdata)
 	d->tcfd_defdata = kzalloc(SIMP_MAX_DATA, GFP_KERNEL);
 	if (unlikely(!d->tcfd_defdata))
 		return -ENOMEM;
-	nla_strlcpy(d->tcfd_defdata, defdata, SIMP_MAX_DATA);
+	nla_strscpy(d->tcfd_defdata, defdata, SIMP_MAX_DATA);
 	return 0;
 }
 
@@ -71,7 +71,7 @@ static int reset_policy(struct tc_action *a, const struct nlattr *defdata,
 	spin_lock_bh(&d->tcf_lock);
 	goto_ch = tcf_action_set_ctrlact(a, p->action, goto_ch);
 	memset(d->tcfd_defdata, 0, SIMP_MAX_DATA);
-	nla_strlcpy(d->tcfd_defdata, defdata, SIMP_MAX_DATA);
+	nla_strscpy(d->tcfd_defdata, defdata, SIMP_MAX_DATA);
 	spin_unlock_bh(&d->tcf_lock);
 	if (goto_ch)
 		tcf_chain_put_by_act(goto_ch);
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index c78241c853a5..6ff3b817083a 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -223,7 +223,7 @@ static inline u32 tcf_auto_prio(struct tcf_proto *tp)
 static bool tcf_proto_check_kind(struct nlattr *kind, char *name)
 {
 	if (kind)
-		return nla_strlcpy(name, kind, IFNAMSIZ) < 0;
+		return nla_strscpy(name, kind, IFNAMSIZ) < 0;
 	memset(name, 0, IFNAMSIZ);
 	return false;
 }
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index f9b053b30a7b..cb4f30700c74 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -1170,7 +1170,7 @@ static struct Qdisc *qdisc_create(struct net_device *dev,
 #ifdef CONFIG_MODULES
 	if (ops == NULL && kind != NULL) {
 		char name[IFNAMSIZ];
-		if (nla_strlcpy(name, kind, IFNAMSIZ) > 0) {
+		if (nla_strscpy(name, kind, IFNAMSIZ) > 0) {
 			/* We dropped the RTNL semaphore in order to
 			 * perform the module load.  So, even if we
 			 * succeeded in loading the module we have to
diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c
index 1c7aa51cc2a3..644c7ec41ddf 100644
--- a/net/tipc/netlink_compat.c
+++ b/net/tipc/netlink_compat.c
@@ -695,7 +695,7 @@ static int tipc_nl_compat_link_dump(struct tipc_nl_compat_msg *msg,
 
 	link_info.dest = nla_get_flag(link[TIPC_NLA_LINK_DEST]);
 	link_info.up = htonl(nla_get_flag(link[TIPC_NLA_LINK_UP]));
-	nla_strlcpy(link_info.str, link[TIPC_NLA_LINK_NAME],
+	nla_strscpy(link_info.str, link[TIPC_NLA_LINK_NAME],
 		    TIPC_MAX_LINK_NAME);
 
 	return tipc_add_tlv(msg->rep, TIPC_TLV_LINK_INFO,
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [RFC][PATCH v3 1/3] Fix unefficient call to memset before memcpu in nla_strlcpy.
  2020-10-20 16:47 ` [RFC][PATCH v3 1/3] Fix unefficient call to memset before memcpu in nla_strlcpy laniel_francis
@ 2020-10-21 23:46   ` Kees Cook
  0 siblings, 0 replies; 17+ messages in thread
From: Kees Cook @ 2020-10-21 23:46 UTC (permalink / raw)
  To: laniel_francis; +Cc: linux-hardening, netdev, davem, kuba

On Tue, Oct 20, 2020 at 06:47:05PM +0200, laniel_francis@privacyrequired.com wrote:
> From: Francis Laniel <laniel_francis@privacyrequired.com>
> 
> Before this commit, nla_strlcpy first memseted dst to 0 then wrote src into it.
> This is inefficient because bytes whom number is less than src length are written
> twice.
> 
> This patch solves this issue by first writing src into dst then fill dst with
> 0's.
> Note that, in the case where src length is higher than dst, only 0 is written.
> Otherwise there are as many 0's written to fill dst.
> 
> For example, if src is "foo\0" and dst is 5 bytes long, the result will be:
> 1. "fooGG" after memcpy (G means garbage).
> 2. "foo\0\0" after memset.
> 
> Signed-off-by: Francis Laniel <laniel_francis@privacyrequired.com>

Looks good! (If there are future versions of this series, I think you
can drop the RFC part...)

Reviewed-by: Kees Cook <keescook@chromium.org>

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC][PATCH v3 2/3] Modify return value of nla_strlcpy to match that of strscpy.
  2020-10-20 16:47 ` [RFC][PATCH v3 2/3] Modify return value of nla_strlcpy to match that of strscpy laniel_francis
@ 2020-10-21 23:48   ` Kees Cook
  2020-10-22  9:40     ` Francis Laniel
  0 siblings, 1 reply; 17+ messages in thread
From: Kees Cook @ 2020-10-21 23:48 UTC (permalink / raw)
  To: laniel_francis; +Cc: linux-hardening, netdev, davem, kuba

On Tue, Oct 20, 2020 at 06:47:06PM +0200, laniel_francis@privacyrequired.com wrote:
> From: Francis Laniel <laniel_francis@privacyrequired.com>
> 
> nla_strlcpy now returns -E2BIG if src was truncated when written to dst.
> It also returns this error value if dstsize is 0 or higher than INT_MAX.
> 
> For example, if src is "foo\0" and dst is 3 bytes long, the result will be:
> 1. "foG" after memcpy (G means garbage).
> 2. "fo\0" after memset.
> 3. -E2BIG is returned because src was not completely written into dst.
> 
> The callers of nla_strlcpy were modified to take into account this modification.
> 
> Signed-off-by: Francis Laniel <laniel_francis@privacyrequired.com>

This looks correct to me. Thanks for the respin!

Reviewed-by: Kees Cook <keescook@chromium.org>

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC][PATCH v3 3/3] Rename nla_strlcpy to nla_strscpy.
  2020-10-20 16:47 ` [RFC][PATCH v3 3/3] Rename nla_strlcpy to nla_strscpy laniel_francis
@ 2020-10-21 23:49   ` Kees Cook
  2020-10-22  9:41     ` Francis Laniel
  0 siblings, 1 reply; 17+ messages in thread
From: Kees Cook @ 2020-10-21 23:49 UTC (permalink / raw)
  To: laniel_francis; +Cc: linux-hardening, netdev, davem, kuba

On Tue, Oct 20, 2020 at 06:47:07PM +0200, laniel_francis@privacyrequired.com wrote:
> From: Francis Laniel <laniel_francis@privacyrequired.com>
> 
> Calls to nla_strlcpy are now replaced by calls to nla_strscpy which is the new
> name of this function.
> 
> Signed-off-by: Francis Laniel <laniel_francis@privacyrequired.com>

The Subject could also be: "treewide: Rename nla_strlcpy to nla_strscpy"

But otherwise, yup, easy mechanical change.

Reviewed-by: Kees Cook <keescook@chromium.org>

> ---
>  drivers/infiniband/core/nldev.c            | 10 +++++-----
>  drivers/net/can/vxcan.c                    |  4 ++--
>  drivers/net/veth.c                         |  4 ++--
>  include/linux/genl_magic_struct.h          |  2 +-
>  include/net/netlink.h                      |  4 ++--
>  include/net/pkt_cls.h                      |  2 +-
>  kernel/taskstats.c                         |  2 +-
>  lib/nlattr.c                               |  6 +++---
>  net/core/fib_rules.c                       |  4 ++--
>  net/core/rtnetlink.c                       | 12 ++++++------
>  net/decnet/dn_dev.c                        |  2 +-
>  net/ieee802154/nl-mac.c                    |  2 +-
>  net/ipv4/devinet.c                         |  2 +-
>  net/ipv4/fib_semantics.c                   |  2 +-
>  net/ipv4/metrics.c                         |  2 +-
>  net/netfilter/ipset/ip_set_hash_netiface.c |  4 ++--
>  net/netfilter/nf_tables_api.c              |  6 +++---
>  net/netfilter/nfnetlink_acct.c             |  2 +-
>  net/netfilter/nfnetlink_cthelper.c         |  4 ++--
>  net/netfilter/nft_ct.c                     |  2 +-
>  net/netfilter/nft_log.c                    |  2 +-
>  net/netlabel/netlabel_mgmt.c               |  2 +-
>  net/nfc/netlink.c                          |  2 +-
>  net/sched/act_api.c                        |  2 +-
>  net/sched/act_ipt.c                        |  2 +-
>  net/sched/act_simple.c                     |  4 ++--
>  net/sched/cls_api.c                        |  2 +-
>  net/sched/sch_api.c                        |  2 +-
>  net/tipc/netlink_compat.c                  |  2 +-
>  29 files changed, 49 insertions(+), 49 deletions(-)
> 
> diff --git a/drivers/infiniband/core/nldev.c b/drivers/infiniband/core/nldev.c
> index 12d29d54a081..08366e254b1d 100644
> --- a/drivers/infiniband/core/nldev.c
> +++ b/drivers/infiniband/core/nldev.c
> @@ -932,7 +932,7 @@ static int nldev_set_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
>  	if (tb[RDMA_NLDEV_ATTR_DEV_NAME]) {
>  		char name[IB_DEVICE_NAME_MAX] = {};
>  
> -		nla_strlcpy(name, tb[RDMA_NLDEV_ATTR_DEV_NAME],
> +		nla_strscpy(name, tb[RDMA_NLDEV_ATTR_DEV_NAME],
>  			    IB_DEVICE_NAME_MAX);
>  		if (strlen(name) == 0) {
>  			err = -EINVAL;
> @@ -1529,13 +1529,13 @@ static int nldev_newlink(struct sk_buff *skb, struct nlmsghdr *nlh,
>  	    !tb[RDMA_NLDEV_ATTR_LINK_TYPE] || !tb[RDMA_NLDEV_ATTR_NDEV_NAME])
>  		return -EINVAL;
>  
> -	nla_strlcpy(ibdev_name, tb[RDMA_NLDEV_ATTR_DEV_NAME],
> +	nla_strscpy(ibdev_name, tb[RDMA_NLDEV_ATTR_DEV_NAME],
>  		    sizeof(ibdev_name));
>  	if (strchr(ibdev_name, '%') || strlen(ibdev_name) == 0)
>  		return -EINVAL;
>  
> -	nla_strlcpy(type, tb[RDMA_NLDEV_ATTR_LINK_TYPE], sizeof(type));
> -	nla_strlcpy(ndev_name, tb[RDMA_NLDEV_ATTR_NDEV_NAME],
> +	nla_strscpy(type, tb[RDMA_NLDEV_ATTR_LINK_TYPE], sizeof(type));
> +	nla_strscpy(ndev_name, tb[RDMA_NLDEV_ATTR_NDEV_NAME],
>  		    sizeof(ndev_name));
>  
>  	ndev = dev_get_by_name(sock_net(skb->sk), ndev_name);
> @@ -1602,7 +1602,7 @@ static int nldev_get_chardev(struct sk_buff *skb, struct nlmsghdr *nlh,
>  	if (err || !tb[RDMA_NLDEV_ATTR_CHARDEV_TYPE])
>  		return -EINVAL;
>  
> -	nla_strlcpy(client_name, tb[RDMA_NLDEV_ATTR_CHARDEV_TYPE],
> +	nla_strscpy(client_name, tb[RDMA_NLDEV_ATTR_CHARDEV_TYPE],
>  		    sizeof(client_name));
>  
>  	if (tb[RDMA_NLDEV_ATTR_DEV_INDEX]) {
> diff --git a/drivers/net/can/vxcan.c b/drivers/net/can/vxcan.c
> index d6ba9426be4d..fa47bab510bb 100644
> --- a/drivers/net/can/vxcan.c
> +++ b/drivers/net/can/vxcan.c
> @@ -186,7 +186,7 @@ static int vxcan_newlink(struct net *net, struct net_device *dev,
>  	}
>  
>  	if (ifmp && tbp[IFLA_IFNAME]) {
> -		nla_strlcpy(ifname, tbp[IFLA_IFNAME], IFNAMSIZ);
> +		nla_strscpy(ifname, tbp[IFLA_IFNAME], IFNAMSIZ);
>  		name_assign_type = NET_NAME_USER;
>  	} else {
>  		snprintf(ifname, IFNAMSIZ, DRV_NAME "%%d");
> @@ -223,7 +223,7 @@ static int vxcan_newlink(struct net *net, struct net_device *dev,
>  
>  	/* register first device */
>  	if (tb[IFLA_IFNAME])
> -		nla_strlcpy(dev->name, tb[IFLA_IFNAME], IFNAMSIZ);
> +		nla_strscpy(dev->name, tb[IFLA_IFNAME], IFNAMSIZ);
>  	else
>  		snprintf(dev->name, IFNAMSIZ, DRV_NAME "%%d");
>  
> diff --git a/drivers/net/veth.c b/drivers/net/veth.c
> index 8c737668008a..359d3ab33c4d 100644
> --- a/drivers/net/veth.c
> +++ b/drivers/net/veth.c
> @@ -1329,7 +1329,7 @@ static int veth_newlink(struct net *src_net, struct net_device *dev,
>  	}
>  
>  	if (ifmp && tbp[IFLA_IFNAME]) {
> -		nla_strlcpy(ifname, tbp[IFLA_IFNAME], IFNAMSIZ);
> +		nla_strscpy(ifname, tbp[IFLA_IFNAME], IFNAMSIZ);
>  		name_assign_type = NET_NAME_USER;
>  	} else {
>  		snprintf(ifname, IFNAMSIZ, DRV_NAME "%%d");
> @@ -1379,7 +1379,7 @@ static int veth_newlink(struct net *src_net, struct net_device *dev,
>  		eth_hw_addr_random(dev);
>  
>  	if (tb[IFLA_IFNAME])
> -		nla_strlcpy(dev->name, tb[IFLA_IFNAME], IFNAMSIZ);
> +		nla_strscpy(dev->name, tb[IFLA_IFNAME], IFNAMSIZ);
>  	else
>  		snprintf(dev->name, IFNAMSIZ, DRV_NAME "%%d");
>  
> diff --git a/include/linux/genl_magic_struct.h b/include/linux/genl_magic_struct.h
> index eeae59d3ceb7..35d21fddaf2d 100644
> --- a/include/linux/genl_magic_struct.h
> +++ b/include/linux/genl_magic_struct.h
> @@ -89,7 +89,7 @@ static inline int nla_put_u64_0pad(struct sk_buff *skb, int attrtype, u64 value)
>  			nla_get_u64, nla_put_u64_0pad, false)
>  #define __str_field(attr_nr, attr_flag, name, maxlen) \
>  	__array(attr_nr, attr_flag, name, NLA_NUL_STRING, char, maxlen, \
> -			nla_strlcpy, nla_put, false)
> +			nla_strscpy, nla_put, false)
>  #define __bin_field(attr_nr, attr_flag, name, maxlen) \
>  	__array(attr_nr, attr_flag, name, NLA_BINARY, char, maxlen, \
>  			nla_memcpy, nla_put, false)
> diff --git a/include/net/netlink.h b/include/net/netlink.h
> index 446ca182e13d..1ceec518ab49 100644
> --- a/include/net/netlink.h
> +++ b/include/net/netlink.h
> @@ -142,7 +142,7 @@
>   * Attribute Misc:
>   *   nla_memcpy(dest, nla, count)	copy attribute into memory
>   *   nla_memcmp(nla, data, size)	compare attribute with memory area
> - *   nla_strlcpy(dst, nla, size)	copy attribute to a sized string
> + *   nla_strscpy(dst, nla, size)	copy attribute to a sized string
>   *   nla_strcmp(nla, str)		compare attribute with string
>   *
>   * Attribute Parsing:
> @@ -506,7 +506,7 @@ int __nla_parse(struct nlattr **tb, int maxtype, const struct nlattr *head,
>  		struct netlink_ext_ack *extack);
>  int nla_policy_len(const struct nla_policy *, int);
>  struct nlattr *nla_find(const struct nlattr *head, int len, int attrtype);
> -ssize_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize);
> +ssize_t nla_strscpy(char *dst, const struct nlattr *nla, size_t dstsize);
>  char *nla_strdup(const struct nlattr *nla, gfp_t flags);
>  int nla_memcpy(void *dest, const struct nlattr *src, int count);
>  int nla_memcmp(const struct nlattr *nla, const void *data, size_t size);
> diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
> index db9a828f4f4f..133f9ad4d4f9 100644
> --- a/include/net/pkt_cls.h
> +++ b/include/net/pkt_cls.h
> @@ -512,7 +512,7 @@ tcf_change_indev(struct net *net, struct nlattr *indev_tlv,
>  	char indev[IFNAMSIZ];
>  	struct net_device *dev;
>  
> -	if (nla_strlcpy(indev, indev_tlv, IFNAMSIZ) < 0) {
> +	if (nla_strscpy(indev, indev_tlv, IFNAMSIZ) < 0) {
>  		NL_SET_ERR_MSG_ATTR(extack, indev_tlv,
>  				    "Interface name too long");
>  		return -EINVAL;
> diff --git a/kernel/taskstats.c b/kernel/taskstats.c
> index a2802b6ff4bb..2b4898b4752e 100644
> --- a/kernel/taskstats.c
> +++ b/kernel/taskstats.c
> @@ -346,7 +346,7 @@ static int parse(struct nlattr *na, struct cpumask *mask)
>  	data = kmalloc(len, GFP_KERNEL);
>  	if (!data)
>  		return -ENOMEM;
> -	nla_strlcpy(data, na, len);
> +	nla_strscpy(data, na, len);
>  	ret = cpulist_parse(data, mask);
>  	kfree(data);
>  	return ret;
> diff --git a/lib/nlattr.c b/lib/nlattr.c
> index 447182543c03..09aa181569e0 100644
> --- a/lib/nlattr.c
> +++ b/lib/nlattr.c
> @@ -709,7 +709,7 @@ struct nlattr *nla_find(const struct nlattr *head, int len, int attrtype)
>  EXPORT_SYMBOL(nla_find);
>  
>  /**
> - * nla_strlcpy - Copy string attribute payload into a sized buffer
> + * nla_strscpy - Copy string attribute payload into a sized buffer
>   * @dst: Where to copy the string to.
>   * @nla: Attribute to copy the string from.
>   * @dstsize: Size of destination buffer.
> @@ -722,7 +722,7 @@ EXPORT_SYMBOL(nla_find);
>   * * -E2BIG - If @dstsize is 0 or greater than U16_MAX or @nla length greater
>   *            than @dstsize.
>   */
> -ssize_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize)
> +ssize_t nla_strscpy(char *dst, const struct nlattr *nla, size_t dstsize)
>  {
>  	size_t srclen = nla_len(nla);
>  	char *src = nla_data(nla);
> @@ -749,7 +749,7 @@ ssize_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize)
>  
>  	return ret;
>  }
> -EXPORT_SYMBOL(nla_strlcpy);
> +EXPORT_SYMBOL(nla_strscpy);
>  
>  /**
>   * nla_strdup - Copy string attribute payload into a newly allocated buffer
> diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c
> index 7bcfb16854cb..cd80ffed6d26 100644
> --- a/net/core/fib_rules.c
> +++ b/net/core/fib_rules.c
> @@ -563,7 +563,7 @@ static int fib_nl2rule(struct sk_buff *skb, struct nlmsghdr *nlh,
>  		struct net_device *dev;
>  
>  		nlrule->iifindex = -1;
> -		nla_strlcpy(nlrule->iifname, tb[FRA_IIFNAME], IFNAMSIZ);
> +		nla_strscpy(nlrule->iifname, tb[FRA_IIFNAME], IFNAMSIZ);
>  		dev = __dev_get_by_name(net, nlrule->iifname);
>  		if (dev)
>  			nlrule->iifindex = dev->ifindex;
> @@ -573,7 +573,7 @@ static int fib_nl2rule(struct sk_buff *skb, struct nlmsghdr *nlh,
>  		struct net_device *dev;
>  
>  		nlrule->oifindex = -1;
> -		nla_strlcpy(nlrule->oifname, tb[FRA_OIFNAME], IFNAMSIZ);
> +		nla_strscpy(nlrule->oifname, tb[FRA_OIFNAME], IFNAMSIZ);
>  		dev = __dev_get_by_name(net, nlrule->oifname);
>  		if (dev)
>  			nlrule->oifindex = dev->ifindex;
> diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
> index 68e0682450c6..e0059256fe93 100644
> --- a/net/core/rtnetlink.c
> +++ b/net/core/rtnetlink.c
> @@ -1939,7 +1939,7 @@ static const struct rtnl_link_ops *linkinfo_to_kind_ops(const struct nlattr *nla
>  	if (linfo[IFLA_INFO_KIND]) {
>  		char kind[MODULE_NAME_LEN];
>  
> -		nla_strlcpy(kind, linfo[IFLA_INFO_KIND], sizeof(kind));
> +		nla_strscpy(kind, linfo[IFLA_INFO_KIND], sizeof(kind));
>  		ops = rtnl_link_ops_get(kind);
>  	}
>  
> @@ -2953,9 +2953,9 @@ static struct net_device *rtnl_dev_get(struct net *net,
>  	if (!ifname) {
>  		ifname = buffer;
>  		if (ifname_attr)
> -			nla_strlcpy(ifname, ifname_attr, IFNAMSIZ);
> +			nla_strscpy(ifname, ifname_attr, IFNAMSIZ);
>  		else if (altifname_attr)
> -			nla_strlcpy(ifname, altifname_attr, ALTIFNAMSIZ);
> +			nla_strscpy(ifname, altifname_attr, ALTIFNAMSIZ);
>  		else
>  			return NULL;
>  	}
> @@ -2983,7 +2983,7 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh,
>  		goto errout;
>  
>  	if (tb[IFLA_IFNAME])
> -		nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
> +		nla_strscpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
>  	else
>  		ifname[0] = '\0';
>  
> @@ -3264,7 +3264,7 @@ static int __rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh,
>  		return err;
>  
>  	if (tb[IFLA_IFNAME])
> -		nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
> +		nla_strscpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
>  	else
>  		ifname[0] = '\0';
>  
> @@ -3296,7 +3296,7 @@ static int __rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh,
>  		memset(linkinfo, 0, sizeof(linkinfo));
>  
>  	if (linkinfo[IFLA_INFO_KIND]) {
> -		nla_strlcpy(kind, linkinfo[IFLA_INFO_KIND], sizeof(kind));
> +		nla_strscpy(kind, linkinfo[IFLA_INFO_KIND], sizeof(kind));
>  		ops = rtnl_link_ops_get(kind);
>  	} else {
>  		kind[0] = '\0';
> diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c
> index 15d42353f1a3..d1c50a48614b 100644
> --- a/net/decnet/dn_dev.c
> +++ b/net/decnet/dn_dev.c
> @@ -658,7 +658,7 @@ static int dn_nl_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh,
>  	ifa->ifa_dev = dn_db;
>  
>  	if (tb[IFA_LABEL])
> -		nla_strlcpy(ifa->ifa_label, tb[IFA_LABEL], IFNAMSIZ);
> +		nla_strscpy(ifa->ifa_label, tb[IFA_LABEL], IFNAMSIZ);
>  	else
>  		memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
>  
> diff --git a/net/ieee802154/nl-mac.c b/net/ieee802154/nl-mac.c
> index 6d091e419d3e..9c640d670ffe 100644
> --- a/net/ieee802154/nl-mac.c
> +++ b/net/ieee802154/nl-mac.c
> @@ -149,7 +149,7 @@ static struct net_device *ieee802154_nl_get_dev(struct genl_info *info)
>  	if (info->attrs[IEEE802154_ATTR_DEV_NAME]) {
>  		char name[IFNAMSIZ + 1];
>  
> -		nla_strlcpy(name, info->attrs[IEEE802154_ATTR_DEV_NAME],
> +		nla_strscpy(name, info->attrs[IEEE802154_ATTR_DEV_NAME],
>  			    sizeof(name));
>  		dev = dev_get_by_name(&init_net, name);
>  	} else if (info->attrs[IEEE802154_ATTR_DEV_INDEX]) {
> diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
> index 123a6d39438f..a50951a90f63 100644
> --- a/net/ipv4/devinet.c
> +++ b/net/ipv4/devinet.c
> @@ -881,7 +881,7 @@ static struct in_ifaddr *rtm_to_ifaddr(struct net *net, struct nlmsghdr *nlh,
>  		ifa->ifa_broadcast = nla_get_in_addr(tb[IFA_BROADCAST]);
>  
>  	if (tb[IFA_LABEL])
> -		nla_strlcpy(ifa->ifa_label, tb[IFA_LABEL], IFNAMSIZ);
> +		nla_strscpy(ifa->ifa_label, tb[IFA_LABEL], IFNAMSIZ);
>  	else
>  		memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
>  
> diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
> index 1f75dc686b6b..4b505074b24f 100644
> --- a/net/ipv4/fib_semantics.c
> +++ b/net/ipv4/fib_semantics.c
> @@ -973,7 +973,7 @@ bool fib_metrics_match(struct fib_config *cfg, struct fib_info *fi)
>  			char tmp[TCP_CA_NAME_MAX];
>  			bool ecn_ca = false;
>  
> -			nla_strlcpy(tmp, nla, sizeof(tmp));
> +			nla_strscpy(tmp, nla, sizeof(tmp));
>  			val = tcp_ca_get_key_by_name(fi->fib_net, tmp, &ecn_ca);
>  		} else {
>  			if (nla_len(nla) != sizeof(u32))
> diff --git a/net/ipv4/metrics.c b/net/ipv4/metrics.c
> index 3205d5f7c8c9..25ea6ac44db9 100644
> --- a/net/ipv4/metrics.c
> +++ b/net/ipv4/metrics.c
> @@ -31,7 +31,7 @@ static int ip_metrics_convert(struct net *net, struct nlattr *fc_mx,
>  		if (type == RTAX_CC_ALGO) {
>  			char tmp[TCP_CA_NAME_MAX];
>  
> -			nla_strlcpy(tmp, nla, sizeof(tmp));
> +			nla_strscpy(tmp, nla, sizeof(tmp));
>  			val = tcp_ca_get_key_by_name(net, tmp, &ecn_ca);
>  			if (val == TCP_CA_UNSPEC) {
>  				NL_SET_ERR_MSG(extack, "Unknown tcp congestion algorithm");
> diff --git a/net/netfilter/ipset/ip_set_hash_netiface.c b/net/netfilter/ipset/ip_set_hash_netiface.c
> index be5e95a0d876..b96fd0c55eaa 100644
> --- a/net/netfilter/ipset/ip_set_hash_netiface.c
> +++ b/net/netfilter/ipset/ip_set_hash_netiface.c
> @@ -225,7 +225,7 @@ hash_netiface4_uadt(struct ip_set *set, struct nlattr *tb[],
>  		if (e.cidr > HOST_MASK)
>  			return -IPSET_ERR_INVALID_CIDR;
>  	}
> -	nla_strlcpy(e.iface, tb[IPSET_ATTR_IFACE], IFNAMSIZ);
> +	nla_strscpy(e.iface, tb[IPSET_ATTR_IFACE], IFNAMSIZ);
>  
>  	if (tb[IPSET_ATTR_CADT_FLAGS]) {
>  		u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
> @@ -442,7 +442,7 @@ hash_netiface6_uadt(struct ip_set *set, struct nlattr *tb[],
>  
>  	ip6_netmask(&e.ip, e.cidr);
>  
> -	nla_strlcpy(e.iface, tb[IPSET_ATTR_IFACE], IFNAMSIZ);
> +	nla_strscpy(e.iface, tb[IPSET_ATTR_IFACE], IFNAMSIZ);
>  
>  	if (tb[IPSET_ATTR_CADT_FLAGS]) {
>  		u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
> diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
> index 9957e0ed8658..90c39e694e87 100644
> --- a/net/netfilter/nf_tables_api.c
> +++ b/net/netfilter/nf_tables_api.c
> @@ -1281,7 +1281,7 @@ static struct nft_chain *nft_chain_lookup(struct net *net,
>  	if (nla == NULL)
>  		return ERR_PTR(-EINVAL);
>  
> -	nla_strlcpy(search, nla, sizeof(search));
> +	nla_strscpy(search, nla, sizeof(search));
>  
>  	WARN_ON(!rcu_read_lock_held() &&
>  		!lockdep_commit_lock_is_held(net));
> @@ -1721,7 +1721,7 @@ static struct nft_hook *nft_netdev_hook_alloc(struct net *net,
>  		goto err_hook_alloc;
>  	}
>  
> -	nla_strlcpy(ifname, attr, IFNAMSIZ);
> +	nla_strscpy(ifname, attr, IFNAMSIZ);
>  	dev = __dev_get_by_name(net, ifname);
>  	if (!dev) {
>  		err = -ENOENT;
> @@ -5734,7 +5734,7 @@ struct nft_object *nft_obj_lookup(const struct net *net,
>  	struct rhlist_head *tmp, *list;
>  	struct nft_object *obj;
>  
> -	nla_strlcpy(search, nla, sizeof(search));
> +	nla_strscpy(search, nla, sizeof(search));
>  	k.name = search;
>  
>  	WARN_ON_ONCE(!rcu_read_lock_held() &&
> diff --git a/net/netfilter/nfnetlink_acct.c b/net/netfilter/nfnetlink_acct.c
> index 5bfec829c12f..5e511df8d709 100644
> --- a/net/netfilter/nfnetlink_acct.c
> +++ b/net/netfilter/nfnetlink_acct.c
> @@ -112,7 +112,7 @@ static int nfnl_acct_new(struct net *net, struct sock *nfnl,
>  		nfacct->flags = flags;
>  	}
>  
> -	nla_strlcpy(nfacct->name, tb[NFACCT_NAME], NFACCT_NAME_MAX);
> +	nla_strscpy(nfacct->name, tb[NFACCT_NAME], NFACCT_NAME_MAX);
>  
>  	if (tb[NFACCT_BYTES]) {
>  		atomic64_set(&nfacct->bytes,
> diff --git a/net/netfilter/nfnetlink_cthelper.c b/net/netfilter/nfnetlink_cthelper.c
> index 5b0d0a77379c..0f94fce1d3ed 100644
> --- a/net/netfilter/nfnetlink_cthelper.c
> +++ b/net/netfilter/nfnetlink_cthelper.c
> @@ -146,7 +146,7 @@ nfnl_cthelper_expect_policy(struct nf_conntrack_expect_policy *expect_policy,
>  	    !tb[NFCTH_POLICY_EXPECT_TIMEOUT])
>  		return -EINVAL;
>  
> -	nla_strlcpy(expect_policy->name,
> +	nla_strscpy(expect_policy->name,
>  		    tb[NFCTH_POLICY_NAME], NF_CT_HELPER_NAME_LEN);
>  	expect_policy->max_expected =
>  		ntohl(nla_get_be32(tb[NFCTH_POLICY_EXPECT_MAX]));
> @@ -233,7 +233,7 @@ nfnl_cthelper_create(const struct nlattr * const tb[],
>  	if (ret < 0)
>  		goto err1;
>  
> -	nla_strlcpy(helper->name,
> +	nla_strscpy(helper->name,
>  		    tb[NFCTH_NAME], NF_CT_HELPER_NAME_LEN);
>  	size = ntohl(nla_get_be32(tb[NFCTH_PRIV_DATA_LEN]));
>  	if (size > sizeof_field(struct nf_conn_help, data)) {
> diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c
> index 322bd674963e..a8c4d442231c 100644
> --- a/net/netfilter/nft_ct.c
> +++ b/net/netfilter/nft_ct.c
> @@ -990,7 +990,7 @@ static int nft_ct_helper_obj_init(const struct nft_ctx *ctx,
>  	if (!priv->l4proto)
>  		return -ENOENT;
>  
> -	nla_strlcpy(name, tb[NFTA_CT_HELPER_NAME], sizeof(name));
> +	nla_strscpy(name, tb[NFTA_CT_HELPER_NAME], sizeof(name));
>  
>  	if (tb[NFTA_CT_HELPER_L3PROTO])
>  		family = ntohs(nla_get_be16(tb[NFTA_CT_HELPER_L3PROTO]));
> diff --git a/net/netfilter/nft_log.c b/net/netfilter/nft_log.c
> index 57899454a530..a06a46b039c5 100644
> --- a/net/netfilter/nft_log.c
> +++ b/net/netfilter/nft_log.c
> @@ -152,7 +152,7 @@ static int nft_log_init(const struct nft_ctx *ctx,
>  		priv->prefix = kmalloc(nla_len(nla) + 1, GFP_KERNEL);
>  		if (priv->prefix == NULL)
>  			return -ENOMEM;
> -		nla_strlcpy(priv->prefix, nla, nla_len(nla) + 1);
> +		nla_strscpy(priv->prefix, nla, nla_len(nla) + 1);
>  	} else {
>  		priv->prefix = (char *)nft_log_null_prefix;
>  	}
> diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c
> index eb1d66d20afb..df1b41ed73fd 100644
> --- a/net/netlabel/netlabel_mgmt.c
> +++ b/net/netlabel/netlabel_mgmt.c
> @@ -95,7 +95,7 @@ static int netlbl_mgmt_add_common(struct genl_info *info,
>  			ret_val = -ENOMEM;
>  			goto add_free_entry;
>  		}
> -		nla_strlcpy(entry->domain,
> +		nla_strscpy(entry->domain,
>  			    info->attrs[NLBL_MGMT_A_DOMAIN], tmp_size);
>  	}
>  
> diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c
> index e894254c17d4..438ff1f30a33 100644
> --- a/net/nfc/netlink.c
> +++ b/net/nfc/netlink.c
> @@ -1226,7 +1226,7 @@ static int nfc_genl_fw_download(struct sk_buff *skb, struct genl_info *info)
>  	if (!dev)
>  		return -ENODEV;
>  
> -	nla_strlcpy(firmware_name, info->attrs[NFC_ATTR_FIRMWARE_NAME],
> +	nla_strscpy(firmware_name, info->attrs[NFC_ATTR_FIRMWARE_NAME],
>  		    sizeof(firmware_name));
>  
>  	rc = nfc_fw_download(dev, firmware_name);
> diff --git a/net/sched/act_api.c b/net/sched/act_api.c
> index 541574520c52..eac24a73115f 100644
> --- a/net/sched/act_api.c
> +++ b/net/sched/act_api.c
> @@ -935,7 +935,7 @@ struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
>  			NL_SET_ERR_MSG(extack, "TC action kind must be specified");
>  			goto err_out;
>  		}
> -		if (nla_strlcpy(act_name, kind, IFNAMSIZ) < 0) {
> +		if (nla_strscpy(act_name, kind, IFNAMSIZ) < 0) {
>  			NL_SET_ERR_MSG(extack, "TC action name too long");
>  			goto err_out;
>  		}
> diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c
> index 8dc3bec0d325..ac7297f42355 100644
> --- a/net/sched/act_ipt.c
> +++ b/net/sched/act_ipt.c
> @@ -166,7 +166,7 @@ static int __tcf_ipt_init(struct net *net, unsigned int id, struct nlattr *nla,
>  	if (unlikely(!tname))
>  		goto err1;
>  	if (tb[TCA_IPT_TABLE] == NULL ||
> -	    nla_strlcpy(tname, tb[TCA_IPT_TABLE], IFNAMSIZ) >= IFNAMSIZ)
> +	    nla_strscpy(tname, tb[TCA_IPT_TABLE], IFNAMSIZ) >= IFNAMSIZ)
>  		strcpy(tname, "mangle");
>  
>  	t = kmemdup(td, td->u.target_size, GFP_KERNEL);
> diff --git a/net/sched/act_simple.c b/net/sched/act_simple.c
> index a4f3d0f0daa9..726cc956d06f 100644
> --- a/net/sched/act_simple.c
> +++ b/net/sched/act_simple.c
> @@ -52,7 +52,7 @@ static int alloc_defdata(struct tcf_defact *d, const struct nlattr *defdata)
>  	d->tcfd_defdata = kzalloc(SIMP_MAX_DATA, GFP_KERNEL);
>  	if (unlikely(!d->tcfd_defdata))
>  		return -ENOMEM;
> -	nla_strlcpy(d->tcfd_defdata, defdata, SIMP_MAX_DATA);
> +	nla_strscpy(d->tcfd_defdata, defdata, SIMP_MAX_DATA);
>  	return 0;
>  }
>  
> @@ -71,7 +71,7 @@ static int reset_policy(struct tc_action *a, const struct nlattr *defdata,
>  	spin_lock_bh(&d->tcf_lock);
>  	goto_ch = tcf_action_set_ctrlact(a, p->action, goto_ch);
>  	memset(d->tcfd_defdata, 0, SIMP_MAX_DATA);
> -	nla_strlcpy(d->tcfd_defdata, defdata, SIMP_MAX_DATA);
> +	nla_strscpy(d->tcfd_defdata, defdata, SIMP_MAX_DATA);
>  	spin_unlock_bh(&d->tcf_lock);
>  	if (goto_ch)
>  		tcf_chain_put_by_act(goto_ch);
> diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
> index c78241c853a5..6ff3b817083a 100644
> --- a/net/sched/cls_api.c
> +++ b/net/sched/cls_api.c
> @@ -223,7 +223,7 @@ static inline u32 tcf_auto_prio(struct tcf_proto *tp)
>  static bool tcf_proto_check_kind(struct nlattr *kind, char *name)
>  {
>  	if (kind)
> -		return nla_strlcpy(name, kind, IFNAMSIZ) < 0;
> +		return nla_strscpy(name, kind, IFNAMSIZ) < 0;
>  	memset(name, 0, IFNAMSIZ);
>  	return false;
>  }
> diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
> index f9b053b30a7b..cb4f30700c74 100644
> --- a/net/sched/sch_api.c
> +++ b/net/sched/sch_api.c
> @@ -1170,7 +1170,7 @@ static struct Qdisc *qdisc_create(struct net_device *dev,
>  #ifdef CONFIG_MODULES
>  	if (ops == NULL && kind != NULL) {
>  		char name[IFNAMSIZ];
> -		if (nla_strlcpy(name, kind, IFNAMSIZ) > 0) {
> +		if (nla_strscpy(name, kind, IFNAMSIZ) > 0) {
>  			/* We dropped the RTNL semaphore in order to
>  			 * perform the module load.  So, even if we
>  			 * succeeded in loading the module we have to
> diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c
> index 1c7aa51cc2a3..644c7ec41ddf 100644
> --- a/net/tipc/netlink_compat.c
> +++ b/net/tipc/netlink_compat.c
> @@ -695,7 +695,7 @@ static int tipc_nl_compat_link_dump(struct tipc_nl_compat_msg *msg,
>  
>  	link_info.dest = nla_get_flag(link[TIPC_NLA_LINK_DEST]);
>  	link_info.up = htonl(nla_get_flag(link[TIPC_NLA_LINK_UP]));
> -	nla_strlcpy(link_info.str, link[TIPC_NLA_LINK_NAME],
> +	nla_strscpy(link_info.str, link[TIPC_NLA_LINK_NAME],
>  		    TIPC_MAX_LINK_NAME);
>  
>  	return tipc_add_tlv(msg->rep, TIPC_TLV_LINK_INFO,
> -- 
> 2.20.1
> 

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC][PATCH v3 2/3] Modify return value of nla_strlcpy to match that of strscpy.
  2020-10-21 23:48   ` Kees Cook
@ 2020-10-22  9:40     ` Francis Laniel
  0 siblings, 0 replies; 17+ messages in thread
From: Francis Laniel @ 2020-10-22  9:40 UTC (permalink / raw)
  To: Kees Cook; +Cc: linux-hardening, netdev, davem, kuba

Le jeudi 22 octobre 2020, 01:48:37 CEST Kees Cook a écrit :
> On Tue, Oct 20, 2020 at 06:47:06PM +0200, laniel_francis@privacyrequired.com 
wrote:
> > From: Francis Laniel <laniel_francis@privacyrequired.com>
> > 
> > nla_strlcpy now returns -E2BIG if src was truncated when written to dst.
> > It also returns this error value if dstsize is 0 or higher than INT_MAX.
> > 
> > For example, if src is "foo\0" and dst is 3 bytes long, the result will
> > be:
> > 1. "foG" after memcpy (G means garbage).
> > 2. "fo\0" after memset.
> > 3. -E2BIG is returned because src was not completely written into dst.
> > 
> > The callers of nla_strlcpy were modified to take into account this
> > modification.
> > 
> > Signed-off-by: Francis Laniel <laniel_francis@privacyrequired.com>
> 
> This looks correct to me. Thanks for the respin!

Perfect! You are welcome!

> 
> Reviewed-by: Kees Cook <keescook@chromium.org>





^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC][PATCH v3 3/3] Rename nla_strlcpy to nla_strscpy.
  2020-10-21 23:49   ` Kees Cook
@ 2020-10-22  9:41     ` Francis Laniel
  2020-10-22 20:04       ` Kees Cook
  0 siblings, 1 reply; 17+ messages in thread
From: Francis Laniel @ 2020-10-22  9:41 UTC (permalink / raw)
  To: Kees Cook; +Cc: linux-hardening, netdev, davem, kuba

Le jeudi 22 octobre 2020, 01:49:59 CEST Kees Cook a écrit :
> On Tue, Oct 20, 2020 at 06:47:07PM +0200, laniel_francis@privacyrequired.com 
wrote:
> > From: Francis Laniel <laniel_francis@privacyrequired.com>
> > 
> > Calls to nla_strlcpy are now replaced by calls to nla_strscpy which is the
> > new name of this function.
> > 
> > Signed-off-by: Francis Laniel <laniel_francis@privacyrequired.com>
> 
> The Subject could also be: "treewide: Rename nla_strlcpy to nla_strscpy"
> 
> But otherwise, yup, easy mechanical change.

Should I submit a v4 for this change?

> 
> Reviewed-by: Kees Cook <keescook@chromium.org>
> 
> > ---
> > 
> >  drivers/infiniband/core/nldev.c            | 10 +++++-----
> >  drivers/net/can/vxcan.c                    |  4 ++--
> >  drivers/net/veth.c                         |  4 ++--
> >  include/linux/genl_magic_struct.h          |  2 +-
> >  include/net/netlink.h                      |  4 ++--
> >  include/net/pkt_cls.h                      |  2 +-
> >  kernel/taskstats.c                         |  2 +-
> >  lib/nlattr.c                               |  6 +++---
> >  net/core/fib_rules.c                       |  4 ++--
> >  net/core/rtnetlink.c                       | 12 ++++++------
> >  net/decnet/dn_dev.c                        |  2 +-
> >  net/ieee802154/nl-mac.c                    |  2 +-
> >  net/ipv4/devinet.c                         |  2 +-
> >  net/ipv4/fib_semantics.c                   |  2 +-
> >  net/ipv4/metrics.c                         |  2 +-
> >  net/netfilter/ipset/ip_set_hash_netiface.c |  4 ++--
> >  net/netfilter/nf_tables_api.c              |  6 +++---
> >  net/netfilter/nfnetlink_acct.c             |  2 +-
> >  net/netfilter/nfnetlink_cthelper.c         |  4 ++--
> >  net/netfilter/nft_ct.c                     |  2 +-
> >  net/netfilter/nft_log.c                    |  2 +-
> >  net/netlabel/netlabel_mgmt.c               |  2 +-
> >  net/nfc/netlink.c                          |  2 +-
> >  net/sched/act_api.c                        |  2 +-
> >  net/sched/act_ipt.c                        |  2 +-
> >  net/sched/act_simple.c                     |  4 ++--
> >  net/sched/cls_api.c                        |  2 +-
> >  net/sched/sch_api.c                        |  2 +-
> >  net/tipc/netlink_compat.c                  |  2 +-
> >  29 files changed, 49 insertions(+), 49 deletions(-)
> > 
> > diff --git a/drivers/infiniband/core/nldev.c
> > b/drivers/infiniband/core/nldev.c index 12d29d54a081..08366e254b1d 100644
> > --- a/drivers/infiniband/core/nldev.c
> > +++ b/drivers/infiniband/core/nldev.c
> > @@ -932,7 +932,7 @@ static int nldev_set_doit(struct sk_buff *skb, struct
> > nlmsghdr *nlh,> 
> >  	if (tb[RDMA_NLDEV_ATTR_DEV_NAME]) {
> >  	
> >  		char name[IB_DEVICE_NAME_MAX] = {};
> > 
> > -		nla_strlcpy(name, tb[RDMA_NLDEV_ATTR_DEV_NAME],
> > +		nla_strscpy(name, tb[RDMA_NLDEV_ATTR_DEV_NAME],
> > 
> >  			    IB_DEVICE_NAME_MAX);
> >  		
> >  		if (strlen(name) == 0) {
> >  		
> >  			err = -EINVAL;
> > 
> > @@ -1529,13 +1529,13 @@ static int nldev_newlink(struct sk_buff *skb,
> > struct nlmsghdr *nlh,> 
> >  	    !tb[RDMA_NLDEV_ATTR_LINK_TYPE] || !tb[RDMA_NLDEV_ATTR_NDEV_NAME])
> >  		
> >  		return -EINVAL;
> > 
> > -	nla_strlcpy(ibdev_name, tb[RDMA_NLDEV_ATTR_DEV_NAME],
> > +	nla_strscpy(ibdev_name, tb[RDMA_NLDEV_ATTR_DEV_NAME],
> > 
> >  		    sizeof(ibdev_name));
> >  	
> >  	if (strchr(ibdev_name, '%') || strlen(ibdev_name) == 0)
> >  	
> >  		return -EINVAL;
> > 
> > -	nla_strlcpy(type, tb[RDMA_NLDEV_ATTR_LINK_TYPE], sizeof(type));
> > -	nla_strlcpy(ndev_name, tb[RDMA_NLDEV_ATTR_NDEV_NAME],
> > +	nla_strscpy(type, tb[RDMA_NLDEV_ATTR_LINK_TYPE], sizeof(type));
> > +	nla_strscpy(ndev_name, tb[RDMA_NLDEV_ATTR_NDEV_NAME],
> > 
> >  		    sizeof(ndev_name));
> >  	
> >  	ndev = dev_get_by_name(sock_net(skb->sk), ndev_name);
> > 
> > @@ -1602,7 +1602,7 @@ static int nldev_get_chardev(struct sk_buff *skb,
> > struct nlmsghdr *nlh,> 
> >  	if (err || !tb[RDMA_NLDEV_ATTR_CHARDEV_TYPE])
> >  	
> >  		return -EINVAL;
> > 
> > -	nla_strlcpy(client_name, tb[RDMA_NLDEV_ATTR_CHARDEV_TYPE],
> > +	nla_strscpy(client_name, tb[RDMA_NLDEV_ATTR_CHARDEV_TYPE],
> > 
> >  		    sizeof(client_name));
> >  	
> >  	if (tb[RDMA_NLDEV_ATTR_DEV_INDEX]) {
> > 
> > diff --git a/drivers/net/can/vxcan.c b/drivers/net/can/vxcan.c
> > index d6ba9426be4d..fa47bab510bb 100644
> > --- a/drivers/net/can/vxcan.c
> > +++ b/drivers/net/can/vxcan.c
> > @@ -186,7 +186,7 @@ static int vxcan_newlink(struct net *net, struct
> > net_device *dev,> 
> >  	}
> >  	
> >  	if (ifmp && tbp[IFLA_IFNAME]) {
> > 
> > -		nla_strlcpy(ifname, tbp[IFLA_IFNAME], IFNAMSIZ);
> > +		nla_strscpy(ifname, tbp[IFLA_IFNAME], IFNAMSIZ);
> > 
> >  		name_assign_type = NET_NAME_USER;
> >  	
> >  	} else {
> >  	
> >  		snprintf(ifname, IFNAMSIZ, DRV_NAME "%%d");
> > 
> > @@ -223,7 +223,7 @@ static int vxcan_newlink(struct net *net, struct
> > net_device *dev,> 
> >  	/* register first device */
> >  	if (tb[IFLA_IFNAME])
> > 
> > -		nla_strlcpy(dev->name, tb[IFLA_IFNAME], IFNAMSIZ);
> > +		nla_strscpy(dev->name, tb[IFLA_IFNAME], IFNAMSIZ);
> > 
> >  	else
> >  	
> >  		snprintf(dev->name, IFNAMSIZ, DRV_NAME "%%d");
> > 
> > diff --git a/drivers/net/veth.c b/drivers/net/veth.c
> > index 8c737668008a..359d3ab33c4d 100644
> > --- a/drivers/net/veth.c
> > +++ b/drivers/net/veth.c
> > @@ -1329,7 +1329,7 @@ static int veth_newlink(struct net *src_net, struct
> > net_device *dev,> 
> >  	}
> >  	
> >  	if (ifmp && tbp[IFLA_IFNAME]) {
> > 
> > -		nla_strlcpy(ifname, tbp[IFLA_IFNAME], IFNAMSIZ);
> > +		nla_strscpy(ifname, tbp[IFLA_IFNAME], IFNAMSIZ);
> > 
> >  		name_assign_type = NET_NAME_USER;
> >  	
> >  	} else {
> >  	
> >  		snprintf(ifname, IFNAMSIZ, DRV_NAME "%%d");
> > 
> > @@ -1379,7 +1379,7 @@ static int veth_newlink(struct net *src_net, struct
> > net_device *dev,> 
> >  		eth_hw_addr_random(dev);
> >  	
> >  	if (tb[IFLA_IFNAME])
> > 
> > -		nla_strlcpy(dev->name, tb[IFLA_IFNAME], IFNAMSIZ);
> > +		nla_strscpy(dev->name, tb[IFLA_IFNAME], IFNAMSIZ);
> > 
> >  	else
> >  	
> >  		snprintf(dev->name, IFNAMSIZ, DRV_NAME "%%d");
> > 
> > diff --git a/include/linux/genl_magic_struct.h
> > b/include/linux/genl_magic_struct.h index eeae59d3ceb7..35d21fddaf2d
> > 100644
> > --- a/include/linux/genl_magic_struct.h
> > +++ b/include/linux/genl_magic_struct.h
> > @@ -89,7 +89,7 @@ static inline int nla_put_u64_0pad(struct sk_buff *skb,
> > int attrtype, u64 value)> 
> >  			nla_get_u64, nla_put_u64_0pad, false)
> >  
> >  #define __str_field(attr_nr, attr_flag, name, maxlen) \
> >  
> >  	__array(attr_nr, attr_flag, name, NLA_NUL_STRING, char, maxlen, \
> > 
> > -			nla_strlcpy, nla_put, false)
> > +			nla_strscpy, nla_put, false)
> > 
> >  #define __bin_field(attr_nr, attr_flag, name, maxlen) \
> >  
> >  	__array(attr_nr, attr_flag, name, NLA_BINARY, char, maxlen, \
> >  	
> >  			nla_memcpy, nla_put, false)
> > 
> > diff --git a/include/net/netlink.h b/include/net/netlink.h
> > index 446ca182e13d..1ceec518ab49 100644
> > --- a/include/net/netlink.h
> > +++ b/include/net/netlink.h
> > @@ -142,7 +142,7 @@
> > 
> >   * Attribute Misc:
> >   *   nla_memcpy(dest, nla, count)	copy attribute into memory
> >   *   nla_memcmp(nla, data, size)	compare attribute with memory area
> > 
> > - *   nla_strlcpy(dst, nla, size)	copy attribute to a sized string
> > + *   nla_strscpy(dst, nla, size)	copy attribute to a sized string
> > 
> >   *   nla_strcmp(nla, str)		compare attribute with string
> >   *
> > 
> >   * Attribute Parsing:
> > @@ -506,7 +506,7 @@ int __nla_parse(struct nlattr **tb, int maxtype, const
> > struct nlattr *head,> 
> >  		struct netlink_ext_ack *extack);
> >  
> >  int nla_policy_len(const struct nla_policy *, int);
> >  struct nlattr *nla_find(const struct nlattr *head, int len, int
> >  attrtype);
> > 
> > -ssize_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize);
> > +ssize_t nla_strscpy(char *dst, const struct nlattr *nla, size_t dstsize);
> > 
> >  char *nla_strdup(const struct nlattr *nla, gfp_t flags);
> >  int nla_memcpy(void *dest, const struct nlattr *src, int count);
> >  int nla_memcmp(const struct nlattr *nla, const void *data, size_t size);
> > 
> > diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
> > index db9a828f4f4f..133f9ad4d4f9 100644
> > --- a/include/net/pkt_cls.h
> > +++ b/include/net/pkt_cls.h
> > @@ -512,7 +512,7 @@ tcf_change_indev(struct net *net, struct nlattr
> > *indev_tlv,> 
> >  	char indev[IFNAMSIZ];
> >  	struct net_device *dev;
> > 
> > -	if (nla_strlcpy(indev, indev_tlv, IFNAMSIZ) < 0) {
> > +	if (nla_strscpy(indev, indev_tlv, IFNAMSIZ) < 0) {
> > 
> >  		NL_SET_ERR_MSG_ATTR(extack, indev_tlv,
> >  		
> >  				    "Interface name too long");
> >  		
> >  		return -EINVAL;
> > 
> > diff --git a/kernel/taskstats.c b/kernel/taskstats.c
> > index a2802b6ff4bb..2b4898b4752e 100644
> > --- a/kernel/taskstats.c
> > +++ b/kernel/taskstats.c
> > @@ -346,7 +346,7 @@ static int parse(struct nlattr *na, struct cpumask
> > *mask)> 
> >  	data = kmalloc(len, GFP_KERNEL);
> >  	if (!data)
> >  	
> >  		return -ENOMEM;
> > 
> > -	nla_strlcpy(data, na, len);
> > +	nla_strscpy(data, na, len);
> > 
> >  	ret = cpulist_parse(data, mask);
> >  	kfree(data);
> >  	return ret;
> > 
> > diff --git a/lib/nlattr.c b/lib/nlattr.c
> > index 447182543c03..09aa181569e0 100644
> > --- a/lib/nlattr.c
> > +++ b/lib/nlattr.c
> > @@ -709,7 +709,7 @@ struct nlattr *nla_find(const struct nlattr *head, int
> > len, int attrtype)> 
> >  EXPORT_SYMBOL(nla_find);
> >  
> >  /**
> > 
> > - * nla_strlcpy - Copy string attribute payload into a sized buffer
> > + * nla_strscpy - Copy string attribute payload into a sized buffer
> > 
> >   * @dst: Where to copy the string to.
> >   * @nla: Attribute to copy the string from.
> >   * @dstsize: Size of destination buffer.
> > 
> > @@ -722,7 +722,7 @@ EXPORT_SYMBOL(nla_find);
> > 
> >   * * -E2BIG - If @dstsize is 0 or greater than U16_MAX or @nla length
> >   greater *            than @dstsize.
> >   */
> > 
> > -ssize_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize)
> > +ssize_t nla_strscpy(char *dst, const struct nlattr *nla, size_t dstsize)
> > 
> >  {
> >  
> >  	size_t srclen = nla_len(nla);
> >  	char *src = nla_data(nla);
> > 
> > @@ -749,7 +749,7 @@ ssize_t nla_strlcpy(char *dst, const struct nlattr
> > *nla, size_t dstsize)> 
> >  	return ret;
> >  
> >  }
> > 
> > -EXPORT_SYMBOL(nla_strlcpy);
> > +EXPORT_SYMBOL(nla_strscpy);
> > 
> >  /**
> >  
> >   * nla_strdup - Copy string attribute payload into a newly allocated
> >   buffer
> > 
> > diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c
> > index 7bcfb16854cb..cd80ffed6d26 100644
> > --- a/net/core/fib_rules.c
> > +++ b/net/core/fib_rules.c
> > @@ -563,7 +563,7 @@ static int fib_nl2rule(struct sk_buff *skb, struct
> > nlmsghdr *nlh,> 
> >  		struct net_device *dev;
> >  		
> >  		nlrule->iifindex = -1;
> > 
> > -		nla_strlcpy(nlrule->iifname, tb[FRA_IIFNAME], IFNAMSIZ);
> > +		nla_strscpy(nlrule->iifname, tb[FRA_IIFNAME], IFNAMSIZ);
> > 
> >  		dev = __dev_get_by_name(net, nlrule->iifname);
> >  		if (dev)
> >  		
> >  			nlrule->iifindex = dev->ifindex;
> > 
> > @@ -573,7 +573,7 @@ static int fib_nl2rule(struct sk_buff *skb, struct
> > nlmsghdr *nlh,> 
> >  		struct net_device *dev;
> >  		
> >  		nlrule->oifindex = -1;
> > 
> > -		nla_strlcpy(nlrule->oifname, tb[FRA_OIFNAME], IFNAMSIZ);
> > +		nla_strscpy(nlrule->oifname, tb[FRA_OIFNAME], IFNAMSIZ);
> > 
> >  		dev = __dev_get_by_name(net, nlrule->oifname);
> >  		if (dev)
> >  		
> >  			nlrule->oifindex = dev->ifindex;
> > 
> > diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
> > index 68e0682450c6..e0059256fe93 100644
> > --- a/net/core/rtnetlink.c
> > +++ b/net/core/rtnetlink.c
> > @@ -1939,7 +1939,7 @@ static const struct rtnl_link_ops
> > *linkinfo_to_kind_ops(const struct nlattr *nla> 
> >  	if (linfo[IFLA_INFO_KIND]) {
> >  	
> >  		char kind[MODULE_NAME_LEN];
> > 
> > -		nla_strlcpy(kind, linfo[IFLA_INFO_KIND], sizeof(kind));
> > +		nla_strscpy(kind, linfo[IFLA_INFO_KIND], sizeof(kind));
> > 
> >  		ops = rtnl_link_ops_get(kind);
> >  	
> >  	}
> > 
> > @@ -2953,9 +2953,9 @@ static struct net_device *rtnl_dev_get(struct net
> > *net,> 
> >  	if (!ifname) {
> >  	
> >  		ifname = buffer;
> >  		if (ifname_attr)
> > 
> > -			nla_strlcpy(ifname, ifname_attr, IFNAMSIZ);
> > +			nla_strscpy(ifname, ifname_attr, IFNAMSIZ);
> > 
> >  		else if (altifname_attr)
> > 
> > -			nla_strlcpy(ifname, altifname_attr, ALTIFNAMSIZ);
> > +			nla_strscpy(ifname, altifname_attr, ALTIFNAMSIZ);
> > 
> >  		else
> >  		
> >  			return NULL;
> >  	
> >  	}
> > 
> > @@ -2983,7 +2983,7 @@ static int rtnl_setlink(struct sk_buff *skb, struct
> > nlmsghdr *nlh,> 
> >  		goto errout;
> >  	
> >  	if (tb[IFLA_IFNAME])
> > 
> > -		nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
> > +		nla_strscpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
> > 
> >  	else
> >  	
> >  		ifname[0] = '\0';
> > 
> > @@ -3264,7 +3264,7 @@ static int __rtnl_newlink(struct sk_buff *skb,
> > struct nlmsghdr *nlh,> 
> >  		return err;
> >  	
> >  	if (tb[IFLA_IFNAME])
> > 
> > -		nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
> > +		nla_strscpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
> > 
> >  	else
> >  	
> >  		ifname[0] = '\0';
> > 
> > @@ -3296,7 +3296,7 @@ static int __rtnl_newlink(struct sk_buff *skb,
> > struct nlmsghdr *nlh,> 
> >  		memset(linkinfo, 0, sizeof(linkinfo));
> >  	
> >  	if (linkinfo[IFLA_INFO_KIND]) {
> > 
> > -		nla_strlcpy(kind, linkinfo[IFLA_INFO_KIND], sizeof(kind));
> > +		nla_strscpy(kind, linkinfo[IFLA_INFO_KIND], sizeof(kind));
> > 
> >  		ops = rtnl_link_ops_get(kind);
> >  	
> >  	} else {
> >  	
> >  		kind[0] = '\0';
> > 
> > diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c
> > index 15d42353f1a3..d1c50a48614b 100644
> > --- a/net/decnet/dn_dev.c
> > +++ b/net/decnet/dn_dev.c
> > @@ -658,7 +658,7 @@ static int dn_nl_newaddr(struct sk_buff *skb, struct
> > nlmsghdr *nlh,> 
> >  	ifa->ifa_dev = dn_db;
> >  	
> >  	if (tb[IFA_LABEL])
> > 
> > -		nla_strlcpy(ifa->ifa_label, tb[IFA_LABEL], IFNAMSIZ);
> > +		nla_strscpy(ifa->ifa_label, tb[IFA_LABEL], IFNAMSIZ);
> > 
> >  	else
> >  	
> >  		memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
> > 
> > diff --git a/net/ieee802154/nl-mac.c b/net/ieee802154/nl-mac.c
> > index 6d091e419d3e..9c640d670ffe 100644
> > --- a/net/ieee802154/nl-mac.c
> > +++ b/net/ieee802154/nl-mac.c
> > @@ -149,7 +149,7 @@ static struct net_device *ieee802154_nl_get_dev(struct
> > genl_info *info)> 
> >  	if (info->attrs[IEEE802154_ATTR_DEV_NAME]) {
> >  	
> >  		char name[IFNAMSIZ + 1];
> > 
> > -		nla_strlcpy(name, info->attrs[IEEE802154_ATTR_DEV_NAME],
> > +		nla_strscpy(name, info->attrs[IEEE802154_ATTR_DEV_NAME],
> > 
> >  			    sizeof(name));
> >  		
> >  		dev = dev_get_by_name(&init_net, name);
> >  	
> >  	} else if (info->attrs[IEEE802154_ATTR_DEV_INDEX]) {
> > 
> > diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
> > index 123a6d39438f..a50951a90f63 100644
> > --- a/net/ipv4/devinet.c
> > +++ b/net/ipv4/devinet.c
> > @@ -881,7 +881,7 @@ static struct in_ifaddr *rtm_to_ifaddr(struct net
> > *net, struct nlmsghdr *nlh,> 
> >  		ifa->ifa_broadcast = nla_get_in_addr(tb[IFA_BROADCAST]);
> >  	
> >  	if (tb[IFA_LABEL])
> > 
> > -		nla_strlcpy(ifa->ifa_label, tb[IFA_LABEL], IFNAMSIZ);
> > +		nla_strscpy(ifa->ifa_label, tb[IFA_LABEL], IFNAMSIZ);
> > 
> >  	else
> >  	
> >  		memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
> > 
> > diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
> > index 1f75dc686b6b..4b505074b24f 100644
> > --- a/net/ipv4/fib_semantics.c
> > +++ b/net/ipv4/fib_semantics.c
> > @@ -973,7 +973,7 @@ bool fib_metrics_match(struct fib_config *cfg, struct
> > fib_info *fi)> 
> >  			char tmp[TCP_CA_NAME_MAX];
> >  			bool ecn_ca = false;
> > 
> > -			nla_strlcpy(tmp, nla, sizeof(tmp));
> > +			nla_strscpy(tmp, nla, sizeof(tmp));
> > 
> >  			val = tcp_ca_get_key_by_name(fi->fib_net, tmp, &ecn_ca);
> >  		
> >  		} else {
> >  		
> >  			if (nla_len(nla) != sizeof(u32))
> > 
> > diff --git a/net/ipv4/metrics.c b/net/ipv4/metrics.c
> > index 3205d5f7c8c9..25ea6ac44db9 100644
> > --- a/net/ipv4/metrics.c
> > +++ b/net/ipv4/metrics.c
> > @@ -31,7 +31,7 @@ static int ip_metrics_convert(struct net *net, struct
> > nlattr *fc_mx,> 
> >  		if (type == RTAX_CC_ALGO) {
> >  		
> >  			char tmp[TCP_CA_NAME_MAX];
> > 
> > -			nla_strlcpy(tmp, nla, sizeof(tmp));
> > +			nla_strscpy(tmp, nla, sizeof(tmp));
> > 
> >  			val = tcp_ca_get_key_by_name(net, tmp, &ecn_ca);
> >  			if (val == TCP_CA_UNSPEC) {
> >  			
> >  				NL_SET_ERR_MSG(extack, "Unknown tcp congestion algorithm");
> > 
> > diff --git a/net/netfilter/ipset/ip_set_hash_netiface.c
> > b/net/netfilter/ipset/ip_set_hash_netiface.c index
> > be5e95a0d876..b96fd0c55eaa 100644
> > --- a/net/netfilter/ipset/ip_set_hash_netiface.c
> > +++ b/net/netfilter/ipset/ip_set_hash_netiface.c
> > @@ -225,7 +225,7 @@ hash_netiface4_uadt(struct ip_set *set, struct nlattr
> > *tb[],> 
> >  		if (e.cidr > HOST_MASK)
> >  		
> >  			return -IPSET_ERR_INVALID_CIDR;
> >  	
> >  	}
> > 
> > -	nla_strlcpy(e.iface, tb[IPSET_ATTR_IFACE], IFNAMSIZ);
> > +	nla_strscpy(e.iface, tb[IPSET_ATTR_IFACE], IFNAMSIZ);
> > 
> >  	if (tb[IPSET_ATTR_CADT_FLAGS]) {
> >  	
> >  		u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
> > 
> > @@ -442,7 +442,7 @@ hash_netiface6_uadt(struct ip_set *set, struct nlattr
> > *tb[],> 
> >  	ip6_netmask(&e.ip, e.cidr);
> > 
> > -	nla_strlcpy(e.iface, tb[IPSET_ATTR_IFACE], IFNAMSIZ);
> > +	nla_strscpy(e.iface, tb[IPSET_ATTR_IFACE], IFNAMSIZ);
> > 
> >  	if (tb[IPSET_ATTR_CADT_FLAGS]) {
> >  	
> >  		u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
> > 
> > diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
> > index 9957e0ed8658..90c39e694e87 100644
> > --- a/net/netfilter/nf_tables_api.c
> > +++ b/net/netfilter/nf_tables_api.c
> > @@ -1281,7 +1281,7 @@ static struct nft_chain *nft_chain_lookup(struct net
> > *net,> 
> >  	if (nla == NULL)
> >  	
> >  		return ERR_PTR(-EINVAL);
> > 
> > -	nla_strlcpy(search, nla, sizeof(search));
> > +	nla_strscpy(search, nla, sizeof(search));
> > 
> >  	WARN_ON(!rcu_read_lock_held() &&
> >  	
> >  		!lockdep_commit_lock_is_held(net));
> > 
> > @@ -1721,7 +1721,7 @@ static struct nft_hook *nft_netdev_hook_alloc(struct
> > net *net,> 
> >  		goto err_hook_alloc;
> >  	
> >  	}
> > 
> > -	nla_strlcpy(ifname, attr, IFNAMSIZ);
> > +	nla_strscpy(ifname, attr, IFNAMSIZ);
> > 
> >  	dev = __dev_get_by_name(net, ifname);
> >  	if (!dev) {
> >  	
> >  		err = -ENOENT;
> > 
> > @@ -5734,7 +5734,7 @@ struct nft_object *nft_obj_lookup(const struct net
> > *net,> 
> >  	struct rhlist_head *tmp, *list;
> >  	struct nft_object *obj;
> > 
> > -	nla_strlcpy(search, nla, sizeof(search));
> > +	nla_strscpy(search, nla, sizeof(search));
> > 
> >  	k.name = search;
> >  	
> >  	WARN_ON_ONCE(!rcu_read_lock_held() &&
> > 
> > diff --git a/net/netfilter/nfnetlink_acct.c
> > b/net/netfilter/nfnetlink_acct.c index 5bfec829c12f..5e511df8d709 100644
> > --- a/net/netfilter/nfnetlink_acct.c
> > +++ b/net/netfilter/nfnetlink_acct.c
> > @@ -112,7 +112,7 @@ static int nfnl_acct_new(struct net *net, struct sock
> > *nfnl,> 
> >  		nfacct->flags = flags;
> >  	
> >  	}
> > 
> > -	nla_strlcpy(nfacct->name, tb[NFACCT_NAME], NFACCT_NAME_MAX);
> > +	nla_strscpy(nfacct->name, tb[NFACCT_NAME], NFACCT_NAME_MAX);
> > 
> >  	if (tb[NFACCT_BYTES]) {
> >  	
> >  		atomic64_set(&nfacct->bytes,
> > 
> > diff --git a/net/netfilter/nfnetlink_cthelper.c
> > b/net/netfilter/nfnetlink_cthelper.c index 5b0d0a77379c..0f94fce1d3ed
> > 100644
> > --- a/net/netfilter/nfnetlink_cthelper.c
> > +++ b/net/netfilter/nfnetlink_cthelper.c
> > @@ -146,7 +146,7 @@ nfnl_cthelper_expect_policy(struct
> > nf_conntrack_expect_policy *expect_policy,> 
> >  	    !tb[NFCTH_POLICY_EXPECT_TIMEOUT])
> >  		
> >  		return -EINVAL;
> > 
> > -	nla_strlcpy(expect_policy->name,
> > +	nla_strscpy(expect_policy->name,
> > 
> >  		    tb[NFCTH_POLICY_NAME], NF_CT_HELPER_NAME_LEN);
> >  	
> >  	expect_policy->max_expected =
> >  	
> >  		ntohl(nla_get_be32(tb[NFCTH_POLICY_EXPECT_MAX]));
> > 
> > @@ -233,7 +233,7 @@ nfnl_cthelper_create(const struct nlattr * const tb[],
> > 
> >  	if (ret < 0)
> >  	
> >  		goto err1;
> > 
> > -	nla_strlcpy(helper->name,
> > +	nla_strscpy(helper->name,
> > 
> >  		    tb[NFCTH_NAME], NF_CT_HELPER_NAME_LEN);
> >  	
> >  	size = ntohl(nla_get_be32(tb[NFCTH_PRIV_DATA_LEN]));
> >  	if (size > sizeof_field(struct nf_conn_help, data)) {
> > 
> > diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c
> > index 322bd674963e..a8c4d442231c 100644
> > --- a/net/netfilter/nft_ct.c
> > +++ b/net/netfilter/nft_ct.c
> > @@ -990,7 +990,7 @@ static int nft_ct_helper_obj_init(const struct nft_ctx
> > *ctx,> 
> >  	if (!priv->l4proto)
> >  	
> >  		return -ENOENT;
> > 
> > -	nla_strlcpy(name, tb[NFTA_CT_HELPER_NAME], sizeof(name));
> > +	nla_strscpy(name, tb[NFTA_CT_HELPER_NAME], sizeof(name));
> > 
> >  	if (tb[NFTA_CT_HELPER_L3PROTO])
> >  	
> >  		family = ntohs(nla_get_be16(tb[NFTA_CT_HELPER_L3PROTO]));
> > 
> > diff --git a/net/netfilter/nft_log.c b/net/netfilter/nft_log.c
> > index 57899454a530..a06a46b039c5 100644
> > --- a/net/netfilter/nft_log.c
> > +++ b/net/netfilter/nft_log.c
> > @@ -152,7 +152,7 @@ static int nft_log_init(const struct nft_ctx *ctx,
> > 
> >  		priv->prefix = kmalloc(nla_len(nla) + 1, GFP_KERNEL);
> >  		if (priv->prefix == NULL)
> >  		
> >  			return -ENOMEM;
> > 
> > -		nla_strlcpy(priv->prefix, nla, nla_len(nla) + 1);
> > +		nla_strscpy(priv->prefix, nla, nla_len(nla) + 1);
> > 
> >  	} else {
> >  	
> >  		priv->prefix = (char *)nft_log_null_prefix;
> >  	
> >  	}
> > 
> > diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c
> > index eb1d66d20afb..df1b41ed73fd 100644
> > --- a/net/netlabel/netlabel_mgmt.c
> > +++ b/net/netlabel/netlabel_mgmt.c
> > @@ -95,7 +95,7 @@ static int netlbl_mgmt_add_common(struct genl_info
> > *info,
> > 
> >  			ret_val = -ENOMEM;
> >  			goto add_free_entry;
> >  		
> >  		}
> > 
> > -		nla_strlcpy(entry->domain,
> > +		nla_strscpy(entry->domain,
> > 
> >  			    info->attrs[NLBL_MGMT_A_DOMAIN], tmp_size);
> >  	
> >  	}
> > 
> > diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c
> > index e894254c17d4..438ff1f30a33 100644
> > --- a/net/nfc/netlink.c
> > +++ b/net/nfc/netlink.c
> > @@ -1226,7 +1226,7 @@ static int nfc_genl_fw_download(struct sk_buff *skb,
> > struct genl_info *info)> 
> >  	if (!dev)
> >  	
> >  		return -ENODEV;
> > 
> > -	nla_strlcpy(firmware_name, info->attrs[NFC_ATTR_FIRMWARE_NAME],
> > +	nla_strscpy(firmware_name, info->attrs[NFC_ATTR_FIRMWARE_NAME],
> > 
> >  		    sizeof(firmware_name));
> >  	
> >  	rc = nfc_fw_download(dev, firmware_name);
> > 
> > diff --git a/net/sched/act_api.c b/net/sched/act_api.c
> > index 541574520c52..eac24a73115f 100644
> > --- a/net/sched/act_api.c
> > +++ b/net/sched/act_api.c
> > @@ -935,7 +935,7 @@ struct tc_action *tcf_action_init_1(struct net *net,
> > struct tcf_proto *tp,> 
> >  			NL_SET_ERR_MSG(extack, "TC action kind must be specified");
> >  			goto err_out;
> >  		
> >  		}
> > 
> > -		if (nla_strlcpy(act_name, kind, IFNAMSIZ) < 0) {
> > +		if (nla_strscpy(act_name, kind, IFNAMSIZ) < 0) {
> > 
> >  			NL_SET_ERR_MSG(extack, "TC action name too long");
> >  			goto err_out;
> >  		
> >  		}
> > 
> > diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c
> > index 8dc3bec0d325..ac7297f42355 100644
> > --- a/net/sched/act_ipt.c
> > +++ b/net/sched/act_ipt.c
> > @@ -166,7 +166,7 @@ static int __tcf_ipt_init(struct net *net, unsigned
> > int id, struct nlattr *nla,> 
> >  	if (unlikely(!tname))
> >  	
> >  		goto err1;
> >  	
> >  	if (tb[TCA_IPT_TABLE] == NULL ||
> > 
> > -	    nla_strlcpy(tname, tb[TCA_IPT_TABLE], IFNAMSIZ) >= IFNAMSIZ)
> > +	    nla_strscpy(tname, tb[TCA_IPT_TABLE], IFNAMSIZ) >= IFNAMSIZ)
> > 
> >  		strcpy(tname, "mangle");
> >  	
> >  	t = kmemdup(td, td->u.target_size, GFP_KERNEL);
> > 
> > diff --git a/net/sched/act_simple.c b/net/sched/act_simple.c
> > index a4f3d0f0daa9..726cc956d06f 100644
> > --- a/net/sched/act_simple.c
> > +++ b/net/sched/act_simple.c
> > @@ -52,7 +52,7 @@ static int alloc_defdata(struct tcf_defact *d, const
> > struct nlattr *defdata)> 
> >  	d->tcfd_defdata = kzalloc(SIMP_MAX_DATA, GFP_KERNEL);
> >  	if (unlikely(!d->tcfd_defdata))
> >  	
> >  		return -ENOMEM;
> > 
> > -	nla_strlcpy(d->tcfd_defdata, defdata, SIMP_MAX_DATA);
> > +	nla_strscpy(d->tcfd_defdata, defdata, SIMP_MAX_DATA);
> > 
> >  	return 0;
> >  
> >  }
> > 
> > @@ -71,7 +71,7 @@ static int reset_policy(struct tc_action *a, const
> > struct nlattr *defdata,> 
> >  	spin_lock_bh(&d->tcf_lock);
> >  	goto_ch = tcf_action_set_ctrlact(a, p->action, goto_ch);
> >  	memset(d->tcfd_defdata, 0, SIMP_MAX_DATA);
> > 
> > -	nla_strlcpy(d->tcfd_defdata, defdata, SIMP_MAX_DATA);
> > +	nla_strscpy(d->tcfd_defdata, defdata, SIMP_MAX_DATA);
> > 
> >  	spin_unlock_bh(&d->tcf_lock);
> >  	if (goto_ch)
> >  	
> >  		tcf_chain_put_by_act(goto_ch);
> > 
> > diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
> > index c78241c853a5..6ff3b817083a 100644
> > --- a/net/sched/cls_api.c
> > +++ b/net/sched/cls_api.c
> > @@ -223,7 +223,7 @@ static inline u32 tcf_auto_prio(struct tcf_proto *tp)
> > 
> >  static bool tcf_proto_check_kind(struct nlattr *kind, char *name)
> >  {
> >  
> >  	if (kind)
> > 
> > -		return nla_strlcpy(name, kind, IFNAMSIZ) < 0;
> > +		return nla_strscpy(name, kind, IFNAMSIZ) < 0;
> > 
> >  	memset(name, 0, IFNAMSIZ);
> >  	return false;
> >  
> >  }
> > 
> > diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
> > index f9b053b30a7b..cb4f30700c74 100644
> > --- a/net/sched/sch_api.c
> > +++ b/net/sched/sch_api.c
> > @@ -1170,7 +1170,7 @@ static struct Qdisc *qdisc_create(struct net_device
> > *dev,> 
> >  #ifdef CONFIG_MODULES
> >  
> >  	if (ops == NULL && kind != NULL) {
> >  	
> >  		char name[IFNAMSIZ];
> > 
> > -		if (nla_strlcpy(name, kind, IFNAMSIZ) > 0) {
> > +		if (nla_strscpy(name, kind, IFNAMSIZ) > 0) {
> > 
> >  			/* We dropped the RTNL semaphore in order to
> >  			
> >  			 * perform the module load.  So, even if we
> >  			 * succeeded in loading the module we have to
> > 
> > diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c
> > index 1c7aa51cc2a3..644c7ec41ddf 100644
> > --- a/net/tipc/netlink_compat.c
> > +++ b/net/tipc/netlink_compat.c
> > @@ -695,7 +695,7 @@ static int tipc_nl_compat_link_dump(struct
> > tipc_nl_compat_msg *msg,> 
> >  	link_info.dest = nla_get_flag(link[TIPC_NLA_LINK_DEST]);
> >  	link_info.up = htonl(nla_get_flag(link[TIPC_NLA_LINK_UP]));
> > 
> > -	nla_strlcpy(link_info.str, link[TIPC_NLA_LINK_NAME],
> > +	nla_strscpy(link_info.str, link[TIPC_NLA_LINK_NAME],
> > 
> >  		    TIPC_MAX_LINK_NAME);
> >  	
> >  	return tipc_add_tlv(msg->rep, TIPC_TLV_LINK_INFO,




^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC][PATCH v3 3/3] Rename nla_strlcpy to nla_strscpy.
  2020-10-22  9:41     ` Francis Laniel
@ 2020-10-22 20:04       ` Kees Cook
  2020-10-22 23:05         ` Jakub Kicinski
  2020-10-24 10:41         ` Francis Laniel
  0 siblings, 2 replies; 17+ messages in thread
From: Kees Cook @ 2020-10-22 20:04 UTC (permalink / raw)
  To: Francis Laniel; +Cc: linux-hardening, netdev, davem, kuba

On Thu, Oct 22, 2020 at 11:41:31AM +0200, Francis Laniel wrote:
> Le jeudi 22 octobre 2020, 01:49:59 CEST Kees Cook a écrit :
> > On Tue, Oct 20, 2020 at 06:47:07PM +0200, laniel_francis@privacyrequired.com 
> wrote:
> > > From: Francis Laniel <laniel_francis@privacyrequired.com>
> > > 
> > > Calls to nla_strlcpy are now replaced by calls to nla_strscpy which is the
> > > new name of this function.
> > > 
> > > Signed-off-by: Francis Laniel <laniel_francis@privacyrequired.com>
> > 
> > The Subject could also be: "treewide: Rename nla_strlcpy to nla_strscpy"
> > 
> > But otherwise, yup, easy mechanical change.
> 
> Should I submit a v4 for this change?

I'll say yes. :) Drop the RFC, bump to v4, and send it to netdev (along
with all the other CCs you have here already), and add the Reviewed-bys
from v3.

Thanks!

-Kees

> 
> > 
> > Reviewed-by: Kees Cook <keescook@chromium.org>
> > 
> > > ---
> > > 
> > >  drivers/infiniband/core/nldev.c            | 10 +++++-----
> > >  drivers/net/can/vxcan.c                    |  4 ++--
> > >  drivers/net/veth.c                         |  4 ++--
> > >  include/linux/genl_magic_struct.h          |  2 +-
> > >  include/net/netlink.h                      |  4 ++--
> > >  include/net/pkt_cls.h                      |  2 +-
> > >  kernel/taskstats.c                         |  2 +-
> > >  lib/nlattr.c                               |  6 +++---
> > >  net/core/fib_rules.c                       |  4 ++--
> > >  net/core/rtnetlink.c                       | 12 ++++++------
> > >  net/decnet/dn_dev.c                        |  2 +-
> > >  net/ieee802154/nl-mac.c                    |  2 +-
> > >  net/ipv4/devinet.c                         |  2 +-
> > >  net/ipv4/fib_semantics.c                   |  2 +-
> > >  net/ipv4/metrics.c                         |  2 +-
> > >  net/netfilter/ipset/ip_set_hash_netiface.c |  4 ++--
> > >  net/netfilter/nf_tables_api.c              |  6 +++---
> > >  net/netfilter/nfnetlink_acct.c             |  2 +-
> > >  net/netfilter/nfnetlink_cthelper.c         |  4 ++--
> > >  net/netfilter/nft_ct.c                     |  2 +-
> > >  net/netfilter/nft_log.c                    |  2 +-
> > >  net/netlabel/netlabel_mgmt.c               |  2 +-
> > >  net/nfc/netlink.c                          |  2 +-
> > >  net/sched/act_api.c                        |  2 +-
> > >  net/sched/act_ipt.c                        |  2 +-
> > >  net/sched/act_simple.c                     |  4 ++--
> > >  net/sched/cls_api.c                        |  2 +-
> > >  net/sched/sch_api.c                        |  2 +-
> > >  net/tipc/netlink_compat.c                  |  2 +-
> > >  29 files changed, 49 insertions(+), 49 deletions(-)
> > > 
> > > diff --git a/drivers/infiniband/core/nldev.c
> > > b/drivers/infiniband/core/nldev.c index 12d29d54a081..08366e254b1d 100644
> > > --- a/drivers/infiniband/core/nldev.c
> > > +++ b/drivers/infiniband/core/nldev.c
> > > @@ -932,7 +932,7 @@ static int nldev_set_doit(struct sk_buff *skb, struct
> > > nlmsghdr *nlh,> 
> > >  	if (tb[RDMA_NLDEV_ATTR_DEV_NAME]) {
> > >  	
> > >  		char name[IB_DEVICE_NAME_MAX] = {};
> > > 
> > > -		nla_strlcpy(name, tb[RDMA_NLDEV_ATTR_DEV_NAME],
> > > +		nla_strscpy(name, tb[RDMA_NLDEV_ATTR_DEV_NAME],
> > > 
> > >  			    IB_DEVICE_NAME_MAX);
> > >  		
> > >  		if (strlen(name) == 0) {
> > >  		
> > >  			err = -EINVAL;
> > > 
> > > @@ -1529,13 +1529,13 @@ static int nldev_newlink(struct sk_buff *skb,
> > > struct nlmsghdr *nlh,> 
> > >  	    !tb[RDMA_NLDEV_ATTR_LINK_TYPE] || !tb[RDMA_NLDEV_ATTR_NDEV_NAME])
> > >  		
> > >  		return -EINVAL;
> > > 
> > > -	nla_strlcpy(ibdev_name, tb[RDMA_NLDEV_ATTR_DEV_NAME],
> > > +	nla_strscpy(ibdev_name, tb[RDMA_NLDEV_ATTR_DEV_NAME],
> > > 
> > >  		    sizeof(ibdev_name));
> > >  	
> > >  	if (strchr(ibdev_name, '%') || strlen(ibdev_name) == 0)
> > >  	
> > >  		return -EINVAL;
> > > 
> > > -	nla_strlcpy(type, tb[RDMA_NLDEV_ATTR_LINK_TYPE], sizeof(type));
> > > -	nla_strlcpy(ndev_name, tb[RDMA_NLDEV_ATTR_NDEV_NAME],
> > > +	nla_strscpy(type, tb[RDMA_NLDEV_ATTR_LINK_TYPE], sizeof(type));
> > > +	nla_strscpy(ndev_name, tb[RDMA_NLDEV_ATTR_NDEV_NAME],
> > > 
> > >  		    sizeof(ndev_name));
> > >  	
> > >  	ndev = dev_get_by_name(sock_net(skb->sk), ndev_name);
> > > 
> > > @@ -1602,7 +1602,7 @@ static int nldev_get_chardev(struct sk_buff *skb,
> > > struct nlmsghdr *nlh,> 
> > >  	if (err || !tb[RDMA_NLDEV_ATTR_CHARDEV_TYPE])
> > >  	
> > >  		return -EINVAL;
> > > 
> > > -	nla_strlcpy(client_name, tb[RDMA_NLDEV_ATTR_CHARDEV_TYPE],
> > > +	nla_strscpy(client_name, tb[RDMA_NLDEV_ATTR_CHARDEV_TYPE],
> > > 
> > >  		    sizeof(client_name));
> > >  	
> > >  	if (tb[RDMA_NLDEV_ATTR_DEV_INDEX]) {
> > > 
> > > diff --git a/drivers/net/can/vxcan.c b/drivers/net/can/vxcan.c
> > > index d6ba9426be4d..fa47bab510bb 100644
> > > --- a/drivers/net/can/vxcan.c
> > > +++ b/drivers/net/can/vxcan.c
> > > @@ -186,7 +186,7 @@ static int vxcan_newlink(struct net *net, struct
> > > net_device *dev,> 
> > >  	}
> > >  	
> > >  	if (ifmp && tbp[IFLA_IFNAME]) {
> > > 
> > > -		nla_strlcpy(ifname, tbp[IFLA_IFNAME], IFNAMSIZ);
> > > +		nla_strscpy(ifname, tbp[IFLA_IFNAME], IFNAMSIZ);
> > > 
> > >  		name_assign_type = NET_NAME_USER;
> > >  	
> > >  	} else {
> > >  	
> > >  		snprintf(ifname, IFNAMSIZ, DRV_NAME "%%d");
> > > 
> > > @@ -223,7 +223,7 @@ static int vxcan_newlink(struct net *net, struct
> > > net_device *dev,> 
> > >  	/* register first device */
> > >  	if (tb[IFLA_IFNAME])
> > > 
> > > -		nla_strlcpy(dev->name, tb[IFLA_IFNAME], IFNAMSIZ);
> > > +		nla_strscpy(dev->name, tb[IFLA_IFNAME], IFNAMSIZ);
> > > 
> > >  	else
> > >  	
> > >  		snprintf(dev->name, IFNAMSIZ, DRV_NAME "%%d");
> > > 
> > > diff --git a/drivers/net/veth.c b/drivers/net/veth.c
> > > index 8c737668008a..359d3ab33c4d 100644
> > > --- a/drivers/net/veth.c
> > > +++ b/drivers/net/veth.c
> > > @@ -1329,7 +1329,7 @@ static int veth_newlink(struct net *src_net, struct
> > > net_device *dev,> 
> > >  	}
> > >  	
> > >  	if (ifmp && tbp[IFLA_IFNAME]) {
> > > 
> > > -		nla_strlcpy(ifname, tbp[IFLA_IFNAME], IFNAMSIZ);
> > > +		nla_strscpy(ifname, tbp[IFLA_IFNAME], IFNAMSIZ);
> > > 
> > >  		name_assign_type = NET_NAME_USER;
> > >  	
> > >  	} else {
> > >  	
> > >  		snprintf(ifname, IFNAMSIZ, DRV_NAME "%%d");
> > > 
> > > @@ -1379,7 +1379,7 @@ static int veth_newlink(struct net *src_net, struct
> > > net_device *dev,> 
> > >  		eth_hw_addr_random(dev);
> > >  	
> > >  	if (tb[IFLA_IFNAME])
> > > 
> > > -		nla_strlcpy(dev->name, tb[IFLA_IFNAME], IFNAMSIZ);
> > > +		nla_strscpy(dev->name, tb[IFLA_IFNAME], IFNAMSIZ);
> > > 
> > >  	else
> > >  	
> > >  		snprintf(dev->name, IFNAMSIZ, DRV_NAME "%%d");
> > > 
> > > diff --git a/include/linux/genl_magic_struct.h
> > > b/include/linux/genl_magic_struct.h index eeae59d3ceb7..35d21fddaf2d
> > > 100644
> > > --- a/include/linux/genl_magic_struct.h
> > > +++ b/include/linux/genl_magic_struct.h
> > > @@ -89,7 +89,7 @@ static inline int nla_put_u64_0pad(struct sk_buff *skb,
> > > int attrtype, u64 value)> 
> > >  			nla_get_u64, nla_put_u64_0pad, false)
> > >  
> > >  #define __str_field(attr_nr, attr_flag, name, maxlen) \
> > >  
> > >  	__array(attr_nr, attr_flag, name, NLA_NUL_STRING, char, maxlen, \
> > > 
> > > -			nla_strlcpy, nla_put, false)
> > > +			nla_strscpy, nla_put, false)
> > > 
> > >  #define __bin_field(attr_nr, attr_flag, name, maxlen) \
> > >  
> > >  	__array(attr_nr, attr_flag, name, NLA_BINARY, char, maxlen, \
> > >  	
> > >  			nla_memcpy, nla_put, false)
> > > 
> > > diff --git a/include/net/netlink.h b/include/net/netlink.h
> > > index 446ca182e13d..1ceec518ab49 100644
> > > --- a/include/net/netlink.h
> > > +++ b/include/net/netlink.h
> > > @@ -142,7 +142,7 @@
> > > 
> > >   * Attribute Misc:
> > >   *   nla_memcpy(dest, nla, count)	copy attribute into memory
> > >   *   nla_memcmp(nla, data, size)	compare attribute with memory area
> > > 
> > > - *   nla_strlcpy(dst, nla, size)	copy attribute to a sized string
> > > + *   nla_strscpy(dst, nla, size)	copy attribute to a sized string
> > > 
> > >   *   nla_strcmp(nla, str)		compare attribute with string
> > >   *
> > > 
> > >   * Attribute Parsing:
> > > @@ -506,7 +506,7 @@ int __nla_parse(struct nlattr **tb, int maxtype, const
> > > struct nlattr *head,> 
> > >  		struct netlink_ext_ack *extack);
> > >  
> > >  int nla_policy_len(const struct nla_policy *, int);
> > >  struct nlattr *nla_find(const struct nlattr *head, int len, int
> > >  attrtype);
> > > 
> > > -ssize_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize);
> > > +ssize_t nla_strscpy(char *dst, const struct nlattr *nla, size_t dstsize);
> > > 
> > >  char *nla_strdup(const struct nlattr *nla, gfp_t flags);
> > >  int nla_memcpy(void *dest, const struct nlattr *src, int count);
> > >  int nla_memcmp(const struct nlattr *nla, const void *data, size_t size);
> > > 
> > > diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
> > > index db9a828f4f4f..133f9ad4d4f9 100644
> > > --- a/include/net/pkt_cls.h
> > > +++ b/include/net/pkt_cls.h
> > > @@ -512,7 +512,7 @@ tcf_change_indev(struct net *net, struct nlattr
> > > *indev_tlv,> 
> > >  	char indev[IFNAMSIZ];
> > >  	struct net_device *dev;
> > > 
> > > -	if (nla_strlcpy(indev, indev_tlv, IFNAMSIZ) < 0) {
> > > +	if (nla_strscpy(indev, indev_tlv, IFNAMSIZ) < 0) {
> > > 
> > >  		NL_SET_ERR_MSG_ATTR(extack, indev_tlv,
> > >  		
> > >  				    "Interface name too long");
> > >  		
> > >  		return -EINVAL;
> > > 
> > > diff --git a/kernel/taskstats.c b/kernel/taskstats.c
> > > index a2802b6ff4bb..2b4898b4752e 100644
> > > --- a/kernel/taskstats.c
> > > +++ b/kernel/taskstats.c
> > > @@ -346,7 +346,7 @@ static int parse(struct nlattr *na, struct cpumask
> > > *mask)> 
> > >  	data = kmalloc(len, GFP_KERNEL);
> > >  	if (!data)
> > >  	
> > >  		return -ENOMEM;
> > > 
> > > -	nla_strlcpy(data, na, len);
> > > +	nla_strscpy(data, na, len);
> > > 
> > >  	ret = cpulist_parse(data, mask);
> > >  	kfree(data);
> > >  	return ret;
> > > 
> > > diff --git a/lib/nlattr.c b/lib/nlattr.c
> > > index 447182543c03..09aa181569e0 100644
> > > --- a/lib/nlattr.c
> > > +++ b/lib/nlattr.c
> > > @@ -709,7 +709,7 @@ struct nlattr *nla_find(const struct nlattr *head, int
> > > len, int attrtype)> 
> > >  EXPORT_SYMBOL(nla_find);
> > >  
> > >  /**
> > > 
> > > - * nla_strlcpy - Copy string attribute payload into a sized buffer
> > > + * nla_strscpy - Copy string attribute payload into a sized buffer
> > > 
> > >   * @dst: Where to copy the string to.
> > >   * @nla: Attribute to copy the string from.
> > >   * @dstsize: Size of destination buffer.
> > > 
> > > @@ -722,7 +722,7 @@ EXPORT_SYMBOL(nla_find);
> > > 
> > >   * * -E2BIG - If @dstsize is 0 or greater than U16_MAX or @nla length
> > >   greater *            than @dstsize.
> > >   */
> > > 
> > > -ssize_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize)
> > > +ssize_t nla_strscpy(char *dst, const struct nlattr *nla, size_t dstsize)
> > > 
> > >  {
> > >  
> > >  	size_t srclen = nla_len(nla);
> > >  	char *src = nla_data(nla);
> > > 
> > > @@ -749,7 +749,7 @@ ssize_t nla_strlcpy(char *dst, const struct nlattr
> > > *nla, size_t dstsize)> 
> > >  	return ret;
> > >  
> > >  }
> > > 
> > > -EXPORT_SYMBOL(nla_strlcpy);
> > > +EXPORT_SYMBOL(nla_strscpy);
> > > 
> > >  /**
> > >  
> > >   * nla_strdup - Copy string attribute payload into a newly allocated
> > >   buffer
> > > 
> > > diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c
> > > index 7bcfb16854cb..cd80ffed6d26 100644
> > > --- a/net/core/fib_rules.c
> > > +++ b/net/core/fib_rules.c
> > > @@ -563,7 +563,7 @@ static int fib_nl2rule(struct sk_buff *skb, struct
> > > nlmsghdr *nlh,> 
> > >  		struct net_device *dev;
> > >  		
> > >  		nlrule->iifindex = -1;
> > > 
> > > -		nla_strlcpy(nlrule->iifname, tb[FRA_IIFNAME], IFNAMSIZ);
> > > +		nla_strscpy(nlrule->iifname, tb[FRA_IIFNAME], IFNAMSIZ);
> > > 
> > >  		dev = __dev_get_by_name(net, nlrule->iifname);
> > >  		if (dev)
> > >  		
> > >  			nlrule->iifindex = dev->ifindex;
> > > 
> > > @@ -573,7 +573,7 @@ static int fib_nl2rule(struct sk_buff *skb, struct
> > > nlmsghdr *nlh,> 
> > >  		struct net_device *dev;
> > >  		
> > >  		nlrule->oifindex = -1;
> > > 
> > > -		nla_strlcpy(nlrule->oifname, tb[FRA_OIFNAME], IFNAMSIZ);
> > > +		nla_strscpy(nlrule->oifname, tb[FRA_OIFNAME], IFNAMSIZ);
> > > 
> > >  		dev = __dev_get_by_name(net, nlrule->oifname);
> > >  		if (dev)
> > >  		
> > >  			nlrule->oifindex = dev->ifindex;
> > > 
> > > diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
> > > index 68e0682450c6..e0059256fe93 100644
> > > --- a/net/core/rtnetlink.c
> > > +++ b/net/core/rtnetlink.c
> > > @@ -1939,7 +1939,7 @@ static const struct rtnl_link_ops
> > > *linkinfo_to_kind_ops(const struct nlattr *nla> 
> > >  	if (linfo[IFLA_INFO_KIND]) {
> > >  	
> > >  		char kind[MODULE_NAME_LEN];
> > > 
> > > -		nla_strlcpy(kind, linfo[IFLA_INFO_KIND], sizeof(kind));
> > > +		nla_strscpy(kind, linfo[IFLA_INFO_KIND], sizeof(kind));
> > > 
> > >  		ops = rtnl_link_ops_get(kind);
> > >  	
> > >  	}
> > > 
> > > @@ -2953,9 +2953,9 @@ static struct net_device *rtnl_dev_get(struct net
> > > *net,> 
> > >  	if (!ifname) {
> > >  	
> > >  		ifname = buffer;
> > >  		if (ifname_attr)
> > > 
> > > -			nla_strlcpy(ifname, ifname_attr, IFNAMSIZ);
> > > +			nla_strscpy(ifname, ifname_attr, IFNAMSIZ);
> > > 
> > >  		else if (altifname_attr)
> > > 
> > > -			nla_strlcpy(ifname, altifname_attr, ALTIFNAMSIZ);
> > > +			nla_strscpy(ifname, altifname_attr, ALTIFNAMSIZ);
> > > 
> > >  		else
> > >  		
> > >  			return NULL;
> > >  	
> > >  	}
> > > 
> > > @@ -2983,7 +2983,7 @@ static int rtnl_setlink(struct sk_buff *skb, struct
> > > nlmsghdr *nlh,> 
> > >  		goto errout;
> > >  	
> > >  	if (tb[IFLA_IFNAME])
> > > 
> > > -		nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
> > > +		nla_strscpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
> > > 
> > >  	else
> > >  	
> > >  		ifname[0] = '\0';
> > > 
> > > @@ -3264,7 +3264,7 @@ static int __rtnl_newlink(struct sk_buff *skb,
> > > struct nlmsghdr *nlh,> 
> > >  		return err;
> > >  	
> > >  	if (tb[IFLA_IFNAME])
> > > 
> > > -		nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
> > > +		nla_strscpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
> > > 
> > >  	else
> > >  	
> > >  		ifname[0] = '\0';
> > > 
> > > @@ -3296,7 +3296,7 @@ static int __rtnl_newlink(struct sk_buff *skb,
> > > struct nlmsghdr *nlh,> 
> > >  		memset(linkinfo, 0, sizeof(linkinfo));
> > >  	
> > >  	if (linkinfo[IFLA_INFO_KIND]) {
> > > 
> > > -		nla_strlcpy(kind, linkinfo[IFLA_INFO_KIND], sizeof(kind));
> > > +		nla_strscpy(kind, linkinfo[IFLA_INFO_KIND], sizeof(kind));
> > > 
> > >  		ops = rtnl_link_ops_get(kind);
> > >  	
> > >  	} else {
> > >  	
> > >  		kind[0] = '\0';
> > > 
> > > diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c
> > > index 15d42353f1a3..d1c50a48614b 100644
> > > --- a/net/decnet/dn_dev.c
> > > +++ b/net/decnet/dn_dev.c
> > > @@ -658,7 +658,7 @@ static int dn_nl_newaddr(struct sk_buff *skb, struct
> > > nlmsghdr *nlh,> 
> > >  	ifa->ifa_dev = dn_db;
> > >  	
> > >  	if (tb[IFA_LABEL])
> > > 
> > > -		nla_strlcpy(ifa->ifa_label, tb[IFA_LABEL], IFNAMSIZ);
> > > +		nla_strscpy(ifa->ifa_label, tb[IFA_LABEL], IFNAMSIZ);
> > > 
> > >  	else
> > >  	
> > >  		memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
> > > 
> > > diff --git a/net/ieee802154/nl-mac.c b/net/ieee802154/nl-mac.c
> > > index 6d091e419d3e..9c640d670ffe 100644
> > > --- a/net/ieee802154/nl-mac.c
> > > +++ b/net/ieee802154/nl-mac.c
> > > @@ -149,7 +149,7 @@ static struct net_device *ieee802154_nl_get_dev(struct
> > > genl_info *info)> 
> > >  	if (info->attrs[IEEE802154_ATTR_DEV_NAME]) {
> > >  	
> > >  		char name[IFNAMSIZ + 1];
> > > 
> > > -		nla_strlcpy(name, info->attrs[IEEE802154_ATTR_DEV_NAME],
> > > +		nla_strscpy(name, info->attrs[IEEE802154_ATTR_DEV_NAME],
> > > 
> > >  			    sizeof(name));
> > >  		
> > >  		dev = dev_get_by_name(&init_net, name);
> > >  	
> > >  	} else if (info->attrs[IEEE802154_ATTR_DEV_INDEX]) {
> > > 
> > > diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
> > > index 123a6d39438f..a50951a90f63 100644
> > > --- a/net/ipv4/devinet.c
> > > +++ b/net/ipv4/devinet.c
> > > @@ -881,7 +881,7 @@ static struct in_ifaddr *rtm_to_ifaddr(struct net
> > > *net, struct nlmsghdr *nlh,> 
> > >  		ifa->ifa_broadcast = nla_get_in_addr(tb[IFA_BROADCAST]);
> > >  	
> > >  	if (tb[IFA_LABEL])
> > > 
> > > -		nla_strlcpy(ifa->ifa_label, tb[IFA_LABEL], IFNAMSIZ);
> > > +		nla_strscpy(ifa->ifa_label, tb[IFA_LABEL], IFNAMSIZ);
> > > 
> > >  	else
> > >  	
> > >  		memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
> > > 
> > > diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
> > > index 1f75dc686b6b..4b505074b24f 100644
> > > --- a/net/ipv4/fib_semantics.c
> > > +++ b/net/ipv4/fib_semantics.c
> > > @@ -973,7 +973,7 @@ bool fib_metrics_match(struct fib_config *cfg, struct
> > > fib_info *fi)> 
> > >  			char tmp[TCP_CA_NAME_MAX];
> > >  			bool ecn_ca = false;
> > > 
> > > -			nla_strlcpy(tmp, nla, sizeof(tmp));
> > > +			nla_strscpy(tmp, nla, sizeof(tmp));
> > > 
> > >  			val = tcp_ca_get_key_by_name(fi->fib_net, tmp, &ecn_ca);
> > >  		
> > >  		} else {
> > >  		
> > >  			if (nla_len(nla) != sizeof(u32))
> > > 
> > > diff --git a/net/ipv4/metrics.c b/net/ipv4/metrics.c
> > > index 3205d5f7c8c9..25ea6ac44db9 100644
> > > --- a/net/ipv4/metrics.c
> > > +++ b/net/ipv4/metrics.c
> > > @@ -31,7 +31,7 @@ static int ip_metrics_convert(struct net *net, struct
> > > nlattr *fc_mx,> 
> > >  		if (type == RTAX_CC_ALGO) {
> > >  		
> > >  			char tmp[TCP_CA_NAME_MAX];
> > > 
> > > -			nla_strlcpy(tmp, nla, sizeof(tmp));
> > > +			nla_strscpy(tmp, nla, sizeof(tmp));
> > > 
> > >  			val = tcp_ca_get_key_by_name(net, tmp, &ecn_ca);
> > >  			if (val == TCP_CA_UNSPEC) {
> > >  			
> > >  				NL_SET_ERR_MSG(extack, "Unknown tcp congestion algorithm");
> > > 
> > > diff --git a/net/netfilter/ipset/ip_set_hash_netiface.c
> > > b/net/netfilter/ipset/ip_set_hash_netiface.c index
> > > be5e95a0d876..b96fd0c55eaa 100644
> > > --- a/net/netfilter/ipset/ip_set_hash_netiface.c
> > > +++ b/net/netfilter/ipset/ip_set_hash_netiface.c
> > > @@ -225,7 +225,7 @@ hash_netiface4_uadt(struct ip_set *set, struct nlattr
> > > *tb[],> 
> > >  		if (e.cidr > HOST_MASK)
> > >  		
> > >  			return -IPSET_ERR_INVALID_CIDR;
> > >  	
> > >  	}
> > > 
> > > -	nla_strlcpy(e.iface, tb[IPSET_ATTR_IFACE], IFNAMSIZ);
> > > +	nla_strscpy(e.iface, tb[IPSET_ATTR_IFACE], IFNAMSIZ);
> > > 
> > >  	if (tb[IPSET_ATTR_CADT_FLAGS]) {
> > >  	
> > >  		u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
> > > 
> > > @@ -442,7 +442,7 @@ hash_netiface6_uadt(struct ip_set *set, struct nlattr
> > > *tb[],> 
> > >  	ip6_netmask(&e.ip, e.cidr);
> > > 
> > > -	nla_strlcpy(e.iface, tb[IPSET_ATTR_IFACE], IFNAMSIZ);
> > > +	nla_strscpy(e.iface, tb[IPSET_ATTR_IFACE], IFNAMSIZ);
> > > 
> > >  	if (tb[IPSET_ATTR_CADT_FLAGS]) {
> > >  	
> > >  		u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
> > > 
> > > diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
> > > index 9957e0ed8658..90c39e694e87 100644
> > > --- a/net/netfilter/nf_tables_api.c
> > > +++ b/net/netfilter/nf_tables_api.c
> > > @@ -1281,7 +1281,7 @@ static struct nft_chain *nft_chain_lookup(struct net
> > > *net,> 
> > >  	if (nla == NULL)
> > >  	
> > >  		return ERR_PTR(-EINVAL);
> > > 
> > > -	nla_strlcpy(search, nla, sizeof(search));
> > > +	nla_strscpy(search, nla, sizeof(search));
> > > 
> > >  	WARN_ON(!rcu_read_lock_held() &&
> > >  	
> > >  		!lockdep_commit_lock_is_held(net));
> > > 
> > > @@ -1721,7 +1721,7 @@ static struct nft_hook *nft_netdev_hook_alloc(struct
> > > net *net,> 
> > >  		goto err_hook_alloc;
> > >  	
> > >  	}
> > > 
> > > -	nla_strlcpy(ifname, attr, IFNAMSIZ);
> > > +	nla_strscpy(ifname, attr, IFNAMSIZ);
> > > 
> > >  	dev = __dev_get_by_name(net, ifname);
> > >  	if (!dev) {
> > >  	
> > >  		err = -ENOENT;
> > > 
> > > @@ -5734,7 +5734,7 @@ struct nft_object *nft_obj_lookup(const struct net
> > > *net,> 
> > >  	struct rhlist_head *tmp, *list;
> > >  	struct nft_object *obj;
> > > 
> > > -	nla_strlcpy(search, nla, sizeof(search));
> > > +	nla_strscpy(search, nla, sizeof(search));
> > > 
> > >  	k.name = search;
> > >  	
> > >  	WARN_ON_ONCE(!rcu_read_lock_held() &&
> > > 
> > > diff --git a/net/netfilter/nfnetlink_acct.c
> > > b/net/netfilter/nfnetlink_acct.c index 5bfec829c12f..5e511df8d709 100644
> > > --- a/net/netfilter/nfnetlink_acct.c
> > > +++ b/net/netfilter/nfnetlink_acct.c
> > > @@ -112,7 +112,7 @@ static int nfnl_acct_new(struct net *net, struct sock
> > > *nfnl,> 
> > >  		nfacct->flags = flags;
> > >  	
> > >  	}
> > > 
> > > -	nla_strlcpy(nfacct->name, tb[NFACCT_NAME], NFACCT_NAME_MAX);
> > > +	nla_strscpy(nfacct->name, tb[NFACCT_NAME], NFACCT_NAME_MAX);
> > > 
> > >  	if (tb[NFACCT_BYTES]) {
> > >  	
> > >  		atomic64_set(&nfacct->bytes,
> > > 
> > > diff --git a/net/netfilter/nfnetlink_cthelper.c
> > > b/net/netfilter/nfnetlink_cthelper.c index 5b0d0a77379c..0f94fce1d3ed
> > > 100644
> > > --- a/net/netfilter/nfnetlink_cthelper.c
> > > +++ b/net/netfilter/nfnetlink_cthelper.c
> > > @@ -146,7 +146,7 @@ nfnl_cthelper_expect_policy(struct
> > > nf_conntrack_expect_policy *expect_policy,> 
> > >  	    !tb[NFCTH_POLICY_EXPECT_TIMEOUT])
> > >  		
> > >  		return -EINVAL;
> > > 
> > > -	nla_strlcpy(expect_policy->name,
> > > +	nla_strscpy(expect_policy->name,
> > > 
> > >  		    tb[NFCTH_POLICY_NAME], NF_CT_HELPER_NAME_LEN);
> > >  	
> > >  	expect_policy->max_expected =
> > >  	
> > >  		ntohl(nla_get_be32(tb[NFCTH_POLICY_EXPECT_MAX]));
> > > 
> > > @@ -233,7 +233,7 @@ nfnl_cthelper_create(const struct nlattr * const tb[],
> > > 
> > >  	if (ret < 0)
> > >  	
> > >  		goto err1;
> > > 
> > > -	nla_strlcpy(helper->name,
> > > +	nla_strscpy(helper->name,
> > > 
> > >  		    tb[NFCTH_NAME], NF_CT_HELPER_NAME_LEN);
> > >  	
> > >  	size = ntohl(nla_get_be32(tb[NFCTH_PRIV_DATA_LEN]));
> > >  	if (size > sizeof_field(struct nf_conn_help, data)) {
> > > 
> > > diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c
> > > index 322bd674963e..a8c4d442231c 100644
> > > --- a/net/netfilter/nft_ct.c
> > > +++ b/net/netfilter/nft_ct.c
> > > @@ -990,7 +990,7 @@ static int nft_ct_helper_obj_init(const struct nft_ctx
> > > *ctx,> 
> > >  	if (!priv->l4proto)
> > >  	
> > >  		return -ENOENT;
> > > 
> > > -	nla_strlcpy(name, tb[NFTA_CT_HELPER_NAME], sizeof(name));
> > > +	nla_strscpy(name, tb[NFTA_CT_HELPER_NAME], sizeof(name));
> > > 
> > >  	if (tb[NFTA_CT_HELPER_L3PROTO])
> > >  	
> > >  		family = ntohs(nla_get_be16(tb[NFTA_CT_HELPER_L3PROTO]));
> > > 
> > > diff --git a/net/netfilter/nft_log.c b/net/netfilter/nft_log.c
> > > index 57899454a530..a06a46b039c5 100644
> > > --- a/net/netfilter/nft_log.c
> > > +++ b/net/netfilter/nft_log.c
> > > @@ -152,7 +152,7 @@ static int nft_log_init(const struct nft_ctx *ctx,
> > > 
> > >  		priv->prefix = kmalloc(nla_len(nla) + 1, GFP_KERNEL);
> > >  		if (priv->prefix == NULL)
> > >  		
> > >  			return -ENOMEM;
> > > 
> > > -		nla_strlcpy(priv->prefix, nla, nla_len(nla) + 1);
> > > +		nla_strscpy(priv->prefix, nla, nla_len(nla) + 1);
> > > 
> > >  	} else {
> > >  	
> > >  		priv->prefix = (char *)nft_log_null_prefix;
> > >  	
> > >  	}
> > > 
> > > diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c
> > > index eb1d66d20afb..df1b41ed73fd 100644
> > > --- a/net/netlabel/netlabel_mgmt.c
> > > +++ b/net/netlabel/netlabel_mgmt.c
> > > @@ -95,7 +95,7 @@ static int netlbl_mgmt_add_common(struct genl_info
> > > *info,
> > > 
> > >  			ret_val = -ENOMEM;
> > >  			goto add_free_entry;
> > >  		
> > >  		}
> > > 
> > > -		nla_strlcpy(entry->domain,
> > > +		nla_strscpy(entry->domain,
> > > 
> > >  			    info->attrs[NLBL_MGMT_A_DOMAIN], tmp_size);
> > >  	
> > >  	}
> > > 
> > > diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c
> > > index e894254c17d4..438ff1f30a33 100644
> > > --- a/net/nfc/netlink.c
> > > +++ b/net/nfc/netlink.c
> > > @@ -1226,7 +1226,7 @@ static int nfc_genl_fw_download(struct sk_buff *skb,
> > > struct genl_info *info)> 
> > >  	if (!dev)
> > >  	
> > >  		return -ENODEV;
> > > 
> > > -	nla_strlcpy(firmware_name, info->attrs[NFC_ATTR_FIRMWARE_NAME],
> > > +	nla_strscpy(firmware_name, info->attrs[NFC_ATTR_FIRMWARE_NAME],
> > > 
> > >  		    sizeof(firmware_name));
> > >  	
> > >  	rc = nfc_fw_download(dev, firmware_name);
> > > 
> > > diff --git a/net/sched/act_api.c b/net/sched/act_api.c
> > > index 541574520c52..eac24a73115f 100644
> > > --- a/net/sched/act_api.c
> > > +++ b/net/sched/act_api.c
> > > @@ -935,7 +935,7 @@ struct tc_action *tcf_action_init_1(struct net *net,
> > > struct tcf_proto *tp,> 
> > >  			NL_SET_ERR_MSG(extack, "TC action kind must be specified");
> > >  			goto err_out;
> > >  		
> > >  		}
> > > 
> > > -		if (nla_strlcpy(act_name, kind, IFNAMSIZ) < 0) {
> > > +		if (nla_strscpy(act_name, kind, IFNAMSIZ) < 0) {
> > > 
> > >  			NL_SET_ERR_MSG(extack, "TC action name too long");
> > >  			goto err_out;
> > >  		
> > >  		}
> > > 
> > > diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c
> > > index 8dc3bec0d325..ac7297f42355 100644
> > > --- a/net/sched/act_ipt.c
> > > +++ b/net/sched/act_ipt.c
> > > @@ -166,7 +166,7 @@ static int __tcf_ipt_init(struct net *net, unsigned
> > > int id, struct nlattr *nla,> 
> > >  	if (unlikely(!tname))
> > >  	
> > >  		goto err1;
> > >  	
> > >  	if (tb[TCA_IPT_TABLE] == NULL ||
> > > 
> > > -	    nla_strlcpy(tname, tb[TCA_IPT_TABLE], IFNAMSIZ) >= IFNAMSIZ)
> > > +	    nla_strscpy(tname, tb[TCA_IPT_TABLE], IFNAMSIZ) >= IFNAMSIZ)
> > > 
> > >  		strcpy(tname, "mangle");
> > >  	
> > >  	t = kmemdup(td, td->u.target_size, GFP_KERNEL);
> > > 
> > > diff --git a/net/sched/act_simple.c b/net/sched/act_simple.c
> > > index a4f3d0f0daa9..726cc956d06f 100644
> > > --- a/net/sched/act_simple.c
> > > +++ b/net/sched/act_simple.c
> > > @@ -52,7 +52,7 @@ static int alloc_defdata(struct tcf_defact *d, const
> > > struct nlattr *defdata)> 
> > >  	d->tcfd_defdata = kzalloc(SIMP_MAX_DATA, GFP_KERNEL);
> > >  	if (unlikely(!d->tcfd_defdata))
> > >  	
> > >  		return -ENOMEM;
> > > 
> > > -	nla_strlcpy(d->tcfd_defdata, defdata, SIMP_MAX_DATA);
> > > +	nla_strscpy(d->tcfd_defdata, defdata, SIMP_MAX_DATA);
> > > 
> > >  	return 0;
> > >  
> > >  }
> > > 
> > > @@ -71,7 +71,7 @@ static int reset_policy(struct tc_action *a, const
> > > struct nlattr *defdata,> 
> > >  	spin_lock_bh(&d->tcf_lock);
> > >  	goto_ch = tcf_action_set_ctrlact(a, p->action, goto_ch);
> > >  	memset(d->tcfd_defdata, 0, SIMP_MAX_DATA);
> > > 
> > > -	nla_strlcpy(d->tcfd_defdata, defdata, SIMP_MAX_DATA);
> > > +	nla_strscpy(d->tcfd_defdata, defdata, SIMP_MAX_DATA);
> > > 
> > >  	spin_unlock_bh(&d->tcf_lock);
> > >  	if (goto_ch)
> > >  	
> > >  		tcf_chain_put_by_act(goto_ch);
> > > 
> > > diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
> > > index c78241c853a5..6ff3b817083a 100644
> > > --- a/net/sched/cls_api.c
> > > +++ b/net/sched/cls_api.c
> > > @@ -223,7 +223,7 @@ static inline u32 tcf_auto_prio(struct tcf_proto *tp)
> > > 
> > >  static bool tcf_proto_check_kind(struct nlattr *kind, char *name)
> > >  {
> > >  
> > >  	if (kind)
> > > 
> > > -		return nla_strlcpy(name, kind, IFNAMSIZ) < 0;
> > > +		return nla_strscpy(name, kind, IFNAMSIZ) < 0;
> > > 
> > >  	memset(name, 0, IFNAMSIZ);
> > >  	return false;
> > >  
> > >  }
> > > 
> > > diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
> > > index f9b053b30a7b..cb4f30700c74 100644
> > > --- a/net/sched/sch_api.c
> > > +++ b/net/sched/sch_api.c
> > > @@ -1170,7 +1170,7 @@ static struct Qdisc *qdisc_create(struct net_device
> > > *dev,> 
> > >  #ifdef CONFIG_MODULES
> > >  
> > >  	if (ops == NULL && kind != NULL) {
> > >  	
> > >  		char name[IFNAMSIZ];
> > > 
> > > -		if (nla_strlcpy(name, kind, IFNAMSIZ) > 0) {
> > > +		if (nla_strscpy(name, kind, IFNAMSIZ) > 0) {
> > > 
> > >  			/* We dropped the RTNL semaphore in order to
> > >  			
> > >  			 * perform the module load.  So, even if we
> > >  			 * succeeded in loading the module we have to
> > > 
> > > diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c
> > > index 1c7aa51cc2a3..644c7ec41ddf 100644
> > > --- a/net/tipc/netlink_compat.c
> > > +++ b/net/tipc/netlink_compat.c
> > > @@ -695,7 +695,7 @@ static int tipc_nl_compat_link_dump(struct
> > > tipc_nl_compat_msg *msg,> 
> > >  	link_info.dest = nla_get_flag(link[TIPC_NLA_LINK_DEST]);
> > >  	link_info.up = htonl(nla_get_flag(link[TIPC_NLA_LINK_UP]));
> > > 
> > > -	nla_strlcpy(link_info.str, link[TIPC_NLA_LINK_NAME],
> > > +	nla_strscpy(link_info.str, link[TIPC_NLA_LINK_NAME],
> > > 
> > >  		    TIPC_MAX_LINK_NAME);
> > >  	
> > >  	return tipc_add_tlv(msg->rep, TIPC_TLV_LINK_INFO,
> 
> 
> 

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC][PATCH v3 3/3] Rename nla_strlcpy to nla_strscpy.
  2020-10-22 20:04       ` Kees Cook
@ 2020-10-22 23:05         ` Jakub Kicinski
  2020-10-23  8:07           ` David Laight
  2020-10-23 15:16           ` Francis Laniel
  2020-10-24 10:41         ` Francis Laniel
  1 sibling, 2 replies; 17+ messages in thread
From: Jakub Kicinski @ 2020-10-22 23:05 UTC (permalink / raw)
  To: Kees Cook; +Cc: Francis Laniel, linux-hardening, netdev, davem

On Thu, 22 Oct 2020 13:04:32 -0700 Kees Cook wrote:
> > > > From: Francis Laniel <laniel_francis@privacyrequired.com>
> > > > 
> > > > Calls to nla_strlcpy are now replaced by calls to nla_strscpy which is the
> > > > new name of this function.
> > > > 
> > > > Signed-off-by: Francis Laniel <laniel_francis@privacyrequired.com>  
> > > 
> > > The Subject could also be: "treewide: Rename nla_strlcpy to nla_strscpy"
> > > 
> > > But otherwise, yup, easy mechanical change.  
> > 
> > Should I submit a v4 for this change?  
> 
> I'll say yes. :) Drop the RFC, bump to v4, and send it to netdev (along
> with all the other CCs you have here already), and add the Reviewed-bys
> from v3.

Maybe wait until next week, IIRC this doesn't fix any bugs, so it's
-next material. We don't apply anything to net-next during the merge
window.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* RE: [RFC][PATCH v3 3/3] Rename nla_strlcpy to nla_strscpy.
  2020-10-22 23:05         ` Jakub Kicinski
@ 2020-10-23  8:07           ` David Laight
  2020-10-23 15:15             ` Francis Laniel
  2020-10-23 15:29             ` Jakub Kicinski
  2020-10-23 15:16           ` Francis Laniel
  1 sibling, 2 replies; 17+ messages in thread
From: David Laight @ 2020-10-23  8:07 UTC (permalink / raw)
  To: 'Jakub Kicinski', Kees Cook
  Cc: Francis Laniel, linux-hardening, netdev, davem

From: Jakub Kicinski
> Sent: 23 October 2020 00:06
> 
> On Thu, 22 Oct 2020 13:04:32 -0700 Kees Cook wrote:
> > > > > From: Francis Laniel <laniel_francis@privacyrequired.com>
> > > > >
> > > > > Calls to nla_strlcpy are now replaced by calls to nla_strscpy which is the
> > > > > new name of this function.
> > > > >
> > > > > Signed-off-by: Francis Laniel <laniel_francis@privacyrequired.com>
> > > >
> > > > The Subject could also be: "treewide: Rename nla_strlcpy to nla_strscpy"
> > > >
> > > > But otherwise, yup, easy mechanical change.
> > >
> > > Should I submit a v4 for this change?
> >
> > I'll say yes. :) Drop the RFC, bump to v4, and send it to netdev (along
> > with all the other CCs you have here already), and add the Reviewed-bys
> > from v3.
> 
> Maybe wait until next week, IIRC this doesn't fix any bugs, so it's
> -next material. We don't apply anything to net-next during the merge
> window.

Is this just a rename, or have you changed the result value?
In the latter case the subject is really right.

FWIW I suspect  the 'return -ERR on overflow' is going to bite us.
Code that does p += strsxxx(p, ..., lim - p, ...) assuming (or not
caring) about overflow goes badly wrong.

To my mind returning the full buffer length (ie include the '\0')
on overflow still allows overflow be checked but makes writes
outside the buffer very unlikely.

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC][PATCH v3 3/3] Rename nla_strlcpy to nla_strscpy.
  2020-10-23  8:07           ` David Laight
@ 2020-10-23 15:15             ` Francis Laniel
  2020-10-23 15:29             ` Jakub Kicinski
  1 sibling, 0 replies; 17+ messages in thread
From: Francis Laniel @ 2020-10-23 15:15 UTC (permalink / raw)
  To: David Laight
  Cc: 'Jakub Kicinski', Kees Cook, linux-hardening, netdev, davem

Le vendredi 23 octobre 2020, 10:07:44 CEST David Laight a écrit :
> From: Jakub Kicinski
> 
> > Sent: 23 October 2020 00:06
> > 
> > On Thu, 22 Oct 2020 13:04:32 -0700 Kees Cook wrote:
> > > > > > From: Francis Laniel <laniel_francis@privacyrequired.com>
> > > > > > 
> > > > > > Calls to nla_strlcpy are now replaced by calls to nla_strscpy
> > > > > > which is the
> > > > > > new name of this function.
> > > > > > 
> > > > > > Signed-off-by: Francis Laniel <laniel_francis@privacyrequired.com>
> > > > > 
> > > > > The Subject could also be: "treewide: Rename nla_strlcpy to
> > > > > nla_strscpy"
> > > > > 
> > > > > But otherwise, yup, easy mechanical change.
> > > > 
> > > > Should I submit a v4 for this change?
> > > 
> > > I'll say yes. :) Drop the RFC, bump to v4, and send it to netdev (along
> > > with all the other CCs you have here already), and add the Reviewed-bys
> > > from v3.
> > 
> > Maybe wait until next week, IIRC this doesn't fix any bugs, so it's
> > -next material. We don't apply anything to net-next during the merge
> > window.
> 
> Is this just a rename, or have you changed the result value?
> In the latter case the subject is really right.

I changed the result value so it mimics the return value of strscpy.

> FWIW I suspect  the 'return -ERR on overflow' is going to bite us.
> Code that does p += strsxxx(p, ..., lim - p, ...) assuming (or not
> caring) about overflow goes badly wrong.

Normally, I updated all parts of the code that check the value returned by 
nla_strscpy.
But, if I understood correctly you are afraid of this type of code:
nla_strscpy(p, nla, p_len);
p += strncat(p, something, lim - p, ...);
Am I correct?

> To my mind returning the full buffer length (ie include the '\0')
> on overflow still allows overflow be checked but makes writes
> outside the buffer very unlikely.

Maybe I can keep the original behavior and add a pointer as argument which is 
used to contain -ERR?

> 	David
> 
> -
> Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1
> 1PT, UK Registration No: 1397386 (Wales)




^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC][PATCH v3 3/3] Rename nla_strlcpy to nla_strscpy.
  2020-10-22 23:05         ` Jakub Kicinski
  2020-10-23  8:07           ` David Laight
@ 2020-10-23 15:16           ` Francis Laniel
  1 sibling, 0 replies; 17+ messages in thread
From: Francis Laniel @ 2020-10-23 15:16 UTC (permalink / raw)
  To: Jakub Kicinski; +Cc: Kees Cook, linux-hardening, netdev, davem

Le vendredi 23 octobre 2020, 01:05:51 CEST Jakub Kicinski a écrit :
> On Thu, 22 Oct 2020 13:04:32 -0700 Kees Cook wrote:
> > > > > From: Francis Laniel <laniel_francis@privacyrequired.com>
> > > > > 
> > > > > Calls to nla_strlcpy are now replaced by calls to nla_strscpy which
> > > > > is the
> > > > > new name of this function.
> > > > > 
> > > > > Signed-off-by: Francis Laniel <laniel_francis@privacyrequired.com>
> > > > 
> > > > The Subject could also be: "treewide: Rename nla_strlcpy to
> > > > nla_strscpy"
> > > > 
> > > > But otherwise, yup, easy mechanical change.
> > > 
> > > Should I submit a v4 for this change?
> > 
> > I'll say yes. :) Drop the RFC, bump to v4, and send it to netdev (along
> > with all the other CCs you have here already), and add the Reviewed-bys
> > from v3.
> 
> Maybe wait until next week, IIRC this doesn't fix any bugs, so it's
> -next material. We don't apply anything to net-next during the merge
> window.

I will wait for next Friday to submit the v4.




^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC][PATCH v3 3/3] Rename nla_strlcpy to nla_strscpy.
  2020-10-23  8:07           ` David Laight
  2020-10-23 15:15             ` Francis Laniel
@ 2020-10-23 15:29             ` Jakub Kicinski
  2020-10-23 17:41               ` Kees Cook
  1 sibling, 1 reply; 17+ messages in thread
From: Jakub Kicinski @ 2020-10-23 15:29 UTC (permalink / raw)
  To: David Laight; +Cc: Kees Cook, Francis Laniel, linux-hardening, netdev, davem

On Fri, 23 Oct 2020 08:07:44 +0000 David Laight wrote:
> FWIW I suspect  the 'return -ERR on overflow' is going to bite us.
> Code that does p += strsxxx(p, ..., lim - p, ...) assuming (or not
> caring) about overflow goes badly wrong.

I don't really care either way, but in netlink there's usually an
attribute per value, nothing combines strings like p += strx..().
Looking at the conversion in patch 2 the callers just want to 
check for overflow.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC][PATCH v3 3/3] Rename nla_strlcpy to nla_strscpy.
  2020-10-23 15:29             ` Jakub Kicinski
@ 2020-10-23 17:41               ` Kees Cook
  0 siblings, 0 replies; 17+ messages in thread
From: Kees Cook @ 2020-10-23 17:41 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: David Laight, Francis Laniel, linux-hardening, netdev, davem

On Fri, Oct 23, 2020 at 08:29:20AM -0700, Jakub Kicinski wrote:
> On Fri, 23 Oct 2020 08:07:44 +0000 David Laight wrote:
> > FWIW I suspect  the 'return -ERR on overflow' is going to bite us.
> > Code that does p += strsxxx(p, ..., lim - p, ...) assuming (or not
> > caring) about overflow goes badly wrong.
> 
> I don't really care either way, but in netlink there's usually an
> attribute per value, nothing combines strings like p += strx..().
> Looking at the conversion in patch 2 the callers just want to 
> check for overflow.

Right -- this is a very narrow use-case (NLA). I think this series is
fine as-is.

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC][PATCH v3 3/3] Rename nla_strlcpy to nla_strscpy.
  2020-10-22 20:04       ` Kees Cook
  2020-10-22 23:05         ` Jakub Kicinski
@ 2020-10-24 10:41         ` Francis Laniel
  1 sibling, 0 replies; 17+ messages in thread
From: Francis Laniel @ 2020-10-24 10:41 UTC (permalink / raw)
  To: Kees Cook; +Cc: linux-hardening, netdev, davem, kuba

Le jeudi 22 octobre 2020, 22:04:32 CEST Kees Cook a écrit :
> On Thu, Oct 22, 2020 at 11:41:31AM +0200, Francis Laniel wrote:
> > Le jeudi 22 octobre 2020, 01:49:59 CEST Kees Cook a écrit :
> > > On Tue, Oct 20, 2020 at 06:47:07PM +0200,
> > > laniel_francis@privacyrequired.com> 
> > wrote:
> > > > From: Francis Laniel <laniel_francis@privacyrequired.com>
> > > > 
> > > > Calls to nla_strlcpy are now replaced by calls to nla_strscpy which is
> > > > the
> > > > new name of this function.
> > > > 
> > > > Signed-off-by: Francis Laniel <laniel_francis@privacyrequired.com>
> > > 
> > > The Subject could also be: "treewide: Rename nla_strlcpy to nla_strscpy"
> > > 
> > > But otherwise, yup, easy mechanical change.
> > 
> > Should I submit a v4 for this change?
> 
> I'll say yes. :) Drop the RFC, bump to v4, and send it to netdev (along
> with all the other CCs you have here already), and add the Reviewed-bys
> from v3.

I will add it for the next version (which will be submitted Friday 30th 
October).
About the "Reviewed-by" tags, yesterday I read this document:
https://www.kernel.org/doc/html/latest/process/submitting-patches.html
(I should have read it sooner)
And I found about the "Suggested-by" tag, should I add this tag and quoting 
you as the suggester? Since you put this issue on GitHub and I just 
implemented it.

> Thanks!

You are welcome and thank you for all the reviews!

> -Kees
> 
> > > Reviewed-by: Kees Cook <keescook@chromium.org>
> > > 
> > > > ---
> > > > 
> > > >  drivers/infiniband/core/nldev.c            | 10 +++++-----
> > > >  drivers/net/can/vxcan.c                    |  4 ++--
> > > >  drivers/net/veth.c                         |  4 ++--
> > > >  include/linux/genl_magic_struct.h          |  2 +-
> > > >  include/net/netlink.h                      |  4 ++--
> > > >  include/net/pkt_cls.h                      |  2 +-
> > > >  kernel/taskstats.c                         |  2 +-
> > > >  lib/nlattr.c                               |  6 +++---
> > > >  net/core/fib_rules.c                       |  4 ++--
> > > >  net/core/rtnetlink.c                       | 12 ++++++------
> > > >  net/decnet/dn_dev.c                        |  2 +-
> > > >  net/ieee802154/nl-mac.c                    |  2 +-
> > > >  net/ipv4/devinet.c                         |  2 +-
> > > >  net/ipv4/fib_semantics.c                   |  2 +-
> > > >  net/ipv4/metrics.c                         |  2 +-
> > > >  net/netfilter/ipset/ip_set_hash_netiface.c |  4 ++--
> > > >  net/netfilter/nf_tables_api.c              |  6 +++---
> > > >  net/netfilter/nfnetlink_acct.c             |  2 +-
> > > >  net/netfilter/nfnetlink_cthelper.c         |  4 ++--
> > > >  net/netfilter/nft_ct.c                     |  2 +-
> > > >  net/netfilter/nft_log.c                    |  2 +-
> > > >  net/netlabel/netlabel_mgmt.c               |  2 +-
> > > >  net/nfc/netlink.c                          |  2 +-
> > > >  net/sched/act_api.c                        |  2 +-
> > > >  net/sched/act_ipt.c                        |  2 +-
> > > >  net/sched/act_simple.c                     |  4 ++--
> > > >  net/sched/cls_api.c                        |  2 +-
> > > >  net/sched/sch_api.c                        |  2 +-
> > > >  net/tipc/netlink_compat.c                  |  2 +-
> > > >  29 files changed, 49 insertions(+), 49 deletions(-)
> > > > 
> > > > diff --git a/drivers/infiniband/core/nldev.c
> > > > b/drivers/infiniband/core/nldev.c index 12d29d54a081..08366e254b1d
> > > > 100644
> > > > --- a/drivers/infiniband/core/nldev.c
> > > > +++ b/drivers/infiniband/core/nldev.c
> > > > @@ -932,7 +932,7 @@ static int nldev_set_doit(struct sk_buff *skb,
> > > > struct
> > > > nlmsghdr *nlh,>
> > > > 
> > > >  	if (tb[RDMA_NLDEV_ATTR_DEV_NAME]) {
> > > >  	
> > > >  		char name[IB_DEVICE_NAME_MAX] = {};
> > > > 
> > > > -		nla_strlcpy(name, tb[RDMA_NLDEV_ATTR_DEV_NAME],
> > > > +		nla_strscpy(name, tb[RDMA_NLDEV_ATTR_DEV_NAME],
> > > > 
> > > >  			    IB_DEVICE_NAME_MAX);
> > > >  		
> > > >  		if (strlen(name) == 0) {
> > > >  		
> > > >  			err = -EINVAL;
> > > > 
> > > > @@ -1529,13 +1529,13 @@ static int nldev_newlink(struct sk_buff *skb,
> > > > struct nlmsghdr *nlh,>
> > > > 
> > > >  	    !tb[RDMA_NLDEV_ATTR_LINK_TYPE] ||
> > > >  	    !tb[RDMA_NLDEV_ATTR_NDEV_NAME])
> > > >  		
> > > >  		return -EINVAL;
> > > > 
> > > > -	nla_strlcpy(ibdev_name, tb[RDMA_NLDEV_ATTR_DEV_NAME],
> > > > +	nla_strscpy(ibdev_name, tb[RDMA_NLDEV_ATTR_DEV_NAME],
> > > > 
> > > >  		    sizeof(ibdev_name));
> > > >  	
> > > >  	if (strchr(ibdev_name, '%') || strlen(ibdev_name) == 0)
> > > >  	
> > > >  		return -EINVAL;
> > > > 
> > > > -	nla_strlcpy(type, tb[RDMA_NLDEV_ATTR_LINK_TYPE], sizeof(type));
> > > > -	nla_strlcpy(ndev_name, tb[RDMA_NLDEV_ATTR_NDEV_NAME],
> > > > +	nla_strscpy(type, tb[RDMA_NLDEV_ATTR_LINK_TYPE], sizeof(type));
> > > > +	nla_strscpy(ndev_name, tb[RDMA_NLDEV_ATTR_NDEV_NAME],
> > > > 
> > > >  		    sizeof(ndev_name));
> > > >  	
> > > >  	ndev = dev_get_by_name(sock_net(skb->sk), ndev_name);
> > > > 
> > > > @@ -1602,7 +1602,7 @@ static int nldev_get_chardev(struct sk_buff
> > > > *skb,
> > > > struct nlmsghdr *nlh,>
> > > > 
> > > >  	if (err || !tb[RDMA_NLDEV_ATTR_CHARDEV_TYPE])
> > > >  	
> > > >  		return -EINVAL;
> > > > 
> > > > -	nla_strlcpy(client_name, tb[RDMA_NLDEV_ATTR_CHARDEV_TYPE],
> > > > +	nla_strscpy(client_name, tb[RDMA_NLDEV_ATTR_CHARDEV_TYPE],
> > > > 
> > > >  		    sizeof(client_name));
> > > >  	
> > > >  	if (tb[RDMA_NLDEV_ATTR_DEV_INDEX]) {
> > > > 
> > > > diff --git a/drivers/net/can/vxcan.c b/drivers/net/can/vxcan.c
> > > > index d6ba9426be4d..fa47bab510bb 100644
> > > > --- a/drivers/net/can/vxcan.c
> > > > +++ b/drivers/net/can/vxcan.c
> > > > @@ -186,7 +186,7 @@ static int vxcan_newlink(struct net *net, struct
> > > > net_device *dev,>
> > > > 
> > > >  	}
> > > >  	
> > > >  	if (ifmp && tbp[IFLA_IFNAME]) {
> > > > 
> > > > -		nla_strlcpy(ifname, tbp[IFLA_IFNAME], IFNAMSIZ);
> > > > +		nla_strscpy(ifname, tbp[IFLA_IFNAME], IFNAMSIZ);
> > > > 
> > > >  		name_assign_type = NET_NAME_USER;
> > > >  	
> > > >  	} else {
> > > >  	
> > > >  		snprintf(ifname, IFNAMSIZ, DRV_NAME "%%d");
> > > > 
> > > > @@ -223,7 +223,7 @@ static int vxcan_newlink(struct net *net, struct
> > > > net_device *dev,>
> > > > 
> > > >  	/* register first device */
> > > >  	if (tb[IFLA_IFNAME])
> > > > 
> > > > -		nla_strlcpy(dev->name, tb[IFLA_IFNAME], IFNAMSIZ);
> > > > +		nla_strscpy(dev->name, tb[IFLA_IFNAME], IFNAMSIZ);
> > > > 
> > > >  	else
> > > >  	
> > > >  		snprintf(dev->name, IFNAMSIZ, DRV_NAME "%%d");
> > > > 
> > > > diff --git a/drivers/net/veth.c b/drivers/net/veth.c
> > > > index 8c737668008a..359d3ab33c4d 100644
> > > > --- a/drivers/net/veth.c
> > > > +++ b/drivers/net/veth.c
> > > > @@ -1329,7 +1329,7 @@ static int veth_newlink(struct net *src_net,
> > > > struct
> > > > net_device *dev,>
> > > > 
> > > >  	}
> > > >  	
> > > >  	if (ifmp && tbp[IFLA_IFNAME]) {
> > > > 
> > > > -		nla_strlcpy(ifname, tbp[IFLA_IFNAME], IFNAMSIZ);
> > > > +		nla_strscpy(ifname, tbp[IFLA_IFNAME], IFNAMSIZ);
> > > > 
> > > >  		name_assign_type = NET_NAME_USER;
> > > >  	
> > > >  	} else {
> > > >  	
> > > >  		snprintf(ifname, IFNAMSIZ, DRV_NAME "%%d");
> > > > 
> > > > @@ -1379,7 +1379,7 @@ static int veth_newlink(struct net *src_net,
> > > > struct
> > > > net_device *dev,>
> > > > 
> > > >  		eth_hw_addr_random(dev);
> > > >  	
> > > >  	if (tb[IFLA_IFNAME])
> > > > 
> > > > -		nla_strlcpy(dev->name, tb[IFLA_IFNAME], IFNAMSIZ);
> > > > +		nla_strscpy(dev->name, tb[IFLA_IFNAME], IFNAMSIZ);
> > > > 
> > > >  	else
> > > >  	
> > > >  		snprintf(dev->name, IFNAMSIZ, DRV_NAME "%%d");
> > > > 
> > > > diff --git a/include/linux/genl_magic_struct.h
> > > > b/include/linux/genl_magic_struct.h index eeae59d3ceb7..35d21fddaf2d
> > > > 100644
> > > > --- a/include/linux/genl_magic_struct.h
> > > > +++ b/include/linux/genl_magic_struct.h
> > > > @@ -89,7 +89,7 @@ static inline int nla_put_u64_0pad(struct sk_buff
> > > > *skb,
> > > > int attrtype, u64 value)>
> > > > 
> > > >  			nla_get_u64, nla_put_u64_0pad, false)
> > > >  
> > > >  #define __str_field(attr_nr, attr_flag, name, maxlen) \
> > > >  
> > > >  	__array(attr_nr, attr_flag, name, NLA_NUL_STRING, char, maxlen, \
> > > > 
> > > > -			nla_strlcpy, nla_put, false)
> > > > +			nla_strscpy, nla_put, false)
> > > > 
> > > >  #define __bin_field(attr_nr, attr_flag, name, maxlen) \
> > > >  
> > > >  	__array(attr_nr, attr_flag, name, NLA_BINARY, char, maxlen, \
> > > >  	
> > > >  			nla_memcpy, nla_put, false)
> > > > 
> > > > diff --git a/include/net/netlink.h b/include/net/netlink.h
> > > > index 446ca182e13d..1ceec518ab49 100644
> > > > --- a/include/net/netlink.h
> > > > +++ b/include/net/netlink.h
> > > > @@ -142,7 +142,7 @@
> > > > 
> > > >   * Attribute Misc:
> > > >   *   nla_memcpy(dest, nla, count)	copy attribute into memory
> > > >   *   nla_memcmp(nla, data, size)	compare attribute with memory area
> > > > 
> > > > - *   nla_strlcpy(dst, nla, size)	copy attribute to a sized string
> > > > + *   nla_strscpy(dst, nla, size)	copy attribute to a sized string
> > > > 
> > > >   *   nla_strcmp(nla, str)		compare attribute with string
> > > >   *
> > > > 
> > > >   * Attribute Parsing:
> > > > @@ -506,7 +506,7 @@ int __nla_parse(struct nlattr **tb, int maxtype,
> > > > const
> > > > struct nlattr *head,>
> > > > 
> > > >  		struct netlink_ext_ack *extack);
> > > >  
> > > >  int nla_policy_len(const struct nla_policy *, int);
> > > >  struct nlattr *nla_find(const struct nlattr *head, int len, int
> > > >  attrtype);
> > > > 
> > > > -ssize_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t
> > > > dstsize);
> > > > +ssize_t nla_strscpy(char *dst, const struct nlattr *nla, size_t
> > > > dstsize);
> > > > 
> > > >  char *nla_strdup(const struct nlattr *nla, gfp_t flags);
> > > >  int nla_memcpy(void *dest, const struct nlattr *src, int count);
> > > >  int nla_memcmp(const struct nlattr *nla, const void *data, size_t
> > > >  size);
> > > > 
> > > > diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
> > > > index db9a828f4f4f..133f9ad4d4f9 100644
> > > > --- a/include/net/pkt_cls.h
> > > > +++ b/include/net/pkt_cls.h
> > > > @@ -512,7 +512,7 @@ tcf_change_indev(struct net *net, struct nlattr
> > > > *indev_tlv,>
> > > > 
> > > >  	char indev[IFNAMSIZ];
> > > >  	struct net_device *dev;
> > > > 
> > > > -	if (nla_strlcpy(indev, indev_tlv, IFNAMSIZ) < 0) {
> > > > +	if (nla_strscpy(indev, indev_tlv, IFNAMSIZ) < 0) {
> > > > 
> > > >  		NL_SET_ERR_MSG_ATTR(extack, indev_tlv,
> > > >  		
> > > >  				    "Interface name too long");
> > > >  		
> > > >  		return -EINVAL;
> > > > 
> > > > diff --git a/kernel/taskstats.c b/kernel/taskstats.c
> > > > index a2802b6ff4bb..2b4898b4752e 100644
> > > > --- a/kernel/taskstats.c
> > > > +++ b/kernel/taskstats.c
> > > > @@ -346,7 +346,7 @@ static int parse(struct nlattr *na, struct cpumask
> > > > *mask)>
> > > > 
> > > >  	data = kmalloc(len, GFP_KERNEL);
> > > >  	if (!data)
> > > >  	
> > > >  		return -ENOMEM;
> > > > 
> > > > -	nla_strlcpy(data, na, len);
> > > > +	nla_strscpy(data, na, len);
> > > > 
> > > >  	ret = cpulist_parse(data, mask);
> > > >  	kfree(data);
> > > >  	return ret;
> > > > 
> > > > diff --git a/lib/nlattr.c b/lib/nlattr.c
> > > > index 447182543c03..09aa181569e0 100644
> > > > --- a/lib/nlattr.c
> > > > +++ b/lib/nlattr.c
> > > > @@ -709,7 +709,7 @@ struct nlattr *nla_find(const struct nlattr *head,
> > > > int
> > > > len, int attrtype)>
> > > > 
> > > >  EXPORT_SYMBOL(nla_find);
> > > >  
> > > >  /**
> > > > 
> > > > - * nla_strlcpy - Copy string attribute payload into a sized buffer
> > > > + * nla_strscpy - Copy string attribute payload into a sized buffer
> > > > 
> > > >   * @dst: Where to copy the string to.
> > > >   * @nla: Attribute to copy the string from.
> > > >   * @dstsize: Size of destination buffer.
> > > > 
> > > > @@ -722,7 +722,7 @@ EXPORT_SYMBOL(nla_find);
> > > > 
> > > >   * * -E2BIG - If @dstsize is 0 or greater than U16_MAX or @nla length
> > > >   greater *            than @dstsize.
> > > >   */
> > > > 
> > > > -ssize_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t
> > > > dstsize)
> > > > +ssize_t nla_strscpy(char *dst, const struct nlattr *nla, size_t
> > > > dstsize)
> > > > 
> > > >  {
> > > >  
> > > >  	size_t srclen = nla_len(nla);
> > > >  	char *src = nla_data(nla);
> > > > 
> > > > @@ -749,7 +749,7 @@ ssize_t nla_strlcpy(char *dst, const struct nlattr
> > > > *nla, size_t dstsize)>
> > > > 
> > > >  	return ret;
> > > >  
> > > >  }
> > > > 
> > > > -EXPORT_SYMBOL(nla_strlcpy);
> > > > +EXPORT_SYMBOL(nla_strscpy);
> > > > 
> > > >  /**
> > > >  
> > > >   * nla_strdup - Copy string attribute payload into a newly allocated
> > > >   buffer
> > > > 
> > > > diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c
> > > > index 7bcfb16854cb..cd80ffed6d26 100644
> > > > --- a/net/core/fib_rules.c
> > > > +++ b/net/core/fib_rules.c
> > > > @@ -563,7 +563,7 @@ static int fib_nl2rule(struct sk_buff *skb, struct
> > > > nlmsghdr *nlh,>
> > > > 
> > > >  		struct net_device *dev;
> > > >  		
> > > >  		nlrule->iifindex = -1;
> > > > 
> > > > -		nla_strlcpy(nlrule->iifname, tb[FRA_IIFNAME], IFNAMSIZ);
> > > > +		nla_strscpy(nlrule->iifname, tb[FRA_IIFNAME], IFNAMSIZ);
> > > > 
> > > >  		dev = __dev_get_by_name(net, nlrule->iifname);
> > > >  		if (dev)
> > > >  		
> > > >  			nlrule->iifindex = dev->ifindex;
> > > > 
> > > > @@ -573,7 +573,7 @@ static int fib_nl2rule(struct sk_buff *skb, struct
> > > > nlmsghdr *nlh,>
> > > > 
> > > >  		struct net_device *dev;
> > > >  		
> > > >  		nlrule->oifindex = -1;
> > > > 
> > > > -		nla_strlcpy(nlrule->oifname, tb[FRA_OIFNAME], IFNAMSIZ);
> > > > +		nla_strscpy(nlrule->oifname, tb[FRA_OIFNAME], IFNAMSIZ);
> > > > 
> > > >  		dev = __dev_get_by_name(net, nlrule->oifname);
> > > >  		if (dev)
> > > >  		
> > > >  			nlrule->oifindex = dev->ifindex;
> > > > 
> > > > diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
> > > > index 68e0682450c6..e0059256fe93 100644
> > > > --- a/net/core/rtnetlink.c
> > > > +++ b/net/core/rtnetlink.c
> > > > @@ -1939,7 +1939,7 @@ static const struct rtnl_link_ops
> > > > *linkinfo_to_kind_ops(const struct nlattr *nla>
> > > > 
> > > >  	if (linfo[IFLA_INFO_KIND]) {
> > > >  	
> > > >  		char kind[MODULE_NAME_LEN];
> > > > 
> > > > -		nla_strlcpy(kind, linfo[IFLA_INFO_KIND], sizeof(kind));
> > > > +		nla_strscpy(kind, linfo[IFLA_INFO_KIND], sizeof(kind));
> > > > 
> > > >  		ops = rtnl_link_ops_get(kind);
> > > >  	
> > > >  	}
> > > > 
> > > > @@ -2953,9 +2953,9 @@ static struct net_device *rtnl_dev_get(struct
> > > > net
> > > > *net,>
> > > > 
> > > >  	if (!ifname) {
> > > >  	
> > > >  		ifname = buffer;
> > > >  		if (ifname_attr)
> > > > 
> > > > -			nla_strlcpy(ifname, ifname_attr, IFNAMSIZ);
> > > > +			nla_strscpy(ifname, ifname_attr, IFNAMSIZ);
> > > > 
> > > >  		else if (altifname_attr)
> > > > 
> > > > -			nla_strlcpy(ifname, altifname_attr, ALTIFNAMSIZ);
> > > > +			nla_strscpy(ifname, altifname_attr, ALTIFNAMSIZ);
> > > > 
> > > >  		else
> > > >  		
> > > >  			return NULL;
> > > >  	
> > > >  	}
> > > > 
> > > > @@ -2983,7 +2983,7 @@ static int rtnl_setlink(struct sk_buff *skb,
> > > > struct
> > > > nlmsghdr *nlh,>
> > > > 
> > > >  		goto errout;
> > > >  	
> > > >  	if (tb[IFLA_IFNAME])
> > > > 
> > > > -		nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
> > > > +		nla_strscpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
> > > > 
> > > >  	else
> > > >  	
> > > >  		ifname[0] = '\0';
> > > > 
> > > > @@ -3264,7 +3264,7 @@ static int __rtnl_newlink(struct sk_buff *skb,
> > > > struct nlmsghdr *nlh,>
> > > > 
> > > >  		return err;
> > > >  	
> > > >  	if (tb[IFLA_IFNAME])
> > > > 
> > > > -		nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
> > > > +		nla_strscpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
> > > > 
> > > >  	else
> > > >  	
> > > >  		ifname[0] = '\0';
> > > > 
> > > > @@ -3296,7 +3296,7 @@ static int __rtnl_newlink(struct sk_buff *skb,
> > > > struct nlmsghdr *nlh,>
> > > > 
> > > >  		memset(linkinfo, 0, sizeof(linkinfo));
> > > >  	
> > > >  	if (linkinfo[IFLA_INFO_KIND]) {
> > > > 
> > > > -		nla_strlcpy(kind, linkinfo[IFLA_INFO_KIND], sizeof(kind));
> > > > +		nla_strscpy(kind, linkinfo[IFLA_INFO_KIND], sizeof(kind));
> > > > 
> > > >  		ops = rtnl_link_ops_get(kind);
> > > >  	
> > > >  	} else {
> > > >  	
> > > >  		kind[0] = '\0';
> > > > 
> > > > diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c
> > > > index 15d42353f1a3..d1c50a48614b 100644
> > > > --- a/net/decnet/dn_dev.c
> > > > +++ b/net/decnet/dn_dev.c
> > > > @@ -658,7 +658,7 @@ static int dn_nl_newaddr(struct sk_buff *skb,
> > > > struct
> > > > nlmsghdr *nlh,>
> > > > 
> > > >  	ifa->ifa_dev = dn_db;
> > > >  	
> > > >  	if (tb[IFA_LABEL])
> > > > 
> > > > -		nla_strlcpy(ifa->ifa_label, tb[IFA_LABEL], IFNAMSIZ);
> > > > +		nla_strscpy(ifa->ifa_label, tb[IFA_LABEL], IFNAMSIZ);
> > > > 
> > > >  	else
> > > >  	
> > > >  		memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
> > > > 
> > > > diff --git a/net/ieee802154/nl-mac.c b/net/ieee802154/nl-mac.c
> > > > index 6d091e419d3e..9c640d670ffe 100644
> > > > --- a/net/ieee802154/nl-mac.c
> > > > +++ b/net/ieee802154/nl-mac.c
> > > > @@ -149,7 +149,7 @@ static struct net_device
> > > > *ieee802154_nl_get_dev(struct
> > > > genl_info *info)>
> > > > 
> > > >  	if (info->attrs[IEEE802154_ATTR_DEV_NAME]) {
> > > >  	
> > > >  		char name[IFNAMSIZ + 1];
> > > > 
> > > > -		nla_strlcpy(name, info->attrs[IEEE802154_ATTR_DEV_NAME],
> > > > +		nla_strscpy(name, info->attrs[IEEE802154_ATTR_DEV_NAME],
> > > > 
> > > >  			    sizeof(name));
> > > >  		
> > > >  		dev = dev_get_by_name(&init_net, name);
> > > >  	
> > > >  	} else if (info->attrs[IEEE802154_ATTR_DEV_INDEX]) {
> > > > 
> > > > diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
> > > > index 123a6d39438f..a50951a90f63 100644
> > > > --- a/net/ipv4/devinet.c
> > > > +++ b/net/ipv4/devinet.c
> > > > @@ -881,7 +881,7 @@ static struct in_ifaddr *rtm_to_ifaddr(struct net
> > > > *net, struct nlmsghdr *nlh,>
> > > > 
> > > >  		ifa->ifa_broadcast = nla_get_in_addr(tb[IFA_BROADCAST]);
> > > >  	
> > > >  	if (tb[IFA_LABEL])
> > > > 
> > > > -		nla_strlcpy(ifa->ifa_label, tb[IFA_LABEL], IFNAMSIZ);
> > > > +		nla_strscpy(ifa->ifa_label, tb[IFA_LABEL], IFNAMSIZ);
> > > > 
> > > >  	else
> > > >  	
> > > >  		memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
> > > > 
> > > > diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
> > > > index 1f75dc686b6b..4b505074b24f 100644
> > > > --- a/net/ipv4/fib_semantics.c
> > > > +++ b/net/ipv4/fib_semantics.c
> > > > @@ -973,7 +973,7 @@ bool fib_metrics_match(struct fib_config *cfg,
> > > > struct
> > > > fib_info *fi)>
> > > > 
> > > >  			char tmp[TCP_CA_NAME_MAX];
> > > >  			bool ecn_ca = false;
> > > > 
> > > > -			nla_strlcpy(tmp, nla, sizeof(tmp));
> > > > +			nla_strscpy(tmp, nla, sizeof(tmp));
> > > > 
> > > >  			val = tcp_ca_get_key_by_name(fi->fib_net, tmp, &ecn_ca);
> > > >  		
> > > >  		} else {
> > > >  		
> > > >  			if (nla_len(nla) != sizeof(u32))
> > > > 
> > > > diff --git a/net/ipv4/metrics.c b/net/ipv4/metrics.c
> > > > index 3205d5f7c8c9..25ea6ac44db9 100644
> > > > --- a/net/ipv4/metrics.c
> > > > +++ b/net/ipv4/metrics.c
> > > > @@ -31,7 +31,7 @@ static int ip_metrics_convert(struct net *net,
> > > > struct
> > > > nlattr *fc_mx,>
> > > > 
> > > >  		if (type == RTAX_CC_ALGO) {
> > > >  		
> > > >  			char tmp[TCP_CA_NAME_MAX];
> > > > 
> > > > -			nla_strlcpy(tmp, nla, sizeof(tmp));
> > > > +			nla_strscpy(tmp, nla, sizeof(tmp));
> > > > 
> > > >  			val = tcp_ca_get_key_by_name(net, tmp, &ecn_ca);
> > > >  			if (val == TCP_CA_UNSPEC) {
> > > >  			
> > > >  				NL_SET_ERR_MSG(extack, "Unknown tcp congestion 
algorithm");
> > > > 
> > > > diff --git a/net/netfilter/ipset/ip_set_hash_netiface.c
> > > > b/net/netfilter/ipset/ip_set_hash_netiface.c index
> > > > be5e95a0d876..b96fd0c55eaa 100644
> > > > --- a/net/netfilter/ipset/ip_set_hash_netiface.c
> > > > +++ b/net/netfilter/ipset/ip_set_hash_netiface.c
> > > > @@ -225,7 +225,7 @@ hash_netiface4_uadt(struct ip_set *set, struct
> > > > nlattr
> > > > *tb[],>
> > > > 
> > > >  		if (e.cidr > HOST_MASK)
> > > >  		
> > > >  			return -IPSET_ERR_INVALID_CIDR;
> > > >  	
> > > >  	}
> > > > 
> > > > -	nla_strlcpy(e.iface, tb[IPSET_ATTR_IFACE], IFNAMSIZ);
> > > > +	nla_strscpy(e.iface, tb[IPSET_ATTR_IFACE], IFNAMSIZ);
> > > > 
> > > >  	if (tb[IPSET_ATTR_CADT_FLAGS]) {
> > > >  	
> > > >  		u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
> > > > 
> > > > @@ -442,7 +442,7 @@ hash_netiface6_uadt(struct ip_set *set, struct
> > > > nlattr
> > > > *tb[],>
> > > > 
> > > >  	ip6_netmask(&e.ip, e.cidr);
> > > > 
> > > > -	nla_strlcpy(e.iface, tb[IPSET_ATTR_IFACE], IFNAMSIZ);
> > > > +	nla_strscpy(e.iface, tb[IPSET_ATTR_IFACE], IFNAMSIZ);
> > > > 
> > > >  	if (tb[IPSET_ATTR_CADT_FLAGS]) {
> > > >  	
> > > >  		u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
> > > > 
> > > > diff --git a/net/netfilter/nf_tables_api.c
> > > > b/net/netfilter/nf_tables_api.c
> > > > index 9957e0ed8658..90c39e694e87 100644
> > > > --- a/net/netfilter/nf_tables_api.c
> > > > +++ b/net/netfilter/nf_tables_api.c
> > > > @@ -1281,7 +1281,7 @@ static struct nft_chain *nft_chain_lookup(struct
> > > > net
> > > > *net,>
> > > > 
> > > >  	if (nla == NULL)
> > > >  	
> > > >  		return ERR_PTR(-EINVAL);
> > > > 
> > > > -	nla_strlcpy(search, nla, sizeof(search));
> > > > +	nla_strscpy(search, nla, sizeof(search));
> > > > 
> > > >  	WARN_ON(!rcu_read_lock_held() &&
> > > >  	
> > > >  		!lockdep_commit_lock_is_held(net));
> > > > 
> > > > @@ -1721,7 +1721,7 @@ static struct nft_hook
> > > > *nft_netdev_hook_alloc(struct
> > > > net *net,>
> > > > 
> > > >  		goto err_hook_alloc;
> > > >  	
> > > >  	}
> > > > 
> > > > -	nla_strlcpy(ifname, attr, IFNAMSIZ);
> > > > +	nla_strscpy(ifname, attr, IFNAMSIZ);
> > > > 
> > > >  	dev = __dev_get_by_name(net, ifname);
> > > >  	if (!dev) {
> > > >  	
> > > >  		err = -ENOENT;
> > > > 
> > > > @@ -5734,7 +5734,7 @@ struct nft_object *nft_obj_lookup(const struct
> > > > net
> > > > *net,>
> > > > 
> > > >  	struct rhlist_head *tmp, *list;
> > > >  	struct nft_object *obj;
> > > > 
> > > > -	nla_strlcpy(search, nla, sizeof(search));
> > > > +	nla_strscpy(search, nla, sizeof(search));
> > > > 
> > > >  	k.name = search;
> > > >  	
> > > >  	WARN_ON_ONCE(!rcu_read_lock_held() &&
> > > > 
> > > > diff --git a/net/netfilter/nfnetlink_acct.c
> > > > b/net/netfilter/nfnetlink_acct.c index 5bfec829c12f..5e511df8d709
> > > > 100644
> > > > --- a/net/netfilter/nfnetlink_acct.c
> > > > +++ b/net/netfilter/nfnetlink_acct.c
> > > > @@ -112,7 +112,7 @@ static int nfnl_acct_new(struct net *net, struct
> > > > sock
> > > > *nfnl,>
> > > > 
> > > >  		nfacct->flags = flags;
> > > >  	
> > > >  	}
> > > > 
> > > > -	nla_strlcpy(nfacct->name, tb[NFACCT_NAME], NFACCT_NAME_MAX);
> > > > +	nla_strscpy(nfacct->name, tb[NFACCT_NAME], NFACCT_NAME_MAX);
> > > > 
> > > >  	if (tb[NFACCT_BYTES]) {
> > > >  	
> > > >  		atomic64_set(&nfacct->bytes,
> > > > 
> > > > diff --git a/net/netfilter/nfnetlink_cthelper.c
> > > > b/net/netfilter/nfnetlink_cthelper.c index 5b0d0a77379c..0f94fce1d3ed
> > > > 100644
> > > > --- a/net/netfilter/nfnetlink_cthelper.c
> > > > +++ b/net/netfilter/nfnetlink_cthelper.c
> > > > @@ -146,7 +146,7 @@ nfnl_cthelper_expect_policy(struct
> > > > nf_conntrack_expect_policy *expect_policy,>
> > > > 
> > > >  	    !tb[NFCTH_POLICY_EXPECT_TIMEOUT])
> > > >  		
> > > >  		return -EINVAL;
> > > > 
> > > > -	nla_strlcpy(expect_policy->name,
> > > > +	nla_strscpy(expect_policy->name,
> > > > 
> > > >  		    tb[NFCTH_POLICY_NAME], NF_CT_HELPER_NAME_LEN);
> > > >  	
> > > >  	expect_policy->max_expected =
> > > >  	
> > > >  		ntohl(nla_get_be32(tb[NFCTH_POLICY_EXPECT_MAX]));
> > > > 
> > > > @@ -233,7 +233,7 @@ nfnl_cthelper_create(const struct nlattr * const
> > > > tb[],
> > > > 
> > > >  	if (ret < 0)
> > > >  	
> > > >  		goto err1;
> > > > 
> > > > -	nla_strlcpy(helper->name,
> > > > +	nla_strscpy(helper->name,
> > > > 
> > > >  		    tb[NFCTH_NAME], NF_CT_HELPER_NAME_LEN);
> > > >  	
> > > >  	size = ntohl(nla_get_be32(tb[NFCTH_PRIV_DATA_LEN]));
> > > >  	if (size > sizeof_field(struct nf_conn_help, data)) {
> > > > 
> > > > diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c
> > > > index 322bd674963e..a8c4d442231c 100644
> > > > --- a/net/netfilter/nft_ct.c
> > > > +++ b/net/netfilter/nft_ct.c
> > > > @@ -990,7 +990,7 @@ static int nft_ct_helper_obj_init(const struct
> > > > nft_ctx
> > > > *ctx,>
> > > > 
> > > >  	if (!priv->l4proto)
> > > >  	
> > > >  		return -ENOENT;
> > > > 
> > > > -	nla_strlcpy(name, tb[NFTA_CT_HELPER_NAME], sizeof(name));
> > > > +	nla_strscpy(name, tb[NFTA_CT_HELPER_NAME], sizeof(name));
> > > > 
> > > >  	if (tb[NFTA_CT_HELPER_L3PROTO])
> > > >  	
> > > >  		family = ntohs(nla_get_be16(tb[NFTA_CT_HELPER_L3PROTO]));
> > > > 
> > > > diff --git a/net/netfilter/nft_log.c b/net/netfilter/nft_log.c
> > > > index 57899454a530..a06a46b039c5 100644
> > > > --- a/net/netfilter/nft_log.c
> > > > +++ b/net/netfilter/nft_log.c
> > > > @@ -152,7 +152,7 @@ static int nft_log_init(const struct nft_ctx *ctx,
> > > > 
> > > >  		priv->prefix = kmalloc(nla_len(nla) + 1, GFP_KERNEL);
> > > >  		if (priv->prefix == NULL)
> > > >  		
> > > >  			return -ENOMEM;
> > > > 
> > > > -		nla_strlcpy(priv->prefix, nla, nla_len(nla) + 1);
> > > > +		nla_strscpy(priv->prefix, nla, nla_len(nla) + 1);
> > > > 
> > > >  	} else {
> > > >  	
> > > >  		priv->prefix = (char *)nft_log_null_prefix;
> > > >  	
> > > >  	}
> > > > 
> > > > diff --git a/net/netlabel/netlabel_mgmt.c
> > > > b/net/netlabel/netlabel_mgmt.c
> > > > index eb1d66d20afb..df1b41ed73fd 100644
> > > > --- a/net/netlabel/netlabel_mgmt.c
> > > > +++ b/net/netlabel/netlabel_mgmt.c
> > > > @@ -95,7 +95,7 @@ static int netlbl_mgmt_add_common(struct genl_info
> > > > *info,
> > > > 
> > > >  			ret_val = -ENOMEM;
> > > >  			goto add_free_entry;
> > > >  		
> > > >  		}
> > > > 
> > > > -		nla_strlcpy(entry->domain,
> > > > +		nla_strscpy(entry->domain,
> > > > 
> > > >  			    info->attrs[NLBL_MGMT_A_DOMAIN], tmp_size);
> > > >  	
> > > >  	}
> > > > 
> > > > diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c
> > > > index e894254c17d4..438ff1f30a33 100644
> > > > --- a/net/nfc/netlink.c
> > > > +++ b/net/nfc/netlink.c
> > > > @@ -1226,7 +1226,7 @@ static int nfc_genl_fw_download(struct sk_buff
> > > > *skb,
> > > > struct genl_info *info)>
> > > > 
> > > >  	if (!dev)
> > > >  	
> > > >  		return -ENODEV;
> > > > 
> > > > -	nla_strlcpy(firmware_name, info->attrs[NFC_ATTR_FIRMWARE_NAME],
> > > > +	nla_strscpy(firmware_name, info->attrs[NFC_ATTR_FIRMWARE_NAME],
> > > > 
> > > >  		    sizeof(firmware_name));
> > > >  	
> > > >  	rc = nfc_fw_download(dev, firmware_name);
> > > > 
> > > > diff --git a/net/sched/act_api.c b/net/sched/act_api.c
> > > > index 541574520c52..eac24a73115f 100644
> > > > --- a/net/sched/act_api.c
> > > > +++ b/net/sched/act_api.c
> > > > @@ -935,7 +935,7 @@ struct tc_action *tcf_action_init_1(struct net
> > > > *net,
> > > > struct tcf_proto *tp,>
> > > > 
> > > >  			NL_SET_ERR_MSG(extack, "TC action kind must be specified");
> > > >  			goto err_out;
> > > >  		
> > > >  		}
> > > > 
> > > > -		if (nla_strlcpy(act_name, kind, IFNAMSIZ) < 0) {
> > > > +		if (nla_strscpy(act_name, kind, IFNAMSIZ) < 0) {
> > > > 
> > > >  			NL_SET_ERR_MSG(extack, "TC action name too long");
> > > >  			goto err_out;
> > > >  		
> > > >  		}
> > > > 
> > > > diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c
> > > > index 8dc3bec0d325..ac7297f42355 100644
> > > > --- a/net/sched/act_ipt.c
> > > > +++ b/net/sched/act_ipt.c
> > > > @@ -166,7 +166,7 @@ static int __tcf_ipt_init(struct net *net,
> > > > unsigned
> > > > int id, struct nlattr *nla,>
> > > > 
> > > >  	if (unlikely(!tname))
> > > >  	
> > > >  		goto err1;
> > > >  	
> > > >  	if (tb[TCA_IPT_TABLE] == NULL ||
> > > > 
> > > > -	    nla_strlcpy(tname, tb[TCA_IPT_TABLE], IFNAMSIZ) >= IFNAMSIZ)
> > > > +	    nla_strscpy(tname, tb[TCA_IPT_TABLE], IFNAMSIZ) >= IFNAMSIZ)
> > > > 
> > > >  		strcpy(tname, "mangle");
> > > >  	
> > > >  	t = kmemdup(td, td->u.target_size, GFP_KERNEL);
> > > > 
> > > > diff --git a/net/sched/act_simple.c b/net/sched/act_simple.c
> > > > index a4f3d0f0daa9..726cc956d06f 100644
> > > > --- a/net/sched/act_simple.c
> > > > +++ b/net/sched/act_simple.c
> > > > @@ -52,7 +52,7 @@ static int alloc_defdata(struct tcf_defact *d, const
> > > > struct nlattr *defdata)>
> > > > 
> > > >  	d->tcfd_defdata = kzalloc(SIMP_MAX_DATA, GFP_KERNEL);
> > > >  	if (unlikely(!d->tcfd_defdata))
> > > >  	
> > > >  		return -ENOMEM;
> > > > 
> > > > -	nla_strlcpy(d->tcfd_defdata, defdata, SIMP_MAX_DATA);
> > > > +	nla_strscpy(d->tcfd_defdata, defdata, SIMP_MAX_DATA);
> > > > 
> > > >  	return 0;
> > > >  
> > > >  }
> > > > 
> > > > @@ -71,7 +71,7 @@ static int reset_policy(struct tc_action *a, const
> > > > struct nlattr *defdata,>
> > > > 
> > > >  	spin_lock_bh(&d->tcf_lock);
> > > >  	goto_ch = tcf_action_set_ctrlact(a, p->action, goto_ch);
> > > >  	memset(d->tcfd_defdata, 0, SIMP_MAX_DATA);
> > > > 
> > > > -	nla_strlcpy(d->tcfd_defdata, defdata, SIMP_MAX_DATA);
> > > > +	nla_strscpy(d->tcfd_defdata, defdata, SIMP_MAX_DATA);
> > > > 
> > > >  	spin_unlock_bh(&d->tcf_lock);
> > > >  	if (goto_ch)
> > > >  	
> > > >  		tcf_chain_put_by_act(goto_ch);
> > > > 
> > > > diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
> > > > index c78241c853a5..6ff3b817083a 100644
> > > > --- a/net/sched/cls_api.c
> > > > +++ b/net/sched/cls_api.c
> > > > @@ -223,7 +223,7 @@ static inline u32 tcf_auto_prio(struct tcf_proto
> > > > *tp)
> > > > 
> > > >  static bool tcf_proto_check_kind(struct nlattr *kind, char *name)
> > > >  {
> > > >  
> > > >  	if (kind)
> > > > 
> > > > -		return nla_strlcpy(name, kind, IFNAMSIZ) < 0;
> > > > +		return nla_strscpy(name, kind, IFNAMSIZ) < 0;
> > > > 
> > > >  	memset(name, 0, IFNAMSIZ);
> > > >  	return false;
> > > >  
> > > >  }
> > > > 
> > > > diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
> > > > index f9b053b30a7b..cb4f30700c74 100644
> > > > --- a/net/sched/sch_api.c
> > > > +++ b/net/sched/sch_api.c
> > > > @@ -1170,7 +1170,7 @@ static struct Qdisc *qdisc_create(struct
> > > > net_device
> > > > *dev,>
> > > > 
> > > >  #ifdef CONFIG_MODULES
> > > >  
> > > >  	if (ops == NULL && kind != NULL) {
> > > >  	
> > > >  		char name[IFNAMSIZ];
> > > > 
> > > > -		if (nla_strlcpy(name, kind, IFNAMSIZ) > 0) {
> > > > +		if (nla_strscpy(name, kind, IFNAMSIZ) > 0) {
> > > > 
> > > >  			/* We dropped the RTNL semaphore in order to
> > > >  			
> > > >  			 * perform the module load.  So, even if we
> > > >  			 * succeeded in loading the module we have to
> > > > 
> > > > diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c
> > > > index 1c7aa51cc2a3..644c7ec41ddf 100644
> > > > --- a/net/tipc/netlink_compat.c
> > > > +++ b/net/tipc/netlink_compat.c
> > > > @@ -695,7 +695,7 @@ static int tipc_nl_compat_link_dump(struct
> > > > tipc_nl_compat_msg *msg,>
> > > > 
> > > >  	link_info.dest = nla_get_flag(link[TIPC_NLA_LINK_DEST]);
> > > >  	link_info.up = htonl(nla_get_flag(link[TIPC_NLA_LINK_UP]));
> > > > 
> > > > -	nla_strlcpy(link_info.str, link[TIPC_NLA_LINK_NAME],
> > > > +	nla_strscpy(link_info.str, link[TIPC_NLA_LINK_NAME],
> > > > 
> > > >  		    TIPC_MAX_LINK_NAME);
> > > >  	
> > > >  	return tipc_add_tlv(msg->rep, TIPC_TLV_LINK_INFO,





^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2020-10-24 10:41 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-20 16:47 [RFC][PATCH v3 0/3] Fix inefficiences and rename nla_strlcpy laniel_francis
2020-10-20 16:47 ` [RFC][PATCH v3 1/3] Fix unefficient call to memset before memcpu in nla_strlcpy laniel_francis
2020-10-21 23:46   ` Kees Cook
2020-10-20 16:47 ` [RFC][PATCH v3 2/3] Modify return value of nla_strlcpy to match that of strscpy laniel_francis
2020-10-21 23:48   ` Kees Cook
2020-10-22  9:40     ` Francis Laniel
2020-10-20 16:47 ` [RFC][PATCH v3 3/3] Rename nla_strlcpy to nla_strscpy laniel_francis
2020-10-21 23:49   ` Kees Cook
2020-10-22  9:41     ` Francis Laniel
2020-10-22 20:04       ` Kees Cook
2020-10-22 23:05         ` Jakub Kicinski
2020-10-23  8:07           ` David Laight
2020-10-23 15:15             ` Francis Laniel
2020-10-23 15:29             ` Jakub Kicinski
2020-10-23 17:41               ` Kees Cook
2020-10-23 15:16           ` Francis Laniel
2020-10-24 10:41         ` Francis Laniel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).