usb: usbfs: Enforce page requirements for mmap
commit 0143d148d1e882fb1538dc9974c94d63961719b9 upstream. The current implementation of usbdev_mmap uses usb_alloc_coherent to allocate memory pages that will later be mapped into the user space. Meanwhile, usb_alloc_coherent employs three different methods to allocate memory, as outlined below: * If hcd->localmem_pool is non-null, it uses gen_pool_dma_alloc to allocate memory; * If DMA is not available, it uses kmalloc to allocate memory; * Otherwise, it uses dma_alloc_coherent. However, it should be noted that gen_pool_dma_alloc does not guarantee that the resulting memory will be page-aligned. Furthermore, trying to map slab pages (i.e., memory allocated by kmalloc) into the user space is not resonable and can lead to problems, such as a type confusion bug when PAGE_TABLE_CHECK=y [1]. To address these issues, this patch introduces hcd_alloc_coherent_pages, which addresses the above two problems. Specifically, hcd_alloc_coherent_pages uses gen_pool_dma_alloc_align instead of gen_pool_dma_alloc to ensure that the memory is page-aligned. To replace kmalloc, hcd_alloc_coherent_pages directly allocates pages by calling __get_free_pages. Reported-by: syzbot+fcf1a817ceb50935ce99@syzkaller.appspotmail.comm Closes: https://lore.kernel.org/lkml/000000000000258e5e05fae79fc1@google.com/ [1] Fixes:f7d34b445a
("USB: Add support for usbfs zerocopy.") Fixes:ff2437befd
("usb: host: Fix excessive alignment restriction for local memory allocations") Cc: stable@vger.kernel.org Signed-off-by: Ruihan Li <lrh2000@pku.edu.cn> Acked-by: Alan Stern <stern@rowland.harvard.edu> Link: https://lore.kernel.org/r/20230515130958.32471-2-lrh2000@pku.edu.cn Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:

committed by
Greg Kroah-Hartman

parent
bcd474d183
commit
143f405721
@@ -504,6 +504,11 @@ void *hcd_buffer_alloc(struct usb_bus *bus, size_t size,
|
||||
void hcd_buffer_free(struct usb_bus *bus, size_t size,
|
||||
void *addr, dma_addr_t dma);
|
||||
|
||||
void *hcd_buffer_alloc_pages(struct usb_hcd *hcd,
|
||||
size_t size, gfp_t mem_flags, dma_addr_t *dma);
|
||||
void hcd_buffer_free_pages(struct usb_hcd *hcd,
|
||||
size_t size, void *addr, dma_addr_t dma);
|
||||
|
||||
/* generic bus glue, needed for host controllers that don't use PCI */
|
||||
extern irqreturn_t usb_hcd_irq(int irq, void *__hcd);
|
||||
|
||||
|
Reference in New Issue
Block a user