From: Michal Kubecek <mkubecek@suse.cz>
To: Vivien Didelot <vivien.didelot@gmail.com>
Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
"David S. Miller" <davem@davemloft.net>,
linville@redhat.com, f.fainelli@gmail.com
Subject: Re: [PATCH net-next] ethtool: do not use regs->len after ops->get_regs
Date: Fri, 31 May 2019 08:54:32 +0200 [thread overview]
Message-ID: <20190531065432.GB15954@unicorn.suse.cz> (raw)
In-Reply-To: <20190530235450.11824-1-vivien.didelot@gmail.com>
On Thu, May 30, 2019 at 07:54:50PM -0400, Vivien Didelot wrote:
> The kernel allocates a buffer of size ops->get_regs_len(), and pass
> it to the kernel driver via ops->get_regs() for filling.
>
> There is no restriction about what the kernel drivers can or cannot
> do with the regs->len member. Drivers usually ignore it or set
> the same size again. However, ethtool_get_regs() must not use this
> value when copying the buffer back to the user, because userspace may
> have allocated a smaller buffer. For instance ethtool does that when
> dumping the raw registers directly into a fixed-size file.
>
> Software may still make use of the regs->len value updated by the
> kernel driver, but ethtool_get_regs() must use the original regs->len
> given by userspace, up to ops->get_regs_len(), when copying the buffer.
>
> Also no need to check regbuf twice.
>
> Signed-off-by: Vivien Didelot <vivien.didelot@gmail.com>
> ---
> net/core/ethtool.c | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/net/core/ethtool.c b/net/core/ethtool.c
> index 4a593853cbf2..8f95c7b7cafe 100644
> --- a/net/core/ethtool.c
> +++ b/net/core/ethtool.c
> @@ -1338,38 +1338,40 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
> static int ethtool_get_regs(struct net_device *dev, char __user *useraddr)
> {
> struct ethtool_regs regs;
> const struct ethtool_ops *ops = dev->ethtool_ops;
> void *regbuf;
> int reglen, ret;
>
> if (!ops->get_regs || !ops->get_regs_len)
> return -EOPNOTSUPP;
>
> if (copy_from_user(®s, useraddr, sizeof(regs)))
> return -EFAULT;
>
> reglen = ops->get_regs_len(dev);
> if (reglen <= 0)
> return reglen;
>
> if (regs.len > reglen)
> regs.len = reglen;
> + else
> + reglen = regs.len;
This seems wrong. Most drivers do not check regs.len in their get_regs()
handler (I'm not sure if there are any that do) and simply write as much
data as they have. Thus if userspace passes too short regs.len, this
would replace overflow of a userspace buffer for few drivers by overflow
of a kernel buffer for (almost) all drivers.
So while we should use the original regs.len from userspace for final
copy_to_user(), we have to allocate the buffer for driver ->get_regs()
callback with size returned by its ->get_regs_len() callback.
Michal Kubecek
>
> regbuf = vzalloc(reglen);
> if (!regbuf)
> return -ENOMEM;
>
> ops->get_regs(dev, ®s, regbuf);
>
> ret = -EFAULT;
> if (copy_to_user(useraddr, ®s, sizeof(regs)))
> goto out;
> useraddr += offsetof(struct ethtool_regs, data);
> - if (regbuf && copy_to_user(useraddr, regbuf, regs.len))
> + if (copy_to_user(useraddr, regbuf, reglen))
> goto out;
> ret = 0;
>
> out:
> vfree(regbuf);
> return ret;
> }
> --
> 2.21.0
>
next prev parent reply other threads:[~2019-05-31 6:54 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-05-30 23:54 Vivien Didelot
2019-05-31 6:54 ` Michal Kubecek [this message]
2019-05-31 14:15 ` Vivien Didelot
2019-05-31 14:27 ` Michal Kubecek
2019-05-31 14:46 ` Vivien Didelot
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=20190531065432.GB15954@unicorn.suse.cz \
--to=mkubecek@suse.cz \
--cc=davem@davemloft.net \
--cc=f.fainelli@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linville@redhat.com \
--cc=netdev@vger.kernel.org \
--cc=vivien.didelot@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®