From: Kees Cook <keescook@chromium.org>
To: laniel_francis@privacyrequired.com
Cc: linux-hardening@vger.kernel.org
Subject: Re: [PATCH v1 2/3] Modify return value of nla_strlcpy to match that of strscpy.
Date: Fri, 16 Oct 2020 16:23:10 -0700 [thread overview]
Message-ID: <202010161620.3B240DBCC1@keescook> (raw)
In-Reply-To: <20201016125216.10922-3-laniel_francis@privacyrequired.com>
On Fri, Oct 16, 2020 at 02:52:15PM +0200, laniel_francis@privacyrequired.com wrote:
> From: Francis Laniel <laniel_francis@privacyrequired.com>
>
> This patch solves part 2 of issue: https://github.com/KSPP/linux/issues/110
As with the others, this needs a full commit log (imagine someone
doesn't have access to read that issue, etc).
>
> Signed-off-by: Francis Laniel <laniel_francis@privacyrequired.com>
> ---
> include/net/netlink.h | 2 +-
> include/net/pkt_cls.h | 3 ++-
> lib/nlattr.c | 31 ++++++++++++++++++++-----------
> net/sched/act_api.c | 2 +-
> net/sched/sch_api.c | 2 +-
> 5 files changed, 25 insertions(+), 15 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..f42db07c399b 100644
> --- a/include/net/pkt_cls.h
> +++ b/include/net/pkt_cls.h
> @@ -4,6 +4,7 @@
>
> #include <linux/pkt_cls.h>
> #include <linux/workqueue.h>
> +#include <linux/errno.h>
> #include <net/sch_generic.h>
> #include <net/act_api.h>
> #include <net/net_namespace.h>
> @@ -512,7 +513,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) == -E2BIG) {
I would make these tests all be "< 0" rather than specifically -E2BIG.
> 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 ab96a5f4b9b8..83dd233bbe3e 100644
> --- a/lib/nlattr.c
> +++ b/lib/nlattr.c
> @@ -713,29 +713,38 @@ EXPORT_SYMBOL(nla_find);
> * @dst: where to copy the string to
> * @nla: attribute to copy the string from
> * @dstsize: size of destination buffer
> + * @returns: -E2BIG if @dstsize is 0 or source buffer length greater than
> + * @dstsize, otherwise it returns the number of copied characters (not
> + * including the trailing %NUL).
> *
> * 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.
> - *
> - * Returns the length of the source buffer.
> + * The result is always a valid NUL-terminated string.
> */
> -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 len;
> + ssize_t ret;
> size_t srclen = nla_len(nla);
> char *src = nla_data(nla);
>
> + if (dstsize == 0 || WARN_ON_ONCE(dstsize > INT_MAX))
> + return -E2BIG;
Cool, yeah, good to include.
> +
> if (srclen > 0 && src[srclen - 1] == '\0')
> srclen--;
>
> - if (dstsize > 0) {
> - size_t len = (srclen >= dstsize) ? dstsize - 1 : srclen;
> -
> - memcpy(dst, src, len);
> - dst[len] = '\0';
> + if (srclen >= dstsize) {
> + len = dstsize - 1;
> + ret = -E2BIG;
> + } else {
> + len = srclen;
> + ret = len;
> }
>
> - return srclen;
> + memcpy(dst, src, len);
> + dst[len] = '\0';
> +
> + return ret;
> }
> EXPORT_SYMBOL(nla_strlcpy);
Otherwise, I think this looks good. (Though same note about
zero-padding.)
>
> diff --git a/net/sched/act_api.c b/net/sched/act_api.c
> index f66417d5d2c3..ed411d6c29fc 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) == -E2BIG) {
> NL_SET_ERR_MSG(extack, "TC action name too long");
> goto err_out;
> }
> diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
> index 2a76a2f5ed88..3e89c666d1e8 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) != -E2BIG) {
> /* 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
>
--
Kees Cook
next prev parent reply other threads:[~2020-10-16 23:23 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-10-16 12:52 [RFC][PATCH v1] Fix and rename nla_strlcpy to nla_strcpy laniel_francis
2020-10-16 12:52 ` [PATCH v1 1/3] Fix unefficient call to memset before memcpu in nla_strlcpy laniel_francis
2020-10-16 23:19 ` Kees Cook
2020-10-17 8:50 ` Francis Laniel
2020-10-16 23:29 ` Jann Horn
2020-10-17 8:50 ` Francis Laniel
2020-10-16 12:52 ` [PATCH v1 2/3] Modify return value of nla_strlcpy to match that of strscpy laniel_francis
2020-10-16 23:23 ` Kees Cook [this message]
2020-10-17 8:53 ` Francis Laniel
2020-10-17 0:41 ` Jann Horn
2020-10-17 8:56 ` Francis Laniel
2020-10-16 12:52 ` [PATCH v1 3/3] Rename nla_strlcpy to nla_strcpy laniel_francis
2020-10-16 23:18 ` Kees Cook
2020-10-19 15:23 ` [RFC][PATCH v2 0/3] Fix inefficiences and rename nla_strlcpy laniel_francis
2020-10-19 15:23 ` [RFC][PATCH v2 1/3] Fix unefficient call to memset before memcpu in nla_strlcpy laniel_francis
2020-10-19 15:23 ` [RFC][PATCH v2 2/3] Modify return value of nla_strlcpy to match that of strscpy laniel_francis
2020-10-19 16:43 ` Jakub Kicinski
2020-10-19 23:01 ` Kees Cook
2020-10-19 23:34 ` Jakub Kicinski
2020-10-20 10:28 ` Francis Laniel
2020-10-20 17:23 ` Kees Cook
2020-10-20 17:19 ` Kees Cook
2020-10-20 13:05 ` Francis Laniel
2020-10-20 10:17 ` Francis Laniel
2020-10-19 15:23 ` [RFC][PATCH v2 3/3] Rename nla_strlcpy to nla_strcpy laniel_francis
2020-10-19 16:45 ` [RFC][PATCH v2 0/3] Fix inefficiences and rename nla_strlcpy Jakub Kicinski
2020-10-19 22:58 ` Kees Cook
2020-10-19 23:34 ` Jakub Kicinski
2020-10-20 10:18 ` Francis Laniel
2020-10-19 23:03 ` Kees Cook
2020-10-20 13:06 ` Francis Laniel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=202010161620.3B240DBCC1@keescook \
--to=keescook@chromium.org \
--cc=laniel_francis@privacyrequired.com \
--cc=linux-hardening@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.