]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
USB: core: Use krealloc() in usb_cache_string()
authorBence Csókás <bence98@sch.bme.hu>
Sun, 15 Mar 2026 11:24:44 +0000 (12:24 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 18 Mar 2026 15:03:52 +0000 (16:03 +0100)
Instead of "shrinking" the allocation by kmalloc()ing a new, smaller
buffer, utilize krealloc() to shrink the existing allocation. This saves
a memcpy(), as well as eliminates the temporary `smallbuf` allocation,
which guards against allocation failure under extreme memory pressure.

Signed-off-by: Bence Csókás <bence98@sch.bme.hu>
Link: https://patch.msgid.link/20260315-usb-krealloc-v2-1-32f83e090409@sch.bme.hu
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/core/message.c

index 2ab120ce2fa85e7c7efedbc8e33db722ed0c5dd0..75e2bfd744a984a95f5586bcf5c8d79fdca1c463 100644 (file)
@@ -1063,7 +1063,7 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
 }
 EXPORT_SYMBOL_GPL(usb_string);
 
-/* one UTF-8-encoded 16-bit character has at most three bytes */
+/* one 16-bit character, when UTF-8-encoded, has at most three bytes */
 #define MAX_USB_STRING_SIZE (127 * 3 + 1)
 
 /**
@@ -1084,16 +1084,18 @@ char *usb_cache_string(struct usb_device *udev, int index)
                return NULL;
 
        buf = kmalloc(MAX_USB_STRING_SIZE, GFP_NOIO);
-       if (buf) {
-               len = usb_string(udev, index, buf, MAX_USB_STRING_SIZE);
-               if (len > 0) {
-                       smallbuf = kmalloc(++len, GFP_NOIO);
-                       if (!smallbuf)
-                               return buf;
-                       memcpy(smallbuf, buf, len);
-               }
+       if (!buf)
+               return NULL;
+
+       len = usb_string(udev, index, buf, MAX_USB_STRING_SIZE);
+       if (len <= 0) {
                kfree(buf);
+               return NULL;
        }
+
+       smallbuf = krealloc(buf, len + 1, GFP_NOIO);
+       if (unlikely(!smallbuf))
+               return buf;
        return smallbuf;
 }
 EXPORT_SYMBOL_GPL(usb_cache_string);