-
Notifications
You must be signed in to change notification settings - Fork 22
Restore the stack canary #1273
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Restore the stack canary #1273
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #1273 +/- ##
=======================================
Coverage 62.41% 62.41%
=======================================
Files 14 14
Lines 1868 1868
=======================================
Hits 1166 1166
Misses 702 702
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
e51c779 to
77c50d1
Compare
|
I verified on a locally built clone of the boilerplate:
|
This will allow it to be accessible from several source files.
This restores a behaviour similar to how it used to work in the old io_exchange: all apps call os_io_init in the preamble (the legacy code used io_seproxyhal_init instead), and we check the canary every time the io send/receive functions are called. Since os_io_init, os_io_rx_evt and os_io_tx_cmd in os_io.c are only used if USE_OS_IO_STACK is not defined, the same initialization and checks are also implemented for the analogous weak functions defined in syscalls.c.
99b04dd to
dbdf70b
Compare
This allows to exit with a recognizable value.
dbdf70b to
a4c52f6
Compare
|
In a4c52f6, I replaced |
| #ifdef HAVE_BOLOS_APP_STACK_CANARY | ||
| #define APP_STACK_CANARY_MAGIC 0xDEAD0031 | ||
| #endif // HAVE_BOLOS_APP_STACK_CANARY |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'll need to check if this causes issues with some applications still using legacy IO and the canary
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nothing should change for them. These are moved in os_io.h, which is imported by os_io_legacy.
The only difference is that this define is now visible in anything that imports os_io.h, so it could only conflict if they have a different define with the same name.
| #ifdef HAVE_BOLOS_APP_STACK_CANARY | ||
| // if the canary is corrupted, reset the device | ||
| if (app_stack_canary != APP_STACK_CANARY_MAGIC) { | ||
| os_sched_exit(APP_STACK_CANARY_CORRUPTED_EXIT_VALUE); | ||
| } | ||
| #endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we can factorize this snippet
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was worried about introducing an additional function because if we know the stack is already corrupted, we should use it as little as possible.
Perhaps we can use a macro.
| #ifdef HAVE_BOLOS_APP_STACK_CANARY | ||
| // if the canary is corrupted, reset the device | ||
| if (app_stack_canary != APP_STACK_CANARY_MAGIC) { | ||
| os_sched_exit(APP_STACK_CANARY_CORRUPTED_EXIT_VALUE); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the perfect world it should be automatically tested against an app with and without legacy IO stack.
But we do not seem to have an infrastructure for this.
Might be https://github.com/LedgerHQ/speculos/tree/master/tests/c, but also it does not seem to fit.
| #ifdef HAVE_BOLOS_APP_STACK_CANARY | ||
| app_stack_canary = APP_STACK_CANARY_MAGIC; | ||
| #endif // HAVE_BOLOS_APP_STACK_CANARY | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer to not modify the syscall APIs.
Why not init in an early app start entrypoint?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the syscalls APIs are the only place used for io for most apps (that is, after io revamp and defining USE_OS_IO_STACK). So even if you find a different place for initialization, you still need to modify syscalls.c to check for canary corruption on os_io_rx_evt/os_io_tx_cmd.
(I chose os_io_init because I checked that both the C and the Rust SDK app preamble calls it before any real application code.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Syscalls are not called directly by apps, there is SDK functions that can be used. Let's discuss to find a better solution.
bboilot-ledger
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM from a security standpoint. I agree with other comments especially about modifying syscalls APIs. Unfortunately, I do not see neither where we could put those snippet so it used by apps by default without any snippet needed in the app's codebase.
Is there any impact regarding apps built with zxlib/sdk?
Description
Restores the functionality of
HAVE_BOLOS_APP_STACK_CANARY.Initializes the canary on
os_io_init, and checks it on receive/sends.This restores a behaviour similar to how it used to work in the old
io_exchange: all apps callos_io_initin the preamble (the legacy code usedio_seproxyhal_initinstead), and we check the canary every time the io send/receive functions are called.Since
os_io_init,os_io_rx_evtandos_io_tx_cmdinos_io.care only used ifUSE_OS_IO_STACKis not defined, the same initialization and checks are also implemented for the analogous weak functions defined insyscalls.c.Changes include
Auto cherry-pick in API_LEVEL
[x] TARGET_API_LEVEL: API_LEVEL_24
[x] TARGET_API_LEVEL: API_LEVEL_25