wifi: ipw2x00: replace deprecated strncpy with strscpy_pad
authorJustin Stitt <justinstitt@google.com>
Tue, 17 Oct 2023 21:48:15 +0000 (21:48 +0000)
committerKalle Valo <kvalo@kernel.org>
Mon, 23 Oct 2023 17:26:29 +0000 (20:26 +0300)
strncpy() is deprecated for use on NUL-terminated destination strings
[1] and as such we should prefer more robust and less ambiguous string
interfaces.

`extra` is intended to be NUL-terminated which is evident by the manual
assignment of a NUL-byte as well as its immediate usage with strlen().

Moreover, many of these getters and setters are NUL-padding buffers with
memset():
2439  | memset(&tx_power, 0, sizeof(tx_power));
9998  | memset(sys_config, 0, sizeof(struct ipw_sys_config));
10084 | memset(tfd, 0, sizeof(*tfd));
10261 | memset(&dummystats, 0, sizeof(dummystats));
... let's maintain this behavior and NUL-pad our destination buffer.

Considering the above, a suitable replacement is `strscpy_pad` due to
the fact that it guarantees both NUL-termination and NUL-padding on the
destination buffer.

To be clear, there is no bug in the current implementation as
MAX_WX_STRING is much larger than the size of the string literals being
copied from. Also, strncpy() does NUL-pad the destination buffer and
using strscpy_pad() simply matches that behavior. All in all, there
should be no functional change but we are one step closer to eliminating
usage of strncpy().

Do note that we cannot use the more idiomatic strscpy invocation of
(dest, src, sizeof(dest)) as the destination buffer cannot have its size
determined at compile time. So, let's stick with (dest, src, LEN).

Link: https://www.kernel.org/doc/html/latest/process/deprecated.html#strncpy-on-nul-terminated-strings
Link: https://github.com/KSPP/linux/issues/90
Cc: linux-hardening@vger.kernel.org
Signed-off-by: Justin Stitt <justinstitt@google.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20231017-strncpy-drivers-net-wireless-intel-ipw2x00-ipw2200-c-v2-1-465e10dc817c@google.com
drivers/net/wireless/intel/ipw2x00/ipw2200.c

index 902a772f46499d334fb4b552a10f5b27c1091686..eed9ef17bc29343f49f260adae89106769350263 100644 (file)
@@ -9656,31 +9656,30 @@ static int ipw_wx_get_wireless_mode(struct net_device *dev,
        mutex_lock(&priv->mutex);
        switch (priv->ieee->mode) {
        case IEEE_A:
-               strncpy(extra, "802.11a (1)", MAX_WX_STRING);
+               strscpy_pad(extra, "802.11a (1)", MAX_WX_STRING);
                break;
        case IEEE_B:
-               strncpy(extra, "802.11b (2)", MAX_WX_STRING);
+               strscpy_pad(extra, "802.11b (2)", MAX_WX_STRING);
                break;
        case IEEE_A | IEEE_B:
-               strncpy(extra, "802.11ab (3)", MAX_WX_STRING);
+               strscpy_pad(extra, "802.11ab (3)", MAX_WX_STRING);
                break;
        case IEEE_G:
-               strncpy(extra, "802.11g (4)", MAX_WX_STRING);
+               strscpy_pad(extra, "802.11g (4)", MAX_WX_STRING);
                break;
        case IEEE_A | IEEE_G:
-               strncpy(extra, "802.11ag (5)", MAX_WX_STRING);
+               strscpy_pad(extra, "802.11ag (5)", MAX_WX_STRING);
                break;
        case IEEE_B | IEEE_G:
-               strncpy(extra, "802.11bg (6)", MAX_WX_STRING);
+               strscpy_pad(extra, "802.11bg (6)", MAX_WX_STRING);
                break;
        case IEEE_A | IEEE_B | IEEE_G:
-               strncpy(extra, "802.11abg (7)", MAX_WX_STRING);
+               strscpy_pad(extra, "802.11abg (7)", MAX_WX_STRING);
                break;
        default:
-               strncpy(extra, "unknown", MAX_WX_STRING);
+               strscpy_pad(extra, "unknown", MAX_WX_STRING);
                break;
        }
-       extra[MAX_WX_STRING - 1] = '\0';
 
        IPW_DEBUG_WX("PRIV GET MODE: %s\n", extra);