[PATCH v2] rseq: fix using an uninitialized stack variable in rseq_exit_user_update

Qing Wang posted 1 patch 6 days ago
include/linux/rseq_entry.h | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
[PATCH v2] rseq: fix using an uninitialized stack variable in rseq_exit_user_update
Posted by Qing Wang 6 days ago
There is an bug which is an uninitialized stack variable use in
`rseq_exit_user_update()` reported by syzbot:

BUG: KMSAN: kernel-infoleak in rseq_set_ids_get_csaddr include/linux/rseq_entry.h:502 [inline]

The local variable:
```c
	struct rseq_ids ids = {
		.cpu_id	 = task_cpu(t),
		.mm_cid	 = task_mm_cid(t),
		.node_id = cpu_to_node(ids.cpu_id),
	};
```
According to the C standard, the evaluation order of expressions in an
initializer list is indeterminately sequenced. The compiler (Clang, in this
KMSAN build) evaluates `cpu_to_node(ids.cpu_id)` *before* `ids.cpu_id` is
initialized with `task_cpu(t)`.

This is fixed by moving the assignment of ids.node_id outside the structure
initialization.

Reported-by: syzbot+185a631927096f9da2fc@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=185a631927096f9da2fc
Fixes: 82f572449cfe ("rseq: Implement read only ABI enforcement for optimized RSEQ V2 mode")
Signed-off-by: Qing Wang <wangqing7171@gmail.com>
---
 include/linux/rseq_entry.h | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/include/linux/rseq_entry.h b/include/linux/rseq_entry.h
index 63bc72086e75..ed9da6e41a2a 100644
--- a/include/linux/rseq_entry.h
+++ b/include/linux/rseq_entry.h
@@ -635,10 +635,11 @@ static __always_inline bool rseq_exit_user_update(struct pt_regs *regs, struct t
 		return true;
 	}
 
+	int cpu = task_cpu(t);
 	struct rseq_ids ids = {
-		.cpu_id	 = task_cpu(t),
+		.cpu_id	 = cpu,
 		.mm_cid	 = task_mm_cid(t),
-		.node_id = cpu_to_node(ids.cpu_id),
+		.node_id = cpu_to_node(cpu),
 	};
 
 	return rseq_update_usr(t, regs, &ids);
-- 
2.34.1
Re: [PATCH v2] rseq: fix using an uninitialized stack variable in rseq_exit_user_update
Posted by Peter Zijlstra 5 days, 16 hours ago
On Tue, Jun 02, 2026 at 11:08:54AM +0800, Qing Wang wrote:
> There is an bug which is an uninitialized stack variable use in
> `rseq_exit_user_update()` reported by syzbot:
> 
> BUG: KMSAN: kernel-infoleak in rseq_set_ids_get_csaddr include/linux/rseq_entry.h:502 [inline]
> 
> The local variable:
> ```c
> 	struct rseq_ids ids = {
> 		.cpu_id	 = task_cpu(t),
> 		.mm_cid	 = task_mm_cid(t),
> 		.node_id = cpu_to_node(ids.cpu_id),
> 	};
> ```

FWIW, I've no idea what that ``` nonsense is, but it does not belong in
Changelogs. I've removed it.
Re: [PATCH v2] rseq: fix using an uninitialized stack variable in rseq_exit_user_update
Posted by Mark Rutland 5 days, 17 hours ago
On Tue, Jun 02, 2026 at 11:08:54AM +0800, Qing Wang wrote:
> There is an bug which is an uninitialized stack variable use in
> `rseq_exit_user_update()` reported by syzbot:
> 
> BUG: KMSAN: kernel-infoleak in rseq_set_ids_get_csaddr include/linux/rseq_entry.h:502 [inline]
> 
> The local variable:
> ```c
> 	struct rseq_ids ids = {
> 		.cpu_id	 = task_cpu(t),
> 		.mm_cid	 = task_mm_cid(t),
> 		.node_id = cpu_to_node(ids.cpu_id),
> 	};
> ```
> According to the C standard, the evaluation order of expressions in an
> initializer list is indeterminately sequenced. The compiler (Clang, in this
> KMSAN build) evaluates `cpu_to_node(ids.cpu_id)` *before* `ids.cpu_id` is
> initialized with `task_cpu(t)`.
> 
> This is fixed by moving the assignment of ids.node_id outside the structure
> initialization.
> 
> Reported-by: syzbot+185a631927096f9da2fc@syzkaller.appspotmail.com
> Closes: https://syzkaller.appspot.com/bug?extid=185a631927096f9da2fc
> Fixes: 82f572449cfe ("rseq: Implement read only ABI enforcement for optimized RSEQ V2 mode")
> Signed-off-by: Qing Wang <wangqing7171@gmail.com>

FWIW, this looks sane to me, so:

Acked-by: Mark Rutland <mark.rutland@arm.com>

Mark.

> ---
>  include/linux/rseq_entry.h | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/include/linux/rseq_entry.h b/include/linux/rseq_entry.h
> index 63bc72086e75..ed9da6e41a2a 100644
> --- a/include/linux/rseq_entry.h
> +++ b/include/linux/rseq_entry.h
> @@ -635,10 +635,11 @@ static __always_inline bool rseq_exit_user_update(struct pt_regs *regs, struct t
>  		return true;
>  	}
>  
> +	int cpu = task_cpu(t);
>  	struct rseq_ids ids = {
> -		.cpu_id	 = task_cpu(t),
> +		.cpu_id	 = cpu,
>  		.mm_cid	 = task_mm_cid(t),
> -		.node_id = cpu_to_node(ids.cpu_id),
> +		.node_id = cpu_to_node(cpu),
>  	};
>  
>  	return rseq_update_usr(t, regs, &ids);
> -- 
> 2.34.1
>
[tip: sched/urgent] rseq: Fix using an uninitialized stack variable in rseq_exit_user_update()
Posted by tip-bot2 for Qing Wang 5 days, 16 hours ago
The following commit has been merged into the sched/urgent branch of tip:

Commit-ID:     6d99479799c69c3cb588fcda19c81d8f61d64ecd
Gitweb:        https://git.kernel.org/tip/6d99479799c69c3cb588fcda19c81d8f61d64ecd
Author:        Qing Wang <wangqing7171@gmail.com>
AuthorDate:    Tue, 02 Jun 2026 11:08:54 +08:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Tue, 02 Jun 2026 12:41:15 +02:00

rseq: Fix using an uninitialized stack variable in rseq_exit_user_update()

There is an bug in which an uninitialized stack variable is used in
rseq_exit_user_update() as reported by syzbot:

BUG: KMSAN: kernel-infoleak in rseq_set_ids_get_csaddr include/linux/rseq_entry.h:502 [inline]

The local variable:

	struct rseq_ids ids = {
		.cpu_id	 = task_cpu(t),
		.mm_cid	 = task_mm_cid(t),
		.node_id = cpu_to_node(ids.cpu_id),
	};

According to the C standard, the evaluation order of expressions in an
initializer list is indeterminately sequenced. The compiler (Clang, in
this KMSAN build) evaluates `cpu_to_node(ids.cpu_id)` *before*
`ids.cpu_id` is initialized with `task_cpu(t)`.

This is fixed by moving the assignment of ids.node_id outside the
structure initialization.

Fixes: 82f572449cfe ("rseq: Implement read only ABI enforcement for optimized RSEQ V2 mode")
Closes: https://syzkaller.appspot.com/bug?extid=185a631927096f9da2fc
Reported-by: syzbot+185a631927096f9da2fc@syzkaller.appspotmail.com
Signed-off-by: Qing Wang <wangqing7171@gmail.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Acked-by: Mark Rutland <mark.rutland@arm.com>
Link: https://patch.msgid.link/20260602030854.574038-1-wangqing7171@gmail.com
---
 include/linux/rseq_entry.h | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/include/linux/rseq_entry.h b/include/linux/rseq_entry.h
index 63bc720..ed9da6e 100644
--- a/include/linux/rseq_entry.h
+++ b/include/linux/rseq_entry.h
@@ -635,10 +635,11 @@ static __always_inline bool rseq_exit_user_update(struct pt_regs *regs, struct t
 		return true;
 	}
 
+	int cpu = task_cpu(t);
 	struct rseq_ids ids = {
-		.cpu_id	 = task_cpu(t),
+		.cpu_id	 = cpu,
 		.mm_cid	 = task_mm_cid(t),
-		.node_id = cpu_to_node(ids.cpu_id),
+		.node_id = cpu_to_node(cpu),
 	};
 
 	return rseq_update_usr(t, regs, &ids);