Re: [PATCH v2] params: fix charp corruption on allocation failure

Jiacheng Yu <[email protected]> Thu, 30 Jul 2026 09:27:28 +0800
Newsgroups org.kernel.vger.linux-modules,dev.linux.lists.sashiko-reviews
Message-ID <[email protected]>

On 29/07/2026 19:38, [email protected] wrote:
> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
> 
> Pre-existing issues:
> - [High] Use-After-Free race condition due to dangling global pointer during module parameter update.
> --
> 
> --- Patch [1]: [PATCH v2] params: fix charp corruption on allocation failure ---
> commit c59e6d7e9f9563e1394c57f9eedf07a9bb5f212b
> Author: Jiacheng Yu <[email protected]>
> 
> params: fix charp corruption on allocation failure
> 
> This patch fixes a corruption issue when param_set_charp() fails to allocate
> memory for the replacement string. It allocates and copies the replacement
> first, replacing the parameter value only after allocation succeeds.
> 
>> diff --git a/kernel/params.c b/kernel/params.c
>> index d3a4ecab4f278..8b25133fed242 100644
>> --- a/kernel/params.c
>> +++ b/kernel/params.c
> [ ... ]
>> @@ -269,19 +270,20 @@ int param_set_charp(const char *val, const struct kernel_param *kp)
>>  		return -ENOSPC;
>>  	}
>>  
>> -	maybe_kfree_parameter(*(char **)kp->arg);
>> -
>>  	/*
>>  	 * This is a hack. We can't kmalloc() in early boot, and we
>>  	 * don't need to; this mangled commandline is preserved.
>>  	 */
>>  	if (slab_is_available()) {
>> -		*(char **)kp->arg = kmalloc_parameter(len + 1);
>> -		if (!*(char **)kp->arg)
>> +		tmp = kmalloc_parameter(len + 1);
>> +		if (!tmp)
>>  			return -ENOMEM;
>> -		strcpy(*(char **)kp->arg, val);
>> +		memcpy(tmp, val, len + 1);
>>  	} else
>> -		*(const char **)kp->arg = val;
>> +		tmp = (char *)val;
>> +
>> +	maybe_kfree_parameter(*(char **)kp->arg);
>> +	*(char **)kp->arg = tmp;
> 
> [Severity: High]
> This isn't a bug introduced by this patch, but does this sequence leave a
> deterministic use-after-free window for concurrent readers?
> 
> Because maybe_kfree_parameter() frees the old string while the global
> parameter variable still points to it, any concurrent lockless reader of
> the parameter might dereference a freed pointer before the reassignment
> on the next line.

As Petr pointed out, concurrent access to a writable charp parameter
is protected by kernel_param_lock(), as documented in
include/linux/moduleparam.h.No reorder is needed here.

> 
> Could this be safely reordered to update the pointer before freeing the old
> memory? For example:
> 
> 	char *old = *(char **)kp->arg;
> 	*(char **)kp->arg = tmp;
> 	maybe_kfree_parameter(old);
> 
>>  
>>  	return 0;
>>  }
>