Skip to contentSkip to conversation

module/decompress: Adjust module_extend_max_pages() allocation type

PATCH In review Kees Cook 2 participants 3 messages Apr 26, 2025 – Apr 30, 2025 Module support

lore
Share & tools
lore

Kees Cook

author
#0 lore raw

PATCH 1/1 module/decompress: Adjust module_extend_max_pages() allocation type

In preparation for making the kmalloc family of allocators type aware, we need to make sure that the returned type from the allocation matches the type of the variable being assigned. (Before, the allocator would always return "void *", which can be implicitly cast to any pointer type.)

The assigned type is "struct page **" but the returned type will be "struct page ***". These have the same allocation size (pointer size), but the types don't match. Adjust the allocation type to match the assignment.

---
Cc: Luis Chamberlain <[email protected]>
Cc: Petr Pavlu <[email protected]>
Cc: Sami Tolvanen <[email protected]>
Cc: Daniel Gomez <[email protected]>
Cc: <[email protected]>

---
 kernel/module/decompress.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/module/decompress.c +1 -1
index 474e68f0f063..bbb2a55568cd 100644
@@ -19,7 +19,7 @@ static int module_extend_max_pages(struct load_info *info, unsigned int extent)
 	struct page **new_pages;
 
 	new_pages = kvmalloc_array(info->max_pages + extent,
-				   sizeof(info->pages), GFP_KERNEL);
+				   sizeof(*new_pages), GFP_KERNEL);
 	if (!new_pages)
 		return -ENOMEM;
 
Signature · 1 line
2.34.1
maintainer
#1 lore raw
Quoted 25 lines · Kees Cook

In preparation for making the kmalloc family of allocators type aware, we need to make sure that the returned type from the allocation matches the type of the variable being assigned. (Before, the allocator would always return "void *", which can be implicitly cast to any pointer type.)

The assigned type is "struct page **" but the returned type will be "struct page ***". These have the same allocation size (pointer size), but the types don't match. Adjust the allocation type to match the assignment.

---
Cc: Luis Chamberlain <[email protected]>
Cc: Petr Pavlu <[email protected]>
Cc: Sami Tolvanen <[email protected]>
Cc: Daniel Gomez <[email protected]>
Cc: <[email protected]>

---
 kernel/module/decompress.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/module/decompress.c +0 -0
index 474e68f0f063..bbb2a55568cd 100644

kernel/module/decompress.c static int module_extend_max_pages(struct load_info *info, unsigned int extent) · line 25

Quoted 8 lines
kernel/module/decompress.c +1 -1
@@ -19,7 +19,7 @@ static int module_extend_max_pages(struct load_info *info, unsigned int extent)
 	struct page **new_pages;
 
 	new_pages = kvmalloc_array(info->max_pages + extent,
-				   sizeof(info->pages), GFP_KERNEL);
+				   sizeof(*new_pages), GFP_KERNEL);
 	if (!new_pages)
 		return -ENOMEM;
 

The function has a similar type mismatch a few lines below:

memcpy(new_pages, info->pages, info->max_pages * sizeof(info->pages));

The sizeof operator is used on 'struct page **', but it should be really on 'struct page *'.

Could you please fix this as well? For consistency with your patch, I suggest changing it to 'sizeof(*new_pages)'.

Signature · 2 lines
Thanks,
Petr
author
#2 lore raw
Quoted 37 lines · Petr Pavlu
Quoted 25 lines · Kees Cook

In preparation for making the kmalloc family of allocators type aware, we need to make sure that the returned type from the allocation matches the type of the variable being assigned. (Before, the allocator would always return "void *", which can be implicitly cast to any pointer type.)

The assigned type is "struct page **" but the returned type will be "struct page ***". These have the same allocation size (pointer size), but the types don't match. Adjust the allocation type to match the assignment.

---
Cc: Luis Chamberlain <[email protected]>
Cc: Petr Pavlu <[email protected]>
Cc: Sami Tolvanen <[email protected]>
Cc: Daniel Gomez <[email protected]>
Cc: <[email protected]>

---
 kernel/module/decompress.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/module/decompress.c +0 -0
index 474e68f0f063..bbb2a55568cd 100644

kernel/module/decompress.c static int module_extend_max_pages(struct load_info *info, unsigned int extent) · line 25

Quoted 8 lines
kernel/module/decompress.c +1 -1
@@ -19,7 +19,7 @@ static int module_extend_max_pages(struct load_info *info, unsigned int extent)
 	struct page **new_pages;
 
 	new_pages = kvmalloc_array(info->max_pages + extent,
-				   sizeof(info->pages), GFP_KERNEL);
+				   sizeof(*new_pages), GFP_KERNEL);
 	if (!new_pages)
 		return -ENOMEM;
 

The function has a similar type mismatch a few lines below:

Quoted 7 lines

memcpy(new_pages, info->pages, info->max_pages * sizeof(info->pages));

The sizeof operator is used on 'struct page **', but it should be really on 'struct page *'.

Could you please fix this as well? For consistency with your patch, I suggest changing it to 'sizeof(*new_pages)'.

Actually, this whole function is basically just open-coded kvrealloc... I will send a v2.

Signature · 1 line
Kees Cook