From: Kees Cook <keescook@chromium.org>
To: Alexander Popov <alex.popov@linux.com>
Cc: Mark Rutland <mark.rutland@arm.com>,
linux-arm-kernel@lists.infradead.org, akpm@linux-foundation.org,
catalin.marinas@arm.com, linux-kernel@vger.kernel.org,
luto@kernel.org, will@kernel.org
Subject: Re: [PATCH v2 07/13] stackleak: rework poison scanning
Date: Tue, 31 May 2022 11:13:44 -0700 [thread overview]
Message-ID: <202205311108.40D216E6@keescook> (raw)
In-Reply-To: <73e3a82b-fbf6-5448-56ba-adda130230d3@linux.com>
On Fri, May 27, 2022 at 02:25:12AM +0300, Alexander Popov wrote:
> On 24.05.2022 16:31, Mark Rutland wrote:
> > [...]
> > It's also worth noting that `noinstr` code will also not be instrumented
> > regardless of frame size -- we might want some build-time assertion for those.
>
> I developed a trick that shows noinstr functions that stackleak would like to instrument:
>
> diff --git a/scripts/gcc-plugins/stackleak_plugin.c b/scripts/gcc-plugins/stackleak_plugin.c
> index 42f0252ee2a4..6db748d44957 100644
> --- a/scripts/gcc-plugins/stackleak_plugin.c
> +++ b/scripts/gcc-plugins/stackleak_plugin.c
> @@ -397,6 +397,9 @@ static unsigned int stackleak_cleanup_execute(void)
> const char *fn = DECL_NAME_POINTER(current_function_decl);
> bool removed = false;
>
> + if (verbose)
> + fprintf(stderr, "stackleak: I see noinstr function %s()\n", fn);
> +
> /*
> * Leave stack tracking in functions that call alloca().
> * Additional case:
> @@ -464,12 +467,12 @@ static bool stackleak_gate(void)
> if (STRING_EQUAL(section, ".meminit.text"))
> return false;
> if (STRING_EQUAL(section, ".noinstr.text"))
> - return false;
> + return true;
> if (STRING_EQUAL(section, ".entry.text"))
> return false;
> }
>
> - return track_frame_size >= 0;
> + return false;
> }
>
> /* Build the function declaration for stackleak_track_stack() */
> @@ -589,8 +592,6 @@ __visible int plugin_init(struct plugin_name_args *plugin_info,
> build_for_x86 = true;
> } else if (!strcmp(argv[i].key, "disable")) {
> disable = true;
> - } else if (!strcmp(argv[i].key, "verbose")) {
> - verbose = true;
> } else {
> error(G_("unknown option '-fplugin-arg-%s-%s'"),
> plugin_name, argv[i].key);
> @@ -598,6 +599,8 @@ __visible int plugin_init(struct plugin_name_args *plugin_info,
> }
> }
>
> + verbose = true;
> +
> if (disable) {
> if (verbose)
> fprintf(stderr, "stackleak: disabled for this translation unit\n");
>
>
> Building defconfig for x86_64 gives this:
>
> stackleak: I see noinstr function __do_fast_syscall_32()
> stackleak: instrument __do_fast_syscall_32(): calls_alloca
> --
> stackleak: I see noinstr function do_syscall_64()
> stackleak: instrument do_syscall_64(): calls_alloca
> --
> stackleak: I see noinstr function do_int80_syscall_32()
> stackleak: instrument do_int80_syscall_32(): calls_alloca
As you say, these are from RANDOMIZE_KSTACK_OFFSET, and are around
bounds-checked, and should already be getting wiped since these will
call into deeper (non-noinst) functions.
> stackleak: I see noinstr function do_machine_check()
> stackleak: instrument do_machine_check()
> --
> stackleak: I see noinstr function exc_general_protection()
> stackleak: instrument exc_general_protection()
> --
> stackleak: I see noinstr function fixup_bad_iret()
> stackleak: instrument fixup_bad_iret()
>
>
> The cases with calls_alloca are caused by CONFIG_RANDOMIZE_KSTACK_OFFSET=y.
> Kees knows about that peculiarity.
>
> Other cases are noinstr functions with large stack frame:
> do_machine_check(), exc_general_protection(), and fixup_bad_iret().
>
> I think adding a build-time assertion is not possible, since it would break
> building the kernel.
Do these functions share the syscall behavior of always calling into
non-noinst functions that _do_ have stack depth instrumentation?
> [...]
> > In security/Kconfig.hardening we have:
> >
> > | config STACKLEAK_TRACK_MIN_SIZE
> > | int "Minimum stack frame size of functions tracked by STACKLEAK"
> > | default 100
> > | range 0 4096
> > | depends on GCC_PLUGIN_STACKLEAK
> > | help
> > | The STACKLEAK gcc plugin instruments the kernel code for tracking
> > | the lowest border of the kernel stack (and for some other purposes).
> > | It inserts the stackleak_track_stack() call for the functions with
> > | a stack frame size greater than or equal to this parameter.
> > | If unsure, leave the default value 100.
> >
> > ... where the vast majority of that range is going to lead to a BUILD_BUG().
>
> Honestly, I don't like the idea of having the STACKLEAK_TRACK_MIN_SIZE option in the Kconfig.
>
> I was forced by the maintainers to introduce it when I was working on the stackleak patchset.
>
> How about dropping CONFIG_STACKLEAK_TRACK_MIN_SIZE from Kconfig?
>
> That would also allow to drop this build-time assertion.
Should this be arch-specific? (i.e. just make it a per-arch Kconfig
default, instead of user-selectable into weird values?)
--
Kees Cook
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
WARNING: multiple messages have this Message-ID (diff)
From: Kees Cook <keescook@chromium.org>
To: Alexander Popov <alex.popov@linux.com>
Cc: Mark Rutland <mark.rutland@arm.com>,
linux-arm-kernel@lists.infradead.org, akpm@linux-foundation.org,
catalin.marinas@arm.com, linux-kernel@vger.kernel.org,
luto@kernel.org, will@kernel.org
Subject: Re: [PATCH v2 07/13] stackleak: rework poison scanning
Date: Tue, 31 May 2022 11:13:44 -0700 [thread overview]
Message-ID: <202205311108.40D216E6@keescook> (raw)
In-Reply-To: <73e3a82b-fbf6-5448-56ba-adda130230d3@linux.com>
On Fri, May 27, 2022 at 02:25:12AM +0300, Alexander Popov wrote:
> On 24.05.2022 16:31, Mark Rutland wrote:
> > [...]
> > It's also worth noting that `noinstr` code will also not be instrumented
> > regardless of frame size -- we might want some build-time assertion for those.
>
> I developed a trick that shows noinstr functions that stackleak would like to instrument:
>
> diff --git a/scripts/gcc-plugins/stackleak_plugin.c b/scripts/gcc-plugins/stackleak_plugin.c
> index 42f0252ee2a4..6db748d44957 100644
> --- a/scripts/gcc-plugins/stackleak_plugin.c
> +++ b/scripts/gcc-plugins/stackleak_plugin.c
> @@ -397,6 +397,9 @@ static unsigned int stackleak_cleanup_execute(void)
> const char *fn = DECL_NAME_POINTER(current_function_decl);
> bool removed = false;
>
> + if (verbose)
> + fprintf(stderr, "stackleak: I see noinstr function %s()\n", fn);
> +
> /*
> * Leave stack tracking in functions that call alloca().
> * Additional case:
> @@ -464,12 +467,12 @@ static bool stackleak_gate(void)
> if (STRING_EQUAL(section, ".meminit.text"))
> return false;
> if (STRING_EQUAL(section, ".noinstr.text"))
> - return false;
> + return true;
> if (STRING_EQUAL(section, ".entry.text"))
> return false;
> }
>
> - return track_frame_size >= 0;
> + return false;
> }
>
> /* Build the function declaration for stackleak_track_stack() */
> @@ -589,8 +592,6 @@ __visible int plugin_init(struct plugin_name_args *plugin_info,
> build_for_x86 = true;
> } else if (!strcmp(argv[i].key, "disable")) {
> disable = true;
> - } else if (!strcmp(argv[i].key, "verbose")) {
> - verbose = true;
> } else {
> error(G_("unknown option '-fplugin-arg-%s-%s'"),
> plugin_name, argv[i].key);
> @@ -598,6 +599,8 @@ __visible int plugin_init(struct plugin_name_args *plugin_info,
> }
> }
>
> + verbose = true;
> +
> if (disable) {
> if (verbose)
> fprintf(stderr, "stackleak: disabled for this translation unit\n");
>
>
> Building defconfig for x86_64 gives this:
>
> stackleak: I see noinstr function __do_fast_syscall_32()
> stackleak: instrument __do_fast_syscall_32(): calls_alloca
> --
> stackleak: I see noinstr function do_syscall_64()
> stackleak: instrument do_syscall_64(): calls_alloca
> --
> stackleak: I see noinstr function do_int80_syscall_32()
> stackleak: instrument do_int80_syscall_32(): calls_alloca
As you say, these are from RANDOMIZE_KSTACK_OFFSET, and are around
bounds-checked, and should already be getting wiped since these will
call into deeper (non-noinst) functions.
> stackleak: I see noinstr function do_machine_check()
> stackleak: instrument do_machine_check()
> --
> stackleak: I see noinstr function exc_general_protection()
> stackleak: instrument exc_general_protection()
> --
> stackleak: I see noinstr function fixup_bad_iret()
> stackleak: instrument fixup_bad_iret()
>
>
> The cases with calls_alloca are caused by CONFIG_RANDOMIZE_KSTACK_OFFSET=y.
> Kees knows about that peculiarity.
>
> Other cases are noinstr functions with large stack frame:
> do_machine_check(), exc_general_protection(), and fixup_bad_iret().
>
> I think adding a build-time assertion is not possible, since it would break
> building the kernel.
Do these functions share the syscall behavior of always calling into
non-noinst functions that _do_ have stack depth instrumentation?
> [...]
> > In security/Kconfig.hardening we have:
> >
> > | config STACKLEAK_TRACK_MIN_SIZE
> > | int "Minimum stack frame size of functions tracked by STACKLEAK"
> > | default 100
> > | range 0 4096
> > | depends on GCC_PLUGIN_STACKLEAK
> > | help
> > | The STACKLEAK gcc plugin instruments the kernel code for tracking
> > | the lowest border of the kernel stack (and for some other purposes).
> > | It inserts the stackleak_track_stack() call for the functions with
> > | a stack frame size greater than or equal to this parameter.
> > | If unsure, leave the default value 100.
> >
> > ... where the vast majority of that range is going to lead to a BUILD_BUG().
>
> Honestly, I don't like the idea of having the STACKLEAK_TRACK_MIN_SIZE option in the Kconfig.
>
> I was forced by the maintainers to introduce it when I was working on the stackleak patchset.
>
> How about dropping CONFIG_STACKLEAK_TRACK_MIN_SIZE from Kconfig?
>
> That would also allow to drop this build-time assertion.
Should this be arch-specific? (i.e. just make it a per-arch Kconfig
default, instead of user-selectable into weird values?)
--
Kees Cook
next prev parent reply other threads:[~2022-05-31 18:14 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
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 [this message]
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=202205311108.40D216E6@keescook \
--to=keescook@chromium.org \
--cc=akpm@linux-foundation.org \
--cc=alex.popov@linux.com \
--cc=catalin.marinas@arm.com \
--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.