diff mbox series

block: replace deprecated strncpy with strscpy

Message ID 20231018-strncpy-drivers-nvdimm-btt-c-v1-1-58070f7dc5c9@google.com (mailing list archive)
State Changes Requested
Headers show
Series block: replace deprecated strncpy with strscpy | expand

Commit Message

Justin Stitt Oct. 18, 2023, 10:35 p.m. UTC
strncpy() is deprecated for use on NUL-terminated destination strings
[1] and as such we should prefer more robust and less ambiguous string
interfaces.

We expect super->signature to be NUL-terminated based on its usage with
memcpy against a NUL-term'd buffer:
btt_devs.c:
253 | if (memcmp(super->signature, BTT_SIG, BTT_SIG_LEN) != 0)
btt.h:
13  | #define BTT_SIG "BTT_ARENA_INFO\0"

NUL-padding is not required as `super` is already zero-allocated:
btt.c:
985 | super = kzalloc(sizeof(struct btt_sb), GFP_NOIO);
... rendering any additional NUL-padding superfluous.

Considering the above, a suitable replacement is `strscpy` [2] due to
the fact that it guarantees NUL-termination on the destination buffer
without unnecessarily NUL-padding.

Let's also use the more idiomatic strscpy usage of (dest, src,
sizeof(dest)) instead of (dest, src, XYZ_LEN) for buffers that the
compiler can determine the size of. This more tightly correlates the
destination buffer to the amount of bytes copied.

Side note, this pattern of memcmp() on two NUL-terminated strings should
really be changed to just a strncmp(), if i'm not mistaken? I see
multiple instances of this pattern in this system.

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
Signed-off-by: Justin Stitt <justinstitt@google.com>
---
Note: build-tested only.

Found with: $ rg "strncpy\("
---
 drivers/nvdimm/btt.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)


---
base-commit: 58720809f52779dc0f08e53e54b014209d13eebb
change-id: 20231018-strncpy-drivers-nvdimm-btt-c-15f93879989e

Best regards,
--
Justin Stitt <justinstitt@google.com>

Comments

Justin Stitt Oct. 18, 2023, 10:39 p.m. UTC | #1
I have a feeling I may have botched the subject line for this patch.
Can anyone confirm if it's good or not?

Automated tooling told me that this was the most common patch
prefix but it may be caused by large patch series that just
happened to touch this file once.

Should the subject be: nvdimm/btt: ... ?

Judging from [1] I see a few "block" and a few of nvdimm/btt.

On Wed, Oct 18, 2023 at 3:35 PM Justin Stitt <justinstitt@google.com> 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.
>
> We expect super->signature to be NUL-terminated based on its usage with
> memcpy against a NUL-term'd buffer:
> btt_devs.c:
> 253 | if (memcmp(super->signature, BTT_SIG, BTT_SIG_LEN) != 0)
> btt.h:
> 13  | #define BTT_SIG "BTT_ARENA_INFO\0"
>
> NUL-padding is not required as `super` is already zero-allocated:
> btt.c:
> 985 | super = kzalloc(sizeof(struct btt_sb), GFP_NOIO);
> ... rendering any additional NUL-padding superfluous.
>
> Considering the above, a suitable replacement is `strscpy` [2] due to
> the fact that it guarantees NUL-termination on the destination buffer
> without unnecessarily NUL-padding.
>
> Let's also use the more idiomatic strscpy usage of (dest, src,
> sizeof(dest)) instead of (dest, src, XYZ_LEN) for buffers that the
> compiler can determine the size of. This more tightly correlates the
> destination buffer to the amount of bytes copied.
>
> Side note, this pattern of memcmp() on two NUL-terminated strings should
> really be changed to just a strncmp(), if i'm not mistaken? I see
> multiple instances of this pattern in this system.
>
> 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
> Signed-off-by: Justin Stitt <justinstitt@google.com>
> ---
> Note: build-tested only.
>
> Found with: $ rg "strncpy\("
> ---
>  drivers/nvdimm/btt.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/nvdimm/btt.c b/drivers/nvdimm/btt.c
> index d5593b0dc700..9372c36e8f76 100644
> --- a/drivers/nvdimm/btt.c
> +++ b/drivers/nvdimm/btt.c
> @@ -986,7 +986,7 @@ static int btt_arena_write_layout(struct arena_info *arena)
>         if (!super)
>                 return -ENOMEM;
>
> -       strncpy(super->signature, BTT_SIG, BTT_SIG_LEN);
> +       strscpy(super->signature, BTT_SIG, sizeof(super->signature));
>         export_uuid(super->uuid, nd_btt->uuid);
>         export_uuid(super->parent_uuid, parent_uuid);
>         super->flags = cpu_to_le32(arena->flags);
>
> ---
> base-commit: 58720809f52779dc0f08e53e54b014209d13eebb
> change-id: 20231018-strncpy-drivers-nvdimm-btt-c-15f93879989e
>
> Best regards,
> --
> Justin Stitt <justinstitt@google.com>
>

[1]: https://lore.kernel.org/all/?q=dfn%3Adrivers%2Fnvdimm%2Fbtt.c

Thanks
Justin
Alison Schofield Oct. 18, 2023, 11:33 p.m. UTC | #2
On Wed, Oct 18, 2023 at 03:39:59PM -0700, Justin Stitt wrote:
> I have a feeling I may have botched the subject line for this patch.
> Can anyone confirm if it's good or not?
> 
> Automated tooling told me that this was the most common patch
> prefix but it may be caused by large patch series that just
> happened to touch this file once.
> 
> Should the subject be: nvdimm/btt: ... ?
> 
> Judging from [1] I see a few "block" and a few of nvdimm/btt.

Hi Justin,

It should be nvdimm/btt because it only touches btt.c.

Here's the old school way that I use to find prefixes. Maybe you can
train your automated tooling to do this, and then share it with me ;)

I do:

~/git/linux/drivers/nvdimm$ git log --pretty=oneline --abbrev-commit btt.c

3222d8c2a7f8 block: remove ->rw_page
ba229aa8f249 nvdimm-btt: Use the enum req_op type
86947df3a923 block: Change the type of the last .rw_page() argument
8b9ab6266204 block: remove blk_cleanup_disk
3205190655ea nvdimm-btt: use bvec_kmap_local in btt_rw_integrity
322cbb50de71 block: remove genhd.h

And I see a few choices, with 'block' being pretty common.
I peek in those patches and see that block was used when the patch
included files in drivers/block AND also in nvdimm/btt.

Use nvdimm/btt for your patch.

A bit more below -

> 
> On Wed, Oct 18, 2023 at 3:35 PM Justin Stitt <justinstitt@google.com> 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.
> >
> > We expect super->signature to be NUL-terminated based on its usage with
> > memcpy against a NUL-term'd buffer:
> > btt_devs.c:
> > 253 | if (memcmp(super->signature, BTT_SIG, BTT_SIG_LEN) != 0)
> > btt.h:
> > 13  | #define BTT_SIG "BTT_ARENA_INFO\0"
> >
> > NUL-padding is not required as `super` is already zero-allocated:
> > btt.c:
> > 985 | super = kzalloc(sizeof(struct btt_sb), GFP_NOIO);
> > ... rendering any additional NUL-padding superfluous.
> >
> > Considering the above, a suitable replacement is `strscpy` [2] due to
> > the fact that it guarantees NUL-termination on the destination buffer
> > without unnecessarily NUL-padding.
> >
> > Let's also use the more idiomatic strscpy usage of (dest, src,
> > sizeof(dest)) instead of (dest, src, XYZ_LEN) for buffers that the
> > compiler can determine the size of. This more tightly correlates the
> > destination buffer to the amount of bytes copied.
> >
> > Side note, this pattern of memcmp() on two NUL-terminated strings should
> > really be changed to just a strncmp(), if i'm not mistaken? I see
> > multiple instances of this pattern in this system.

I'm not following this note about memcmp() usage. Where is that?

> >
> > 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
> > Signed-off-by: Justin Stitt <justinstitt@google.com>
> > ---
> > Note: build-tested only.
> >
> > Found with: $ rg "strncpy\("

How you found it goes in the commit log, not below the line.

> > ---
> >  drivers/nvdimm/btt.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/nvdimm/btt.c b/drivers/nvdimm/btt.c
> > index d5593b0dc700..9372c36e8f76 100644
> > --- a/drivers/nvdimm/btt.c
> > +++ b/drivers/nvdimm/btt.c
> > @@ -986,7 +986,7 @@ static int btt_arena_write_layout(struct arena_info *arena)
> >         if (!super)
> >                 return -ENOMEM;
> >
> > -       strncpy(super->signature, BTT_SIG, BTT_SIG_LEN);
> > +       strscpy(super->signature, BTT_SIG, sizeof(super->signature));
> >         export_uuid(super->uuid, nd_btt->uuid);
> >         export_uuid(super->parent_uuid, parent_uuid);
> >         super->flags = cpu_to_le32(arena->flags);
> >
> > ---
> > base-commit: 58720809f52779dc0f08e53e54b014209d13eebb
> > change-id: 20231018-strncpy-drivers-nvdimm-btt-c-15f93879989e
> >
> > Best regards,
> > --
> > Justin Stitt <justinstitt@google.com>
> >
> 
> [1]: https://lore.kernel.org/all/?q=dfn%3Adrivers%2Fnvdimm%2Fbtt.c
> 
> Thanks
> Justin
>
Kees Cook Oct. 19, 2023, 4:32 a.m. UTC | #3
On Wed, Oct 18, 2023 at 04:33:29PM -0700, Alison Schofield wrote:
> On Wed, Oct 18, 2023 at 03:39:59PM -0700, Justin Stitt wrote:
> > I have a feeling I may have botched the subject line for this patch.
> > Can anyone confirm if it's good or not?
> > 
> > Automated tooling told me that this was the most common patch
> > prefix but it may be caused by large patch series that just
> > happened to touch this file once.
> > 
> > Should the subject be: nvdimm/btt: ... ?
> > 
> > Judging from [1] I see a few "block" and a few of nvdimm/btt.
> 
> Hi Justin,
> 
> It should be nvdimm/btt because it only touches btt.c.
> 
> Here's the old school way that I use to find prefixes. Maybe you can
> train your automated tooling to do this, and then share it with me ;)
> 
> I do:
> 
> ~/git/linux/drivers/nvdimm$ git log --pretty=oneline --abbrev-commit btt.c
> 
> 3222d8c2a7f8 block: remove ->rw_page
> ba229aa8f249 nvdimm-btt: Use the enum req_op type
> 86947df3a923 block: Change the type of the last .rw_page() argument
> 8b9ab6266204 block: remove blk_cleanup_disk
> 3205190655ea nvdimm-btt: use bvec_kmap_local in btt_rw_integrity
> 322cbb50de71 block: remove genhd.h
> 
> And I see a few choices, with 'block' being pretty common.
> I peek in those patches and see that block was used when the patch
> included files in drivers/block AND also in nvdimm/btt.

Yeah, this "look into the patch" step is what was missing from the
tool[1]. I've just tweaked it to weight based on number of files,
and the results are more in line with what I'd expect now. The "top 5"
best guesses are now:

	libnvdimm, btt:
	nvdimm/btt:
	nvdimm-btt:
	libnvdimm/btt:
	block:

[1] https://github.com/kees/kernel-tools/blob/trunk/helpers/get-prefix

> Use nvdimm/btt for your patch.
> 
> A bit more below -
> 
> > 
> > On Wed, Oct 18, 2023 at 3:35 PM Justin Stitt <justinstitt@google.com> 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.
> > >
> > > We expect super->signature to be NUL-terminated based on its usage with
> > > memcpy against a NUL-term'd buffer:

typo memcpy -> memcmp above?

> > > btt_devs.c:
> > > 253 | if (memcmp(super->signature, BTT_SIG, BTT_SIG_LEN) != 0)
> > > btt.h:
> > > 13  | #define BTT_SIG "BTT_ARENA_INFO\0"
                             1234567890123456

That's a funny way to define a string. :) Now it has two %NULs at the
end. ;) It doesn't need that trailing '\0'

#define BTT_SIG_LEN 16

And then this could be:

#define BTT_SIG_LEN sizeof(BTT_SIG)

But anyway...

> > >
> > > NUL-padding is not required as `super` is already zero-allocated:
> > > btt.c:
> > > 985 | super = kzalloc(sizeof(struct btt_sb), GFP_NOIO);
> > > ... rendering any additional NUL-padding superfluous.
> > >
> > > Considering the above, a suitable replacement is `strscpy` [2] due to
> > > the fact that it guarantees NUL-termination on the destination buffer
> > > without unnecessarily NUL-padding.
> > >
> > > Let's also use the more idiomatic strscpy usage of (dest, src,
> > > sizeof(dest)) instead of (dest, src, XYZ_LEN) for buffers that the
> > > compiler can determine the size of. This more tightly correlates the
> > > destination buffer to the amount of bytes copied.
> > >
> > > Side note, this pattern of memcmp() on two NUL-terminated strings should
> > > really be changed to just a strncmp(), if i'm not mistaken? I see
> > > multiple instances of this pattern in this system.
> 
> I'm not following this note about memcmp() usage. Where is that?
> 
> > >
> > > 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
> > > Signed-off-by: Justin Stitt <justinstitt@google.com>
> > > ---
> > > Note: build-tested only.
> > >
> > > Found with: $ rg "strncpy\("
> 
> How you found it goes in the commit log, not below the line.
> 
> > > ---
> > >  drivers/nvdimm/btt.c | 2 +-
> > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > >
> > > diff --git a/drivers/nvdimm/btt.c b/drivers/nvdimm/btt.c
> > > index d5593b0dc700..9372c36e8f76 100644
> > > --- a/drivers/nvdimm/btt.c
> > > +++ b/drivers/nvdimm/btt.c
> > > @@ -986,7 +986,7 @@ static int btt_arena_write_layout(struct arena_info *arena)
> > >         if (!super)
> > >                 return -ENOMEM;
> > >
> > > -       strncpy(super->signature, BTT_SIG, BTT_SIG_LEN);
> > > +       strscpy(super->signature, BTT_SIG, sizeof(super->signature));

Yup, this looks right to me.

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

-Kees
Justin Stitt Oct. 19, 2023, 5:59 p.m. UTC | #4
On Wed, Oct 18, 2023 at 4:33 PM Alison Schofield
<alison.schofield@intel.com> wrote:
>
> On Wed, Oct 18, 2023 at 03:39:59PM -0700, Justin Stitt wrote:
> > I have a feeling I may have botched the subject line for this patch.
> > Can anyone confirm if it's good or not?
> >
> > Automated tooling told me that this was the most common patch
> > prefix but it may be caused by large patch series that just
> > happened to touch this file once.
> >
> > Should the subject be: nvdimm/btt: ... ?
> >
> > Judging from [1] I see a few "block" and a few of nvdimm/btt.
>
> Hi Justin,
>
> It should be nvdimm/btt because it only touches btt.c.

Got it. I just sent a [v2].

>
> Here's the old school way that I use to find prefixes. Maybe you can
> train your automated tooling to do this, and then share it with me ;)

I use a gently modified version of [1] which I've hardwired into my b4
installation to automatically set the prefix when creating a patch.

>
> I do:
>
> ~/git/linux/drivers/nvdimm$ git log --pretty=oneline --abbrev-commit btt.c
>
> 3222d8c2a7f8 block: remove ->rw_page
> ba229aa8f249 nvdimm-btt: Use the enum req_op type
> 86947df3a923 block: Change the type of the last .rw_page() argument
> 8b9ab6266204 block: remove blk_cleanup_disk
> 3205190655ea nvdimm-btt: use bvec_kmap_local in btt_rw_integrity
> 322cbb50de71 block: remove genhd.h
>
> And I see a few choices, with 'block' being pretty common.
> I peek in those patches and see that block was used when the patch
> included files in drivers/block AND also in nvdimm/btt.
>
> Use nvdimm/btt for your patch.
>
> A bit more below -
>
> >
> > On Wed, Oct 18, 2023 at 3:35 PM Justin Stitt <justinstitt@google.com> 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.
> > >
> > > We expect super->signature to be NUL-terminated based on its usage with
> > > memcpy against a NUL-term'd buffer:
> > > btt_devs.c:
> > > 253 | if (memcmp(super->signature, BTT_SIG, BTT_SIG_LEN) != 0)
> > > btt.h:
> > > 13  | #define BTT_SIG "BTT_ARENA_INFO\0"
> > >
> > > NUL-padding is not required as `super` is already zero-allocated:
> > > btt.c:
> > > 985 | super = kzalloc(sizeof(struct btt_sb), GFP_NOIO);
> > > ... rendering any additional NUL-padding superfluous.
> > >
> > > Considering the above, a suitable replacement is `strscpy` [2] due to
> > > the fact that it guarantees NUL-termination on the destination buffer
> > > without unnecessarily NUL-padding.
> > >
> > > Let's also use the more idiomatic strscpy usage of (dest, src,
> > > sizeof(dest)) instead of (dest, src, XYZ_LEN) for buffers that the
> > > compiler can determine the size of. This more tightly correlates the
> > > destination buffer to the amount of bytes copied.
> > >
> > > Side note, this pattern of memcmp() on two NUL-terminated strings should
> > > really be changed to just a strncmp(), if i'm not mistaken? I see
> > > multiple instances of this pattern in this system.
>
> I'm not following this note about memcmp() usage. Where is that?

Sorry, I wasn't very clear. I've added more info in [v2] but tl;dr is that
it seems weird to me to use memcmp() on two NUL-terminated strings
when we have something like strncmp() or strcmp() for that purpose.
See [2].

>
> > >
> > > 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
> > > Signed-off-by: Justin Stitt <justinstitt@google.com>
> > > ---
> > > Note: build-tested only.
> > >
> > > Found with: $ rg "strncpy\("
>
> How you found it goes in the commit log, not below the line.

Whoops, fixed in [v2].

>
> > > ---
> > >  drivers/nvdimm/btt.c | 2 +-
> > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > >
> > > diff --git a/drivers/nvdimm/btt.c b/drivers/nvdimm/btt.c
> > > index d5593b0dc700..9372c36e8f76 100644
> > > --- a/drivers/nvdimm/btt.c
> > > +++ b/drivers/nvdimm/btt.c
> > > @@ -986,7 +986,7 @@ static int btt_arena_write_layout(struct arena_info *arena)
> > >         if (!super)
> > >                 return -ENOMEM;
> > >
> > > -       strncpy(super->signature, BTT_SIG, BTT_SIG_LEN);
> > > +       strscpy(super->signature, BTT_SIG, sizeof(super->signature));
> > >         export_uuid(super->uuid, nd_btt->uuid);
> > >         export_uuid(super->parent_uuid, parent_uuid);
> > >         super->flags = cpu_to_le32(arena->flags);
> > >
> > > ---
> > > base-commit: 58720809f52779dc0f08e53e54b014209d13eebb
> > > change-id: 20231018-strncpy-drivers-nvdimm-btt-c-15f93879989e
> > >
> > > Best regards,
> > > --
> > > Justin Stitt <justinstitt@google.com>
> > >
> >
> > [1]: https://lore.kernel.org/all/?q=dfn%3Adrivers%2Fnvdimm%2Fbtt.c
> >
> > Thanks
> > Justin
> >

[v2]: https://lore.kernel.org/r/20231019-strncpy-drivers-nvdimm-btt-c-v2-1-366993878cf0@google.com
[1] https://github.com/kees/kernel-tools/blob/trunk/helpers/get-prefix
[2]: https://elixir.bootlin.com/linux/v6.6-rc6/source/drivers/nvdimm/btt_devs.c#L253

Thanks
Justin
diff mbox series

Patch

diff --git a/drivers/nvdimm/btt.c b/drivers/nvdimm/btt.c
index d5593b0dc700..9372c36e8f76 100644
--- a/drivers/nvdimm/btt.c
+++ b/drivers/nvdimm/btt.c
@@ -986,7 +986,7 @@  static int btt_arena_write_layout(struct arena_info *arena)
 	if (!super)
 		return -ENOMEM;
 
-	strncpy(super->signature, BTT_SIG, BTT_SIG_LEN);
+	strscpy(super->signature, BTT_SIG, sizeof(super->signature));
 	export_uuid(super->uuid, nd_btt->uuid);
 	export_uuid(super->parent_uuid, parent_uuid);
 	super->flags = cpu_to_le32(arena->flags);