]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[efi] Fix reporting of USB supported languages array
authorMichael Brown <mcb30@ipxe.org>
Thu, 1 Oct 2020 17:41:37 +0000 (18:41 +0100)
committerMichael Brown <mcb30@ipxe.org>
Thu, 1 Oct 2020 22:27:53 +0000 (23:27 +0100)
The length as returned by UsbGetSupportedLanguages() should not
include the length of the descriptor header itself.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/include/ipxe/efi/efi_usb.h
src/interface/efi/efi_usb.c

index 05b4fad009573c79d20f88985f94bc0ada0d1276..41d9cc665f253745c61fc2c509b2a6844361f7d2 100644 (file)
@@ -24,7 +24,9 @@ struct efi_usb_device {
        /** Configuration descriptor */
        struct usb_configuration_descriptor *config;
        /** Supported languages */
-       struct usb_descriptor_header *languages;
+       uint16_t *lang;
+       /** Length of supported languages */
+       size_t lang_len;
        /** List of interfaces */
        struct list_head interfaces;
 };
index a8c274a57b4929c070c65c938755e825e35138a6..7f761145fb5e40b1610f288f3bd6a3d966b8b3e3 100644 (file)
@@ -1044,9 +1044,8 @@ efi_usb_get_supported_languages ( EFI_USB_IO_PROTOCOL *usbio,
        DBGC2 ( usbdev, "USBDEV %s get supported languages\n", usbintf->name );
 
        /* Return cached supported languages */
-       *languages = ( ( ( void * ) usbdev->languages ) +
-                      sizeof ( *(usbdev->languages) ) );
-       *len = usbdev->languages->len;
+       *languages = usbdev->lang;
+       *len = usbdev->lang_len;
 
        return 0;
 }
@@ -1255,7 +1254,9 @@ static int efi_usb_probe ( struct usb_function *func,
        struct efi_usb_interface *usbintf;
        struct efi_device *efidev;
        struct usb_descriptor_header header;
+       struct usb_descriptor_header *lang;
        size_t config_len;
+       size_t lang_len;
        unsigned int i;
        int rc;
 
@@ -1275,9 +1276,12 @@ static int efi_usb_probe ( struct usb_function *func,
                /* Assume no strings are present */
                header.len = 0;
        }
+       lang_len = ( ( header.len >= sizeof ( header ) ) ?
+                    ( header.len - sizeof ( header ) ) : 0 );
 
        /* Allocate and initialise structure */
-       usbdev = zalloc ( sizeof ( *usbdev ) + config_len + header.len );
+       usbdev = zalloc ( sizeof ( *usbdev ) + config_len +
+                         sizeof ( *lang ) + lang_len );
        if ( ! usbdev ) {
                rc = -ENOMEM;
                goto err_alloc;
@@ -1288,14 +1292,15 @@ static int efi_usb_probe ( struct usb_function *func,
        usbdev->efidev = efidev;
        usbdev->config = ( ( ( void * ) usbdev ) + sizeof ( *usbdev ) );
        memcpy ( usbdev->config, config, config_len );
-       usbdev->languages = ( ( ( void * ) usbdev->config ) + config_len );
+       lang = ( ( ( void * ) usbdev->config ) + config_len );
+       usbdev->lang = ( ( ( void * ) lang ) + sizeof ( *lang ) );
+       usbdev->lang_len = lang_len;
        INIT_LIST_HEAD ( &usbdev->interfaces );
 
-       /* Get supported languages descriptor */
-       if ( header.len &&
-            ( rc = usb_get_descriptor ( usb, 0, USB_STRING_DESCRIPTOR, 0, 0,
-                                        usbdev->languages,
-                                        header.len ) ) != 0 ) {
+       /* Get supported languages descriptor, if applicable */
+       if ( lang_len &&
+            ( ( rc = usb_get_descriptor ( usb, 0, USB_STRING_DESCRIPTOR,
+                                          0, 0, lang, header.len ) ) != 0 ) ) {
                DBGC ( usbdev, "USBDEV %s could not get supported languages: "
                       "%s\n", usbdev->name, strerror ( rc ) );
                goto err_get_languages;