From: Mark Rutland <mark.rutland@arm.com>
To: linux-kernel@vger.kernel.org
Cc: akpm@linux-foundation.org, alex.popov@linux.com,
catalin.marinas@arm.com, keescook@chromium.org,
linux-arm-kernel@lists.infradead.org, luto@kernel.org,
mark.rutland@arm.com, will@kernel.org
Subject: [PATCH 1/8] arm64: stackleak: fix current_top_of_stack()
Date: Mon, 25 Apr 2022 12:55:56 +0100 [thread overview]
Message-ID: <20220425115603.781311-2-mark.rutland@arm.com> (raw)
In-Reply-To: <20220425115603.781311-1-mark.rutland@arm.com>
Due to some historical confusion, arm64's current_top_of_stack() isn't
what the stackleak code expects. This could in theory result in a number
of problems, and practically results in an unnecessary performance hit.
We can avoid this by aligning the arm64 implementation with the x86
implementation.
The arm64 implementation of current_top_of_stack() was added
specifically for stackleak in commit:
0b3e336601b82c6a ("arm64: Add support for STACKLEAK gcc plugin")
This was intended to be equivalent to the x86 implementation, but the
implementation, semantics, and performance characteristics differ
wildly:
* On x86, current_top_of_stack() returns the top of the current task's
task stack, regardless of which stack is in active use.
The implementation accesses a percpu variable which the x86 entry code
maintains, and returns the location immediately above the pt_regs on
the task stack (above which x86 has some padding).
* On arm64 current_top_of_stack() returns the top of the stack in active
use (i.e. the one which is currently being used).
The implementation checks the SP against a number of
potentially-accessible stacks, and will BUG() if no stack is found.
The core stackleak_erase() code determines the upper bound of stack to
erase with:
| if (on_thread_stack())
| boundary = current_stack_pointer;
| else
| boundary = current_top_of_stack();
On arm64 stackleak_erase() is always called on a task stack, and
on_thread_stack() should always be true. On x86, stackleak_erase() is
mostly called on a trampoline stack, and is sometimes called on a task
stack.
Currently, this results in a lot of unnecessary code being generated for
arm64 for the impossible !on_thread_stack() case. Some of this is
inlined, bloating stackleak_erase(), while portions of this are left
out-of-line and permitted to be instrumented (which would be a
functional problem if that code were reachable).
As a first step towards improving this, this patch aligns arm64's
implementation of current_top_of_stack() with x86's, always returning
the top of the current task's stack. With GCC 11.1.0 this results in the
bulk of the unnecessary code being removed, including all of the
out-of-line instrumentable code.
While I don't believe there's a functional problem in practice I've
marked this as a fix since the semantic was clearly wrong, the fix
itself is simple, and other code might rely upon this in future.
Fixes: 0b3e336601b82c6a ("arm64: Add support for STACKLEAK gcc plugin")
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: Catalin Marinas <catalin.marinas@arm.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Will Deacon <will@kernel.org>
---
arch/arm64/include/asm/processor.h | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index 73e38d9a540ce..6b1a12c23fe77 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -381,12 +381,10 @@ long get_tagged_addr_ctrl(struct task_struct *task);
* of header definitions for the use of task_stack_page.
*/
-#define current_top_of_stack() \
-({ \
- struct stack_info _info; \
- BUG_ON(!on_accessible_stack(current, current_stack_pointer, 1, &_info)); \
- _info.high; \
-})
+/*
+ * The top of the current task's task stack
+ */
+#define current_top_of_stack() ((unsigned long)current->stack + THREAD_SIZE)
#define on_thread_stack() (on_task_stack(current, current_stack_pointer, 1, NULL))
#endif /* __ASSEMBLY__ */
--
2.30.2
next prev parent reply other threads:[~2022-04-25 11:56 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-04-25 11:55 [PATCH 0/8] stackleak: fixes and rework Mark Rutland
2022-04-25 11:55 ` Mark Rutland [this message]
2022-04-25 11:55 ` [PATCH 2/8] stackleak: move skip_erasing() check earlier Mark Rutland
2022-04-25 11:55 ` [PATCH 3/8] stackleak: rework stack low bound handling Mark Rutland
2022-04-25 11:55 ` [PATCH 4/8] stackleak: clarify variable names Mark Rutland
2022-04-25 11:56 ` [PATCH 5/8] stackleak: rework stack high bound handling Mark Rutland
2022-04-25 11:56 ` [PATCH 6/8] stackleak: remove redundant check Mark Rutland
2022-04-25 11:56 ` [PATCH 7/8] stackleak: add on/off stack variants Mark Rutland
2022-04-25 11:56 ` [PATCH 8/8] arm64: entry: use stackleak_erase_on_task_stack() Mark Rutland
2022-04-25 22:54 ` [PATCH 0/8] stackleak: fixes and rework Kees Cook
2022-04-26 10:10 ` Mark Rutland
2022-04-26 10:37 ` Mark Rutland
2022-04-26 11:15 ` Mark Rutland
2022-04-26 15:51 ` Alexander Popov
2022-04-26 16:07 ` Mark Rutland
2022-04-26 16:01 ` Mark Rutland
2022-04-26 18:01 ` Kees Cook
2022-04-26 17:51 ` 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=20220425115603.781311-2-mark.rutland@arm.com \
--to=mark.rutland@arm.com \
--cc=akpm@linux-foundation.org \
--cc=alex.popov@linux.com \
--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=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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®