aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHimbeer <himbeer@disroot.org>2024-08-01 11:58:57 +0200
committerHimbeer <himbeer@disroot.org>2024-08-01 11:58:57 +0200
commit22f46cb26cedf3837cd876d738236f9522ceb355 (patch)
tree4fe2855d94c1c3fcc7d02b745415232947cdf0d1
parent635477e59ecd18bf67defc750a009a5d99ea88a4 (diff)
process: Fix ELF physical allocation overrun
Fixes #71.
-rw-r--r--src/lib/process.zig39
1 files changed, 25 insertions, 14 deletions
diff --git a/src/lib/process.zig b/src/lib/process.zig
index c8e6d5e..265d9b3 100644
--- a/src/lib/process.zig
+++ b/src/lib/process.zig
@@ -47,7 +47,7 @@ pub const Info = struct {
id: u16,
thread_id: usize,
trap_frame: TrapFrame,
- pages: []align(paging.page_size) u8,
+ sections: std.ArrayList([]align(paging.page_size) u8),
stack: []align(paging.page_size) u8,
pc: usize,
page_table: *paging.Table,
@@ -116,7 +116,14 @@ pub const Info = struct {
if (self.thread_id == 0) {
self.page_table.unmap();
paging.free(self.page_table);
- paging.free(self.pages);
+ self.freeSections();
+ }
+ }
+
+ fn freeSections(self: *Info) void {
+ defer self.sections.deinit();
+ for (self.sections.items) |section| {
+ paging.free(section);
}
}
@@ -225,11 +232,6 @@ pub fn create(allocator: Allocator, elf_buf: []align(@alignOf(elf.Elf64_Ehdr)) c
try validateElfHeader(hdr, hdr_buf);
- const len_aligned = std.mem.alignForwardLog2(elf_buf.len, paging.log2_page_size);
- const num_pages = len_aligned / paging.page_size + 1;
- const pages = try paging.zeroedAlloc(num_pages);
- errdefer paging.free(pages);
-
const procmem: *paging.Table = @ptrCast(try paging.zeroedAlloc(1));
errdefer paging.free(procmem);
@@ -237,22 +239,31 @@ pub fn create(allocator: Allocator, elf_buf: []align(@alignOf(elf.Elf64_Ehdr)) c
const parse_source = std.io.fixedBufferStream(elf_buf);
+ var sections = std.ArrayList([]align(paging.page_size) u8).init(allocator);
+
var it = hdr.program_header_iterator(parse_source);
while (try it.next()) |phdr| {
if (phdr.p_type != elf.PT_LOAD) continue;
if (phdr.p_filesz == 0 or phdr.p_memsz == 0) continue;
- if (phdr.p_filesz > elf_buf.len or phdr.p_memsz > pages.len) {
+ if (phdr.p_offset + phdr.p_filesz >= elf_buf.len) {
return ExeError.LengthOutOfBounds;
}
+ const offset = paging.offsetOf(phdr.p_vaddr);
+ const memsz_aligned = std.mem.alignForward(usize, offset + phdr.p_memsz, paging.page_size);
+ const num_pages = @divExact(memsz_aligned, paging.page_size);
+
+ const pages = try paging.zeroedAlloc(num_pages);
+ errdefer paging.free(pages);
+
+ try sections.append(pages);
+
const sz = @min(phdr.p_filesz, phdr.p_memsz);
- @memcpy(pages[phdr.p_offset .. phdr.p_offset + sz], elf_buf[phdr.p_offset .. phdr.p_offset + sz]);
+ @memcpy(pages[offset .. offset + sz], elf_buf[phdr.p_offset .. phdr.p_offset + sz]);
- const memsz_aligned = std.mem.alignForwardLog2(phdr.p_memsz, paging.log2_page_size);
- const num_mappings = @divExact(memsz_aligned, paging.page_size);
- for (0..num_mappings) |page| {
+ for (0..num_pages) |page| {
const vaddr = phdr.p_vaddr + page * paging.page_size;
- const paddr = @intFromPtr(pages.ptr) + phdr.p_offset + page * paging.page_size;
+ const paddr = @intFromPtr(pages.ptr) + page * paging.page_size;
const flags = paging.EntryFlags{
.valid = 1,
.read = @bitCast(phdr.p_flags & elf.PF_R != 0),
@@ -286,7 +297,7 @@ pub fn create(allocator: Allocator, elf_buf: []align(@alignOf(elf.Elf64_Ehdr)) c
.id = next_pid,
.thread_id = 0,
.trap_frame = std.mem.zeroInit(TrapFrame, .{}),
- .pages = pages,
+ .sections = sections,
.stack = @ptrCast(stack),
.pc = hdr.entry,
.page_table = procmem,