diff options
author | Himbeer <himbeer@disroot.org> | 2024-07-08 16:21:49 +0200 |
---|---|---|
committer | Himbeer <himbeer@disroot.org> | 2024-07-08 16:21:49 +0200 |
commit | c20f8ceeba73e68f5db1619c287283a739a95755 (patch) | |
tree | 50cd59fa041e67987e2e7a988ed457a076feb94b /src/lib/vfs.zig | |
parent | 862678c2323a57005a2ed55417a0d2b00bcf1d7c (diff) |
vfs: Provide drivers with secure copies of caller buffers
Fixes #45.
Diffstat (limited to 'src/lib/vfs.zig')
-rw-r--r-- | src/lib/vfs.zig | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/src/lib/vfs.zig b/src/lib/vfs.zig index d9a7b90..b6646bf 100644 --- a/src/lib/vfs.zig +++ b/src/lib/vfs.zig @@ -4,6 +4,7 @@ const std = @import("std"); +const paging = @import("paging.zig"); const process = @import("process.zig"); const sysexchange = @import("sysexchange.zig"); @@ -133,10 +134,15 @@ pub const ResourceDescriptor = struct { return switch (self.inode.resource) { .stream => |stream| { const driver = process.latestThread(self.inode.pid).?; + const copy = try driver.copyBuffer(buffer); const readFn = stream.readFn orelse return Error.ReadNotSupported; proc.state = .suspended; - try call(driver, readFn, .{ buffer.ptr, buffer.len }, .{ + try call(driver, readFn, .{ copy.ptr, copy.len }, .{ + .cleanupFn = moveBack, + .buffer = buffer, + .copy = copy, + }, .{ .hookFn = crossProcessReturn, .context = proc, }); @@ -150,10 +156,11 @@ pub const ResourceDescriptor = struct { return switch (self.inode.resource) { .stream => |stream| { const driver = process.latestThread(self.inode.pid).?; + const copy = try driver.copyBytes(bytes); const writeFn = stream.writeFn orelse return Error.WriteNotSupported; proc.state = .suspended; - try call(driver, writeFn, .{ bytes.ptr, bytes.len }, .{ + try call(driver, writeFn, .{ copy.ptr, copy.len }, null, .{ .hookFn = crossProcessReturn, .context = proc, }); @@ -162,6 +169,19 @@ pub const ResourceDescriptor = struct { else => Error.WriteNotSupported, }; } + + fn moveBack(driver: *const process.Info, buffer: []u8, copy: []const u8) void { + paging.setUserMemoryAccess(true); + defer paging.setUserMemoryAccess(false); + + @memcpy(buffer, copy); + + var addr = @intFromPtr(copy.ptr); + const limit = addr + copy.len; + while (addr < limit) : (addr += paging.page_size) { + driver.page_table.unmapEntry(addr); + } + } }; pub const UserInfo = union(enum) { @@ -222,7 +242,7 @@ pub fn open(proc: *process.Info, path: []const u8, pid: u16, data: usize) !Resou const driver = process.latestThread(node.data.pid).?; proc.state = .suspended; - try call(driver, hook.callback, .{ pid, data }, .{ + try call(driver, hook.callback, .{ pid, data }, null, .{ .hookFn = crossProcessReturn, .context = proc, }); @@ -235,9 +255,9 @@ pub fn openZ(proc: *process.Info, path_c: [*:0]const u8, pid: u16, data: usize) return open(proc, mem.sliceTo(path_c, 0), pid, data); } -fn call(proc: *process.Info, function: *const anyopaque, args: anytype, termHook: ?process.Info.TermHook) !noreturn { +fn call(proc: *process.Info, function: *const anyopaque, args: anytype, cleanup_hook: ?process.Info.CleanupHook, term_hook: ?process.Info.TermHook) !noreturn { const callback_thread = try proc.createThread(null); - callback_thread.call(@intFromPtr(function), args, termHook); + callback_thread.call(@intFromPtr(function), args, cleanup_hook, term_hook); } fn crossProcessReturn(context: *anyopaque, driver: *const process.Info) void { |