-
Notifications
You must be signed in to change notification settings - Fork 84
Add a section to place the veneers in memory #297
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @adamgreig (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
With this then one can do: let peripherals = Peripherals::take().unwrap();
let mut sau = peripherals.SAU;
// Those symbols come from the linker file.
extern "C" {
static mut __veneer_base: u32;
static mut __veneer_limit: u32;
}
let base_nsc = unsafe { core::mem::transmute::<&mut u32, u32>(&mut __veneer_base) };
let limit_nsc = unsafe { core::mem::transmute::<&mut u32, u32>(&mut __veneer_limit) };
// Non-Secure Callable area
sau.set_region(2, SauRegion {
base_address: base_nsc,
limit_address: limit_nsc | 0x1F,
attribute: SauRegionAttribute::NonSecureCallable,
}).unwrap();
sau.enable(); to configure its Non-Secure Callable section 🚀 |
__veneer_base = .; | ||
*(.gnu.sgstubs*) | ||
__veneer_limit = .; | ||
} > FLASH |
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.
Are there any plans to support this in other linkers, like LLD? Presumably those won't use the GNU section, so we should make sure that we can support that without having multiple definitions of the __veneer_
symbols.
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.
Are there any plans to support this in other linkers, like LLD?
I am not aware of any plans for LLVM tools.
That's a good point. I think it is possible to have #define
in linker scripts and pass preprocessor constants to activate some code or not. We could do something like that in the future to either choose the LLVM or GNU sections, using the link-arg
option in .cargo/config
.
Alternatively we can prefix those symbols with gnu_
for now (eg __gnu_veneer_base
).
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.
Is it worth putting those symbols immediately outside the .gnu.sgstubs
section, for the same reasons we have with the other sections? That way we could define multiple sections within those symbol bounds, or users could define their own in memory.x
without needing to change link.x.in.
Should the end symbol be aligned?
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.
Is it worth putting those symbols immediately outside the .gnu.sgstubs section, for the same reasons we have with the other sections?
Sure that sounds like a good idea! That could solve the problem we were talking just before. Do you mean with "users could define their own in memory.x without needing to change link.x.in" that users will be able to override those symbols to put the ones they want?
If that is the case I would be a little bit worried. The content of what is in between __veneer_base
and __veneer_limit
can be an entry point to the Secure world, needs to be as small as possible and carefully audited. Although Secure application developpers ultimately need to be trusted that is maybe better to leave those symbols being only maintained here, just to avoid possible errors that could lead to security issues?
Should the end symbol be aligned?
It is fine if it is not, ultimately you would do limit_nsc | 0x1F
as in the example above to align it with 32 bytes anyway. Maybe better to keep the information of the real size of the veneers there.
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.
Users (the top-level project, not libraries) can already override anything in link.x.in (by specifying their own link.x). If the symbols are outside the section, then users can put a new section into their memory.x
and specify INSERT AFTER .gnu.sgstubs
and the section will be 'inside' the start/end symbols but with whatever name they require.
In any event nothing stops any user or library code writing #[link_section=".gnu.sgstubs"]
, right?
Re alignment, sure, I don't mind too much. Aligning it in the linker means we don't need to OR it in the code, but you lose knowledge of the 'actual size' (does anything need to know that, though?).
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 any event nothing stops any user or library code writing #[link_section=".gnu.sgstubs"], right?
😨 oops that is a very valid point and I have just done a test to try putting another function in the .gnu.sgstubs
section with that attribute. I will look into it a bit more but if there is no protection from the linker against that it would mean that the Secure application developper needs to trust all of its dependencies. A malicious one could put a backdoor entry function in the veneers section...
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.
Malicious dependencies can already do pretty much whatever they want, so that doesn't seem like an issue to me
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.
Yea, you have to trust all your dependencies anyway. They can all run arbitrary code at build time, so...
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.
Yes you are both absolutely right, it will always come down to the fact that you have to trust your dependencies to not contain security vulnerabilities/be malicious. How a Secure application developper can be sure this is the case is another topic and does not concern this PR.
I will update the PR as discussed but would still like to keep the __veneer_limit
symbol unaligned. It could be used as a way to count the number of entry functions declared in all the dependency graph as well (well if no malicious crate modify all of the build system 😰).
The veneers are for now only generated by the Arm GNU linker when it spots an entry function (one that was decorated with the cmse_nonsecure_entry attribute). Adding this section will allow to configure the SAU to make this section Non-Secure Callable. Signed-off-by: Hugues de Valon <[email protected]>
65e5158
to
c599230
Compare
Ok I did the change, I hope this is what you were expecting. I think this is fine to align everything to 4 bytes as veneers are 32 bits long (two thumb instructions). Only the start is aligned to 32 bytes because of SAU requirements. |
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.
bors r+
The veneers are for now only generated by the Arm GNU linker when it
spots an entry function (one that was decorated with the
cmse_nonsecure_entry attribute).
Adding this section will allow to configure the SAU to make this section
Non-Secure Callable.
Doing tests locally I could not see any warnings if this section was empty so I think this is fine. It is highly specific to the GNU toolchain so maybe you would want some preprocessing directive and
cfg
options which I am happy to add.There is documentation for the section name at the end of this page.
It needs to be aligned on 32 bytes as a requirement from the Security Attribute Unit.