lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <5e45a1a9-4ac3-56ee-1415-0b2128b4ed9a@loongson.cn>
Date: Wed, 10 Sep 2025 09:11:52 +0800
From: Jinyang He <hejinyang@...ngson.cn>
To: Tiezhu Yang <yangtiezhu@...ngson.cn>
Cc: Josh Poimboeuf <jpoimboe@...nel.org>, Huacai Chen
 <chenhuacai@...nel.org>, Xi Zhang <zhangxi@...inos.cn>,
 live-patching@...r.kernel.org, loongarch@...ts.linux.dev,
 linux-kernel@...r.kernel.org
Subject: Re: [PATCH v1 2/2] LoongArch: Return 0 for user tasks in
 arch_stack_walk_reliable()

On 2025-09-09 19:31, Tiezhu Yang wrote:

> When testing the kernel live patching with "modprobe livepatch-sample",
> there is a timeout over 15 seconds from "starting patching transition"
> to "patching complete", dmesg shows "unreliable stack" for user tasks
> in debug mode. When executing "rmmod livepatch-sample", there exists
> the similar issue.
>
> Like x86, arch_stack_walk_reliable() should return 0 for user tasks.
> It is necessary to set regs->csr_prmd as task->thread.csr_prmd first,
> then use user_mode() to check whether the task is in userspace.
>
> Here are the call chains:
>
>    klp_enable_patch()
>      klp_try_complete_transition()
>        klp_try_switch_task()
>          klp_check_and_switch_task()
>            klp_check_stack()
>              stack_trace_save_tsk_reliable()
>                arch_stack_walk_reliable()
>
> With this patch, it takes a short time for patching and unpatching.
>
> Before:
>
>    # modprobe livepatch-sample
>    # dmesg -T | tail -3
>    [Sat Sep  6 11:00:20 2025] livepatch: 'livepatch_sample': starting patching transition
>    [Sat Sep  6 11:00:35 2025] livepatch: signaling remaining tasks
>    [Sat Sep  6 11:00:36 2025] livepatch: 'livepatch_sample': patching complete
>
>    # echo 0 > /sys/kernel/livepatch/livepatch_sample/enabled
>    # rmmod livepatch_sample
>    rmmod: ERROR: Module livepatch_sample is in use
>    # rmmod livepatch_sample
>    # dmesg -T | tail -3
>    [Sat Sep  6 11:06:05 2025] livepatch: 'livepatch_sample': starting unpatching transition
>    [Sat Sep  6 11:06:20 2025] livepatch: signaling remaining tasks
>    [Sat Sep  6 11:06:21 2025] livepatch: 'livepatch_sample': unpatching complete
>
> After:
>
>    # modprobe livepatch-sample
>    # dmesg -T | tail -2
>    [Sat Sep  6 11:19:00 2025] livepatch: 'livepatch_sample': starting patching transition
>    [Sat Sep  6 11:19:01 2025] livepatch: 'livepatch_sample': patching complete
>
>    # echo 0 > /sys/kernel/livepatch/livepatch_sample/enabled
>    # rmmod livepatch_sample
>    # dmesg -T | tail -2
>    [Sat Sep  6 11:21:10 2025] livepatch: 'livepatch_sample': starting unpatching transition
>    [Sat Sep  6 11:21:11 2025] livepatch: 'livepatch_sample': unpatching complete
>
> While at it, do the similar thing for arch_stack_walk() to avoid
> potential issues.
>
> Cc: stable@...r.kernel.org # v6.9+
> Fixes: 199cc14cb4f1 ("LoongArch: Add kernel livepatching support")
> Reported-by: Xi Zhang <zhangxi@...inos.cn>
> Signed-off-by: Tiezhu Yang <yangtiezhu@...ngson.cn>
> ---
>   arch/loongarch/kernel/stacktrace.c | 10 ++++++++++
>   1 file changed, 10 insertions(+)
>
> diff --git a/arch/loongarch/kernel/stacktrace.c b/arch/loongarch/kernel/stacktrace.c
> index 9a038d1070d7..0454cce3b667 100644
> --- a/arch/loongarch/kernel/stacktrace.c
> +++ b/arch/loongarch/kernel/stacktrace.c
> @@ -30,10 +30,15 @@ void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie,
>   		}
>   		regs->regs[1] = 0;
>   		regs->regs[22] = 0;
> +		regs->csr_prmd = task->thread.csr_prmd;
>   	}
>   
>   	for (unwind_start(&state, task, regs);
>   	     !unwind_done(&state); unwind_next_frame(&state)) {
> +		/* Success path for user tasks */
> +		if (user_mode(regs))
> +			return;
> +
>   		addr = unwind_get_return_address(&state);
>   		if (!addr || !consume_entry(cookie, addr))
>   			break;
> @@ -57,9 +62,14 @@ int arch_stack_walk_reliable(stack_trace_consume_fn consume_entry,
>   	}
>   	regs->regs[1] = 0;
>   	regs->regs[22] = 0;
> +	regs->csr_prmd = task->thread.csr_prmd;
>   
>   	for (unwind_start(&state, task, regs);
>   	     !unwind_done(&state) && !unwind_error(&state); unwind_next_frame(&state)) {
> +		/* Success path for user tasks */
> +		if (user_mode(regs))
> +			return 0;
> +
>   		addr = unwind_get_return_address(&state);
>   
>   		/*
Hi, Tiezhu,

We update stack info by get_stack_info when meet ORC_TYPE_REGS in
unwind_next_frame. And in arch_stack_walk(_reliable), we always
do unwind_done before unwind_next_frame. So is there anything
error in get_stack_info which causing regs is user_mode while
stack is not STACK_TYPE_UNKNOWN?


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ