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

UserspaceEmulator: Honor the read/write/execute bits in mmap regions

UE will now correctly crash when accessing an mmap memory region in
some way it's not supposed to be accessed.
This commit is contained in:
Andreas Kling 2020-11-14 15:13:50 +01:00
parent ef9ac8a8a2
commit d4509647d8
5 changed files with 72 additions and 5 deletions

View file

@ -920,9 +920,17 @@ u32 Emulator::virt$unveil(u32)
return 0;
}
u32 Emulator::virt$mprotect(FlatPtr, size_t, int)
u32 Emulator::virt$mprotect(FlatPtr base, size_t size, int prot)
{
if (auto* region = mmu().find_region({ m_cpu.ds(), base })) {
if (!region->is_mmap())
return -EINVAL;
ASSERT(region->size() == size);
auto& mmap_region = *(MmapRegion*)region;
mmap_region.set_prot(prot);
return 0;
}
return -EINVAL;
}
u32 Emulator::virt$madvise(FlatPtr, size_t, int)

View file

@ -50,13 +50,15 @@ public:
u8* data() { return m_data; }
u8* shadow_data() { return m_shadow_data; }
bool is_readable() const { return m_prot & PROT_READ; }
bool is_writable() const { return m_prot & PROT_WRITE; }
bool is_executable() const { return m_prot & PROT_EXEC; }
virtual bool is_readable() const override { return m_prot & PROT_READ; }
virtual bool is_writable() const override { return m_prot & PROT_WRITE; }
virtual bool is_executable() const override { return m_prot & PROT_EXEC; }
bool is_malloc_block() const { return m_malloc; }
void set_malloc(bool b) { m_malloc = b; }
void set_prot(int prot) { m_prot = prot; }
private:
MmapRegion(u32 base, u32 size, int prot);
virtual bool is_mmap() const override { return true; }

View file

@ -134,6 +134,12 @@ void SoftCPU::update_code_cache()
auto* region = m_emulator.mmu().find_region({ cs(), eip() });
ASSERT(region);
if (!region->is_executable()) {
reportln("SoftCPU::update_code_cache: Non-readable region @ {:p}", eip());
Emulator::the().dump_backtrace();
TODO();
}
m_cached_code_ptr = region->cacheable_ptr(eip() - region->base());
m_cached_code_end = region->cacheable_ptr(region->size());
}

View file

@ -75,6 +75,12 @@ ValueWithShadow<u8> SoftMMU::read8(X86::LogicalAddress address)
TODO();
}
if (!region->is_readable()) {
reportln("SoftMMU::read8: Non-readable region @ {:p}", address.offset());
Emulator::the().dump_backtrace();
TODO();
}
return region->read8(address.offset() - region->base());
}
@ -87,6 +93,12 @@ ValueWithShadow<u16> SoftMMU::read16(X86::LogicalAddress address)
TODO();
}
if (!region->is_readable()) {
reportln("SoftMMU::read16: Non-readable region @ {:p}", address.offset());
Emulator::the().dump_backtrace();
TODO();
}
return region->read16(address.offset() - region->base());
}
@ -99,6 +111,12 @@ ValueWithShadow<u32> SoftMMU::read32(X86::LogicalAddress address)
TODO();
}
if (!region->is_readable()) {
reportln("SoftMMU::read32: Non-readable region @ {:p}", address.offset());
Emulator::the().dump_backtrace();
TODO();
}
return region->read32(address.offset() - region->base());
}
@ -111,6 +129,12 @@ ValueWithShadow<u64> SoftMMU::read64(X86::LogicalAddress address)
TODO();
}
if (!region->is_readable()) {
reportln("SoftMMU::read64: Non-readable region @ {:p}", address.offset());
Emulator::the().dump_backtrace();
TODO();
}
return region->read64(address.offset() - region->base());
}
@ -123,6 +147,11 @@ void SoftMMU::write8(X86::LogicalAddress address, ValueWithShadow<u8> value)
TODO();
}
if (!region->is_writable()) {
reportln("SoftMMU::write8: Non-writable region @ {:p}", address.offset());
Emulator::the().dump_backtrace();
TODO();
}
region->write8(address.offset() - region->base(), value);
}
@ -135,6 +164,12 @@ void SoftMMU::write16(X86::LogicalAddress address, ValueWithShadow<u16> value)
TODO();
}
if (!region->is_writable()) {
reportln("SoftMMU::write16: Non-writable region @ {:p}", address.offset());
Emulator::the().dump_backtrace();
TODO();
}
region->write16(address.offset() - region->base(), value);
}
@ -147,6 +182,12 @@ void SoftMMU::write32(X86::LogicalAddress address, ValueWithShadow<u32> value)
TODO();
}
if (!region->is_writable()) {
reportln("SoftMMU::write32: Non-writable region @ {:p}", address.offset());
Emulator::the().dump_backtrace();
TODO();
}
region->write32(address.offset() - region->base(), value);
}
@ -159,6 +200,12 @@ void SoftMMU::write64(X86::LogicalAddress address, ValueWithShadow<u64> value)
TODO();
}
if (!region->is_writable()) {
reportln("SoftMMU::write64: Non-writable region @ {:p}", address.offset());
Emulator::the().dump_backtrace();
TODO();
}
region->write64(address.offset() - region->base(), value);
}

View file

@ -69,6 +69,10 @@ public:
bool is_text() const { return m_text; }
void set_text(bool b) { m_text = b; }
virtual bool is_readable() const { return true; }
virtual bool is_writable() const { return true; }
virtual bool is_executable() const { return true; }
protected:
Region(u32 base, u32 size)
: m_base(base)