Bug 2233236 (CVE-2023-4039) - CVE-2023-4039 gcc: -fstack-protector fails to guard dynamic stack allocations on ARM64
Summary: CVE-2023-4039 gcc: -fstack-protector fails to guard dynamic stack allocations...
Keywords:
Status: CLOSED NOTABUG
Alias: CVE-2023-4039
Product: Security Response
Classification: Other
Component: vulnerability
Version: unspecified
Hardware: All
OS: Linux
medium
medium
Target Milestone: ---
Assignee: Product Security
QA Contact:
URL:
Whiteboard:
Depends On: 2233240 2233260 2233261 2233241 2233242 2233249 2233250 2233251 2233252 2233253 2233254 2233255 2233256 2233257 2233258 2233259 2235333 2235336 2238670 2238671
Blocks: 2233230
TreeView+ depends on / blocked
 
Reported: 2023-08-21 18:52 UTC by Guilherme de Almeida Suckevicz
Modified: 2023-11-17 14:08 UTC (History)
50 users (show)

Fixed In Version:
Doc Type: If docs needed, set a value
Doc Text:
A vulnerability was found in GCC. The GCC's stack protection feature, enabled with the flag -fstack-protector, aims to detect buffer overflows in C/C++ function local variables that might allow an attacker to overwrite saved registers on the stack. If an attacker can modify saved register values, it may be possible for them to subvert program flow control. The feature operates by placing a canary value between local variables and saved registers on the stack on function entry and triggers an error handler on function exit if the canary value has been unexpectedly modified. When targeting AArch64, this feature did not protect the saved registers from overflows in C99-style dynamically-sized local variables and alloca() objects. Other local variables, including statically-sized local arrays, are not affected because of their different placement on the stack relative to saved registers.
Clone Of:
Environment:
Last Closed: 2023-11-17 13:46:59 UTC
Embargoed:


Attachments (Terms of Use)

Description Guilherme de Almeida Suckevicz 2023-08-21 18:52:36 UTC
GCC's stack protection feature (enabled with the flag -fstack-protector) aims to detect buffer overflows in C/C++ function local variables that might allow an attacker to overwrite saved registers on the stack. If an attacker can modify saved register values then it might be possible for them to subvert program flow control. The feature operates by placing a canary value between local variables and saved registers on the stack on function entry, and triggers an error handler on function exit if the canary value has been unexpectedly modified.

When targeting AArch64, this feature did not protect the saved registers from overflows in dynamically-sized local variables, these being C99-style variable length arrays and alloca() objects. Other local variables, including statically-sized local arrays, are not affected because of their different placement on the stack relative to saved registers. This issue affects all GCC releases. Arm has reserved CVE-2023-4039 for this issue.

GCC also has a feature (enabled with the flag -fstack-clash-protection) to protect against the Stack Clash vulnerability identified by the Qualys Research Team in 2017. This GCC feature ensures that all stack allocations are broken down into chunks that are no bigger than the OS's guard page size, with each allocation being probed via a store to memory. While developing the fix for the stack protection vulnerability, Arm also identified a case in which the stack clash protection feature could fail to probe an allocation properly, and so leave an entire guard page unprobed. As it stands, this missed probe can only occur in extreme circumstances: specifically, vulnerable code must have a function call with at least 4096 16-byte arguments or 8192 8-byte arguments, or some other similar combination. However, the fix for the stack protection issue removes this condition. Instead, it would be enough for vulnerable code to have more than 64k of local variables. It is therefore important that both issues are fixed together.

Arm has also examined GCC targeting AArch32 and clang targeting AArch32 and AArch64 and believes none of these are affected by these issues.

What is the fix?

The fix for the stack protection issue is to modify GCC to generate an alternative stack frame that places all local variables below saved registers, with the stack-protector canary between them. Developers worried about this issue will then need to recompile their software using the fixed compiler. Developers should be aware that the fixed compiler will generate slightly different code than before and this may impact code size or performance. The modified stack layout is local to each function and is not expected to introduce any binary compatibility issues.

The fix for the stack clash protection issue is to modify some boundary conditions in generated AArch64 code to ensure that all allocations are probed at the correct offset. This is not expected to have any noticeable effect on code size or performance.

Comment 32 Florian Weimer 2023-09-12 15:46:43 UTC
Public via:

[PATCH 00/19] aarch64: Fix -fstack-protector issue
https://inbox.sourceware.org/gcc-patches/20230912152529.3322336-1-richard.sandiford@arm.com/

Quoting from that message:

This series of patches fixes deficiencies in GCC's -fstack-protector implementation for AArch64 when using dynamically allocated stack space.  This is CVE-2023-4039.  See:

https://developer.arm.com/Arm%20Security%20Center/GCC%20Stack%20Protector%20Vulnerability%20AArch64
https://github.com/metaredteam/external-disclosures/security/advisories/GHSA-x7ch-h5rf-w2mf

for more details.

The fix is to put the saved registers above the locals area when -fstack-protector is used.

The series also fixes a stack-clash problem that I found while working on the CVE.  In unpatched sources, the stack-clash problem would only trigger for unrealistic numbers of arguments (8K 64-bit arguments, or an equivalent).  But it would be a more significant issue with the new -fstack-protector frame layout.  It's therefore important that both problems are fixed together.

Comment 33 Sandipan Roy 2023-09-13 05:06:44 UTC
Created gcc tracking bugs for this issue:

Affects: fedora-all [bug 2238670]


Created mingw-gcc tracking bugs for this issue:

Affects: fedora-all [bug 2238671]


Note You need to log in before you can comment on or make changes to this bug.