1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 02:17:35 +00:00

UserspaceEmulator: Warn on conditional op with uninitialized dependency

We now track whether the flags register is tainted by the use of one or
more uninitialized values in a computation.

For now, the state is binary; the flags are either tainted or not.
We could be more precise about this and only taint the specific flags
that get updated by each instruction, but I think this will already get
us 99% of the results we want. :^)
This commit is contained in:
Andreas Kling 2020-07-21 16:40:09 +02:00
parent 30025dd576
commit e634fe6072
2 changed files with 87 additions and 26 deletions

View file

@ -421,6 +421,26 @@ public:
template<bool check_zf, typename Callback>
void do_once_or_repeat(const X86::Instruction& insn, Callback);
template<typename A>
void taint_flags_from(const A& a)
{
m_flags_tainted = a.is_uninitialized();
}
template<typename A, typename B>
void taint_flags_from(const A& a, const B& b)
{
m_flags_tainted = a.is_uninitialized() || b.is_uninitialized();
}
template<typename A, typename B, typename C>
void taint_flags_from(const A& a, const B& b, const C& c)
{
m_flags_tainted = a.is_uninitialized() || b.is_uninitialized() || c.is_uninitialized();
}
void warn_if_flags_tainted(const char* message) const;
// ^X86::InstructionStream
virtual bool can_read() override { return false; }
virtual u8 read8() override;
@ -958,6 +978,8 @@ private:
u16 m_segment[8] { 0 };
u32 m_eflags { 0 };
bool m_flags_tainted { false };
u32 m_eip { 0 };
const u8* m_cached_code_ptr { nullptr };