Bug 1983526

Summary: Provide a more reliable way to exclude code from stack-protector annocheck checks
Product: Red Hat Enterprise Linux 9 Reporter: Siddhesh Poyarekar <sipoyare>
Component: glibcAssignee: glibc team <glibc-bugzilla>
Status: CLOSED UPSTREAM QA Contact: qe-baseos-tools-bugs
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: 9.0CC: ashankar, codonell, dj, fweimer, jpazdziora, mnewsome, nickc, pfrankli, rlemosor, sipoyare
Target Milestone: betaKeywords: FutureFeature, Triaged
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2021-11-05 13:38:58 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 2044387    

Description Siddhesh Poyarekar 2021-07-19 04:11:49 UTC
Description of problem:
annobin flags early startup functions in glibc as unprotected with stack-protector.  These functions cannot however be built with -fstack-protector because the stack guard has not yet been initialized.  Any changes to these functions require new exceptions in annoheck, which is not a scalable solution.  Using -fno-stack-protector as a hint is also not feasible because some projects wrongly do that in their code and annocheck would want to flag that.

Provide a way for annocheck to identify that certain code is early startup and hence not eligible for stack-protector checks.

Comment 1 Nick Clifton 2021-07-19 16:39:56 UTC
To be clear - there needs to be a way to tell annocheck to skip any particular test or tests, not just stack protector.  For example memory handling functions like free_mem are not compiled with FORTIFY_SOURCE enabled.

In addition it is not just start-up code that needs this annotation.  For example the stack checking functions (eg: __stack_chk_fail_local) do not themselves have stack protection enabled.

Comment 2 Carlos O'Donell 2021-08-06 19:15:50 UTC
(In reply to Nick Clifton from comment #1)
> To be clear - there needs to be a way to tell annocheck to skip any
> particular test or tests, not just stack protector.  For example memory
> handling functions like free_mem are not compiled with FORTIFY_SOURCE
> enabled.
> 
> In addition it is not just start-up code that needs this annotation.  For
> example the stack checking functions (eg: __stack_chk_fail_local) do not
> themselves have stack protection enabled.

I want to urge caution here.

If a system has resiliancy by having two indirect paths for information we have redundancy.

This prevents common mode failure.

If glibc defines it's own exclusion lists then the generated code and the list have common mode failure problems.

I would like to avoid such common mode failures.

The best path forward for me would be exclusion lists in annocheck based on what glibc is doing.

I'm not sure we need a more reliable way, because such a way has costs, may create common mode failures, etc.

It may be sufficient to just update the exclusions.

Comment 3 Nick Clifton 2021-08-11 14:22:57 UTC
(In reply to Carlos O'Donell from comment #2)

> If a system has resiliancy by having two indirect paths for information we
> have redundancy.
> 
> This prevents common mode failure.
> 
> If glibc defines it's own exclusion lists then the generated code and the
> list have common mode failure problems.

But this does also mean that there is only one point of failure - the lists.

However I would agree that using a generated list is a bad idea.  There is 
no easy way to ensure that annocheck will use the correct list, or even
that it will be able to find a list at all.


> The best path forward for me would be exclusion lists in annocheck based on
> what glibc is doing.

This is the current solution, but it does mean that annocheck needs regular
updating when glibc changes its unsecured code and/or the compiler changes
such that a different symbol ends up appearing at the start of the region
of unsecured instructions.

My personal preference would be for glibc to include its own annobin notes
in the assembler sources (and unsecure C sources) that it compiles.  Notes 
that tell annocheck that the code is OK.  Then there would be no need for 
annocheck to have exceptions at all.

Comment 4 Carlos O'Donell 2021-08-12 21:56:25 UTC
(In reply to Nick Clifton from comment #3)
> (In reply to Carlos O'Donell from comment #2)
> 
> > If a system has resiliancy by having two indirect paths for information we
> > have redundancy.
> > 
> > This prevents common mode failure.
> > 
> > If glibc defines it's own exclusion lists then the generated code and the
> > list have common mode failure problems.
> 
> But this does also mean that there is only one point of failure - the lists.

The concept is called "failing safe." Which means that even though Annobin
has a distinct list of failures and because that list is out of date, raises
false positives such a situation is "failing safe." That is OK.

> However I would agree that using a generated list is a bad idea.  There is 
> no easy way to ensure that annocheck will use the correct list, or even
> that it will be able to find a list at all.
 
That is a technical problem that could be solved, but not one that I think
should be solved.
 
> > The best path forward for me would be exclusion lists in annocheck based on
> > what glibc is doing.
> 
> This is the current solution, but it does mean that annocheck needs regular
> updating when glibc changes its unsecured code and/or the compiler changes
> such that a different symbol ends up appearing at the start of the region
> of unsecured instructions.

Correct, and that is OK IMO. We should look at ways to make this process
smoother.

> My personal preference would be for glibc to include its own annobin notes
> in the assembler sources (and unsecure C sources) that it compiles.  Notes 
> that tell annocheck that the code is OK.  Then there would be no need for 
> annocheck to have exceptions at all.

I disagree strongly with this as a technical direction since it cannot be
described as "safe." We must not have common mode failures in this case.

Annobin and Annocheck are critical to our security story with our tooling,
and we must move in a direction where it is robust and as correct as we
can make the results.

A project which I would support:

- Upstream glibc build infrastructure work to enable sanitizers, and also
  use that work to clearly demarcate what is *before* hardening and what
  is *after* hardening. The sanitizers likewise can't run in early
  startup.

- Once the line is clearly demarcated glibc works to make it very
  reliable in what the startup will look like so annocheck/annobin
  notes are not required.

Comment 5 Nick Clifton 2021-08-17 11:35:01 UTC
(In reply to Carlos O'Donell from comment #4)
 
> A project which I would support:
> 
> - Upstream glibc build infrastructure work to enable sanitizers, and also
>   use that work to clearly demarcate what is *before* hardening and what
>   is *after* hardening. The sanitizers likewise can't run in early
>   startup.
> 
> - Once the line is clearly demarcated glibc works to make it very
>   reliable in what the startup will look like so annocheck/annobin
>   notes are not required.

OK, I can definitely support a project like that.

Cheers
  Nick

Comment 6 Carlos O'Donell 2021-11-05 13:38:58 UTC
I'm marking this bug CLOSED UPSTREAM. I want to be able to find this bug again as I review what might be fixed upstream.

We need to do the work upstream to split the build infra and layer the *before* hardening and *after* hardening parts of glibc.

This is going to be a future project for somone on the glibc team.

Until then we don't need to track this for RHEL9.

There is no upstream bug for this.