[PATCH] resource: use kstrdup_const to prevent wild pointer issues
From: kingdix10
Date: Wed Jan 01 2025 - 08:54:30 EST
From: King Dix <kingdix10@xxxxxx>
When a stack string variable is passed during the request resource
operation, it causes an oops problem when executing cat /proc/iomem.
In the original code, in functions like __request_region_locked, the name
member of the resource structure was directly assigned the stack string
pointer without proper memory management.
This fix changes the assignment of res->name to use kstrdup_const for
string copying, ensuring the correct storage and release of the string
and thus avoiding potential memory errors and oops issues.
Signed-off-by: King Dix <kingdix10@xxxxxx>
---
kernel/resource.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/kernel/resource.c b/kernel/resource.c
index b7c0e24d9398..87d22741c066 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -168,8 +168,10 @@ static void free_resource(struct resource *res)
* buddy and trying to be smart and reusing them eventually in
* alloc_resource() overcomplicates resource handling.
*/
- if (res && PageSlab(virt_to_head_page(res)))
+ if (res && PageSlab(virt_to_head_page(res))) {
+ kfree_const(res->name);
kfree(res);
+ }
}
static struct resource *alloc_resource(gfp_t flags)
@@ -1098,7 +1100,7 @@ __reserve_region_with_split(struct resource *root, resource_size_t start,
if (!res)
return;
- res->name = name;
+ res->name = kstrdup_const(name, GFP_ATOMIC);
res->start = start;
res->end = end;
res->flags = type | IORESOURCE_BUSY;
@@ -1133,7 +1135,7 @@ __reserve_region_with_split(struct resource *root, resource_size_t start,
free_resource(res);
break;
}
- next_res->name = name;
+ next_res->name = kstrdup_const(name, GFP_ATOMIC);
next_res->start = conflict->end + 1;
next_res->end = end;
next_res->flags = type | IORESOURCE_BUSY;
@@ -1261,7 +1263,7 @@ static int __request_region_locked(struct resource *res, struct resource *parent
{
DECLARE_WAITQUEUE(wait, current);
- res->name = name;
+ res->name = kstrdup_const(name, GFP_KERNEL);
res->start = start;
res->end = start + n - 1;
@@ -1474,7 +1476,7 @@ void release_mem_region_adjustable(resource_size_t start, resource_size_t size)
goto retry;
}
}
- new_res->name = res->name;
+ new_res->name = kstrdup_const(res->name, GFP_ATOMIC);
new_res->start = end + 1;
new_res->end = res->end;
new_res->flags = res->flags;
@@ -1978,7 +1980,7 @@ get_free_mem_region(struct device *dev, struct resource *base,
} else {
res->start = addr;
res->end = addr + size - 1;
- res->name = name;
+ res->name = kstrdup_const(name, GFP_KERNEL);
res->desc = desc;
res->flags = IORESOURCE_MEM;
--
2.43.0