Prefer tag clearing to trapping when manipulating a sealed capability

This causes the behaviour of CCSeal and CSeal to diverge in non-trapping cases,
meaning an extra case is added to CapModify.
This commit is contained in:
Peter Rugg
2022-10-18 15:48:35 +01:00
parent e37339b147
commit 04ba0cb7ab
3 changed files with 14 additions and 35 deletions

View File

@@ -948,8 +948,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
opcOpCHERI: begin
case (funct3)
f3_cap_CIncOffsetImmediate: begin
dInst.capChecks.src1_unsealed = True;
dInst.iType = Cap;
regs.dst = Valid(tagged Gpr rd);
regs.src1 = Valid(tagged Gpr rs1);
@@ -957,8 +955,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
dInst.capFunc = CapModify (ModifyOffset (IncOffset));
end
f3_cap_CSetBoundsImmediate: begin
dInst.capChecks.src1_unsealed = True;
dInst.capChecks.check_enable = True;
dInst.capChecks.check_authority_src = Src1;
dInst.capChecks.check_low_src = Src1Addr;
@@ -997,8 +993,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
dInst.capFunc = CapModify (SpecialRW (scrType));
end
f7_cap_CSetBounds: begin
dInst.capChecks.src1_unsealed = True;
dInst.capChecks.check_enable = True;
dInst.capChecks.check_authority_src = Src1;
dInst.capChecks.check_low_src = Src1Addr;
@@ -1012,7 +1006,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
dInst.capFunc = CapModify (SetBounds (SetBounds));
end
f7_cap_CSetBoundsExact: begin
dInst.capChecks.src1_unsealed = True;
dInst.capChecks.cap_exact = True;
dInst.capChecks.check_enable = True;
@@ -1028,8 +1021,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
dInst.capFunc = CapModify (SetBounds (SetBounds));
end
f7_cap_CSetOffset: begin
dInst.capChecks.src1_unsealed = True;
dInst.iType = Cap;
regs.dst = Valid(tagged Gpr rd);
regs.src1 = Valid(tagged Gpr rs1);
@@ -1037,8 +1028,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
dInst.capFunc = CapModify (ModifyOffset (SetOffset));
end
f7_cap_CSetAddr: begin
dInst.capChecks.src2_unsealed = True;
dInst.iType = Cap;
regs.dst = Valid(tagged Gpr rd);
regs.src1 = Valid(tagged Gpr rs2);
@@ -1046,8 +1035,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
dInst.capFunc = CapModify (SetAddr (Src1Addr));
end
f7_cap_CIncOffset: begin
dInst.capChecks.src1_unsealed = True;
dInst.iType = Cap;
regs.dst = Valid(tagged Gpr rd);
regs.src1 = Valid(tagged Gpr rs1);
@@ -1056,7 +1043,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
end
f7_cap_CSeal: begin
dInst.capChecks.src2_tag = True;
dInst.capChecks.src1_unsealed = True;
dInst.capChecks.src2_unsealed = True;
dInst.capChecks.src2_permit_seal = True;
dInst.capChecks.src2_addr_valid_type = True;
@@ -1074,7 +1060,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
dInst.capFunc = CapModify (Seal);
end
f7_cap_CCSeal: begin
dInst.capChecks.src1_unsealed = True;
dInst.capChecks.src2_unsealed = True;
dInst.capChecks.src2_addr_valid_type = True;
dInst.capChecks.src2_permit_seal = True;
@@ -1159,8 +1144,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
dInst.capFunc = CapInspect (SetEqualExact);
end
f7_cap_CCopyType: begin
dInst.capChecks.src2_unsealed = True;
dInst.capChecks.check_enable = True;
dInst.capChecks.check_authority_src = Src2;
dInst.capChecks.check_low_src = Src1Type;
@@ -1175,8 +1158,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
dInst.capFunc = CapModify (SetAddr (Src1Type));
end
f7_cap_CAndPerm: begin
dInst.capChecks.src1_unsealed = True;
dInst.iType = Cap;
regs.dst = Valid(tagged Gpr rd);
regs.src1 = Valid(tagged Gpr rs1);
@@ -1184,8 +1165,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
dInst.capFunc = CapModify (AndPerm);
end
f7_cap_CSetFlags: begin
dInst.capChecks.src1_unsealed = True;
dInst.iType = Cap;
regs.dst = Valid(tagged Gpr rd);
regs.src1 = Valid(tagged Gpr rs1);
@@ -1193,8 +1172,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
dInst.capFunc = CapModify (SetFlags);
end
f7_cap_CToPtr: begin
dInst.capChecks.src1_unsealed = True;
dInst.iType = Cap;
regs.dst = Valid(tagged Gpr rd);
regs.src1 = Valid(tagged Gpr rs1);
@@ -1208,7 +1185,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
dInst.capFunc = CapInspect (ToPtr);
end
f7_cap_CFromPtr: begin
dInst.capChecks.src2_unsealed = True;
dInst.capChecks.cfromptr_bypass = True;
dInst.iType = Cap;
@@ -1227,7 +1203,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
dInst.execFunc = Alu (Sub);
end
f7_cap_CBuildCap: begin
dInst.capChecks.src2_unsealed = True;
dInst.capChecks.src1_perm_subset_src2 = True;
dInst.capChecks.src1_derivable = True;
@@ -1337,7 +1312,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
dInst.capFunc = CapInspect (GetAddr);
end
f5rs2_cap_CSealEntry: begin
dInst.capChecks.src1_unsealed = True;
dInst.capChecks.src1_permit_x = True;
dInst.iType = Cap;

View File

@@ -240,11 +240,13 @@ endfunction
(* noinline *)
function Tuple2#(CapPipe,Bool) capModify(CapPipe a, CapPipe b, CapModifyFunc func);
function t (x) = tuple2(x, ?);
let a_mut = setValidCap(a, isValidCap(a) && getKind(a) == UNSEALED);
let b_mut = setValidCap(b, isValidCap(b) && getKind(b) == UNSEALED);
Tuple2#(CapPipe, Bool) res = (case(func) matches
tagged ModifyOffset .offsetOp :
t(modifyOffset(a, getAddr(b), offsetOp == IncOffset).value);
t(modifyOffset(a_mut, getAddr(b), offsetOp == IncOffset).value);
tagged SetBounds .boundsOp :
setBoundsALU(a, getAddr(b), boundsOp);
setBoundsALU(a_mut, getAddr(b), boundsOp);
tagged SpecialRW .scrType :
t(case (scrType) matches
tagged TCC: b;
@@ -258,23 +260,25 @@ function Tuple2#(CapPipe,Bool) capModify(CapPipe a, CapPipe b, CapModifyFunc fun
else if (addrSource == Src1Type && (getKind(a) == SENTRY )) return t(nullWithAddr(otype_sentry_ext));
else if (addrSource == Src1Type && (getKind(a) == RES0 )) return t(nullWithAddr(otype_res0_ext));
else if (addrSource == Src1Type && (getKind(a) == RES1 )) return t(nullWithAddr(otype_res1_ext));
else return t(setAddr(b, (addrSource == Src1Type) ? zeroExtend(getKind(a).SEALED_WITH_TYPE) : getAddr(a) ).value);
else return t(setAddr(b_mut, (addrSource == Src1Type) ? zeroExtend(getKind(a).SEALED_WITH_TYPE) : getAddr(a) ).value);
tagged SealEntry :
t(setKind(a, SENTRY));
t(setKind(a_mut, SENTRY));
tagged Seal :
t(setKind(a_mut, SEALED_WITH_TYPE (truncate(getAddr(b)))));
tagged CSeal :
t((validAsType(b, getAddr(b)) && isValidCap(b) && getKind(a) == UNSEALED) ?
setKind(a, SEALED_WITH_TYPE (truncate(getAddr(b))))
setKind(a_mut, SEALED_WITH_TYPE (truncate(getAddr(b))))
: a);
tagged Unseal .src :
t(setKind(((src == Src1) ? a:b), UNSEALED));
tagged AndPerm :
t(setPerms(a, pack(getPerms(a)) & truncate(getAddr(b))));
t(setPerms(a_mut, pack(getPerms(a)) & truncate(getAddr(b))));
tagged SetFlags :
t(setFlags(a, truncate(getAddr(b))));
t(setFlags(a_mut, truncate(getAddr(b))));
tagged FromPtr :
t(getAddr(a) == 0 ? nullCap : setOffset(b, getAddr(a)).value);
t(getAddr(a_mut) == 0 ? nullCap : setOffset(b, getAddr(a)).value);
tagged BuildCap :
t(setKind(setValidCap(a, isValidCap(b)), getKind(a)==SENTRY ? SENTRY : UNSEALED));
t(setKind(setValidCap(a_mut, isValidCap(b_mut)), getKind(a)==SENTRY ? SENTRY : UNSEALED));
tagged Move :
t(a);
tagged ClearTag :

View File

@@ -330,6 +330,7 @@ typedef union tagged {
SpecialRWFunc SpecialRW;
AddrSource SetAddr;
void Seal;
void CSeal;
void SealEntry;
SrcSelector Unseal;
void AndPerm;