From: Kees Cook <keescook@chromium.org>
To: Justin Stitt <justinstitt@google.com>
Cc: David Rheinsberg <david@readahead.eu>,
Jiri Kosina <jikos@kernel.org>,
Benjamin Tissoires <benjamin.tissoires@redhat.com>,
linux-input@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-hardening@vger.kernel.org,
David Herrmann <dh.herrmann@gmail.com>
Subject: Re: [PATCH] HID: uhid: refactor deprecated strncpy
Date: Thu, 14 Sep 2023 22:13:57 -0700 [thread overview]
Message-ID: <202309142206.60836CE@keescook> (raw)
In-Reply-To: <20230914-strncpy-drivers-hid-uhid-c-v1-1-18a190060d8d@google.com>
On Thu, Sep 14, 2023 at 10:47:21PM +0000, Justin Stitt wrote:
> `strncpy` is deprecated for use on NUL-terminated destination strings [1].
>
> We should prefer more robust and less ambiguous string interfaces.
>
> A suitable replacement is `strscpy` [2] due to the fact that it
> guarantees NUL-termination on the destination buffer without
> unnecessarily NUL-padding.
>
> Looking at: Commit 4d26d1d1e806 ("Revert "HID: uhid: use strlcpy() instead of strncpy()"")
> we see referenced the fact that many attempts have been made to change
> these strncpy's into strlcpy to no success. I think strscpy is an
> objectively better interface here as it doesn't unnecessarily NUL-pad
> the destination buffer whilst allowing us to drop the `len = min(...)`
> pattern as strscpy will implicitly limit the number of bytes copied by
> the smaller of its dest and src arguments.
I think the worry here is that ev->u.create2.name may not be %NUL
terminated. But I think that doesn't matter, see below...
Also, note, this should CC David Herrmann <dh.herrmann@gmail.com>
(now added).
> So while the existing code may not have a bug (i.e: overread problems)
> we should still favor strscpy due to readability (plus a very slight
> performance boost).
>
> Link: https://www.kernel.org/doc/html/latest/process/deprecated.html#strncpy-on-nul-terminated-strings [1]
> Link: https://manpages.debian.org/testing/linux-manual-4.8/strscpy.9.en.html [2]
> Link: https://github.com/KSPP/linux/issues/90
> Cc: linux-hardening@vger.kernel.org
> Cc: Kees Cook <keescook@chromium.org>
> Signed-off-by: Justin Stitt <justinstitt@google.com>
> ---
> drivers/hid/uhid.c | 12 ++++--------
> 1 file changed, 4 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c
> index 4588d2cd4ea4..00e1566ad37b 100644
> --- a/drivers/hid/uhid.c
> +++ b/drivers/hid/uhid.c
> @@ -490,7 +490,7 @@ static int uhid_dev_create2(struct uhid_device *uhid,
> const struct uhid_event *ev)
> {
> struct hid_device *hid;
> - size_t rd_size, len;
> + size_t rd_size;
> void *rd_data;
> int ret;
>
> @@ -514,13 +514,9 @@ static int uhid_dev_create2(struct uhid_device *uhid,
> goto err_free;
> }
>
> - /* @hid is zero-initialized, strncpy() is correct, strlcpy() not */
> - len = min(sizeof(hid->name), sizeof(ev->u.create2.name)) - 1;
> - strncpy(hid->name, ev->u.create2.name, len);
> - len = min(sizeof(hid->phys), sizeof(ev->u.create2.phys)) - 1;
> - strncpy(hid->phys, ev->u.create2.phys, len);
> - len = min(sizeof(hid->uniq), sizeof(ev->u.create2.uniq)) - 1;
> - strncpy(hid->uniq, ev->u.create2.uniq, len);
ev->u.create2 is:
struct uhid_create2_req {
__u8 name[128];
__u8 phys[64];
__u8 uniq[64];
...
hid is:
struct hid_device { /* device report descriptor */
...
char name[128]; /* Device name */
char phys[64]; /* Device physical location */
char uniq[64]; /* Device unique identifier (serial #) */
So these "min" calls are redundant -- it wants to copy at most 1 less so
it can be %NUL terminated. Which is what strscpy() already does. And
source and dest are the same size, so we can't over-read source if it
weren't terminated (since strscpy won't overread like strlcpy).
> + strscpy(hid->name, ev->u.create2.name, sizeof(hid->name));
> + strscpy(hid->phys, ev->u.create2.phys, sizeof(hid->phys));
> + strscpy(hid->uniq, ev->u.create2.uniq, sizeof(hid->uniq));
Reviewed-by: Kees Cook <keescook@chromium.org>
-Kees
>
> hid->ll_driver = &uhid_hid_driver;
> hid->bus = ev->u.create2.bus;
>
> ---
> base-commit: 3669558bdf354cd352be955ef2764cde6a9bf5ec
> change-id: 20230914-strncpy-drivers-hid-uhid-c-a465f3e784dd
>
> Best regards,
> --
> Justin Stitt <justinstitt@google.com>
>
--
Kees Cook
next prev parent reply other threads:[~2023-09-15 5:14 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-09-14 22:47 [PATCH] HID: uhid: refactor deprecated strncpy Justin Stitt
2023-09-15 5:13 ` Kees Cook [this message]
2023-09-15 7:36 ` David Rheinsberg
2023-09-15 20:48 ` Kees Cook
2023-09-18 7:37 ` David Rheinsberg
2023-09-29 18:52 ` Kees Cook
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=202309142206.60836CE@keescook \
--to=keescook@chromium.org \
--cc=benjamin.tissoires@redhat.com \
--cc=david@readahead.eu \
--cc=dh.herrmann@gmail.com \
--cc=jikos@kernel.org \
--cc=justinstitt@google.com \
--cc=linux-hardening@vger.kernel.org \
--cc=linux-input@vger.kernel.org \
--cc=linux-kernel@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.