Re: [PATCH] gcc: Disallow trampolines when -fhardened

2023-12-07 Thread Eric Botcazou
> I don't know either of these languages to write a test, and I don't see
> anything that mentions the word trampoline in gfortran.dg/.  Ada has
> gnat.dg/trampoline3.adb but:
> 
> $ gcc -c -Wtrampolines trampoline3.adb
> trampoline3.adb:6:03: warning: variable "A" is read but never assigned
> [-gnatwv]
> 
> so there is no warning.

Look at the last line of the test (Ada has not used trampolines for ages!).

-- 
Eric Botcazou




Re: [PATCH] gcc: Disallow trampolines when -fhardened

2023-12-04 Thread Martin Uecker
Am Montag, dem 04.12.2023 um 11:46 -0500 schrieb Siddhesh Poyarekar:
> On 2023-12-04 11:39, Andreas Schwab wrote:
> > On Dez 04 2023, Siddhesh Poyarekar wrote:
> > 
> > > For hardened code in C, I think we really should look to step away from
> > > nested functions instead of adding ways to continue supporting it. There's
> > > probably a larger conversation to be had about the utility of nested
> > > functions in general for C (and whether this GCC extension should be
> > > deprecated altogether in future), but I feel like the -fhardened subset
> > > gives us the opportunity to enforce at least a safe subset for now,
> > > possibly extending it in future.
> > 
> > Nested functions by itself don't need a trampoline, only if the address
> > of it is passed outside the containing function's scope (as a callback,
> > for example).
> 
> Yes, that's why I said that the conversation about deprecating the C 
> nested functions extension is a broader one (and hence for gcc 15) that 
> will likely involve the question of whether dropping the extension 
> altogether gives any benefit or if dropping support for on-stack 
> trampolines is sufficient.  On-heap trampolines are maybe slightly 
> better in that they don't need an executable stack, but defaulting to 
> on-heap trampolines for -fhardened seems like a lost opportunity to 
> enforce better user code.

I do not really agree with that.  Nested functions can substantially
improve code quality and in C can avoid type unsafe use of
void* pointers in callbacks. The code is often much better with
nested functions than without.  Nested functions and lambdas
(i.e. anonymous nested functions) are used in many languages
because they make code better and GNU's nested function are no
exception.

So I disagree with the idea that discouraging nested functions leads 
to better code - I think the exact opposite is true.

I am generally wary of mitigations that may make exploitation of
buffer overflows a bit harder  while increasing the likelihood
of buffer overflows by reducing type safety and/or code quality.

But I would agree that trampolines are generally problematic. A
better strategy would be wide function pointer type (as in Apple'
Blocks extension). Alternatively, an explicit way to obtain the
static chain for a nested function which could be used with 
__builtin_call_with_static_chain  could also work.

But in any case, I think it diminishes the value of -fhardening 
it if requires source code changes, because then it is not as easy
to simply turn it on in larger projects / distributitions. 

Martin



> 
> Thanks,
> Sid



Re: [PATCH] gcc: Disallow trampolines when -fhardened

2023-12-04 Thread Siddhesh Poyarekar

On 2023-12-04 11:39, Andreas Schwab wrote:

On Dez 04 2023, Siddhesh Poyarekar wrote:


For hardened code in C, I think we really should look to step away from
nested functions instead of adding ways to continue supporting it. There's
probably a larger conversation to be had about the utility of nested
functions in general for C (and whether this GCC extension should be
deprecated altogether in future), but I feel like the -fhardened subset
gives us the opportunity to enforce at least a safe subset for now,
possibly extending it in future.


Nested functions by itself don't need a trampoline, only if the address
of it is passed outside the containing function's scope (as a callback,
for example).


Yes, that's why I said that the conversation about deprecating the C 
nested functions extension is a broader one (and hence for gcc 15) that 
will likely involve the question of whether dropping the extension 
altogether gives any benefit or if dropping support for on-stack 
trampolines is sufficient.  On-heap trampolines are maybe slightly 
better in that they don't need an executable stack, but defaulting to 
on-heap trampolines for -fhardened seems like a lost opportunity to 
enforce better user code.


Thanks,
Sid


Re: [PATCH] gcc: Disallow trampolines when -fhardened

2023-12-04 Thread Jakub Jelinek
On Mon, Dec 04, 2023 at 05:39:04PM +0100, Andreas Schwab wrote:
> On Dez 04 2023, Siddhesh Poyarekar wrote:
> 
> > For hardened code in C, I think we really should look to step away from
> > nested functions instead of adding ways to continue supporting it. There's
> > probably a larger conversation to be had about the utility of nested
> > functions in general for C (and whether this GCC extension should be
> > deprecated altogether in future), but I feel like the -fhardened subset
> > gives us the opportunity to enforce at least a safe subset for now,
> > possibly extending it in future.
> 
> Nested functions by itself don't need a trampoline, only if the address
> of it is passed outside the containing function's scope (as a callback,
> for example).

And only if the code to which it is passed can't be inlined back.

I'm afraid contained functions in Fortran or in Ada (whatever it is called
there) aren't going away any time soon and having the possibility to test it
also in C and not just Fortran/Ada is very useful at least from compiler
testing POV.

Jakub



Re: [PATCH] gcc: Disallow trampolines when -fhardened

2023-12-04 Thread Andreas Schwab
On Dez 04 2023, Siddhesh Poyarekar wrote:

> For hardened code in C, I think we really should look to step away from
> nested functions instead of adding ways to continue supporting it. There's
> probably a larger conversation to be had about the utility of nested
> functions in general for C (and whether this GCC extension should be
> deprecated altogether in future), but I feel like the -fhardened subset
> gives us the opportunity to enforce at least a safe subset for now,
> possibly extending it in future.

Nested functions by itself don't need a trampoline, only if the address
of it is passed outside the containing function's scope (as a callback,
for example).

-- 
Andreas Schwab, SUSE Labs, sch...@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."


Re: [PATCH] gcc: Disallow trampolines when -fhardened

2023-12-04 Thread Siddhesh Poyarekar

On 2023-12-02 04:42, Martin Uecker wrote:



Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?

-- >8 --
It came up that a good hardening strategy is to disable trampolines
which may require executable stack.  Therefore the following patch
adds -Werror=trampolines to -fhardened.


This would add a warning about specific code (where it is then
unclear whether rewriting it is feasible or even an improvement),
which seems different to all the other flags -fhardening has
now.


It's actually -Werror=trampolines, not just -Wtrampolines; the aim is to 
hard fail on producing trampolines and consequently, an executable 
stack.  In general the goal of -fhardened is to produce hardened code 
and the nested function trampolines do the exact reverse of that, so 
-Werror=trampolines seems to align perfectly with that goal, doesn't it?



GCC now has an option to allocate trampolines on the heap,
which would seem to be a better fit.  On the other hand,
it does not work with longjmp which may be a limitation.


For hardened code in C, I think we really should look to step away from 
nested functions instead of adding ways to continue supporting it. 
There's probably a larger conversation to be had about the utility of 
nested functions in general for C (and whether this GCC extension should 
be deprecated altogether in future), but I feel like the -fhardened 
subset gives us the opportunity to enforce at least a safe subset for 
now, possibly extending it in future.


Thanks,
Sid


Re: [PATCH] gcc: Disallow trampolines when -fhardened

2023-12-02 Thread Iain Sandoe



> On 2 Dec 2023, at 09:42, Martin Uecker  wrote:
> 
> 
>> Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
>> 
>> -- >8 --
>> It came up that a good hardening strategy is to disable trampolines
>> which may require executable stack.  Therefore the following patch
>> adds -Werror=trampolines to -fhardened.
> 
> This would add a warning about specific code (where it is then
> unclear whether rewriting it is feasible or even an improvement),
> which seems different to all the other flags -fhardening has
> now.
> 
> GCC now has an option to allocate trampolines on the heap,
> which would seem to be a better fit.

Indeed, I was thinking of mentioning this.

>  On the other hand,
> it does not work with longjmp which may be a limitation.

I suspect that we can make this work using handlers and forced unwind,
but unfortunately do not have time to work on it at the moment.

Iain

> 
> Martin
> 
> 
>> 
>> gcc/ChangeLog:
>> 
>>  * common.opt (Wtrampolines): Enable by -fhardened.
>>  * doc/invoke.texi: Reflect that -fhardened enables -Werror=trampolines.
>>  * opts.cc (print_help_hardened): Add -Werror=trampolines.
>>  * toplev.cc (process_options): Enable -Werror=trampolines for
>>  -fhardened.
>> 
>> gcc/testsuite/ChangeLog:
>> 
>>  * gcc.dg/fhardened-1.c: New test.
>>  * gcc.dg/fhardened-2.c: New test.
>>  * gcc.dg/fhardened-3.c: New test.
>>  * gcc.dg/fhardened-4.c: New test.
>>  * gcc.dg/fhardened-5.c: New test.
>> ---
>> gcc/common.opt |  2 +-
>> gcc/doc/invoke.texi|  1 +
>> gcc/opts.cc|  1 +
>> gcc/testsuite/gcc.dg/fhardened-1.c | 27 +++
>> gcc/testsuite/gcc.dg/fhardened-2.c | 25 +
>> gcc/testsuite/gcc.dg/fhardened-3.c | 25 +
>> gcc/testsuite/gcc.dg/fhardened-4.c | 25 +
>> gcc/testsuite/gcc.dg/fhardened-5.c | 27 +++
>> gcc/toplev.cc  |  8 +++-
>> 9 files changed, 139 insertions(+), 2 deletions(-)
>> create mode 100644 gcc/testsuite/gcc.dg/fhardened-1.c
>> create mode 100644 gcc/testsuite/gcc.dg/fhardened-2.c
>> create mode 100644 gcc/testsuite/gcc.dg/fhardened-3.c
>> create mode 100644 gcc/testsuite/gcc.dg/fhardened-4.c
>> create mode 100644 gcc/testsuite/gcc.dg/fhardened-5.c
>> 
>> diff --git a/gcc/common.opt b/gcc/common.opt
>> index 161a035d736..9b09c7cb3df 100644
>> --- a/gcc/common.opt
>> +++ b/gcc/common.opt
>> @@ -807,7 +807,7 @@ Common Var(warn_system_headers) Warning
>> Do not suppress warnings from system headers.
>> 
>> Wtrampolines
>> -Common Var(warn_trampolines) Warning
>> +Common Var(warn_trampolines) Warning EnabledBy(fhardened)
>> Warn whenever a trampoline is generated.
>> 
>> Wtrivial-auto-var-init
>> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
>> index 2fab4c5d71f..c1664a1a0f1 100644
>> --- a/gcc/doc/invoke.texi
>> +++ b/gcc/doc/invoke.texi
>> @@ -17745,6 +17745,7 @@ may change between major releases of GCC, but are 
>> currently:
>> -fstack-protector-strong
>> -fstack-clash-protection
>> -fcf-protection=full @r{(x86 GNU/Linux only)}
>> +-Werror=trampolines
>> }
>> 
>> The list of options enabled by @option{-fhardened} can be generated using
>> diff --git a/gcc/opts.cc b/gcc/opts.cc
>> index 5d5efaf1b9e..aa062b87cef 100644
>> --- a/gcc/opts.cc
>> +++ b/gcc/opts.cc
>> @@ -2517,6 +2517,7 @@ print_help_hardened ()
>>   printf ("  %s\n", "-fstack-protector-strong");
>>   printf ("  %s\n", "-fstack-clash-protection");
>>   printf ("  %s\n", "-fcf-protection=full");
>> +  printf ("  %s\n", "-Werror=trampolines");
>>   putchar ('\n');
>> }
>> 
>> diff --git a/gcc/testsuite/gcc.dg/fhardened-1.c 
>> b/gcc/testsuite/gcc.dg/fhardened-1.c
>> new file mode 100644
>> index 000..8710959b6f1
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.dg/fhardened-1.c
>> @@ -0,0 +1,27 @@
>> +/* { dg-do compile { target *-*-linux* *-*-gnu* } } */
>> +/* { dg-require-effective-target trampolines } */
>> +/* { dg-options "-fhardened -O" } */
>> +
>> +static void
>> +baz (int (*bar) (void))
>> +{
>> +  bar ();
>> +}
>> +
>> +int
>> +main (void)
>> +{
>> +  int a = 6;
>> +
>> +  int
>> +  bar (void)// { dg-error "trampoline" }
>> +  {
>> +return a;
>> +  }
>> +
>> +  baz (bar);
>> +
>> +  return 0;
>> +}
>> +
>> +/* { dg-prune-output "some warnings being treated as errors" } */
>> diff --git a/gcc/testsuite/gcc.dg/fhardened-2.c 
>> b/gcc/testsuite/gcc.dg/fhardened-2.c
>> new file mode 100644
>> index 000..d47512aa47f
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.dg/fhardened-2.c
>> @@ -0,0 +1,25 @@
>> +/* { dg-do compile { target *-*-linux* *-*-gnu* } } */
>> +/* { dg-require-effective-target trampolines } */
>> +/* { dg-options "-fhardened -O -Wno-trampolines" } */
>> +
>> +static void
>> +baz (int (*bar) (void))
>> +{
>> +  bar ();
>> +}
>> +
>> +int
>> +main (void)
>> +{
>> +  int a = 6;
>> +
>> +  int
>> +  bar (void)// { 

Re: [PATCH] gcc: Disallow trampolines when -fhardened

2023-12-02 Thread Martin Uecker


> Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
> 
> -- >8 --
> It came up that a good hardening strategy is to disable trampolines
> which may require executable stack.  Therefore the following patch
> adds -Werror=trampolines to -fhardened.

This would add a warning about specific code (where it is then
unclear whether rewriting it is feasible or even an improvement),
which seems different to all the other flags -fhardening has
now.

GCC now has an option to allocate trampolines on the heap,
which would seem to be a better fit.  On the other hand,
it does not work with longjmp which may be a limitation.

Martin


> 
> gcc/ChangeLog:
> 
>   * common.opt (Wtrampolines): Enable by -fhardened.
>   * doc/invoke.texi: Reflect that -fhardened enables -Werror=trampolines.
>   * opts.cc (print_help_hardened): Add -Werror=trampolines.
>   * toplev.cc (process_options): Enable -Werror=trampolines for
>   -fhardened.
> 
> gcc/testsuite/ChangeLog:
> 
>   * gcc.dg/fhardened-1.c: New test.
>   * gcc.dg/fhardened-2.c: New test.
>   * gcc.dg/fhardened-3.c: New test.
>   * gcc.dg/fhardened-4.c: New test.
>   * gcc.dg/fhardened-5.c: New test.
> ---
>  gcc/common.opt |  2 +-
>  gcc/doc/invoke.texi|  1 +
>  gcc/opts.cc|  1 +
>  gcc/testsuite/gcc.dg/fhardened-1.c | 27 +++
>  gcc/testsuite/gcc.dg/fhardened-2.c | 25 +
>  gcc/testsuite/gcc.dg/fhardened-3.c | 25 +
>  gcc/testsuite/gcc.dg/fhardened-4.c | 25 +
>  gcc/testsuite/gcc.dg/fhardened-5.c | 27 +++
>  gcc/toplev.cc  |  8 +++-
>  9 files changed, 139 insertions(+), 2 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.dg/fhardened-1.c
>  create mode 100644 gcc/testsuite/gcc.dg/fhardened-2.c
>  create mode 100644 gcc/testsuite/gcc.dg/fhardened-3.c
>  create mode 100644 gcc/testsuite/gcc.dg/fhardened-4.c
>  create mode 100644 gcc/testsuite/gcc.dg/fhardened-5.c
> 
> diff --git a/gcc/common.opt b/gcc/common.opt
> index 161a035d736..9b09c7cb3df 100644
> --- a/gcc/common.opt
> +++ b/gcc/common.opt
> @@ -807,7 +807,7 @@ Common Var(warn_system_headers) Warning
>  Do not suppress warnings from system headers.
>  
>  Wtrampolines
> -Common Var(warn_trampolines) Warning
> +Common Var(warn_trampolines) Warning EnabledBy(fhardened)
>  Warn whenever a trampoline is generated.
>  
>  Wtrivial-auto-var-init
> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
> index 2fab4c5d71f..c1664a1a0f1 100644
> --- a/gcc/doc/invoke.texi
> +++ b/gcc/doc/invoke.texi
> @@ -17745,6 +17745,7 @@ may change between major releases of GCC, but are 
> currently:
>  -fstack-protector-strong
>  -fstack-clash-protection
>  -fcf-protection=full @r{(x86 GNU/Linux only)}
> +-Werror=trampolines
>  }
>  
>  The list of options enabled by @option{-fhardened} can be generated using
> diff --git a/gcc/opts.cc b/gcc/opts.cc
> index 5d5efaf1b9e..aa062b87cef 100644
> --- a/gcc/opts.cc
> +++ b/gcc/opts.cc
> @@ -2517,6 +2517,7 @@ print_help_hardened ()
>printf ("  %s\n", "-fstack-protector-strong");
>printf ("  %s\n", "-fstack-clash-protection");
>printf ("  %s\n", "-fcf-protection=full");
> +  printf ("  %s\n", "-Werror=trampolines");
>putchar ('\n');
>  }
>  
> diff --git a/gcc/testsuite/gcc.dg/fhardened-1.c 
> b/gcc/testsuite/gcc.dg/fhardened-1.c
> new file mode 100644
> index 000..8710959b6f1
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/fhardened-1.c
> @@ -0,0 +1,27 @@
> +/* { dg-do compile { target *-*-linux* *-*-gnu* } } */
> +/* { dg-require-effective-target trampolines } */
> +/* { dg-options "-fhardened -O" } */
> +
> +static void
> +baz (int (*bar) (void))
> +{
> +  bar ();
> +}
> +
> +int
> +main (void)
> +{
> +  int a = 6;
> +
> +  int
> +  bar (void) // { dg-error "trampoline" }
> +  {
> +return a;
> +  }
> +
> +  baz (bar);
> +
> +  return 0;
> +}
> +
> +/* { dg-prune-output "some warnings being treated as errors" } */
> diff --git a/gcc/testsuite/gcc.dg/fhardened-2.c 
> b/gcc/testsuite/gcc.dg/fhardened-2.c
> new file mode 100644
> index 000..d47512aa47f
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/fhardened-2.c
> @@ -0,0 +1,25 @@
> +/* { dg-do compile { target *-*-linux* *-*-gnu* } } */
> +/* { dg-require-effective-target trampolines } */
> +/* { dg-options "-fhardened -O -Wno-trampolines" } */
> +
> +static void
> +baz (int (*bar) (void))
> +{
> +  bar ();
> +}
> +
> +int
> +main (void)
> +{
> +  int a = 6;
> +
> +  int
> +  bar (void) // { dg-bogus "trampoline" }
> +  {
> +return a;
> +  }
> +
> +  baz (bar);
> +
> +  return 0;
> +}
> diff --git a/gcc/testsuite/gcc.dg/fhardened-3.c 
> b/gcc/testsuite/gcc.dg/fhardened-3.c
> new file mode 100644
> index 000..cebae13d8be
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/fhardened-3.c
> @@ -0,0 +1,25 @@
> +/* { dg-do compile { target *-*-linux* *-*-gnu* } } */

Re: [PATCH] gcc: Disallow trampolines when -fhardened

2023-12-01 Thread Jakub Jelinek
On Fri, Dec 01, 2023 at 03:53:14PM -0500, Marek Polacek wrote:
> On Fri, Dec 01, 2023 at 11:44:28AM -0800, Andrew Pinski wrote:
> > On Fri, Dec 1, 2023, 11:36 Marek Polacek  wrote:
> > 
> > > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
> > >
> > > -- >8 --
> > > It came up that a good hardening strategy is to disable trampolines
> > > which may require executable stack.  Therefore the following patch
> > > adds -Werror=trampolines to -fhardened.
> > >
> > 
> > It might make sense to add a fortran testcase too. Especially when that and
> > Ada are 2 biggest users of trampolines.
> 
> I don't know either of these languages to write a test, and I don't see
> anything that mentions the word trampoline in gfortran.dg/.  Ada has

program nesting
  integer :: i
  procedure(), pointer :: p
  p => foo
  i = 5
  call p
  if (i.ne.6) stop 1
contains
  subroutine foo
i = i + 1
  end subroutine
end program

(obviously at -O0 only)?

Jakub



Re: [PATCH] gcc: Disallow trampolines when -fhardened

2023-12-01 Thread Marek Polacek
On Fri, Dec 01, 2023 at 11:44:28AM -0800, Andrew Pinski wrote:
> On Fri, Dec 1, 2023, 11:36 Marek Polacek  wrote:
> 
> > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
> >
> > -- >8 --
> > It came up that a good hardening strategy is to disable trampolines
> > which may require executable stack.  Therefore the following patch
> > adds -Werror=trampolines to -fhardened.
> >
> 
> It might make sense to add a fortran testcase too. Especially when that and
> Ada are 2 biggest users of trampolines.

I don't know either of these languages to write a test, and I don't see
anything that mentions the word trampoline in gfortran.dg/.  Ada has
gnat.dg/trampoline3.adb but:

$ gcc -c -Wtrampolines trampoline3.adb
trampoline3.adb:6:03: warning: variable "A" is read but never assigned [-gnatwv]

so there is no warning.

Marek



Re: [PATCH] gcc: Disallow trampolines when -fhardened

2023-12-01 Thread Andrew Pinski
On Fri, Dec 1, 2023, 11:36 Marek Polacek  wrote:

> Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
>
> -- >8 --
> It came up that a good hardening strategy is to disable trampolines
> which may require executable stack.  Therefore the following patch
> adds -Werror=trampolines to -fhardened.
>

It might make sense to add a fortran testcase too. Especially when that and
Ada are 2 biggest users of trampolines.

Thanks,
Andrew




> gcc/ChangeLog:
>
> * common.opt (Wtrampolines): Enable by -fhardened.
> * doc/invoke.texi: Reflect that -fhardened enables
> -Werror=trampolines.
> * opts.cc (print_help_hardened): Add -Werror=trampolines.
> * toplev.cc (process_options): Enable -Werror=trampolines for
> -fhardened.
>
> gcc/testsuite/ChangeLog:
>
> * gcc.dg/fhardened-1.c: New test.
> * gcc.dg/fhardened-2.c: New test.
> * gcc.dg/fhardened-3.c: New test.
> * gcc.dg/fhardened-4.c: New test.
> * gcc.dg/fhardened-5.c: New test.
> ---
>  gcc/common.opt |  2 +-
>  gcc/doc/invoke.texi|  1 +
>  gcc/opts.cc|  1 +
>  gcc/testsuite/gcc.dg/fhardened-1.c | 27 +++
>  gcc/testsuite/gcc.dg/fhardened-2.c | 25 +
>  gcc/testsuite/gcc.dg/fhardened-3.c | 25 +
>  gcc/testsuite/gcc.dg/fhardened-4.c | 25 +
>  gcc/testsuite/gcc.dg/fhardened-5.c | 27 +++
>  gcc/toplev.cc  |  8 +++-
>  9 files changed, 139 insertions(+), 2 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.dg/fhardened-1.c
>  create mode 100644 gcc/testsuite/gcc.dg/fhardened-2.c
>  create mode 100644 gcc/testsuite/gcc.dg/fhardened-3.c
>  create mode 100644 gcc/testsuite/gcc.dg/fhardened-4.c
>  create mode 100644 gcc/testsuite/gcc.dg/fhardened-5.c
>
> diff --git a/gcc/common.opt b/gcc/common.opt
> index 161a035d736..9b09c7cb3df 100644
> --- a/gcc/common.opt
> +++ b/gcc/common.opt
> @@ -807,7 +807,7 @@ Common Var(warn_system_headers) Warning
>  Do not suppress warnings from system headers.
>
>  Wtrampolines
> -Common Var(warn_trampolines) Warning
> +Common Var(warn_trampolines) Warning EnabledBy(fhardened)
>  Warn whenever a trampoline is generated.
>
>  Wtrivial-auto-var-init
> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
> index 2fab4c5d71f..c1664a1a0f1 100644
> --- a/gcc/doc/invoke.texi
> +++ b/gcc/doc/invoke.texi
> @@ -17745,6 +17745,7 @@ may change between major releases of GCC, but are
> currently:
>  -fstack-protector-strong
>  -fstack-clash-protection
>  -fcf-protection=full @r{(x86 GNU/Linux only)}
> +-Werror=trampolines
>  }
>
>  The list of options enabled by @option{-fhardened} can be generated using
> diff --git a/gcc/opts.cc b/gcc/opts.cc
> index 5d5efaf1b9e..aa062b87cef 100644
> --- a/gcc/opts.cc
> +++ b/gcc/opts.cc
> @@ -2517,6 +2517,7 @@ print_help_hardened ()
>printf ("  %s\n", "-fstack-protector-strong");
>printf ("  %s\n", "-fstack-clash-protection");
>printf ("  %s\n", "-fcf-protection=full");
> +  printf ("  %s\n", "-Werror=trampolines");
>putchar ('\n');
>  }
>
> diff --git a/gcc/testsuite/gcc.dg/fhardened-1.c
> b/gcc/testsuite/gcc.dg/fhardened-1.c
> new file mode 100644
> index 000..8710959b6f1
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/fhardened-1.c
> @@ -0,0 +1,27 @@
> +/* { dg-do compile { target *-*-linux* *-*-gnu* } } */
> +/* { dg-require-effective-target trampolines } */
> +/* { dg-options "-fhardened -O" } */
> +
> +static void
> +baz (int (*bar) (void))
> +{
> +  bar ();
> +}
> +
> +int
> +main (void)
> +{
> +  int a = 6;
> +
> +  int
> +  bar (void)   // { dg-error "trampoline" }
> +  {
> +return a;
> +  }
> +
> +  baz (bar);
> +
> +  return 0;
> +}
> +
> +/* { dg-prune-output "some warnings being treated as errors" } */
> diff --git a/gcc/testsuite/gcc.dg/fhardened-2.c
> b/gcc/testsuite/gcc.dg/fhardened-2.c
> new file mode 100644
> index 000..d47512aa47f
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/fhardened-2.c
> @@ -0,0 +1,25 @@
> +/* { dg-do compile { target *-*-linux* *-*-gnu* } } */
> +/* { dg-require-effective-target trampolines } */
> +/* { dg-options "-fhardened -O -Wno-trampolines" } */
> +
> +static void
> +baz (int (*bar) (void))
> +{
> +  bar ();
> +}
> +
> +int
> +main (void)
> +{
> +  int a = 6;
> +
> +  int
> +  bar (void)   // { dg-bogus "trampoline" }
> +  {
> +return a;
> +  }
> +
> +  baz (bar);
> +
> +  return 0;
> +}
> diff --git a/gcc/testsuite/gcc.dg/fhardened-3.c
> b/gcc/testsuite/gcc.dg/fhardened-3.c
> new file mode 100644
> index 000..cebae13d8be
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/fhardened-3.c
> @@ -0,0 +1,25 @@
> +/* { dg-do compile { target *-*-linux* *-*-gnu* } } */
> +/* { dg-require-effective-target trampolines } */
> +/* { dg-options "-fhardened -O -Wno-error" } */
> +
> +static void
> +baz (int (*bar) (void))
> +{
> +  bar ();
> +}
> +
> +int
> 

[PATCH] gcc: Disallow trampolines when -fhardened

2023-12-01 Thread Marek Polacek
Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?

-- >8 --
It came up that a good hardening strategy is to disable trampolines
which may require executable stack.  Therefore the following patch
adds -Werror=trampolines to -fhardened.

gcc/ChangeLog:

* common.opt (Wtrampolines): Enable by -fhardened.
* doc/invoke.texi: Reflect that -fhardened enables -Werror=trampolines.
* opts.cc (print_help_hardened): Add -Werror=trampolines.
* toplev.cc (process_options): Enable -Werror=trampolines for
-fhardened.

gcc/testsuite/ChangeLog:

* gcc.dg/fhardened-1.c: New test.
* gcc.dg/fhardened-2.c: New test.
* gcc.dg/fhardened-3.c: New test.
* gcc.dg/fhardened-4.c: New test.
* gcc.dg/fhardened-5.c: New test.
---
 gcc/common.opt |  2 +-
 gcc/doc/invoke.texi|  1 +
 gcc/opts.cc|  1 +
 gcc/testsuite/gcc.dg/fhardened-1.c | 27 +++
 gcc/testsuite/gcc.dg/fhardened-2.c | 25 +
 gcc/testsuite/gcc.dg/fhardened-3.c | 25 +
 gcc/testsuite/gcc.dg/fhardened-4.c | 25 +
 gcc/testsuite/gcc.dg/fhardened-5.c | 27 +++
 gcc/toplev.cc  |  8 +++-
 9 files changed, 139 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/fhardened-1.c
 create mode 100644 gcc/testsuite/gcc.dg/fhardened-2.c
 create mode 100644 gcc/testsuite/gcc.dg/fhardened-3.c
 create mode 100644 gcc/testsuite/gcc.dg/fhardened-4.c
 create mode 100644 gcc/testsuite/gcc.dg/fhardened-5.c

diff --git a/gcc/common.opt b/gcc/common.opt
index 161a035d736..9b09c7cb3df 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -807,7 +807,7 @@ Common Var(warn_system_headers) Warning
 Do not suppress warnings from system headers.
 
 Wtrampolines
-Common Var(warn_trampolines) Warning
+Common Var(warn_trampolines) Warning EnabledBy(fhardened)
 Warn whenever a trampoline is generated.
 
 Wtrivial-auto-var-init
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 2fab4c5d71f..c1664a1a0f1 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -17745,6 +17745,7 @@ may change between major releases of GCC, but are 
currently:
 -fstack-protector-strong
 -fstack-clash-protection
 -fcf-protection=full @r{(x86 GNU/Linux only)}
+-Werror=trampolines
 }
 
 The list of options enabled by @option{-fhardened} can be generated using
diff --git a/gcc/opts.cc b/gcc/opts.cc
index 5d5efaf1b9e..aa062b87cef 100644
--- a/gcc/opts.cc
+++ b/gcc/opts.cc
@@ -2517,6 +2517,7 @@ print_help_hardened ()
   printf ("  %s\n", "-fstack-protector-strong");
   printf ("  %s\n", "-fstack-clash-protection");
   printf ("  %s\n", "-fcf-protection=full");
+  printf ("  %s\n", "-Werror=trampolines");
   putchar ('\n');
 }
 
diff --git a/gcc/testsuite/gcc.dg/fhardened-1.c 
b/gcc/testsuite/gcc.dg/fhardened-1.c
new file mode 100644
index 000..8710959b6f1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/fhardened-1.c
@@ -0,0 +1,27 @@
+/* { dg-do compile { target *-*-linux* *-*-gnu* } } */
+/* { dg-require-effective-target trampolines } */
+/* { dg-options "-fhardened -O" } */
+
+static void
+baz (int (*bar) (void))
+{
+  bar ();
+}
+
+int
+main (void)
+{
+  int a = 6;
+
+  int
+  bar (void)   // { dg-error "trampoline" }
+  {
+return a;
+  }
+
+  baz (bar);
+
+  return 0;
+}
+
+/* { dg-prune-output "some warnings being treated as errors" } */
diff --git a/gcc/testsuite/gcc.dg/fhardened-2.c 
b/gcc/testsuite/gcc.dg/fhardened-2.c
new file mode 100644
index 000..d47512aa47f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/fhardened-2.c
@@ -0,0 +1,25 @@
+/* { dg-do compile { target *-*-linux* *-*-gnu* } } */
+/* { dg-require-effective-target trampolines } */
+/* { dg-options "-fhardened -O -Wno-trampolines" } */
+
+static void
+baz (int (*bar) (void))
+{
+  bar ();
+}
+
+int
+main (void)
+{
+  int a = 6;
+
+  int
+  bar (void)   // { dg-bogus "trampoline" }
+  {
+return a;
+  }
+
+  baz (bar);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/fhardened-3.c 
b/gcc/testsuite/gcc.dg/fhardened-3.c
new file mode 100644
index 000..cebae13d8be
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/fhardened-3.c
@@ -0,0 +1,25 @@
+/* { dg-do compile { target *-*-linux* *-*-gnu* } } */
+/* { dg-require-effective-target trampolines } */
+/* { dg-options "-fhardened -O -Wno-error" } */
+
+static void
+baz (int (*bar) (void))
+{
+  bar ();
+}
+
+int
+main (void)
+{
+  int a = 6;
+
+  int
+  bar (void)   // { dg-warning "trampoline" }
+  {
+return a;
+  }
+
+  baz (bar);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/fhardened-4.c 
b/gcc/testsuite/gcc.dg/fhardened-4.c
new file mode 100644
index 000..7e62ed3385d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/fhardened-4.c
@@ -0,0 +1,25 @@
+/* { dg-do compile { target *-*-linux* *-*-gnu* } } */
+/* { dg-require-effective-target trampolines } */
+/* { dg-options "-fhardened -O