[Suggestion] drivers/usb/core: dev-config and dev->rawdescriptors, when processing failure.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello Oliver Neukum:

in drivers/usb/core/config.c, for function usb_get_configuration:

  if processing failed at line 694, we will goto err2 (line 755..759) 
  in this condition, we do not free dev-config and dev->rawdescriptors.

  after checking another relative source code, it seems not an issue (I am not quite sure).
  but I still suggest to:
    free them, when failure occurs
    or check them whether be NULL before new allocation, (if not NULL, free them firstly).

  if this suggestion is valid, please help to send relative patch.

  thanks.

  :-)

gchen.

658 int usb_get_configuration(struct usb_device *dev)
659 {
660         struct device *ddev = &dev->dev;
661         int ncfg = dev->descriptor.bNumConfigurations;
662         int result = 0;
663         unsigned int cfgno, length;
664         unsigned char *bigbuffer;
665         struct usb_config_descriptor *desc;
666 
667         cfgno = 0;
668         if (dev->authorized == 0)       /* Not really an error */
669                 goto out_not_authorized;
670         result = -ENOMEM;
671         if (ncfg > USB_MAXCONFIG) {
672                 dev_warn(ddev, "too many configurations: %d, "
673                     "using maximum allowed: %d\n", ncfg, USB_MAXCONFIG);
674                 dev->descriptor.bNumConfigurations = ncfg = USB_MAXCONFIG;
675         }
676 
677         if (ncfg < 1) {
678                 dev_err(ddev, "no configurations\n");
679                 return -EINVAL;
680         }
681 
682         length = ncfg * sizeof(struct usb_host_config);
683         dev->config = kzalloc(length, GFP_KERNEL);
684         if (!dev->config)
685                 goto err2;
686 
687         length = ncfg * sizeof(char *);
688         dev->rawdescriptors = kzalloc(length, GFP_KERNEL);
689         if (!dev->rawdescriptors)
690                 goto err2;
691 
692         desc = kmalloc(USB_DT_CONFIG_SIZE, GFP_KERNEL);
693         if (!desc)
694                 goto err2;
695 
696         result = 0;
697         for (; cfgno < ncfg; cfgno++) {
698                 /* We grab just the first descriptor so we know how long
699                  * the whole configuration is */
700                 result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno,
701                     desc, USB_DT_CONFIG_SIZE);
702                 if (result < 0) {
703                         dev_err(ddev, "unable to read config index %d "
704                             "descriptor/%s: %d\n", cfgno, "start", result);
705                         if (result != -EPIPE)
706                                 goto err;
707                         dev_err(ddev, "chopping to %d config(s)\n", cfgno);
708                         dev->descriptor.bNumConfigurations = cfgno;
709                         break;
710                 } else if (result < 4) {
711                         dev_err(ddev, "config index %d descriptor too short "
712                             "(expected %i, got %i)\n", cfgno,
713                             USB_DT_CONFIG_SIZE, result);
714                         result = -EINVAL;
715                         goto err;
716                 }
717                 length = max((int) le16_to_cpu(desc->wTotalLength),
718                     USB_DT_CONFIG_SIZE);
719 
720                 /* Now that we know the length, get the whole thing */
721                 bigbuffer = kmalloc(length, GFP_KERNEL);
722                 if (!bigbuffer) {
723                         result = -ENOMEM;
724                         goto err;
725                 }
726                 result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno,
727                     bigbuffer, length);
728                 if (result < 0) {
729                         dev_err(ddev, "unable to read config index %d "
730                             "descriptor/%s\n", cfgno, "all");
731                         kfree(bigbuffer);
732                         goto err;
733                 }
734                 if (result < length) {
735                         dev_warn(ddev, "config index %d descriptor too short "
736                             "(expected %i, got %i)\n", cfgno, length, result);
737                         length = result;
738                 }
739 
740                 dev->rawdescriptors[cfgno] = bigbuffer;
741 
742                 result = usb_parse_configuration(dev, cfgno,
743                     &dev->config[cfgno], bigbuffer, length);
744                 if (result < 0) {
745                         ++cfgno;
746                         goto err;
747                 }
748         }
749         result = 0;
750 
751 err:
752         kfree(desc);
753 out_not_authorized:
754         dev->descriptor.bNumConfigurations = cfgno;
755 err2:
756         if (result == -ENOMEM)
757                 dev_err(ddev, "out of memory\n");
758         return result;
759 }

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux