Skip to content

Commit

Permalink
Use last read-only segment for rodata end
Browse files Browse the repository at this point in the history
  • Loading branch information
fwsGonzo committed Nov 22, 2023
1 parent 879b668 commit 5e48e1d
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 6 deletions.
10 changes: 4 additions & 6 deletions lib/libriscv/memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,10 @@ namespace riscv
attr.read, attr.write, attr.exec);
}

if (attr.read && !attr.write) {
this->m_initial_rodata_end =
std::max(m_initial_rodata_end, static_cast<address_t>(hdr->p_vaddr + len));
}
if (attr.exec && this->cached_execute_segments() == 0)
{
serialize_execute_segment(options, hdr);
Expand All @@ -181,12 +185,6 @@ namespace riscv
throw MachineException(INVALID_PROGRAM, "Execute segment must be execute-only");
}
}
if (attr.write) {
if (this->m_initial_rodata_end == RWREAD_BEGIN)
this->m_initial_rodata_end = hdr->p_vaddr;
else
this->m_initial_rodata_end = std::min(m_initial_rodata_end, static_cast<address_t>(hdr->p_vaddr));
}

// Load into virtual memory
this->memcpy(hdr->p_vaddr, src, len);
Expand Down
24 changes: 24 additions & 0 deletions tests/unit/protections.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,12 @@ TEST_CASE("Writes to read-only segment", "[Memory]")
int main() {
*(volatile int *)array = 1234;
return 666;
}
void write_to(char* dst) {
*dst = 1;
}
int read_from(char* dst) {
return *dst;
})M");

riscv::Machine<RISCV64> machine { binary, { .memory_max = MAX_MEMORY } };
Expand All @@ -119,4 +125,22 @@ TEST_CASE("Writes to read-only segment", "[Memory]")
}(), Catch::Matchers::ContainsSubstring("Protection fault"));

REQUIRE(machine.return_value<int>() != 666);

const auto write_addr = machine.address_of("write_to");
REQUIRE(write_addr != 0x0);
const auto read_addr = machine.address_of("read_from");
REQUIRE(read_addr != 0x0);

// Reads amd writes to invalid locations
REQUIRE_THROWS_WITH([&] {
machine.vmcall<MAX_INSTRUCTIONS>(read_addr, 0);
}(), Catch::Matchers::ContainsSubstring("Protection fault"));

machine.vmcall<MAX_INSTRUCTIONS>(read_addr, 0x1000);

for (uint64_t addr = machine.memory.start_address(); addr < machine.memory.initial_rodata_end(); addr += 0x1000) {
REQUIRE_THROWS_WITH([&] {
machine.vmcall<MAX_INSTRUCTIONS>(write_addr, addr);
}(), Catch::Matchers::ContainsSubstring("Protection fault"));
}
}

0 comments on commit 5e48e1d

Please sign in to comment.