basler / linux-usb-zerocopy

usb3 zerocopy support for linux
https://github.com/Basler/linux-usb-zerocopy/wiki
Other
4 stars 2 forks source link

Check if memory passed from user is writable #1

Open stefanklug opened 9 years ago

stefanklug commented 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)

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.