IOS LLE: StarOS's panic words must not alias
LoadBootstrapELF accepted __panic_state and __panic_code at the same address, or as two words sharing bytes: the code's store would then also set the guard, and nothing could tell the two apart. They must now be two non-overlapping words of the data segment, like the other checks, before any byte is written. BootstrapELFTest.PanicWordsMustNotAlias: the same word and three partial overlaps, all inside the data segment, are rejected; adjacent words are accepted. With the rule disabled, the test fails. (StarOS MMU-001 review of F1.) Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
15da28ad7b
commit
a62c65615a
2 files changed
+34
-2
No files matched your search
@@ -216,9 +216,14 @@ bool LoadBootstrapELF(std::span<const u8> image, ARMBus& bus, BootstrapELFInfo*
|
||||
{
|
||||
return Fail(error, "bootstrap ELF is missing the trace or fault symbols");
|
||||
}
|
||||
// The panic words are optional, but both or neither, as words of the data segment.
|
||||
// The panic words are optional, but both or neither, as two distinct words of the data segment:
|
||||
// aliased, the code's store would also set the guard, and a probe could not tell them apart.
|
||||
const bool panic_words_overlap =
|
||||
static_cast<u64>(parsed.panic_state) < static_cast<u64>(parsed.panic_code) + 4 &&
|
||||
static_cast<u64>(parsed.panic_code) < static_cast<u64>(parsed.panic_state) + 4;
|
||||
if ((parsed.panic_state != 0) != (parsed.panic_code != 0) ||
|
||||
(parsed.panic_state != 0 && (!in_data(parsed.panic_state, 4) || !in_data(parsed.panic_code, 4))))
|
||||
(parsed.panic_state != 0 && (!in_data(parsed.panic_state, 4) ||
|
||||
!in_data(parsed.panic_code, 4) || panic_words_overlap)))
|
||||
{
|
||||
return Fail(error, "bootstrap ELF has an invalid panic symbol");
|
||||
}
|
||||
|
||||
@@ -281,5 +281,32 @@ TEST(BootstrapELFTest, PanicWordsAreOptionalButBothInData)
|
||||
EXPECT_TRUE(rejected.bytes.empty());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(BootstrapELFTest, PanicWordsMustNotAlias)
|
||||
{
|
||||
BootstrapELFInfo info;
|
||||
std::string error;
|
||||
// The same word, or two words sharing bytes, in either order; all inside the 0x420-byte data
|
||||
// segment, so only the aliasing rule rejects them.
|
||||
for (const auto [state, code] :
|
||||
{std::pair{DATA_BASE + 4, DATA_BASE + 4}, std::pair{DATA_BASE + 4, DATA_BASE + 6},
|
||||
std::pair{DATA_BASE + 7, DATA_BASE + 4}, std::pair{DATA_BASE + 0x41c, DATA_BASE + 0x41a}})
|
||||
{
|
||||
RecordingBus rejected;
|
||||
EXPECT_FALSE(LoadBootstrapELF(MakePanicImage(state, code), rejected, &info, &error))
|
||||
<< std::hex << state << ' ' << code;
|
||||
EXPECT_EQ(error, "bootstrap ELF has an invalid panic symbol");
|
||||
EXPECT_TRUE(rejected.bytes.empty());
|
||||
}
|
||||
// Adjacent words do not alias.
|
||||
for (const auto [state, code] :
|
||||
{std::pair{DATA_BASE + 4, DATA_BASE + 8}, std::pair{DATA_BASE + 8, DATA_BASE + 4}})
|
||||
{
|
||||
RecordingBus bus;
|
||||
EXPECT_TRUE(LoadBootstrapELF(MakePanicImage(state, code), bus, &info, &error)) << error;
|
||||
EXPECT_EQ(info.panic_state, state);
|
||||
EXPECT_EQ(info.panic_code, code);
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
} // namespace IOS::LLE
|
||||
Reference in new issue
Block a user