diff mbox series

qlcnic: replace deprecated strncpy with strscpy

Message ID 20231012-strncpy-drivers-net-ethernet-qlogic-qlcnic-qlcnic_83xx_init-c-v1-1-f0008d5e43be@google.com (mailing list archive)
State Mainlined
Commit f8dd2412ba66128de4325c187c9504c6da511bc8
Headers show
Series qlcnic: replace deprecated strncpy with strscpy | expand

Commit Message

Justin Stitt Oct. 12, 2023, 7:44 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 fw_info->fw_file_name to be NUL-terminated based on its use
within _request_firmware_prepare() wherein `name` refers to it:
|       if (firmware_request_builtin_buf(firmware, name, dbuf, size)) {
|               dev_dbg(device, "using built-in %s\n", name);
|               return 0; /* assigned */
|       }
... and with firmware_request_builtin() also via `name`:
|       if (strcmp(name, b_fw->name) == 0) {

There is no evidence that NUL-padding is required.

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.

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/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)


---
base-commit: cbf3a2cb156a2c911d8f38d8247814b4c07f49a2
change-id: 20231012-strncpy-drivers-net-ethernet-qlogic-qlcnic-qlcnic_83xx_init-c-7858019dc583

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

Comments

Kees Cook Oct. 15, 2023, 2:47 a.m. UTC | #1
On Thu, Oct 12, 2023 at 07:44:29PM +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.
> 
> We expect fw_info->fw_file_name to be NUL-terminated based on its use
> within _request_firmware_prepare() wherein `name` refers to it:
> |       if (firmware_request_builtin_buf(firmware, name, dbuf, size)) {
> |               dev_dbg(device, "using built-in %s\n", name);
> |               return 0; /* assigned */
> |       }
> ... and with firmware_request_builtin() also via `name`:
> |       if (strcmp(name, b_fw->name) == 0) {
> 
> There is no evidence that NUL-padding is required.
> 
> 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.

When doing the hard-coded value to sizeof(), can you include in the
commit log the rationale for it? For example:

  Additionally replace size macro (QLC_FW_FILE_NAME_LEN) with
  sizeof(fw_info->fw_file_name) to more directly tie the maximum buffer
  size to the destination buffer:

  struct qlc_83xx_fw_info {
          ...
          char    fw_file_name[QLC_FW_FILE_NAME_LEN];
  };


> 
> 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/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c | 12 ++++++------
>  1 file changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
> index c95d56e56c59..b733374b4dc5 100644
> --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
> +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
> @@ -2092,8 +2092,8 @@ static int qlcnic_83xx_run_post(struct qlcnic_adapter *adapter)
>  		return -EINVAL;
>  	}
>  
> -	strncpy(fw_info->fw_file_name, QLC_83XX_POST_FW_FILE_NAME,
> -		QLC_FW_FILE_NAME_LEN);
> +	strscpy(fw_info->fw_file_name, QLC_83XX_POST_FW_FILE_NAME,
> +		sizeof(fw_info->fw_file_name));
>  
>  	ret = request_firmware(&fw_info->fw, fw_info->fw_file_name, dev);
>  	if (ret) {
> @@ -2396,12 +2396,12 @@ static int qlcnic_83xx_get_fw_info(struct qlcnic_adapter *adapter)
>  		switch (pdev->device) {
>  		case PCI_DEVICE_ID_QLOGIC_QLE834X:
>  		case PCI_DEVICE_ID_QLOGIC_QLE8830:
> -			strncpy(fw_info->fw_file_name, QLC_83XX_FW_FILE_NAME,
> -				QLC_FW_FILE_NAME_LEN);
> +			strscpy(fw_info->fw_file_name, QLC_83XX_FW_FILE_NAME,
> +				sizeof(fw_info->fw_file_name));
>  			break;
>  		case PCI_DEVICE_ID_QLOGIC_QLE844X:
> -			strncpy(fw_info->fw_file_name, QLC_84XX_FW_FILE_NAME,
> -				QLC_FW_FILE_NAME_LEN);
> +			strscpy(fw_info->fw_file_name, QLC_84XX_FW_FILE_NAME,
> +				sizeof(fw_info->fw_file_name));
>  			break;
>  		default:
>  			dev_err(&pdev->dev, "%s: Invalid device id\n",

But yes, this all looks right to me.

Reviewed-by: Kees Cook <keescook@chromium.org>
Justin Stitt Oct. 16, 2023, 6:14 p.m. UTC | #2
On Sat, Oct 14, 2023 at 7:47 PM Kees Cook <keescook@chromium.org> wrote:
>
> On Thu, Oct 12, 2023 at 07:44:29PM +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.
> >
> > We expect fw_info->fw_file_name to be NUL-terminated based on its use
> > within _request_firmware_prepare() wherein `name` refers to it:
> > |       if (firmware_request_builtin_buf(firmware, name, dbuf, size)) {
> > |               dev_dbg(device, "using built-in %s\n", name);
> > |               return 0; /* assigned */
> > |       }
> > ... and with firmware_request_builtin() also via `name`:
> > |       if (strcmp(name, b_fw->name) == 0) {
> >
> > There is no evidence that NUL-padding is required.
> >
> > 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.
>
> When doing the hard-coded value to sizeof(), can you include in the
> commit log the rationale for it? For example:
>
>   Additionally replace size macro (QLC_FW_FILE_NAME_LEN) with
>   sizeof(fw_info->fw_file_name) to more directly tie the maximum buffer
>   size to the destination buffer:
>
>   struct qlc_83xx_fw_info {
>           ...
>           char    fw_file_name[QLC_FW_FILE_NAME_LEN];
>   };
>

Sure, I'll be doing this from now on to make the change more clear!

>
> >
> > 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/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c | 12 ++++++------
> >  1 file changed, 6 insertions(+), 6 deletions(-)
> >
> > diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
> > index c95d56e56c59..b733374b4dc5 100644
> > --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
> > +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
> > @@ -2092,8 +2092,8 @@ static int qlcnic_83xx_run_post(struct qlcnic_adapter *adapter)
> >               return -EINVAL;
> >       }
> >
> > -     strncpy(fw_info->fw_file_name, QLC_83XX_POST_FW_FILE_NAME,
> > -             QLC_FW_FILE_NAME_LEN);
> > +     strscpy(fw_info->fw_file_name, QLC_83XX_POST_FW_FILE_NAME,
> > +             sizeof(fw_info->fw_file_name));
> >
> >       ret = request_firmware(&fw_info->fw, fw_info->fw_file_name, dev);
> >       if (ret) {
> > @@ -2396,12 +2396,12 @@ static int qlcnic_83xx_get_fw_info(struct qlcnic_adapter *adapter)
> >               switch (pdev->device) {
> >               case PCI_DEVICE_ID_QLOGIC_QLE834X:
> >               case PCI_DEVICE_ID_QLOGIC_QLE8830:
> > -                     strncpy(fw_info->fw_file_name, QLC_83XX_FW_FILE_NAME,
> > -                             QLC_FW_FILE_NAME_LEN);
> > +                     strscpy(fw_info->fw_file_name, QLC_83XX_FW_FILE_NAME,
> > +                             sizeof(fw_info->fw_file_name));
> >                       break;
> >               case PCI_DEVICE_ID_QLOGIC_QLE844X:
> > -                     strncpy(fw_info->fw_file_name, QLC_84XX_FW_FILE_NAME,
> > -                             QLC_FW_FILE_NAME_LEN);
> > +                     strscpy(fw_info->fw_file_name, QLC_84XX_FW_FILE_NAME,
> > +                             sizeof(fw_info->fw_file_name));
> >                       break;
> >               default:
> >                       dev_err(&pdev->dev, "%s: Invalid device id\n",
>
> But yes, this all looks right to me.
>
> Reviewed-by: Kees Cook <keescook@chromium.org>
>
> --
> Kees Cook

Thanks
Justin
Kees Cook Nov. 30, 2023, 10 p.m. UTC | #3
On Thu, 12 Oct 2023 19:44:29 +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.
> 
> We expect fw_info->fw_file_name to be NUL-terminated based on its use
> within _request_firmware_prepare() wherein `name` refers to it:
> |       if (firmware_request_builtin_buf(firmware, name, dbuf, size)) {
> |               dev_dbg(device, "using built-in %s\n", name);
> |               return 0; /* assigned */
> |       }
> ... and with firmware_request_builtin() also via `name`:
> |       if (strcmp(name, b_fw->name) == 0) {
> 
> [...]

Applied to for-next/hardening, thanks!

[1/1] qlcnic: replace deprecated strncpy with strscpy
      https://git.kernel.org/kees/c/f8bef1ef8095

Take care,
Jakub Kicinski Dec. 1, 2023, 6:43 a.m. UTC | #4
On Thu, 30 Nov 2023 14:00:28 -0800 Kees Cook wrote:
> [1/1] qlcnic: replace deprecated strncpy with strscpy
>       https://git.kernel.org/kees/c/f8bef1ef8095

You asked for changes yourself here, please drop all the networking
patches you applied today :|
Kees Cook Dec. 1, 2023, 6:21 p.m. UTC | #5
On Thu, Nov 30, 2023 at 10:43:12PM -0800, Jakub Kicinski wrote:
> On Thu, 30 Nov 2023 14:00:28 -0800 Kees Cook wrote:
> > [1/1] qlcnic: replace deprecated strncpy with strscpy
> >       https://git.kernel.org/kees/c/f8bef1ef8095
> 
> You asked for changes yourself here, please drop all the networking
> patches you applied today :|

It was a request for future commit logs. But yes, dropped. Justin, can
you refresh this patch as well, and include the comments about the
sizeof() replacement being safe?
diff mbox series

Patch

diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
index c95d56e56c59..b733374b4dc5 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
@@ -2092,8 +2092,8 @@  static int qlcnic_83xx_run_post(struct qlcnic_adapter *adapter)
 		return -EINVAL;
 	}
 
-	strncpy(fw_info->fw_file_name, QLC_83XX_POST_FW_FILE_NAME,
-		QLC_FW_FILE_NAME_LEN);
+	strscpy(fw_info->fw_file_name, QLC_83XX_POST_FW_FILE_NAME,
+		sizeof(fw_info->fw_file_name));
 
 	ret = request_firmware(&fw_info->fw, fw_info->fw_file_name, dev);
 	if (ret) {
@@ -2396,12 +2396,12 @@  static int qlcnic_83xx_get_fw_info(struct qlcnic_adapter *adapter)
 		switch (pdev->device) {
 		case PCI_DEVICE_ID_QLOGIC_QLE834X:
 		case PCI_DEVICE_ID_QLOGIC_QLE8830:
-			strncpy(fw_info->fw_file_name, QLC_83XX_FW_FILE_NAME,
-				QLC_FW_FILE_NAME_LEN);
+			strscpy(fw_info->fw_file_name, QLC_83XX_FW_FILE_NAME,
+				sizeof(fw_info->fw_file_name));
 			break;
 		case PCI_DEVICE_ID_QLOGIC_QLE844X:
-			strncpy(fw_info->fw_file_name, QLC_84XX_FW_FILE_NAME,
-				QLC_FW_FILE_NAME_LEN);
+			strscpy(fw_info->fw_file_name, QLC_84XX_FW_FILE_NAME,
+				sizeof(fw_info->fw_file_name));
 			break;
 		default:
 			dev_err(&pdev->dev, "%s: Invalid device id\n",