Re: [PATCH v2 4/5] of: reserved_mem: release dynamically allocated no-map region on init failure

Wandun <[email protected]>
Newsgroups dev.linux.lists.sashiko-reviews,org.kernel.vger.linux-devicetree
Message-ID <[email protected]>

On 8/18/26 17:38, [email protected] wrote:
> Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
> 
> Pre-existing issues:
> - [High] `__reserved_mem_alloc_size()` ignores the error return value and checks `base == 0` for failure, leading to Use-After-Free of reserved memory regions.
> - [High] Statically allocated reserved memory is unconditionally freed back to the OS on driver initialization failure, violating the DT specification and causing memory corruption.
> --
> 
> --- Patch [4]: [PATCH v2 4/5] of: reserved_mem: release dynamically allocated no-map region on init failure ---
> commit cf35e3414292da4070c89965dbb1bce8416755e9
> Author: Wandun Chen <[email protected]>
> 
> of: reserved_mem: release dynamically allocated no-map region on init failure
> 
> Dynamically reserved-memory regions are added to memblock.reserved by
> memblock_phys_alloc_range() during __reserved_mem_alloc_size(). When a
> reserved-memory region's driver initialization fails,
> fdt_init_reserved_mem_node() cleans up the reservation. For no-map
> regions it only calls memblock_clear_nomap(), leaving the range in
> memblock.reserved and unavailable for normal memory use.
> 
> Fix it by freeing the region on init failure when it was dynamically
> allocated.
> 
> Sashiko found this issue in [1].
> 
> Link: https://sashiko.dev/#/message/20260806100605.2C2C01F000E9%40smtp.kernel.org [1]
> 
>> diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
>> --- a/drivers/of/of_reserved_mem.c
>> +++ b/drivers/of/of_reserved_mem.c
> 
> [ ... ]
> 
>> @@ -567,7 +568,7 @@ static int __init __reserved_mem_alloc_size(unsigned long node, const char *unam
>>  	}
>>  
>>  	fdt_fixup_reserved_mem_node(node, base, size);
>> -	fdt_init_reserved_mem_node(node, uname, base, size);
>> +	fdt_init_reserved_mem_node(node, uname, base, size, true);
>>  
>>  	return 0;
>>  }
> 
> [Severity: High]
> This is a pre-existing issue, but is it possible for
> __reserved_mem_alloc_size() to ignore the error return value from
> early_init_dt_alloc_reserved_memory_arch() and only check if base is 0 for
> failure?
> 
> If early_init_dt_alloc_reserved_memory_arch() fails after setting *res_base
> because memblock_mark_nomap() fails:
> 
> early_init_dt_alloc_reserved_memory_arch() {
>         ...
>         *res_base = base;
>         if (nomap) {
>                 err = memblock_mark_nomap(base, size);
>                 if (err)
>                         memblock_phys_free(base, size);
>         }
>         ...
> }
> 
> The base variable in __reserved_mem_alloc_size() will be non-zero, but the
> memory has already been freed. Since __reserved_mem_alloc_size() only checks
> if base is 0, it passes the error check and registers the freed memory.
> 
> Could this result in a use-after-free if the OS hands the memory out to
> other subsystems while it is still mapped or used by the reserved region?
> 

If too many nodes init fail, it will fallback to the current behavior.

> [ ... ]
> 
>> @@ -707,7 +710,8 @@ static void __init fdt_init_reserved_mem_node(unsigned long node, const char *un
>>  
>>  		if (nomap)
>>  			memblock_clear_nomap(rmem->base, rmem->size);
>> -		else
>> +
>> +		if (dynamic || !nomap)
>>  			memblock_phys_free(rmem->base, rmem->size);
>>  		return;
>>  	} else {
> 
> [Severity: High]
> This isn't a bug introduced by this patch, but could this logic
> unconditionally free statically allocated memory without the no-map
> property back to the general pool?
> 
> If a driver fails to initialize a statically defined reserved memory region,
> and the region does not have the no-map property, it is freed here.

This is pre-existing behavior for static non-no-map regions.
> 
> According to the Device Tree specification, if a driver fails to initialize,
> the OS must not use the memory for general purposes unless the reusable
> property is explicitly present.
> 
> Will this cause kernel memory corruption if the general buddy allocator
> hands this memory out to unrelated kernel subsystems, but the firmware or a
> coprocessor still expects the region to remain reserved and accesses it?
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.