Index: src/trusted/validator_mips/validator.cc |
diff --git a/src/trusted/validator_mips/validator.cc b/src/trusted/validator_mips/validator.cc |
index 02c7ff9cdf44edc8df9b95457622f3a02e8d888a..5b2bd880dbaa990e94072196b2a277db14a1ec12 100644 |
--- a/src/trusted/validator_mips/validator.cc |
+++ b/src/trusted/validator_mips/validator.cc |
@@ -216,6 +216,33 @@ static PatternMatch CheckLoadStore(const SfiValidator &sfi, |
/* |
+ * A thread pointer access is only allowed by these two instructions: |
+ * lw Rn, 0($t8) ; load user thread pointer. |
+ * lw Rn, 4($t8) ; load IRT thread pointer. |
+ */ |
+static PatternMatch CheckLoadThreadPointer(const SfiValidator &sfi, |
+ const DecodedInstruction &instr, |
+ ProblemSink *out) { |
+ UNREFERENCED_PARAMETER(sfi); |
+ if (!instr.IsLoadStore()) |
+ return NO_MATCH; |
+ |
+ Register base_addr_reg = instr.BaseAddressRegister(); |
+ if (!base_addr_reg.Equals(Register::Tls())) |
+ return NO_MATCH; |
+ |
+ if (instr.IsLoadWord()) { |
+ uint32_t offset = instr.GetImm(); |
+ if (offset == 0 || offset == 4) |
+ return PATTERN_SAFE; |
+ } |
+ |
+ out->ReportProblem(instr.addr(), instr.safety(), |
+ kProblemUnsafeLoadStoreThreadPointer); |
+ return PATTERN_UNSAFE; |
+} |
+ |
+/* |
* Checks if there is jump/branch in the delay slot. |
*/ |
static PatternMatch CheckBranchInDelaySlot(const SfiValidator &sfi, |
@@ -423,7 +450,8 @@ bool SfiValidator::ApplyPatterns(const DecodedInstruction &inst, |
&CheckSafety, |
&CheckReadOnly, |
&CheckCallPosition, |
- &CheckJumpDestAddr |
+ &CheckJumpDestAddr, |
+ &CheckLoadThreadPointer |
}; |
bool complete_success = true; |