summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2021-03-09 14:59:41 +0100
committerAndreas Kling <kling@serenityos.org>2021-03-09 15:01:08 +0100
commitc192b6c61d8d56c55f45974cd53a0ca4a89dd619 (patch)
treec8d9f2f5e91cb164b090c4d554fd9c66151302b8 /Userland
parent0c46918b739739201493b8e1bdadc7d8b1a92d69 (diff)
downloadserenity-c192b6c61d8d56c55f45974cd53a0ca4a89dd619.zip
Emulator: Use libc.so bounds to fast-reject non-malloc addresses
The auditing code always starts by checking if we're in one of the ignored code ranges (malloc, free, realloc, syscall, etc.) To reduce the number of checks needed, we can cache the bounds of the LibC text segment. This allows us to fast-reject addresses that cannot possibly be a LibC function.
Diffstat (limited to 'Userland')
-rw-r--r--Userland/DevTools/UserspaceEmulator/Emulator.cpp2
-rw-r--r--Userland/DevTools/UserspaceEmulator/Emulator.h10
2 files changed, 12 insertions, 0 deletions
diff --git a/Userland/DevTools/UserspaceEmulator/Emulator.cpp b/Userland/DevTools/UserspaceEmulator/Emulator.cpp
index 0afe309bc6..0c9ea2c73a 100644
--- a/Userland/DevTools/UserspaceEmulator/Emulator.cpp
+++ b/Userland/DevTools/UserspaceEmulator/Emulator.cpp
@@ -1054,6 +1054,8 @@ u32 Emulator::virt$mmap(u32 params_addr)
} else {
auto region = MmapRegion::create_file_backed(final_address, final_size, params.prot, params.flags, params.fd, params.offset, move(name_str));
if (region->name() == "libc.so: .text") {
+ m_libc_start = final_address;
+ m_libc_end = final_address + final_size;
bool rc = find_malloc_symbols(*region);
VERIFY(rc);
}
diff --git a/Userland/DevTools/UserspaceEmulator/Emulator.h b/Userland/DevTools/UserspaceEmulator/Emulator.h
index d4fc71d5ea..e0ce264453 100644
--- a/Userland/DevTools/UserspaceEmulator/Emulator.h
+++ b/Userland/DevTools/UserspaceEmulator/Emulator.h
@@ -65,6 +65,7 @@ public:
bool is_in_malloc_or_free() const;
bool is_in_loader_code() const;
bool is_in_libsystem() const;
+ bool is_in_libc() const;
void did_receive_signal(int signum) { m_pending_signals |= (1 << signum); }
@@ -199,6 +200,8 @@ private:
FlatPtr m_malloc_size_symbol_start { 0 };
FlatPtr m_malloc_size_symbol_end { 0 };
+ FlatPtr m_libc_start { 0 };
+ FlatPtr m_libc_end { 0 };
FlatPtr m_libsystem_start { 0 };
FlatPtr m_libsystem_end { 0 };
@@ -226,6 +229,11 @@ private:
RangeAllocator m_range_allocator;
};
+ALWAYS_INLINE bool Emulator::is_in_libc() const
+{
+ return m_cpu.base_eip() >= m_libc_start && m_cpu.base_eip() < m_libc_end;
+}
+
ALWAYS_INLINE bool Emulator::is_in_libsystem() const
{
return m_cpu.base_eip() >= m_libsystem_start && m_cpu.base_eip() < m_libsystem_end;
@@ -233,6 +241,8 @@ ALWAYS_INLINE bool Emulator::is_in_libsystem() const
ALWAYS_INLINE bool Emulator::is_in_malloc_or_free() const
{
+ if (!is_in_libc())
+ return false;
return (m_cpu.base_eip() >= m_malloc_symbol_start && m_cpu.base_eip() < m_malloc_symbol_end)
|| (m_cpu.base_eip() >= m_free_symbol_start && m_cpu.base_eip() < m_free_symbol_end)
|| (m_cpu.base_eip() >= m_realloc_symbol_start && m_cpu.base_eip() < m_realloc_symbol_end)