Στις 2020-02-13 22:30, John Hauser έγραψε: Nick Kossifidis wrote:
The new mechanism (when MML is set) introduces a barrier between S/U mode and M mode, We want to be able to distinguish between an access fault due to crossing that barrier, from other access faults. In other words if M mode gets an access fault on its own memory we'll get an access fault as in the current spec, if it gets an access fault on memory that's marked for S/U use (see truth table) we'll get a security exception. The reason is that we may want to handle this differently in sw and it also helps in debugging. I'm sorry to say, providing information to a debugger is not usually considered a valid reason for additional RISC-V exception codes when the same information can be extracted from elsewhere. If it were, RISC-V would have dozens more exception codes than it does. A debugger is assumed to be able to examine the PMP table itself, if necessary, to learn more about the cause of a fault. Your reason that "we may want to handle this differently in software" is no more specific than before. I see your desire to be as helpful as possible to software (and debugging), but please understand, this sort of "might be useful" argument for additional exception codes has already been rejected many times before. To make a better case, you need at a minimum a compelling example that requires different handling, and probably one where speed matters (so the software can't just examine the PMP table to separate the cases itself).
S/U mode doesn't have access to PMP registers so it's not possible to distinguish between an access fault e.g. due to a bug on an application / driver, from an access fault due to M mode trying to access one of the S/U-mode-only regions, or from an application / driver trying to access an M-mode-only region. It may be possible to recover from such a bug e.g. by restarting the application but handling / recovering from such a security violation is a different thing and usually involves different reporting and possibly running the system in a kind of "safe mode" with certain features disabled. mstatus.MXR is not related to PMP, it's related to virtual memory permissions and is outside PMP's scope, the scenario you mention involves using mstatus.MPRV to access the region with S/U privileges (and virtual memory in place). That's still possible because the access in this case happens as S/U mode (not as M mode) and so the S/U mode PMP rules apply. The case that needs to be dealt with is an S/U-mode-only region that is execute-only, without read permission. (Please see my correction in another message.) In such a case, M mode has the authority to temporarily reprogram the PMP entry to grant read permission to S/U mode, then perform a read with MPRV = 1, and lastly restore the PMP entry to execute-only. If address translation is active, this actually requires M mode first walk the page tables to translate the virtual address into a physical address before searching the PMP table to find the relevant PMP entry. But there's no reason for us to make software go through all this trouble; we should just have MXR = 1 grant read permission to S/U level while executing in M mode. (Yes, that sounds contradictory, but remember it's for when MPRV = 1.)
So the idea is to have MXR also work for S/U-mode-only PMP regions ? I see how that would help on a system without an MMU, it'll also be more consistent this way, but on a system with MMU I don't see why it makes sense to use PMP to mark a region as execute-only. It makes more sense to mark the region as R/W/X for S/U mode and leave it to the OS running on S mode to add further restrictions through the MMU, in which case MXR will work as-is. I agree with this approach as long as we make sure that MXR can only be set to 1 when running on M-mode, on the current spec it's allowed to be set regardless of privilege mode as with MPRV. I remember there was a discussion regarding MPRV to mandate it can only be set when on M-mode but I just checked the latest draft and it hasn't changed. Leaving MPRV set will most probably result the sw to crash, but if MXR is left set outside M-mode we basically remove the protection on any execute-only memory region, especially if this also works for PMP regions. Have in mind that this proposal is meant to solve a specific problem related to a specific threat model, it's not about changing PMP in general to do all sorts of stuff. Before we have something else I'd appreciate a threat model and a problem description. I believe we need to widen the scope of this proposal to cover other cases. Sticking to the narrower scope you prefer would be fine except for one thing: We know that handling these other cases is going to also involve PMP, so there's an overlap there. If we don't try to address all the demands on PMP together, we will end up with a layering of modifications that, as Greg Favor has said, are not likely to fit together as well.
I just want to be sure that we are after specific issues and -in case of security controls- have specific threat models in mind. Coming up with solutions without having discussed the problem first and proposing security controls without a threat model won't work. Locking down mtvec may also be important, but since it doesn't involve PMP, such other security features can be defined independently, as you propose.
P.S. U-boot usually knows the executable regions of the kernel, first because it needs to jump there, second because it's the one that put the kernel there (and/or unpacked it). Unless we are talking about a kernel that self-extracts or relocates itself, u-boot can set MML before jumping to the kernel if needed (and there are no modules to load). As you put it yourself, "U-Boot usually knows the executable regions of the kernel", except when it doesn't, because the kernel self-extracts, or relocates itself, or has loadable modules. And yes, if desired, an OS's loadable modules might be signed; I don't see why not. I think we should want to cover as many use cases as we reasonably can, as best as we can.
Still MML can always be set after decompression/relocation/loading modules, I don't see why it's an issue and I don't see what's the added security gain by allowing temporary M-mode-only regions (removable) during boot or in general, where anything running there can remove them in a few instructions. The threat model Tariq brought up was about detecting a glitch attack but the glitch can also happen when setting a rule in the first place, I don't see how this is the proper approach, PMP is not there as an anti-tampering mechanism. If we want this as a debug feature I'm ok with it but it must be treated as such and not as a security improvement. Same goes for the ability to let M-mode still execute any region not covered by PMP, or being able to register new executable regions for "greater flexibility". We first need to decide if there are valid use cases / threat models that need to be addressed and then talk about possible modifications to the proposal. Regards, Nick
|