All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alexander Popov <alex.popov@linux.com>
To: Mark Rutland <mark.rutland@arm.com>,
	linux-arm-kernel@lists.infradead.org
Cc: akpm@linux-foundation.org, catalin.marinas@arm.com,
	keescook@chromium.org, linux-kernel@vger.kernel.org,
	luto@kernel.org, will@kernel.org
Subject: Re: [PATCH v2 05/13] stackleak: clarify variable names
Date: Sun, 8 May 2022 23:49:46 +0300	[thread overview]
Message-ID: <e1cf0177-40a0-ffca-6be4-57fd97860c4a@linux.com> (raw)
In-Reply-To: <20220427173128.2603085-6-mark.rutland@arm.com>

On 27.04.2022 20:31, Mark Rutland wrote:
> The logic within __stackleak_erase() can be a little hard to follow, as
> `boundary` switches from being the low bound to the high bound mid way
> through the function, and `kstack_ptr` is used to represent the start of
> the region to erase while `boundary` represents the end of the region to
> erase.
> 
> Make this a little clearer by consistently using clearer variable names.
> The `boundary` variable is removed, the bounds of the region to erase
> are described by `erase_low` and `erase_high`, and bounds of the task
> stack are described by `task_stack_low` and `task_stck_high`.

A typo here in `task_stck_high`.

> As the same time, remove the comment above the variables, since it is
> unclear whether it's intended as rationale, a complaint, or a TODO, and
> is more confusing than helpful.

Yes, this comment is a bit confusing :) I can elaborate.

In the original grsecurity patch, the stackleak erasing was written in asm.
When I adopted it and proposed for the upstream, Linus strongly opposed this.
So I developed stackleak erasing in C.

And I wrote this comment to remember that having 'kstack_ptr' and 'boundary' 
variables on the stack (which we are clearing) would not be good.

That was also the main reason why I reused the 'boundary' variable: I wanted the 
compiler to allocate it in the register and I avoided creating many local variables.

Mark, did your refactoring make the compiler allocate local variables on the 
stack instead of the registers?

> There should be no functional change as a result of this patch.
> 
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Cc: Alexander Popov <alex.popov@linux.com>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: Andy Lutomirski <luto@kernel.org>
> Cc: Kees Cook <keescook@chromium.org>
> ---
>   kernel/stackleak.c | 30 ++++++++++++++----------------
>   1 file changed, 14 insertions(+), 16 deletions(-)
> 
> diff --git a/kernel/stackleak.c b/kernel/stackleak.c
> index 24b7cf01b2972..d5f684dc0a2d9 100644
> --- a/kernel/stackleak.c
> +++ b/kernel/stackleak.c
> @@ -73,40 +73,38 @@ late_initcall(stackleak_sysctls_init);
>   static __always_inline void __stackleak_erase(void)
>   {
>   	const unsigned long task_stack_low = stackleak_task_low_bound(current);
> -
> -	/* It would be nice not to have 'kstack_ptr' and 'boundary' on stack */
> -	unsigned long kstack_ptr = current->lowest_stack;
> -	unsigned long boundary = task_stack_low;
> +	unsigned long erase_low = current->lowest_stack;
> +	unsigned long erase_high;
>   	unsigned int poison_count = 0;
>   	const unsigned int depth = STACKLEAK_SEARCH_DEPTH / sizeof(unsigned long);
>   
>   	/* Search for the poison value in the kernel stack */
> -	while (kstack_ptr > boundary && poison_count <= depth) {
> -		if (*(unsigned long *)kstack_ptr == STACKLEAK_POISON)
> +	while (erase_low > task_stack_low && poison_count <= depth) {
> +		if (*(unsigned long *)erase_low == STACKLEAK_POISON)
>   			poison_count++;
>   		else
>   			poison_count = 0;
>   
> -		kstack_ptr -= sizeof(unsigned long);
> +		erase_low -= sizeof(unsigned long);
>   	}
>   
>   #ifdef CONFIG_STACKLEAK_METRICS
> -	current->prev_lowest_stack = kstack_ptr;
> +	current->prev_lowest_stack = erase_low;
>   #endif
>   
>   	/*
> -	 * Now write the poison value to the kernel stack. Start from
> -	 * 'kstack_ptr' and move up till the new 'boundary'. We assume that
> -	 * the stack pointer doesn't change when we write poison.
> +	 * Now write the poison value to the kernel stack between 'erase_low'
> +	 * and 'erase_high'. We assume that the stack pointer doesn't change
> +	 * when we write poison.
>   	 */
>   	if (on_thread_stack())
> -		boundary = current_stack_pointer;
> +		erase_high = current_stack_pointer;
>   	else
> -		boundary = current_top_of_stack();
> +		erase_high = current_top_of_stack();
>   
> -	while (kstack_ptr < boundary) {
> -		*(unsigned long *)kstack_ptr = STACKLEAK_POISON;
> -		kstack_ptr += sizeof(unsigned long);
> +	while (erase_low < erase_high) {
> +		*(unsigned long *)erase_low = STACKLEAK_POISON;
> +		erase_low += sizeof(unsigned long);
>   	}
>   
>   	/* Reset the 'lowest_stack' value for the next syscall */


WARNING: multiple messages have this Message-ID (diff)
From: Alexander Popov <alex.popov@linux.com>
To: Mark Rutland <mark.rutland@arm.com>,
	linux-arm-kernel@lists.infradead.org
Cc: akpm@linux-foundation.org, catalin.marinas@arm.com,
	keescook@chromium.org, linux-kernel@vger.kernel.org,
	luto@kernel.org, will@kernel.org
Subject: Re: [PATCH v2 05/13] stackleak: clarify variable names
Date: Sun, 8 May 2022 23:49:46 +0300	[thread overview]
Message-ID: <e1cf0177-40a0-ffca-6be4-57fd97860c4a@linux.com> (raw)
In-Reply-To: <20220427173128.2603085-6-mark.rutland@arm.com>

On 27.04.2022 20:31, Mark Rutland wrote:
> The logic within __stackleak_erase() can be a little hard to follow, as
> `boundary` switches from being the low bound to the high bound mid way
> through the function, and `kstack_ptr` is used to represent the start of
> the region to erase while `boundary` represents the end of the region to
> erase.
> 
> Make this a little clearer by consistently using clearer variable names.
> The `boundary` variable is removed, the bounds of the region to erase
> are described by `erase_low` and `erase_high`, and bounds of the task
> stack are described by `task_stack_low` and `task_stck_high`.

A typo here in `task_stck_high`.

> As the same time, remove the comment above the variables, since it is
> unclear whether it's intended as rationale, a complaint, or a TODO, and
> is more confusing than helpful.

Yes, this comment is a bit confusing :) I can elaborate.

In the original grsecurity patch, the stackleak erasing was written in asm.
When I adopted it and proposed for the upstream, Linus strongly opposed this.
So I developed stackleak erasing in C.

And I wrote this comment to remember that having 'kstack_ptr' and 'boundary' 
variables on the stack (which we are clearing) would not be good.

That was also the main reason why I reused the 'boundary' variable: I wanted the 
compiler to allocate it in the register and I avoided creating many local variables.

Mark, did your refactoring make the compiler allocate local variables on the 
stack instead of the registers?

> There should be no functional change as a result of this patch.
> 
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Cc: Alexander Popov <alex.popov@linux.com>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: Andy Lutomirski <luto@kernel.org>
> Cc: Kees Cook <keescook@chromium.org>
> ---
>   kernel/stackleak.c | 30 ++++++++++++++----------------
>   1 file changed, 14 insertions(+), 16 deletions(-)
> 
> diff --git a/kernel/stackleak.c b/kernel/stackleak.c
> index 24b7cf01b2972..d5f684dc0a2d9 100644
> --- a/kernel/stackleak.c
> +++ b/kernel/stackleak.c
> @@ -73,40 +73,38 @@ late_initcall(stackleak_sysctls_init);
>   static __always_inline void __stackleak_erase(void)
>   {
>   	const unsigned long task_stack_low = stackleak_task_low_bound(current);
> -
> -	/* It would be nice not to have 'kstack_ptr' and 'boundary' on stack */
> -	unsigned long kstack_ptr = current->lowest_stack;
> -	unsigned long boundary = task_stack_low;
> +	unsigned long erase_low = current->lowest_stack;
> +	unsigned long erase_high;
>   	unsigned int poison_count = 0;
>   	const unsigned int depth = STACKLEAK_SEARCH_DEPTH / sizeof(unsigned long);
>   
>   	/* Search for the poison value in the kernel stack */
> -	while (kstack_ptr > boundary && poison_count <= depth) {
> -		if (*(unsigned long *)kstack_ptr == STACKLEAK_POISON)
> +	while (erase_low > task_stack_low && poison_count <= depth) {
> +		if (*(unsigned long *)erase_low == STACKLEAK_POISON)
>   			poison_count++;
>   		else
>   			poison_count = 0;
>   
> -		kstack_ptr -= sizeof(unsigned long);
> +		erase_low -= sizeof(unsigned long);
>   	}
>   
>   #ifdef CONFIG_STACKLEAK_METRICS
> -	current->prev_lowest_stack = kstack_ptr;
> +	current->prev_lowest_stack = erase_low;
>   #endif
>   
>   	/*
> -	 * Now write the poison value to the kernel stack. Start from
> -	 * 'kstack_ptr' and move up till the new 'boundary'. We assume that
> -	 * the stack pointer doesn't change when we write poison.
> +	 * Now write the poison value to the kernel stack between 'erase_low'
> +	 * and 'erase_high'. We assume that the stack pointer doesn't change
> +	 * when we write poison.
>   	 */
>   	if (on_thread_stack())
> -		boundary = current_stack_pointer;
> +		erase_high = current_stack_pointer;
>   	else
> -		boundary = current_top_of_stack();
> +		erase_high = current_top_of_stack();
>   
> -	while (kstack_ptr < boundary) {
> -		*(unsigned long *)kstack_ptr = STACKLEAK_POISON;
> -		kstack_ptr += sizeof(unsigned long);
> +	while (erase_low < erase_high) {
> +		*(unsigned long *)erase_low = STACKLEAK_POISON;
> +		erase_low += sizeof(unsigned long);
>   	}
>   
>   	/* Reset the 'lowest_stack' value for the next syscall */


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  reply	other threads:[~2022-05-08 20:50 UTC|newest]

Thread overview: 94+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-04-27 17:31 [PATCH v2 00/13] stackleak: fixes and rework Mark Rutland
2022-04-27 17:31 ` Mark Rutland
2022-04-27 17:31 ` [PATCH v2 01/13] arm64: stackleak: fix current_top_of_stack() Mark Rutland
2022-04-27 17:31   ` Mark Rutland
2022-05-04 16:41   ` Catalin Marinas
2022-05-04 16:41     ` Catalin Marinas
2022-05-04 19:01     ` Kees Cook
2022-05-04 19:01       ` Kees Cook
2022-05-04 19:55       ` Catalin Marinas
2022-05-04 19:55         ` Catalin Marinas
2022-05-05  8:25         ` Will Deacon
2022-05-05  8:25           ` Will Deacon
2022-05-08 17:24   ` Alexander Popov
2022-05-08 17:24     ` Alexander Popov
2022-05-10 11:36     ` Mark Rutland
2022-05-10 11:36       ` Mark Rutland
2022-04-27 17:31 ` [PATCH v2 02/13] stackleak: move skip_erasing() check earlier Mark Rutland
2022-04-27 17:31   ` Mark Rutland
2022-05-08 17:44   ` Alexander Popov
2022-05-08 17:44     ` Alexander Popov
2022-05-10 11:40     ` Mark Rutland
2022-05-10 11:40       ` Mark Rutland
2022-04-27 17:31 ` [PATCH v2 03/13] stackleak: remove redundant check Mark Rutland
2022-04-27 17:31   ` Mark Rutland
2022-05-08 18:17   ` Alexander Popov
2022-05-08 18:17     ` Alexander Popov
2022-05-10 11:46     ` Mark Rutland
2022-05-10 11:46       ` Mark Rutland
2022-05-11  3:00       ` Kees Cook
2022-05-11  3:00         ` Kees Cook
2022-05-11  8:02         ` Mark Rutland
2022-05-11  8:02           ` Mark Rutland
2022-05-11 14:44           ` Kees Cook
2022-05-11 14:44             ` Kees Cook
2022-05-12  9:14             ` Mark Rutland
2022-05-12  9:14               ` Mark Rutland
2022-05-15 16:17               ` Alexander Popov
2022-05-15 16:17                 ` Alexander Popov
2022-05-24 10:03                 ` Mark Rutland
2022-05-24 10:03                   ` Mark Rutland
2022-05-26 22:09                   ` Alexander Popov
2022-05-26 22:09                     ` Alexander Popov
2022-04-27 17:31 ` [PATCH v2 04/13] stackleak: rework stack low bound handling Mark Rutland
2022-04-27 17:31   ` Mark Rutland
2022-04-27 17:31 ` [PATCH v2 05/13] stackleak: clarify variable names Mark Rutland
2022-04-27 17:31   ` Mark Rutland
2022-05-08 20:49   ` Alexander Popov [this message]
2022-05-08 20:49     ` Alexander Popov
2022-05-10 13:01     ` Mark Rutland
2022-05-10 13:01       ` Mark Rutland
2022-05-11  3:05       ` Kees Cook
2022-05-11  3:05         ` Kees Cook
2022-04-27 17:31 ` [PATCH v2 06/13] stackleak: rework stack high bound handling Mark Rutland
2022-04-27 17:31   ` Mark Rutland
2022-05-08 21:27   ` Alexander Popov
2022-05-08 21:27     ` Alexander Popov
2022-05-10 11:22     ` Mark Rutland
2022-05-10 11:22       ` Mark Rutland
2022-05-15 16:32       ` Alexander Popov
2022-05-15 16:32         ` Alexander Popov
2022-04-27 17:31 ` [PATCH v2 07/13] stackleak: rework poison scanning Mark Rutland
2022-04-27 17:31   ` Mark Rutland
2022-05-09 13:51   ` Alexander Popov
2022-05-09 13:51     ` Alexander Popov
2022-05-10 13:13     ` Mark Rutland
2022-05-10 13:13       ` Mark Rutland
2022-05-15 17:33       ` Alexander Popov
2022-05-15 17:33         ` Alexander Popov
2022-05-24 13:31         ` Mark Rutland
2022-05-24 13:31           ` Mark Rutland
2022-05-26 23:25           ` Alexander Popov
2022-05-26 23:25             ` Alexander Popov
2022-05-31 18:13             ` Kees Cook
2022-05-31 18:13               ` Kees Cook
2022-06-03 16:55               ` Alexander Popov
2022-06-03 16:55                 ` Alexander Popov
2022-04-27 17:31 ` [PATCH v2 08/13] lkdtm/stackleak: avoid spurious failure Mark Rutland
2022-04-27 17:31   ` Mark Rutland
2022-04-27 17:31 ` [PATCH v2 09/13] lkdtm/stackleak: rework boundary management Mark Rutland
2022-04-27 17:31   ` Mark Rutland
2022-05-04 19:07   ` Kees Cook
2022-05-04 19:07     ` Kees Cook
2022-04-27 17:31 ` [PATCH v2 10/13] lkdtm/stackleak: prevent unexpected stack usage Mark Rutland
2022-04-27 17:31   ` Mark Rutland
2022-04-27 17:31 ` [PATCH v2 11/13] lkdtm/stackleak: check stack boundaries Mark Rutland
2022-04-27 17:31   ` Mark Rutland
2022-04-27 17:31 ` [PATCH v2 12/13] stackleak: add on/off stack variants Mark Rutland
2022-04-27 17:31   ` Mark Rutland
2022-04-27 17:31 ` [PATCH v2 13/13] arm64: entry: use stackleak_erase_on_task_stack() Mark Rutland
2022-04-27 17:31   ` Mark Rutland
2022-05-04 16:42   ` Catalin Marinas
2022-05-04 16:42     ` Catalin Marinas
2022-05-04 19:16 ` [PATCH v2 00/13] stackleak: fixes and rework Kees Cook
2022-05-04 19:16   ` Kees Cook

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=e1cf0177-40a0-ffca-6be4-57fd97860c4a@linux.com \
    --to=alex.popov@linux.com \
    --cc=akpm@linux-foundation.org \
    --cc=catalin.marinas@arm.com \
    --cc=keescook@chromium.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luto@kernel.org \
    --cc=mark.rutland@arm.com \
    --cc=will@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.