YGREC32 has several features that I described in recent articles, in particular is can "shield" the bottom of the stack from read and/or write. This means that a caller can prevent callees from extracting or altering its own state.
There is a series of articles that cover the matter:
Les « tourments de la monopile », ou le « Single-Stack Syndrome »
Une histoire des piles et de leur protection
Une (autre) pile matérielle pour le modèle bipilaire
Au-delà de la fonction : libérez tout le potentiel de la pile de contrôle !
Recently I was thinking about what happens when a function returns but its data remain "on the stack" : the next call can scan these data and extract information.
The usual approach is to flush the data on exit. This is wasteful and new functions usually start by initialising/flushing their stack frame anyway. So this would be required only for "secure" functions, but this is another slippery slope, since "what needs to be secured ?"
So here is the proposal. YGREC32 already has the read_shield and write_shield ancillary registers, that trap when reading or writing below said addresses. Their values can be updated during call and return, thanks to the protected control stack. So why not make something similar but for the addresses above the stack frame ?
The behaviour is different though :
- reading above the given address will return 0 (or some canary value)
- writing will work and replace the old value in the cache. This will also invalidate the corresponding cache line, except for the written word.
This way :
- writing to the top of the stack will not trigger a cache read even
- reading above the stack top does not leak information from previous calls.
- all function calls are safe and fast.
Of course this requires cooperation with the data cache...
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.