Message ID | 20180213144836.GU3443@dhcp22.suse.cz (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On 13/02/2018 15:48, Michal Hocko wrote: > On Thu 08-02-18 13:35:08, David Rientjes wrote: >> The KVM_SET_GSI_ROUTING ioctl does a vmalloc() of >> sizeof(struct kvm_irq_routing_entry) multiplied by a user-supplied value. >> This can be up to 4096 entries on architectures such as arm64 and s390 >> (and the upper bound may be increased on s390 eventually). >> >> This can produce a vmalloc allocation failure warning: >> >> vmalloc: allocation failure: 0 bytes, mode:0x24000c2(GFP_KERNEL|__GFP_HIGHMEM) > > I am not arguing about the kvm change but do we actaully want to warn > for 0 sized allocations? This just doesn't make much sense to me. > In other words don't we want this? > > diff --git a/mm/vmalloc.c b/mm/vmalloc.c > index 673942094328..c5d832510c54 100644 > --- a/mm/vmalloc.c > +++ b/mm/vmalloc.c > @@ -1748,7 +1748,9 @@ void *__vmalloc_node_range(unsigned long size, unsigned long align, > unsigned long real_size = size; > > size = PAGE_ALIGN(size); > - if (!size || (size >> PAGE_SHIFT) > totalram_pages) > + if (!size) > + return NULL; > + if ((size >> PAGE_SHIFT) > totalram_pages) > goto fail; > > area = __get_vm_area_node(size, align, VM_ALLOC | VM_UNINITIALIZED | > There have been quite a few reports of this from syzkaller and generally we've fixed them. It does seem like a recipe for NULL-pointer dereferences when the size is user-controlled (as in this case). But here I'm actually not sure that the "allocation failure: 0 bytes" can happen, since we have a check above for "if (routing.nr)", and there is a check also so that the maximum allocation here is a meager 128 KiB. So I'm wondering if this patch is obsolete actually after commit f8c1b85b2523. David? Thanks, Paolo Paolo
On Tue 13-02-18 16:03:09, Paolo Bonzini wrote: > On 13/02/2018 15:48, Michal Hocko wrote: > > On Thu 08-02-18 13:35:08, David Rientjes wrote: > >> The KVM_SET_GSI_ROUTING ioctl does a vmalloc() of > >> sizeof(struct kvm_irq_routing_entry) multiplied by a user-supplied value. > >> This can be up to 4096 entries on architectures such as arm64 and s390 > >> (and the upper bound may be increased on s390 eventually). > >> > >> This can produce a vmalloc allocation failure warning: > >> > >> vmalloc: allocation failure: 0 bytes, mode:0x24000c2(GFP_KERNEL|__GFP_HIGHMEM) > > > > I am not arguing about the kvm change but do we actaully want to warn > > for 0 sized allocations? This just doesn't make much sense to me. > > In other words don't we want this? > > > > diff --git a/mm/vmalloc.c b/mm/vmalloc.c > > index 673942094328..c5d832510c54 100644 > > --- a/mm/vmalloc.c > > +++ b/mm/vmalloc.c > > @@ -1748,7 +1748,9 @@ void *__vmalloc_node_range(unsigned long size, unsigned long align, > > unsigned long real_size = size; > > > > size = PAGE_ALIGN(size); > > - if (!size || (size >> PAGE_SHIFT) > totalram_pages) > > + if (!size) > > + return NULL; > > + if ((size >> PAGE_SHIFT) > totalram_pages) > > goto fail; > > > > area = __get_vm_area_node(size, align, VM_ALLOC | VM_UNINITIALIZED | > > > > There have been quite a few reports of this from syzkaller and generally > we've fixed them. It does seem like a recipe for NULL-pointer > dereferences when the size is user-controlled (as in this case). We do return NULL for that case regardless the above. The patch just doesn't warn. Or do you think it is helpful to warn?
On 13/02/2018 16:44, Michal Hocko wrote: > On Tue 13-02-18 16:03:09, Paolo Bonzini wrote: >> On 13/02/2018 15:48, Michal Hocko wrote: >>> On Thu 08-02-18 13:35:08, David Rientjes wrote: >>>> The KVM_SET_GSI_ROUTING ioctl does a vmalloc() of >>>> sizeof(struct kvm_irq_routing_entry) multiplied by a user-supplied value. >>>> This can be up to 4096 entries on architectures such as arm64 and s390 >>>> (and the upper bound may be increased on s390 eventually). >>>> >>>> This can produce a vmalloc allocation failure warning: >>>> >>>> vmalloc: allocation failure: 0 bytes, mode:0x24000c2(GFP_KERNEL|__GFP_HIGHMEM) >>> >>> I am not arguing about the kvm change but do we actaully want to warn >>> for 0 sized allocations? This just doesn't make much sense to me. >>> In other words don't we want this? >>> >>> diff --git a/mm/vmalloc.c b/mm/vmalloc.c >>> index 673942094328..c5d832510c54 100644 >>> --- a/mm/vmalloc.c >>> +++ b/mm/vmalloc.c >>> @@ -1748,7 +1748,9 @@ void *__vmalloc_node_range(unsigned long size, unsigned long align, >>> unsigned long real_size = size; >>> >>> size = PAGE_ALIGN(size); >>> - if (!size || (size >> PAGE_SHIFT) > totalram_pages) >>> + if (!size) >>> + return NULL; >>> + if ((size >> PAGE_SHIFT) > totalram_pages) >>> goto fail; >>> >>> area = __get_vm_area_node(size, align, VM_ALLOC | VM_UNINITIALIZED | >>> >> >> There have been quite a few reports of this from syzkaller and generally >> we've fixed them. It does seem like a recipe for NULL-pointer >> dereferences when the size is user-controlled (as in this case). > > We do return NULL for that case regardless the above. The patch just > doesn't warn. Or do you think it is helpful to warn? It certainly helps bringing potential issues in the spotlight (through fuzzing, mostly). Paolo
On Tue 13-02-18 16:49:20, Paolo Bonzini wrote: > On 13/02/2018 16:44, Michal Hocko wrote: > > On Tue 13-02-18 16:03:09, Paolo Bonzini wrote: [...] > >> There have been quite a few reports of this from syzkaller and generally > >> we've fixed them. It does seem like a recipe for NULL-pointer > >> dereferences when the size is user-controlled (as in this case). > > > > We do return NULL for that case regardless the above. The patch just > > doesn't warn. Or do you think it is helpful to warn? > > It certainly helps bringing potential issues in the spotlight (through > fuzzing, mostly). Fair enough.
diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 673942094328..c5d832510c54 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -1748,7 +1748,9 @@ void *__vmalloc_node_range(unsigned long size, unsigned long align, unsigned long real_size = size; size = PAGE_ALIGN(size); - if (!size || (size >> PAGE_SHIFT) > totalram_pages) + if (!size) + return NULL; + if ((size >> PAGE_SHIFT) > totalram_pages) goto fail; area = __get_vm_area_node(size, align, VM_ALLOC | VM_UNINITIALIZED |