On Tue, Dec 1, 2020 at 9:21 PM Arnd Bergmann <[email protected]> wrote: > > On Mon, Nov 23, 2020 at 10:01 PM Norbert Slusarek <[email protected]> wrote: > > > > From: Norbert Slusarek <[email protected]> > > Date: Mon, 23 Nov 2020 21:53:41 +0100 > > Subject: [PATCH RESEND] misc/vmw_vmci: bail out earlier on too big queue > > allocation > > > > For the allocation of a queue pair in qp_host_alloc_queue() an arbitrary > > value > > can be passed for produce_size, which can lead to miscalculation of memory > > we'd > > like to allocate in one take. A warning is triggered at > > __alloc_pages_nodemask() > > in mm/page_alloc.c:4737 which aborts the false allocation, but it results > > in a > > VMware machine freezing for an infinite time. > > > > Signed-off-by: Norbert Slusarek <[email protected]> > > Thank you for sending a patch with such a detailed analysis and even > including a test case!
Yeah agree, very good details! > > > diff --git a/drivers/misc/vmw_vmci/vmci_queue_pair.c > > b/drivers/misc/vmw_vmci/vmci_queue_pair.c > > index c49065887e8f..997ff32475b2 100644 > > --- a/drivers/misc/vmw_vmci/vmci_queue_pair.c > > +++ b/drivers/misc/vmw_vmci/vmci_queue_pair.c > > @@ -526,6 +526,7 @@ static struct vmci_queue *qp_host_alloc_queue(u64 size) > > struct vmci_queue *queue; > > size_t queue_page_size; > > u64 num_pages; > > + unsigned int order; > > const size_t queue_size = sizeof(*queue) + > > sizeof(*(queue->kernel_if)); > > > > if (size > SIZE_MAX - PAGE_SIZE) > > @@ -537,6 +538,10 @@ static struct vmci_queue *qp_host_alloc_queue(u64 size) > > > > queue_page_size = num_pages * sizeof(*queue->kernel_if->u.h.page); > > > > + order = get_order(queue_size + queue_page_size); > > + if (order >= MAX_ORDER) > > + return NULL; > > + > > queue = kzalloc(queue_size + queue_page_size, GFP_KERNEL); > > Calling kzalloc() with that user-provided size may still not be a great > idea, and MAX_ORDER is probably more than anyone ever needs here > (I don't know what the interface is needed for, but usually it is). > > If there is a reasonable upper bound smaller than MAX_ORDER, I > would suggest using that. It might also be helpful to use kvzalloc()/kvfree() > in this case, which can return an arbitrary number of pages > and suffers less from fragmentation. I don't know well vmw_vmci, but I took a brief look, and I saw that there is a macro (VMCI_MAX_GUEST_QP_MEMORY) used in vmci_qpair_alloc(), I'm not sure if we can use the same macro, but maybe something similar. Honestly I don't know where that limit comes from, maybe it was chosen as an arbitrary and reasonable value but I suggest to check if we can reuse the same macro here with some adjustments. I think in some way that limit is related to the max memory that the host should allocate. @Jorgen any thought? Thanks, Stefano > > Note that both kzalloc() and kvzalloc() will fail for much smaller > sizes if the kernel is low on memory, so that might have the same > problem. > > Arnd >

