diff mbox series

proc_sysclt: fix oops caused by incorrect command parameters.

Message ID 20201224074256.117413-1-nixiaoming@huawei.com (mailing list archive)
State New, archived
Headers show
Series proc_sysclt: fix oops caused by incorrect command parameters. | expand

Commit Message

Nixiaoming Dec. 24, 2020, 7:42 a.m. UTC
The process_sysctl_arg() does not check whether val is empty before
 invoking strlen(val). If the command line parameter () is incorrectly
 configured and val is empty, oops is triggered.

For example, "hung_task_panic=1" is incorrectly written as "hung_task_panic".

log:
	Kernel command line: .... hung_task_panic
	....
	[000000000000000n] user address but active_mm is swapper
	Internal error: Oops: 96000005 [#1] SMP
	Modules linked in:
	CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.10.1 #1
	Hardware name: linux,dummy-virt (DT)
	pstate: 40000005 (nZcv daif -PAN -UAO -TCO BTYPE=--)
	pc : __pi_strlen+0x10/0x98
	lr : process_sysctl_arg+0x1e4/0x2ac
	sp : ffffffc01104bd40
	x29: ffffffc01104bd40 x28: 0000000000000000
	x27: ffffff80c0a4691e x26: ffffffc0102a7c8c
	x25: 0000000000000000 x24: ffffffc01104be80
	x23: ffffff80c22f0b00 x22: ffffff80c02e28c0
	x21: ffffffc0109f9000 x20: 0000000000000000
	x19: ffffffc0107c08de x18: 0000000000000003
	x17: ffffffc01105d000 x16: 0000000000000054
	x15: ffffffffffffffff x14: 3030253078413830
	x13: 000000000000ffff x12: 0000000000000000
	x11: 0101010101010101 x10: 0000000000000005
	x9 : 0000000000000003 x8 : ffffff80c0980c08
	x7 : 0000000000000000 x6 : 0000000000000002
	x5 : ffffff80c0235000 x4 : ffffff810f7c7ee0
	x3 : 000000000000043a x2 : 00bdcc4ebacf1a54
	x1 : 0000000000000000 x0 : 0000000000000000
	Call trace:
	 __pi_strlen+0x10/0x98
	 parse_args+0x278/0x344
	 do_sysctl_args+0x8c/0xfc
	 kernel_init+0x5c/0xf4
	 ret_from_fork+0x10/0x30
	Code: b200c3eb 927cec01 f2400c07 54000301 (a8c10c22)

Fixes: 3db978d480e2843 ("kernel/sysctl: support setting sysctl parameters
 from kernel command line")
Signed-off-by: Xiaoming Ni <nixiaoming@huawei.com>
---
 fs/proc/proc_sysctl.c | 3 +++
 1 file changed, 3 insertions(+)

Comments

Nixiaoming Jan. 4, 2021, 6:19 a.m. UTC | #1
ping


On 2020/12/24 15:42, Xiaoming Ni wrote:
> The process_sysctl_arg() does not check whether val is empty before
>   invoking strlen(val). If the command line parameter () is incorrectly
>   configured and val is empty, oops is triggered.
> 
> For example, "hung_task_panic=1" is incorrectly written as "hung_task_panic".
> 
> log:
> 	Kernel command line: .... hung_task_panic
> 	....
> 	[000000000000000n] user address but active_mm is swapper
> 	Internal error: Oops: 96000005 [#1] SMP
> 	Modules linked in:
> 	CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.10.1 #1
> 	Hardware name: linux,dummy-virt (DT)
> 	pstate: 40000005 (nZcv daif -PAN -UAO -TCO BTYPE=--)
> 	pc : __pi_strlen+0x10/0x98
> 	lr : process_sysctl_arg+0x1e4/0x2ac
> 	sp : ffffffc01104bd40
> 	x29: ffffffc01104bd40 x28: 0000000000000000
> 	x27: ffffff80c0a4691e x26: ffffffc0102a7c8c
> 	x25: 0000000000000000 x24: ffffffc01104be80
> 	x23: ffffff80c22f0b00 x22: ffffff80c02e28c0
> 	x21: ffffffc0109f9000 x20: 0000000000000000
> 	x19: ffffffc0107c08de x18: 0000000000000003
> 	x17: ffffffc01105d000 x16: 0000000000000054
> 	x15: ffffffffffffffff x14: 3030253078413830
> 	x13: 000000000000ffff x12: 0000000000000000
> 	x11: 0101010101010101 x10: 0000000000000005
> 	x9 : 0000000000000003 x8 : ffffff80c0980c08
> 	x7 : 0000000000000000 x6 : 0000000000000002
> 	x5 : ffffff80c0235000 x4 : ffffff810f7c7ee0
> 	x3 : 000000000000043a x2 : 00bdcc4ebacf1a54
> 	x1 : 0000000000000000 x0 : 0000000000000000
> 	Call trace:
> 	 __pi_strlen+0x10/0x98
> 	 parse_args+0x278/0x344
> 	 do_sysctl_args+0x8c/0xfc
> 	 kernel_init+0x5c/0xf4
> 	 ret_from_fork+0x10/0x30
> 	Code: b200c3eb 927cec01 f2400c07 54000301 (a8c10c22)
> 
> Fixes: 3db978d480e2843 ("kernel/sysctl: support setting sysctl parameters
>   from kernel command line")
> Signed-off-by: Xiaoming Ni <nixiaoming@huawei.com>
> ---
>   fs/proc/proc_sysctl.c | 3 +++
>   1 file changed, 3 insertions(+)
> 
> diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c
> index 317899222d7f..4516411a2b44 100644
> --- a/fs/proc/proc_sysctl.c
> +++ b/fs/proc/proc_sysctl.c
> @@ -1757,6 +1757,9 @@ static int process_sysctl_arg(char *param, char *val,
>   	loff_t pos = 0;
>   	ssize_t wret;
>   
> +	if (!val)
> +		return 0;
> +
>   	if (strncmp(param, "sysctl", sizeof("sysctl") - 1) == 0) {
>   		param += sizeof("sysctl") - 1;
>   
>
Kees Cook Jan. 6, 2021, 11:46 p.m. UTC | #2
subject typo: "sysclt" -> "sysctl"

On Thu, Dec 24, 2020 at 03:42:56PM +0800, Xiaoming Ni wrote:
> The process_sysctl_arg() does not check whether val is empty before
>  invoking strlen(val). If the command line parameter () is incorrectly
>  configured and val is empty, oops is triggered.
> 
> For example, "hung_task_panic=1" is incorrectly written as "hung_task_panic".
> 
> log:
> 	Kernel command line: .... hung_task_panic
> 	....
> 	[000000000000000n] user address but active_mm is swapper
> 	Internal error: Oops: 96000005 [#1] SMP
> 	Modules linked in:
> 	CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.10.1 #1
> 	Hardware name: linux,dummy-virt (DT)
> 	pstate: 40000005 (nZcv daif -PAN -UAO -TCO BTYPE=--)
> 	pc : __pi_strlen+0x10/0x98
> 	lr : process_sysctl_arg+0x1e4/0x2ac
> 	sp : ffffffc01104bd40
> 	x29: ffffffc01104bd40 x28: 0000000000000000
> 	x27: ffffff80c0a4691e x26: ffffffc0102a7c8c
> 	x25: 0000000000000000 x24: ffffffc01104be80
> 	x23: ffffff80c22f0b00 x22: ffffff80c02e28c0
> 	x21: ffffffc0109f9000 x20: 0000000000000000
> 	x19: ffffffc0107c08de x18: 0000000000000003
> 	x17: ffffffc01105d000 x16: 0000000000000054
> 	x15: ffffffffffffffff x14: 3030253078413830
> 	x13: 000000000000ffff x12: 0000000000000000
> 	x11: 0101010101010101 x10: 0000000000000005
> 	x9 : 0000000000000003 x8 : ffffff80c0980c08
> 	x7 : 0000000000000000 x6 : 0000000000000002
> 	x5 : ffffff80c0235000 x4 : ffffff810f7c7ee0
> 	x3 : 000000000000043a x2 : 00bdcc4ebacf1a54
> 	x1 : 0000000000000000 x0 : 0000000000000000
> 	Call trace:
> 	 __pi_strlen+0x10/0x98
> 	 parse_args+0x278/0x344
> 	 do_sysctl_args+0x8c/0xfc
> 	 kernel_init+0x5c/0xf4
> 	 ret_from_fork+0x10/0x30
> 	Code: b200c3eb 927cec01 f2400c07 54000301 (a8c10c22)
> 
> Fixes: 3db978d480e2843 ("kernel/sysctl: support setting sysctl parameters
>  from kernel command line")
> Signed-off-by: Xiaoming Ni <nixiaoming@huawei.com>
> ---
>  fs/proc/proc_sysctl.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c
> index 317899222d7f..4516411a2b44 100644
> --- a/fs/proc/proc_sysctl.c
> +++ b/fs/proc/proc_sysctl.c
> @@ -1757,6 +1757,9 @@ static int process_sysctl_arg(char *param, char *val,
>  	loff_t pos = 0;
>  	ssize_t wret;
>  
> +	if (!val)
> +		return 0;
> +
>  	if (strncmp(param, "sysctl", sizeof("sysctl") - 1) == 0) {
>  		param += sizeof("sysctl") - 1;

Otherwise, yeah, this is a good test to add. I would make it more
verbose, though:

	if (!val) {
		pr_err("Missing param value! Expected '%s=...value...'\n", param);
		return 0;
	}
Nixiaoming Jan. 7, 2021, 6:14 a.m. UTC | #3
On 2021/1/7 7:46, Kees Cook wrote:
> subject typo: "sysclt" -> "sysctl"
> 
> On Thu, Dec 24, 2020 at 03:42:56PM +0800, Xiaoming Ni wrote:
>> The process_sysctl_arg() does not check whether val is empty before
>>   invoking strlen(val). If the command line parameter () is incorrectly
>>   configured and val is empty, oops is triggered.
>>
>> For example, "hung_task_panic=1" is incorrectly written as "hung_task_panic".
>>
>> log:
>> 	Kernel command line: .... hung_task_panic
>> 	....
>> 	[000000000000000n] user address but active_mm is swapper
>> 	Internal error: Oops: 96000005 [#1] SMP
>> 	Modules linked in:
>> 	CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.10.1 #1
>> 	Hardware name: linux,dummy-virt (DT)
>> 	pstate: 40000005 (nZcv daif -PAN -UAO -TCO BTYPE=--)
>> 	pc : __pi_strlen+0x10/0x98
>> 	lr : process_sysctl_arg+0x1e4/0x2ac
>> 	sp : ffffffc01104bd40
>> 	x29: ffffffc01104bd40 x28: 0000000000000000
>> 	x27: ffffff80c0a4691e x26: ffffffc0102a7c8c
>> 	x25: 0000000000000000 x24: ffffffc01104be80
>> 	x23: ffffff80c22f0b00 x22: ffffff80c02e28c0
>> 	x21: ffffffc0109f9000 x20: 0000000000000000
>> 	x19: ffffffc0107c08de x18: 0000000000000003
>> 	x17: ffffffc01105d000 x16: 0000000000000054
>> 	x15: ffffffffffffffff x14: 3030253078413830
>> 	x13: 000000000000ffff x12: 0000000000000000
>> 	x11: 0101010101010101 x10: 0000000000000005
>> 	x9 : 0000000000000003 x8 : ffffff80c0980c08
>> 	x7 : 0000000000000000 x6 : 0000000000000002
>> 	x5 : ffffff80c0235000 x4 : ffffff810f7c7ee0
>> 	x3 : 000000000000043a x2 : 00bdcc4ebacf1a54
>> 	x1 : 0000000000000000 x0 : 0000000000000000
>> 	Call trace:
>> 	 __pi_strlen+0x10/0x98
>> 	 parse_args+0x278/0x344
>> 	 do_sysctl_args+0x8c/0xfc
>> 	 kernel_init+0x5c/0xf4
>> 	 ret_from_fork+0x10/0x30
>> 	Code: b200c3eb 927cec01 f2400c07 54000301 (a8c10c22)
>>
>> Fixes: 3db978d480e2843 ("kernel/sysctl: support setting sysctl parameters
>>   from kernel command line")
>> Signed-off-by: Xiaoming Ni <nixiaoming@huawei.com>
>> ---
>>   fs/proc/proc_sysctl.c | 3 +++
>>   1 file changed, 3 insertions(+)
>>
>> diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c
>> index 317899222d7f..4516411a2b44 100644
>> --- a/fs/proc/proc_sysctl.c
>> +++ b/fs/proc/proc_sysctl.c
>> @@ -1757,6 +1757,9 @@ static int process_sysctl_arg(char *param, char *val,
>>   	loff_t pos = 0;
>>   	ssize_t wret;
>>   
>> +	if (!val)
>> +		return 0;
>> +
>>   	if (strncmp(param, "sysctl", sizeof("sysctl") - 1) == 0) {
>>   		param += sizeof("sysctl") - 1;
> 
> Otherwise, yeah, this is a good test to add. I would make it more
> verbose, though:
> 
> 	if (!val) {
> 		pr_err("Missing param value! Expected '%s=...value...'\n", param);
> 		return 0;
> 	}
> 
Yes, it's better to add log output.
Thank you for your review.
Do I need to send V2 patch based on review comments?

Thanks
Xiaoming Ni
Kees Cook Jan. 7, 2021, 9:08 p.m. UTC | #4
On Thu, Jan 07, 2021 at 02:14:18PM +0800, Xiaoming Ni wrote:
> On 2021/1/7 7:46, Kees Cook wrote:
> > subject typo: "sysclt" -> "sysctl"
> > 
> > On Thu, Dec 24, 2020 at 03:42:56PM +0800, Xiaoming Ni wrote:
> > > [...]
> > > +	if (!val)
> > > +		return 0;
> > > +
> > >   	if (strncmp(param, "sysctl", sizeof("sysctl") - 1) == 0) {
> > >   		param += sizeof("sysctl") - 1;
> > 
> > Otherwise, yeah, this is a good test to add. I would make it more
> > verbose, though:
> > 
> > 	if (!val) {
> > 		pr_err("Missing param value! Expected '%s=...value...'\n", param);
> > 		return 0;
> > 	}
> > 
> Yes, it's better to add log output.
> Thank you for your review.
> Do I need to send V2 patch based on review comments?

Yes please. :)
diff mbox series

Patch

diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c
index 317899222d7f..4516411a2b44 100644
--- a/fs/proc/proc_sysctl.c
+++ b/fs/proc/proc_sysctl.c
@@ -1757,6 +1757,9 @@  static int process_sysctl_arg(char *param, char *val,
 	loff_t pos = 0;
 	ssize_t wret;
 
+	if (!val)
+		return 0;
+
 	if (strncmp(param, "sysctl", sizeof("sysctl") - 1) == 0) {
 		param += sizeof("sysctl") - 1;