usb: core: fix quirks_param_set() writing to a const pointer
authorKars Mulder <kerneldev@karsmulder.nl>
Tue, 7 Jul 2020 14:43:50 +0000 (16:43 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 21 Jul 2020 11:38:21 +0000 (13:38 +0200)
The function quirks_param_set() takes as argument a const char* pointer
to the new value of the usbcore.quirks parameter. It then casts this
pointer to a non-const char* pointer and passes it to the strsep()
function, which overwrites the value.

Fix this by creating a copy of the value using kstrdup() and letting
that copy be written to by strsep().

Fixes: 027bd6cafd9a ("usb: core: Add "quirks" parameter for usbcore")
Signed-off-by: Kars Mulder <kerneldev@karsmulder.nl>
Link: https://lore.kernel.org/r/5ee2-5f048a00-21-618c5c00@230659773
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/core/quirks.c

index 870df71..7c1198f 100644 (file)
@@ -25,17 +25,23 @@ static unsigned int quirk_count;
 
 static char quirks_param[128];
 
-static int quirks_param_set(const char *val, const struct kernel_param *kp)
+static int quirks_param_set(const char *value, const struct kernel_param *kp)
 {
-       char *p, *field;
+       char *val, *p, *field;
        u16 vid, pid;
        u32 flags;
        size_t i;
        int err;
 
+       val = kstrdup(value, GFP_KERNEL);
+       if (!val)
+               return -ENOMEM;
+
        err = param_set_copystring(val, kp);
-       if (err)
+       if (err) {
+               kfree(val);
                return err;
+       }
 
        mutex_lock(&quirk_mutex);
 
@@ -60,10 +66,11 @@ static int quirks_param_set(const char *val, const struct kernel_param *kp)
        if (!quirk_list) {
                quirk_count = 0;
                mutex_unlock(&quirk_mutex);
+               kfree(val);
                return -ENOMEM;
        }
 
-       for (i = 0, p = (char *)val; p && *p;) {
+       for (i = 0, p = val; p && *p;) {
                /* Each entry consists of VID:PID:flags */
                field = strsep(&p, ":");
                if (!field)
@@ -144,6 +151,7 @@ static int quirks_param_set(const char *val, const struct kernel_param *kp)
 
 unlock:
        mutex_unlock(&quirk_mutex);
+       kfree(val);
 
        return 0;
 }