firmware_loader: Strip off \n from customized path
authorFlorian Fainelli <f.fainelli@gmail.com>
Thu, 13 Apr 2023 19:17:57 +0000 (12:17 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 20 Apr 2023 09:42:27 +0000 (11:42 +0200)
Having helped an user recently figure out why the customized path being
specified was not taken into account landed on a subtle difference
between using:

echo "/xyz/firmware" > /sys/module/firmware_class/parameters/path

which inserts an additional newline which is passed as is down to
fw_get_filesystem_firmware() and ultimately kernel_read_file_from_path()
and fails.

Strip off \n from the customized firmware path such that users do not
run into these hard to debug situations.

Link: https://lore.kernel.org/all/20230402135423.3235-1-f.fainelli@gmail.com/
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Link: https://lore.kernel.org/r/20230413191757.1949088-1-f.fainelli@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/base/firmware_loader/main.c

index b2c292c..9d79d5a 100644 (file)
@@ -493,9 +493,9 @@ fw_get_filesystem_firmware(struct device *device, struct fw_priv *fw_priv,
                                             const void *in_buffer))
 {
        size_t size;
-       int i, len;
+       int i, len, maxlen = 0;
        int rc = -ENOENT;
-       char *path;
+       char *path, *nt = NULL;
        size_t msize = INT_MAX;
        void *buffer = NULL;
 
@@ -518,8 +518,17 @@ fw_get_filesystem_firmware(struct device *device, struct fw_priv *fw_priv,
                if (!fw_path[i][0])
                        continue;
 
-               len = snprintf(path, PATH_MAX, "%s/%s%s",
-                              fw_path[i], fw_priv->fw_name, suffix);
+               /* strip off \n from customized path */
+               maxlen = strlen(fw_path[i]);
+               if (i == 0) {
+                       nt = strchr(fw_path[i], '\n');
+                       if (nt)
+                               maxlen = nt - fw_path[i];
+               }
+
+               len = snprintf(path, PATH_MAX, "%.*s/%s%s",
+                              maxlen, fw_path[i],
+                              fw_priv->fw_name, suffix);
                if (len >= PATH_MAX) {
                        rc = -ENAMETOOLONG;
                        break;