Skip to content

Check if memory passed from user is writable #1

Description

@stefanklug

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_pages_sizeof(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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions