Am Donnerstag, 15. Dezember 2005 22:13 schrieb Sam Bishop:
> Oliver Neukum wrote:
> > On second thought, the skeleton driver doesn't even limit the buffersize
> > to something sane. Triggering 128K allocations in unlimited numbers is
> > not nice at all.
> > 
> >     Regards
> >             Oliver
> > 
> 
> That's right; I forgot that I'd seen that too.
> 
> I suppose this is the difference between a "skeleton" and an "example?" :)
> 
> As you mentioned, any limit on the number of URBs in flight would 
> require a counting semaphore or some other kind of locking.  There's a 
> comment at the top of the code extolling the fact that there is no 
> locking, which made me think that issues like this were now being 
> handled lower in the kernel--which I admit doesn't make much sense.  As 
> things stand though, I could see this turning into a FAQ.

Does this fix your trouble?

        Regards
                Oliver

--- linux-2.6.15-rc5-vanilla/drivers/usb/usb-skeleton.c 2005-12-04 
06:10:42.000000000 +0100
+++ linux-2.6.15-rc5/drivers/usb/usb-skeleton.c 2005-12-17 09:41:39.000000000 
+0100
@@ -39,10 +39,15 @@
 /* Get a minor range for your devices from the usb maintainer */
 #define USB_SKEL_MINOR_BASE    192
 
+/* our private defines. if this grows any larger, use your own .h file */
+#define MAX_TRANSFER           ( PAGE_SIZE - 512 )
+#define WRITES_IN_FLIGHT       8
+
 /* Structure to hold all of our device specific stuff */
 struct usb_skel {
        struct usb_device *     udev;                   /* the usb device for 
this device */
        struct usb_interface *  interface;              /* the interface for 
this device */
+       struct semaphore        limit_sem;              /* limiting the number 
of writes in progress */
        unsigned char *         bulk_in_buffer;         /* the buffer to 
receive data */
        size_t                  bulk_in_size;           /* the size of the 
receive buffer */
        __u8                    bulk_in_endpointAddr;   /* the address of the 
bulk in endpoint */
@@ -152,6 +157,7 @@
        /* free up our allocated buffer */
        usb_buffer_free(urb->dev, urb->transfer_buffer_length, 
                        urb->transfer_buffer, urb->transfer_dma);
+       up(&dev->limit_sem);
 }
 
 static ssize_t skel_write(struct file *file, const char *user_buffer, size_t 
count, loff_t *ppos)
@@ -160,6 +166,7 @@
        int retval = 0;
        struct urb *urb = NULL;
        char *buf = NULL;
+       size_t writesize = max(count, MAX_TRANSFER);
 
        dev = (struct usb_skel *)file->private_data;
 
@@ -167,6 +174,9 @@
        if (count == 0)
                goto exit;
 
+       /* limit the number of URBs in flight to stop a user from using up all 
RAM */
+       down (&dev->limit_sem);
+
        /* create a urb, and a buffer for it, and copy the data to the urb */
        urb = usb_alloc_urb(0, GFP_KERNEL);
        if (!urb) {
@@ -174,13 +184,13 @@
                goto error;
        }
 
-       buf = usb_buffer_alloc(dev->udev, count, GFP_KERNEL, 
&urb->transfer_dma);
+       buf = usb_buffer_alloc(dev->udev, writesize, GFP_KERNEL, 
&urb->transfer_dma);
        if (!buf) {
                retval = -ENOMEM;
                goto error;
        }
 
-       if (copy_from_user(buf, user_buffer, count)) {
+       if (copy_from_user(buf, user_buffer, writesize)) {
                retval = -EFAULT;
                goto error;
        }
@@ -188,7 +198,7 @@
        /* initialize the urb properly */
        usb_fill_bulk_urb(urb, dev->udev,
                          usb_sndbulkpipe(dev->udev, 
dev->bulk_out_endpointAddr),
-                         buf, count, skel_write_bulk_callback, dev);
+                         buf, writesize, skel_write_bulk_callback, dev);
        urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
        /* send the data out the bulk port */
@@ -202,11 +212,12 @@
        usb_free_urb(urb);
 
 exit:
-       return count;
+       return writesize;
 
 error:
        usb_buffer_free(dev->udev, count, buf, urb->transfer_dma);
        usb_free_urb(urb);
+       up(&dev->limit_sem);
        return retval;
 }
 
@@ -238,13 +249,13 @@
        int retval = -ENOMEM;
 
        /* allocate memory for our device state and initialize it */
-       dev = kmalloc(sizeof(*dev), GFP_KERNEL);
+       dev = kzalloc(sizeof(*dev), GFP_KERNEL);
        if (dev == NULL) {
                err("Out of memory");
                goto error;
        }
-       memset(dev, 0x00, sizeof(*dev));
        kref_init(&dev->kref);
+       sema_init(&dev->limit_sem, WRITES_IN_FLIGHT);
 
        dev->udev = usb_get_dev(interface_to_usbdev(interface));
        dev->interface = interface;


-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log files
for problems?  Stop!  Download the new AJAX search engine that makes
searching your log files as easy as surfing the  web.  DOWNLOAD SPLUNK!
http://ads.osdn.com/?ad_id=7637&alloc_id=16865&op=click
_______________________________________________
linux-usb-devel@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to