Strange optimization of TrustZone callback security determination
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
GNU Arm Embedded Toolchain |
New
|
Undecided
|
Unassigned |
Bug Description
This was posted to the Answers section, but there have been no replies.
Pertinent bug report info:
- Issue present on 10-2020-q2, 9-2020-q2 and 9-2019-q4 at least
- Using Linux binaries
---------
Consider the following basic implementation of a callback system in a secure TrustZone environment:
```c
typedef __attribute_
void (* callback_
void secure_
{
__BKPT(0);
}
void set_callback(void (p_callback)(void))
{
bool callback_is_secure = (NULL == cmse_check_
callback_ptr = callback_is_secure ? p_callback : (void (*)(void)
}
__attribute_
{
set_
}
void call_callback(void)
{
if(
{
}
else
{
ns_callback p_callback = (ns_callback) (callback_ptr);
}
}
void main(void) {
set_
call_
while(1)
{
__BKPT(0);
}
}
```
At O0 and O1, the program halts at the breakpoint in `call_callback`. However, at O2 `call_callback` is optimized to always call the `else` branch, causing a Secure Fault as `p_callback` points to a secure function.
If `volatile` is added to the `ns_callback` typedef as below:
```c
typedef __attribute_
```
...then at O2 the compiler correctly picks the true branch in `call_callback` but still optimizes away the other branch, causing issues if `p_callback` is non-secure.
Is this behavior expected? If so, is there a recommended way to ensure both branches of `call_callback` are available without using pragmas or dropping the optimization level?
Ich bin bis 28.09. nicht im Haus und kann Ihre Nachricht daher leider nicht bearbeiten. In dringenden Fällen wenden Sie sich bitte an <email address hidden> bzw. für technische Fragen an <email address hidden>.
I am out of office until September 28th and won't be able to read your message. In urgent cases, please refer to <email address hidden> or for technical questions to <email address hidden>.
Mit freundlichen Grüßen / Best regards
Steffen Wolfer
--
Dipl.-Inform. Steffen Wolfer
Software Engineer Embedded Systems
WEISS ROBOTICS GmbH & Co. KG Käferle- Str. 8
Karl-Heinrich-
D-71640 Ludwigsburg, Germany
Phone: +49 7141 94702-22 www.weiss- robotics. com
Fax: +49 7141 94702-99
http://
Sitz der Gesellschaft: Ludwigsburg
Registergericht Stuttgart, HRA725006
Pers. haftende Gesellschafterin:
Weiss Robotics Verwaltungs-GmbH, Sitz Ludwigsburg
Registergericht Stuttgart, HRB73310
Geschäftsführer: Dr. Karsten Weiß
Public bug reported:
This was posted to the Answers section, but there have been no replies.
Pertinent bug report info:
- Issue present on 10-2020-q2, 9-2020-q2 and 9-2019-q4 at least
- Using Linux binaries
---------
Consider the following basic implementation of a callback system in a
secure TrustZone environment:
```c _((cmse_ nonsecure_ call)) void (* ns_callback)(void);
typedef __attribute_
void (* callback_ ptr)(void) ;
void secure_ callback( void)
{
__BKPT(0);
}
void set_callback(void (p_callback)(void)) pointed_ object( (void *) p_callback, CMSE_AU_ NONSECURE) );
{
bool callback_is_secure = (NULL == cmse_check_
callback_ptr = callback_is_secure ? p_callback : (void (*)(void) )cmse_nsfptr_ create( p_callback) ;
}
__attribute_ _((cmse_ nonsecure_ entry)) void set_callback_ guard(void (p_callback)(void)) callback( p_callback) ;
{
set_
}
void call_callback(void) !cmse_is_ nsfptr( callback_ ptr))
callback_ ptr();
p_callback( );
{
if(
{
}
else
{
ns_callback p_callback = (ns_callback) (callback_ptr);
}
}
void main(void) {
set_ callback( secure_ callback) ;
call_ callback( );
while(1)
{
__BKPT(0);
}
}
```
At O0 and O1, the program halts at the breakpoint in `call_callback`.
However, at O2 `call_callback` is optimized to always call the `else`
branch, causing a Secure Fault as `p_callback` points to a secure
function.
If `volatile` is added to the `ns_callback` typedef as below:
```c _((cmse_ nonsecure_ call)) void (* volatile ns_callback)(void);
typedef __attribute_
```
...then at O2 the compiler correctly picks the true branch in
`call_callback` but still optimizes away the other branch, causing
issues if `p_callback` is non-secure.
Is this behavior expected? If so, is there a recommended way to ensure
both branches of `call_callback` are available without using pragmas or
dropping the optimization level?
** Affects: gcc-arm-embedded
Importance: Undecided
Status: New
-- /bugs.launchpad .net/bugs/ 1895867
You received this bug notification because you are subscribed to GNU Arm
Embedded Toolchain.
Matching subscriptions: Älles
https:/
Title:
Strange optimization of TrustZone callback security determination
Status in GNU Arm Embed...