Re: comments on PMP enhancements

Bill Huffman

On 2/13/20 12:30 PM, John Hauser wrote:

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).
I'm afraid I agree with John. I asked the same question myself some
months ago - but less forcefully. :-)

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.)
On one level, I agree with John here. But MXR and MPRV were set up when
M mode never had less permission than S/U. I'm not sure I understand
current behavior when the PMP entry is locked with execute-only
permission (which applies to M as well as S/U) and MXR is set. Does
that make M mode able to read instructions even though M mode itself
couldn't otherwise read them? That seems to me to reduce the meaning of
execute-only to something less than execute-only.

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
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.

Locking down mtvec may also be important, but since it doesn't involve
PMP, such other security features can be defined independently, as you
I tend to think the broader view is good. Otherwise we'll get contorted
bits here (sooner than we otherwise would :-) ). Locking mtvec seems
like it might be related. To me, even though it's, in some ways a
separate proposal, understanding the level of security provided should
include as many aspects as possible. Otherwise we may find when we get
to mtvec we didn't consider something.


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.


- John Hauser

Join to automatically receive all group messages.