aboutsummaryrefslogtreecommitdiff
path: root/src/lib/vfs.zig
diff options
context:
space:
mode:
authorHimbeer <himbeer@disroot.org>2024-07-08 16:21:49 +0200
committerHimbeer <himbeer@disroot.org>2024-07-08 16:21:49 +0200
commitc20f8ceeba73e68f5db1619c287283a739a95755 (patch)
tree50cd59fa041e67987e2e7a988ed457a076feb94b /src/lib/vfs.zig
parent862678c2323a57005a2ed55417a0d2b00bcf1d7c (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.zig30
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 {