public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Alexandre Oliva <oliva@adacore.com>
To: Qing Zhao <qing.zhao@oracle.com>
Cc: Qing Zhao via Gcc-patches <gcc-patches@gcc.gnu.org>,
	Jeremy Bennett <jeremy.bennett@embecosm.com>,
	Craig Blackmore <craig.blackmore@embecosm.com>,
	Graham Markall <graham.markall@embecosm.com>,
	Martin Jambor <mjambor@suse.cz>, Jan Hubicka <hubicka@ucw.cz>,
	Richard Biener <richard.guenther@gmail.com>,
	Jim Wilson <wilson@tuliptree.org>
Subject: Re: [PATCH v3] Introduce strub: machine-independent stack scrubbing
Date: Wed, 28 Jun 2023 05:20:32 -0300	[thread overview]
Message-ID: <orh6qsf167.fsf@lxoliva.fsfla.org> (raw)
In-Reply-To: <A553C465-A6D7-4BA7-BF44-FF86E34D14D1@oracle.com> (Qing Zhao's message of "Tue, 27 Jun 2023 21:28:41 +0000")

Hello, Qing,

On Jun 27, 2023, Qing Zhao <qing.zhao@oracle.com> wrote:

> I am wondering why stack scrubbing, proposed in this patch series, cannot do the stack scrubbing in the routine’s epilogue similar as
> register scrubbing?

There were multiple considerations that led to this design decision:

- Stack scrubbing in epilogues would be highly target-dependent

An epilogue expected to scrub the stack of its containing function would
not usually be able to call memset; there might not even be registers
available to do the cleaning, let alone to do it efficiently.  Since
epilogues are output after register allocation, the epilogue code
generator would have to allocate registers itself to do the job,
avoiding call-saved registers (that would have to be restored before
scrubbing the stack holding them), those holding return values, and
taking care of any machine- or ABI-specific conventions that apply to
epilogues.

- Exception Handling

Raising or propagating an exception requires a function's stack frame to
be active.  It wouldn't be possible for e.g. a cleanup handler to clean
up the stack frame holding it and then propagating the exception: either
the scrubbing would have to leave much of the stack frame alone for
propagation to work, or it would scrub too much and propagation would
fail.

So we had to devise a way for stack frames to be scrubbed and protect
the sensitive data in them even if an exception is raised or propagated
out of the sensitive frame.

- Variable frame size

Though many functions have static frame sizes, there are cases in which
a function dynamically allocates and releases stack space, and that
extra space should be scrubbed as well.  So the improvements out of a
known frame size are not a given, and we may need a watermark to handle
the general case.

Now consider that this watermark needs to survive past the point in
which the epilogue restores call-saved registers, so that the save area
can be scrubbed.  Call-clobbered registers might not be available, or
need scrubbing themselves.

A caller-owned watermark relieves the callee from these contradictory
requirements, enables the register pointing to the watermark to be
reused by the callee as soon as it's no longer needed; aggregation of
scrubbing, passing on the watermark when tail-calling another scrubbed
subprogram; caller and callee to be compiled separately, circumstances
in which the caller (in the strub("at-calls") mode) wouldn't know how
much stack space used by the callee is to be scrubbed.

- Watermark as in/out argument

Thus, watermarks, and caller-based scrubbing were required, so we might
as well use the same strategy for non-exceptional exit paths to make it
portable.

We've explored various possibilities of watermark passing to reduce the
impact on the ABI:

-- a single global variable wouldn't do in multi-threaded programs;
we need per-thread stack information.  TLS is not available on every
target, it's emulated with high overhead on some, and even when it
doesn't use part of the thread's stack for static thread-local
storage, each caller of a scrubbing function would have to preserve
that variable somehow (presumably in its own stack frame) before
reusing it to communicate with its callee.

-- a thread-local pointer to a heap-allocated parallel stack of
stack-scrubbing ranges might avoid holding the watermarks in the
stack, or passing pointers to them as arguments, leaving the entire
scrub range management in the library.  that would make the __strub_*
library components heavy enough that inlining them would not be
viable.  Furthermore, making such low-level APIs heap allocators
normally makes for problems of async-signal safety, and prevents heap
implementations from relying on such low-level APIs.

-- using the static chain machinery to convey to scrubbed callees
access to the callee's watermark seems viable, if onerous, but the
chained records live in the stack anyway, and there are targets that
do not support static chains.

-- an out parameter might do for "amount of stack used", but
making it an in/out watermark enabled aggregation and tail-calling;
early set-and-forget on fixed-size stack frames; and assured
initialization, even in case of an early asynchronous exception.

- Internal scrubbing

Though we have implemented strub("internal") through wrappers that call
the actual function and then scrub its stack space, we have envisioned
an alternate implementation that, through machine-specific support,
performs actual internal scrubbing, arranging the stack frame in such a
way that epilogues and EH cleanups can scrub most, if not all of the
stack frame (analogous to how the wrapper only scrubs the wrapped frame,
not its own), and taking advantage of constant frame sizes where
possible.  At least with variable frame sizes, the amount of stack space
to be scrubbed in the epilogue (or in an EH cleanup) will have to be
held in a local variable or somesuch, and at least for nonleaf
functions, that surely will end up in the stack one way or another.

> 2.  I have concerns on the runtime performance overhead, do you have any data on this for your current implementation?

Though one could conceivable build entire applications with the testing
option -fstrub=all, and that works AFAICT, the expected use case is
marking sensitive functions or variables for strubbing, and there aren't
benchmarks for this use case.


> 3. You mentioned that there are several “modes” for this feature,
> could you please provide more details on the modes and their
> description?

There's strict vs relaxed, and there's internal vs at-calls.  The
documentation for these modes included in the patch in quite extensive.
Rather than duplicating it here in other words, I suppose it would be a
better "test" for the documentation to have others go through it, try to
make sense of it, and point out passages that are unclear or hard to
understand.  WDYT?

Thanks,

-- 
Alexandre Oliva, happy hacker                https://FSFLA.org/blogs/lxo/
   Free Software Activist                       GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about <https://stallmansupport.org>

  reply	other threads:[~2023-06-28  8:20 UTC|newest]

Thread overview: 59+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <ormtqpsbuc.fsf@lxoliva.fsfla.org>
2021-09-09  7:11 ` [PATCH] " Alexandre Oliva
2022-07-29  6:16   ` [PATCH v2 00/10] Introduce " Alexandre Oliva
2022-07-29  6:24     ` [PATCH v2 01/10] Introduce strub: documentation, and new command-line options Alexandre Oliva
2022-07-29  6:25     ` [PATCH v2 02/10] Introduce strub: torture tests for C and C++ Alexandre Oliva
2022-08-09 13:34       ` Alexandre Oliva
2022-07-29  6:25     ` [PATCH v2 03/10] Introduce strub: non-torture " Alexandre Oliva
2022-07-29  6:26     ` [PATCH v2 04/10] Introduce strub: tests for C++ and Ada Alexandre Oliva
2022-07-29  6:26     ` [PATCH v2 05/10] Introduce strub: builtins and runtime Alexandre Oliva
2022-07-29  6:27     ` [PATCH v2 06/10] Introduce strub: attributes Alexandre Oliva
2022-07-29  6:28     ` [PATCH v2 07/10] Introduce strub: infrastructure interfaces and adjustments Alexandre Oliva
2022-07-29  6:28     ` [PATCH v2 08/10] Introduce strub: strub modes Alexandre Oliva
2022-07-29  6:30     ` [PATCH v2 09/10] Introduce strub: strubm (mode assignment) pass Alexandre Oliva
2022-07-29  6:34     ` [PATCH v2 10/10] Introduce strub: strub pass Alexandre Oliva
2022-07-29  6:36     ` [PATCH v2 00/10] Introduce strub: machine-independent stack scrubbing Alexandre Oliva
2022-10-10  8:48       ` Richard Biener
2022-10-11 11:57         ` Alexandre Oliva
2022-10-11 11:59           ` Richard Biener
2022-10-11 13:33             ` Alexandre Oliva
2022-10-13 11:38               ` Richard Biener
2022-10-13 13:15                 ` Alexandre Oliva
2023-06-16  6:09     ` [PATCH v3] " Alexandre Oliva
2023-06-27 21:28       ` Qing Zhao
2023-06-28  8:20         ` Alexandre Oliva [this message]
2023-10-20  6:03       ` [PATCH v4] " Alexandre Oliva
2023-10-26  6:15         ` Alexandre Oliva
2023-11-20 12:40           ` Alexandre Oliva
2023-11-22 14:14             ` Richard Biener
2023-11-23 10:56               ` Alexandre Oliva
2023-11-23 12:05                 ` Richard Biener
2023-11-29  8:53                   ` Alexandre Oliva
2023-11-29 12:48                     ` Richard Biener
2023-11-30  4:13                       ` Alexandre Oliva
2023-11-30 12:00                         ` Richard Biener
2023-12-02 17:56                           ` [PATCH v5] " Alexandre Oliva
2023-12-05  6:25                             ` Alexandre Oliva
2023-12-06  1:04                               ` Alexandre Oliva
2023-12-05  9:01                             ` Richard Biener
2023-12-06  8:36                             ` Causes to nvptx bootstrap fail: " Tobias Burnus
2023-12-06 11:32                               ` Thomas Schwinge
2023-12-06 22:12                                 ` Alexandre Oliva
2023-12-07  3:33                                   ` [PATCH] strub: enable conditional support Alexandre Oliva
2023-12-07  7:24                                     ` Richard Biener
2023-12-07 16:44                                     ` Thomas Schwinge
2023-12-07 17:52                                       ` [PATCH] Alexandre Oliva
2023-12-08  6:46                                         ` [PATCH] Richard Biener
2023-12-08  9:33                                         ` [PATCH] strub: skip emutls after strubm errors Thomas Schwinge
2023-12-10  9:16                                           ` FX Coudert
2023-12-07  7:21                                   ` Causes to nvptx bootstrap fail: [PATCH v5] Introduce strub: machine-independent stack scrubbing Richard Biener
2023-12-06 10:22                             ` Jan Hubicka
2023-12-07 21:19                               ` Alexandre Oliva
2023-12-07 21:39                               ` Alexandre Oliva
2023-12-09  2:08                                 ` [PATCH] strub: add note on attribute access Alexandre Oliva
2023-12-11  7:26                                   ` Richard Biener
2023-12-12 14:21                                   ` Jan Hubicka
2023-12-11  8:40                             ` [PATCH] testsuite: Disable -fstack-protector* for some strub tests Jakub Jelinek
2023-12-11  8:59                               ` Richard Biener
2023-12-20  8:15                           ` [PATCH FYI] www: new AdaCore-contributed hardening features in gcc 13 and 14 Alexandre Oliva
2023-11-30  5:04                       ` [PATCH v4] Introduce strub: machine-independent stack scrubbing Alexandre Oliva
2023-11-30 11:56                         ` Richard Biener

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=orh6qsf167.fsf@lxoliva.fsfla.org \
    --to=oliva@adacore.com \
    --cc=craig.blackmore@embecosm.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=graham.markall@embecosm.com \
    --cc=hubicka@ucw.cz \
    --cc=jeremy.bennett@embecosm.com \
    --cc=mjambor@suse.cz \
    --cc=qing.zhao@oracle.com \
    --cc=richard.guenther@gmail.com \
    --cc=wilson@tuliptree.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;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).