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:
parent
ef9ac8a8a2
commit
d4509647d8
5 changed files with 72 additions and 5 deletions
|
@ -920,9 +920,17 @@ u32 Emulator::virt$unveil(u32)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 Emulator::virt$mprotect(FlatPtr, size_t, int)
|
u32 Emulator::virt$mprotect(FlatPtr base, size_t size, int prot)
|
||||||
{
|
{
|
||||||
return 0;
|
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)
|
u32 Emulator::virt$madvise(FlatPtr, size_t, int)
|
||||||
|
|
|
@ -50,13 +50,15 @@ public:
|
||||||
u8* data() { return m_data; }
|
u8* data() { return m_data; }
|
||||||
u8* shadow_data() { return m_shadow_data; }
|
u8* shadow_data() { return m_shadow_data; }
|
||||||
|
|
||||||
bool is_readable() const { return m_prot & PROT_READ; }
|
virtual bool is_readable() const override { return m_prot & PROT_READ; }
|
||||||
bool is_writable() const { return m_prot & PROT_WRITE; }
|
virtual bool is_writable() const override { return m_prot & PROT_WRITE; }
|
||||||
bool is_executable() const { return m_prot & PROT_EXEC; }
|
virtual bool is_executable() const override { return m_prot & PROT_EXEC; }
|
||||||
|
|
||||||
bool is_malloc_block() const { return m_malloc; }
|
bool is_malloc_block() const { return m_malloc; }
|
||||||
void set_malloc(bool b) { m_malloc = b; }
|
void set_malloc(bool b) { m_malloc = b; }
|
||||||
|
|
||||||
|
void set_prot(int prot) { m_prot = prot; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MmapRegion(u32 base, u32 size, int prot);
|
MmapRegion(u32 base, u32 size, int prot);
|
||||||
virtual bool is_mmap() const override { return true; }
|
virtual bool is_mmap() const override { return true; }
|
||||||
|
|
|
@ -134,6 +134,12 @@ void SoftCPU::update_code_cache()
|
||||||
auto* region = m_emulator.mmu().find_region({ cs(), eip() });
|
auto* region = m_emulator.mmu().find_region({ cs(), eip() });
|
||||||
ASSERT(region);
|
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_ptr = region->cacheable_ptr(eip() - region->base());
|
||||||
m_cached_code_end = region->cacheable_ptr(region->size());
|
m_cached_code_end = region->cacheable_ptr(region->size());
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,6 +75,12 @@ ValueWithShadow<u8> SoftMMU::read8(X86::LogicalAddress address)
|
||||||
TODO();
|
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());
|
return region->read8(address.offset() - region->base());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,6 +93,12 @@ ValueWithShadow<u16> SoftMMU::read16(X86::LogicalAddress address)
|
||||||
TODO();
|
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());
|
return region->read16(address.offset() - region->base());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,6 +111,12 @@ ValueWithShadow<u32> SoftMMU::read32(X86::LogicalAddress address)
|
||||||
TODO();
|
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());
|
return region->read32(address.offset() - region->base());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,6 +129,12 @@ ValueWithShadow<u64> SoftMMU::read64(X86::LogicalAddress address)
|
||||||
TODO();
|
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());
|
return region->read64(address.offset() - region->base());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,6 +147,11 @@ void SoftMMU::write8(X86::LogicalAddress address, ValueWithShadow<u8> value)
|
||||||
TODO();
|
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);
|
region->write8(address.offset() - region->base(), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,6 +164,12 @@ void SoftMMU::write16(X86::LogicalAddress address, ValueWithShadow<u16> value)
|
||||||
TODO();
|
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);
|
region->write16(address.offset() - region->base(), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,6 +182,12 @@ void SoftMMU::write32(X86::LogicalAddress address, ValueWithShadow<u32> value)
|
||||||
TODO();
|
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);
|
region->write32(address.offset() - region->base(), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,6 +200,12 @@ void SoftMMU::write64(X86::LogicalAddress address, ValueWithShadow<u64> value)
|
||||||
TODO();
|
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);
|
region->write64(address.offset() - region->base(), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,10 @@ public:
|
||||||
bool is_text() const { return m_text; }
|
bool is_text() const { return m_text; }
|
||||||
void set_text(bool b) { m_text = b; }
|
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:
|
protected:
|
||||||
Region(u32 base, u32 size)
|
Region(u32 base, u32 size)
|
||||||
: m_base(base)
|
: m_base(base)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue