Skip to content

Check if memory passed from user is writable #1

@stefanklug

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.

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