Skip to content
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

CUnseal: permit any in-bound type #87

Merged
merged 1 commit into from
Nov 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions archdoc/chap-changes.tex
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,8 @@ \chapter{Version history}
Make it explicitly 16-byte aligned and point out the unaligned write spanning \mshwmb{} corner case, which we do not require hardware to handle.
\item[\ghpr{54}] Create backward sentries for function returns and add more checks in \rvcheriasminsnref{CJAL}
Because CHERIoT allows manipulating the status of the interrupt through a function call (and function return) by encoding the interrupt type in the otype, the following attack can occur: A caller calling an interrupt-disabling callee can set the return sentry of the callee to the same callee. This means, the callee will call itself on return all the while operating with interrupts disabled. This will lead to infinite repeated calls to the callee with interrupts disabled, violating availability. This attack can be prevented in CHERIoT by adding two new ``backwards-edge'' sentries and adding more checks on \rvcheriasminsnref{CJALR}.
\item[\ghissue{71}, \ghpr{87}] \rvcheriasminsnref{CUnseal} now no longer requires exact equality between sealed input otype and authority address.
Instead, it merely requires that the otype of the sealed input is within bounds to yield a tagged result.
The address of a sealing-root capability is now meaningful only to \rvcheriasminsnref{CSeal}.
\end{description}
\end{description}
10 changes: 4 additions & 6 deletions src/cheri_insts.sail
Original file line number Diff line number Diff line change
Expand Up @@ -743,21 +743,19 @@ union clause ast = CUnseal : (regidx, regidx, regidx)
* Capability register *cd* is replaced with capability register *cs1* and is
* unsealed, using capability register *cs2* as the authority for the unsealing
* operation. If *cs2*.**perms** does not grant **Global** then *cd*.**perms**
* is stripped of **Global**. If *cs2* is unable to authorize the unsealing,
* is stripped of **Global**. If *cs2* is unable to authorize the unsealing
* (because *cs1*.**otype** is not within the bounsd of *cs2*),
* the **tag** field of *cd* is cleared.
*/
function clause execute (CUnseal(cd, cs1, cs2)) = {
let cs1_val = C(cs1);
let cs2_val = C(cs2);
let cs2_addr = unsigned(cs2_val.address);
let (cs2_base, cs2_top) = getCapBounds(cs2_val);
let permitted = cs2_val.tag
& isCapSealed(cs1_val)
& not(isCapSealed(cs2_val))
& (cs2_addr == unsigned(cs1_val.otype))
& cs2_val.permit_unseal
& (cs2_addr >= cs2_base)
& (cs2_addr < cs2_top);
& inCapBounds(cs2_val, zero_extend(cs1_val.otype), 1)
rmn30 marked this conversation as resolved.
Show resolved Hide resolved
& cs2_val.permit_unseal;
let new_global = cs1_val.global & cs2_val.global;
let newCap = {unsealCap(cs1_val) with global=new_global};
C(cd) = clearTagIf(newCap, not(permitted));
Expand Down
Loading