From: Kees Cook <keescook@chromium.org>
To: Justin Stitt <justinstitt@google.com>
Cc: Ariel Elior <aelior@marvell.com>,
Manish Chopra <manishc@marvell.com>,
"David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-hardening@vger.kernel.org
Subject: Re: [PATCH] qed: replace uses of strncpy
Date: Wed, 11 Oct 2023 16:48:37 -0700 [thread overview]
Message-ID: <202310111636.94AD8172F@keescook> (raw)
In-Reply-To: <20231011-strncpy-drivers-net-ethernet-qlogic-qed-qed_debug-c-v1-1-60c9ca2d54a2@google.com>
On Wed, Oct 11, 2023 at 10:20:10PM +0000, Justin Stitt wrote:
> strncpy() is deprecated for use on NUL-terminated destination strings
> [1] and as such we should prefer more robust and less ambiguous string
> interfaces.
>
> This patch eliminates three uses of strncpy():
>
> Firstly, `dest` is expected to be NUL-terminated which is evident by the
> manual setting of a NUL-byte at size - 1. For this use specifically,
> strscpy() is a viable replacement due to the fact that it guarantees
> NUL-termination on the destination buffer.
>
> The next two changes utilizes snprintf() to make the copying behavior
> more obvious. Previously, strncpy() was used to overwrite the first 3
> characters of mem_name and type_name by setting a length argument less
> than the size of the buffers themselves. This enables, in a roundabout
> way, creating a string like "ASD_BIG_RAM" or "ASD_RAM". Let's just use
> snprintf() with a precision specifier to hold the name prefix to exactly
> 3 characters long.
>
> To be clear, there are no buffer overread bugs in the current code as
> the sizes and offsets are carefully managed such that buffers are
> NUL-terminated. However, with these changes, the code is now more robust
> and less ambiguous (and hopefully easier to read).
>
> 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>
> ---
> Note: build-tested only.
>
> Found with: $ rg "strncpy\("
> ---
> drivers/net/ethernet/qlogic/qed/qed_debug.c | 14 ++++++++------
> 1 file changed, 8 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/net/ethernet/qlogic/qed/qed_debug.c b/drivers/net/ethernet/qlogic/qed/qed_debug.c
> index cdcead614e9f..0a4fd1b04353 100644
> --- a/drivers/net/ethernet/qlogic/qed/qed_debug.c
> +++ b/drivers/net/ethernet/qlogic/qed/qed_debug.c
> @@ -3192,8 +3192,8 @@ static u32 qed_grc_dump_big_ram(struct qed_hwfn *p_hwfn,
> {
> struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
> u32 block_size, ram_size, offset = 0, reg_val, i;
> - char mem_name[12] = "???_BIG_RAM";
> - char type_name[8] = "???_RAM";
> + char mem_name[12];
> + char type_name[8];
> struct big_ram_defs *big_ram;
>
> big_ram = &s_big_ram_defs[big_ram_id];
> @@ -3204,8 +3204,11 @@ static u32 qed_grc_dump_big_ram(struct qed_hwfn *p_hwfn,
> BIT(big_ram->is_256b_bit_offset[dev_data->chip_id]) ? 256
> : 128;
>
> - strncpy(type_name, big_ram->instance_name, BIG_RAM_NAME_LEN);
> - strncpy(mem_name, big_ram->instance_name, BIG_RAM_NAME_LEN);
> + snprintf(mem_name, sizeof(mem_name), "%.*s_BIG_RAM",
> + BIG_RAM_NAME_LEN, big_ram->instance_name);
> +
> + snprintf(type_name, sizeof(type_name), "%.*s_RAM",
> + BIG_RAM_NAME_LEN, big_ram->instance_name);
I actually think just replacing strncpy with memcpy makes more sense and
is what this code intended. It already assumes big_ram->instance_name is
always 3 characters (which it is):
static struct big_ram_defs s_big_ram_defs[] = {
{"BRB", MEM_GROUP_BRB_MEM, MEM_GROUP_BRB_RAM, ...
{"BTB", MEM_GROUP_BTB_MEM, MEM_GROUP_BTB_RAM, ...
{"BMB", MEM_GROUP_BMB_MEM, MEM_GROUP_BMB_RAM, ...
So just copy those three bytes -- no need to call into sprintf for it.
>
> /* Dump memory header */
> offset += qed_grc_dump_mem_hdr(p_hwfn,
> @@ -6359,8 +6362,7 @@ static void qed_read_str_from_buf(void *buf, u32 *offset, u32 size, char *dest)
> {
> const char *source_str = &((const char *)buf)[*offset];
>
> - strncpy(dest, source_str, size);
> - dest[size - 1] = '\0';
> + strscpy(dest, source_str, size);
> *offset += size;
> }
This one looks right to me.
--
Kees Cook
prev parent reply other threads:[~2023-10-11 23:48 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-10-11 22:20 [PATCH] qed: replace uses of strncpy Justin Stitt
2023-10-11 23:48 ` Kees Cook [this message]
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=202310111636.94AD8172F@keescook \
--to=keescook@chromium.org \
--cc=aelior@marvell.com \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=justinstitt@google.com \
--cc=kuba@kernel.org \
--cc=linux-hardening@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=manishc@marvell.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.