Open stefanklug opened 9 years ago
From http://article.gmane.org/gmane.linux.kernel/1738948
@@ -1471,6 +1526,57 @@ static int proc_do_submiturb(struct usb_dev_state ps, struct usbdevfs_urb uurb } totlen -= u; } } else if(num_pages) { pages = kmalloc(num_pagessizeof(struct page), GFP_KERNEL); if(!pages) { ret = -ENOMEM; goto error; } + //create the scatterlist as->urb->sg = kmalloc(num_pages * sizeof(struct scatterlist), GFP_KERNEL); if (!as->urb->sg) { ret = -ENOMEM; goto error; } + ret = get_user_pages_fast((unsigned long)buf_aligned, num_pages, is_in, pages); + if(ret < 0) { printk("get_user_pages failed %i\n", ret); goto error; } + //did we get all pages? if(ret < num_pages) { printk("get_user_pages didn't deliver all pages %i\n", ret); //free the pages and error out for(i=0; i<ret; i++) { page_cache_release(pages[i]); } ret = -ENOMEM; goto error; } + as->is_user_mem = 1; as->urb->num_sgs = num_pages; sg_init_table(as->urb->sg, as->urb->num_sgs); + totlen = uurb->buffer_length + buf_offset; o = buf_offset; for (i = 0; i < as->urb->num_sgs; i++) { u = (totlen > PAGE_SIZE) ? PAGE_SIZE : totlen; u-= o; sg_set_page(&as->urb->sg[i], pages[i], u, o); totlen -= u + o; o = 0; } + kfree(pages); pages = NULL; } else if (uurb->buffer_length > 0) { as->urb->transfer_buffer = kmalloc(uurb->buffer_length, GFP_KERNEL)
@@ -1471,6 +1526,57 @@ static int proc_do_submiturb(struct usb_dev_state ps, struct usbdevfs_urb uurb } totlen -= u; }
One more thing: Where do you check that the memory the user has passed a pointer to is actually writable? It seems to me that for zerocopy you must do the check before you submit the URB to the HCD.
From http://article.gmane.org/gmane.linux.kernel/1738948
One more thing: Where do you check that the memory the user has passed a pointer to is actually writable? It seems to me that for zerocopy you must do the check before you submit the URB to the HCD.