All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2][next] virt: acrn: Prefer array_size and struct_size over open coded arithmetic
@ 2021-10-23 10:15 Len Baker
  2021-10-25 22:22 ` Gustavo A. R. Silva
  0 siblings, 1 reply; 2+ messages in thread
From: Len Baker @ 2021-10-23 10:15 UTC (permalink / raw)
  To: Gustavo A. R. Silva, Fei Li
  Cc: Len Baker, Kees Cook, linux-hardening, linux-kernel

As noted in the "Deprecated Interfaces, Language Features, Attributes,
and Conventions" documentation [1], size calculations (especially
multiplication) should not be performed in memory allocator (or similar)
function arguments due to the risk of them overflowing. This could lead
to values wrapping around and a smaller allocation being made than the
caller was expecting. Using those allocations could lead to linear
overflows of heap memory and other misbehaviors.

So, use the array_size() helper to do the arithmetic instead of the
argument "count * size" in the vzalloc() function.

Also, take the opportunity to add a flexible array member of struct
vm_memory_region_op to the vm_memory_region_batch structure. And then,
change the code accordingly and use the struct_size() helper to do the
arithmetic instead of the argument "size + size * count" in the kzalloc
function.

This code was detected with the help of Coccinelle and audited and fixed
manually.

[1] https://www.kernel.org/doc/html/latest/process/deprecated.html#open-coded-arithmetic-in-allocator-arguments

Acked-by: Fei Li <fei1.li@intel.com>
Signed-off-by: Len Baker <len.baker@gmx.com>
---
Changelog v1 -> v2
- Fix the typo "syze -> size" in the subject (Kees Cook).
- Reduce the number of tabs in the definition of the structure
  vm_memory_region_batch (Fei Li).
- Add the "Acked-by" tag.

Hi Gustavo,

If there are no more comments in this version, can you take this patch?

Thanks,
Len

 drivers/virt/acrn/acrn_drv.h | 10 ++++++----
 drivers/virt/acrn/mm.c       |  9 ++++-----
 2 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/drivers/virt/acrn/acrn_drv.h b/drivers/virt/acrn/acrn_drv.h
index 1be54efa666c..5663c17ad37c 100644
--- a/drivers/virt/acrn/acrn_drv.h
+++ b/drivers/virt/acrn/acrn_drv.h
@@ -48,6 +48,7 @@ struct vm_memory_region_op {
  * @reserved:		Reserved.
  * @regions_num:	The number of vm_memory_region_op.
  * @regions_gpa:	Physical address of a vm_memory_region_op array.
+ * @regions_op:		Flexible array of vm_memory_region_op.
  *
  * HC_VM_SET_MEMORY_REGIONS uses this structure to manage EPT mappings of
  * multiple memory regions of a User VM. A &struct vm_memory_region_batch
@@ -55,10 +56,11 @@ struct vm_memory_region_op {
  * ACRN Hypervisor.
  */
 struct vm_memory_region_batch {
-	u16	vmid;
-	u16	reserved[3];
-	u32	regions_num;
-	u64	regions_gpa;
+	u16			   vmid;
+	u16			   reserved[3];
+	u32			   regions_num;
+	u64			   regions_gpa;
+	struct vm_memory_region_op regions_op[];
 };

 /**
diff --git a/drivers/virt/acrn/mm.c b/drivers/virt/acrn/mm.c
index c4f2e15c8a2b..a881742cd48d 100644
--- a/drivers/virt/acrn/mm.c
+++ b/drivers/virt/acrn/mm.c
@@ -168,7 +168,7 @@ int acrn_vm_ram_map(struct acrn_vm *vm, struct acrn_vm_memmap *memmap)

 	/* Get the page number of the map region */
 	nr_pages = memmap->len >> PAGE_SHIFT;
-	pages = vzalloc(nr_pages * sizeof(struct page *));
+	pages = vzalloc(array_size(nr_pages, sizeof(struct page *)));
 	if (!pages)
 		return -ENOMEM;

@@ -220,16 +220,15 @@ int acrn_vm_ram_map(struct acrn_vm *vm, struct acrn_vm_memmap *memmap)
 	}

 	/* Prepare the vm_memory_region_batch */
-	regions_info = kzalloc(sizeof(*regions_info) +
-			       sizeof(*vm_region) * nr_regions,
-			       GFP_KERNEL);
+	regions_info = kzalloc(struct_size(regions_info, regions_op,
+					   nr_regions), GFP_KERNEL);
 	if (!regions_info) {
 		ret = -ENOMEM;
 		goto unmap_kernel_map;
 	}

 	/* Fill each vm_memory_region_op */
-	vm_region = (struct vm_memory_region_op *)(regions_info + 1);
+	vm_region = regions_info->regions_op;
 	regions_info->vmid = vm->vmid;
 	regions_info->regions_num = nr_regions;
 	regions_info->regions_gpa = virt_to_phys(vm_region);
--
2.25.1


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH v2][next] virt: acrn: Prefer array_size and struct_size over open coded arithmetic
  2021-10-23 10:15 [PATCH v2][next] virt: acrn: Prefer array_size and struct_size over open coded arithmetic Len Baker
@ 2021-10-25 22:22 ` Gustavo A. R. Silva
  0 siblings, 0 replies; 2+ messages in thread
From: Gustavo A. R. Silva @ 2021-10-25 22:22 UTC (permalink / raw)
  To: Len Baker; +Cc: Fei Li, Kees Cook, linux-hardening, linux-kernel

On Sat, Oct 23, 2021 at 12:15:54PM +0200, Len Baker wrote:
[..]
> diff --git a/drivers/virt/acrn/mm.c b/drivers/virt/acrn/mm.c
> index c4f2e15c8a2b..a881742cd48d 100644
> --- a/drivers/virt/acrn/mm.c
> +++ b/drivers/virt/acrn/mm.c
> @@ -168,7 +168,7 @@ int acrn_vm_ram_map(struct acrn_vm *vm, struct acrn_vm_memmap *memmap)
> 
>  	/* Get the page number of the map region */
>  	nr_pages = memmap->len >> PAGE_SHIFT;
> -	pages = vzalloc(nr_pages * sizeof(struct page *));
> +	pages = vzalloc(array_size(nr_pages, sizeof(struct page *)));

This form is better:

	array_size(nr_pages, sizeof(*pages))

Thanks
--
Gustavo

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2021-10-25 22:17 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-23 10:15 [PATCH v2][next] virt: acrn: Prefer array_size and struct_size over open coded arithmetic Len Baker
2021-10-25 22:22 ` Gustavo A. R. Silva

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.