bunpen: check syscall return codes more strictly

many syscalls say *specifically* in their documentation that they return 0 on success (implying no other value is success)
This commit is contained in:
2024-09-02 22:39:52 +00:00
parent 384472c1c4
commit 0264ed68f4
7 changed files with 20 additions and 11 deletions

View File

@@ -99,7 +99,7 @@ export fn landlock_restrict(what: *resources) void = {
errors::ext::swallow("[landlock/path] omitting from sandbox: failed to add path", allow_path(ruleset_fd, pathstr));
};
errors::ext::check_u64("landlock_restrict_self", rt::ext::landlock_restrict_self(ruleset_fd));
errors::ext::check("landlock_restrict_self", rt::ext::landlock_restrict_self(ruleset_fd));
log::println("landlock restrictions activated");
};

View File

@@ -375,7 +375,7 @@ export fn capset(eff: caps, prm: caps, inh: caps) (void | rt::errno) = {
inheritable = inh_hi,
}),
];
syscall(rt::SYS_capset, &hdr: uintptr, &data: uintptr)?;
return syscall_0_on_success(rt::SYS_capset, &hdr: uintptr, &data: uintptr);
};
// add the provided capability to the ambient set.

View File

@@ -78,17 +78,17 @@ export fn landlock_add_rule(
ruleset_fd: u64,
rule_attr: (*landlock_path_beneath_attr | *landlock_net_port_attr),
flags: u64 = 0,
) (rt::errno | u64) = {
) (rt::errno | void) = {
const (rule_type, rule_attr) = match (rule_attr) {
case let p: *landlock_path_beneath_attr => yield (landlock_rule_type::PATH_BENEATH, p: uintptr);
case let p: *landlock_net_port_attr => yield (landlock_rule_type::NET_PORT, p: uintptr);
};
return syscall(__NR_landlock_add_rule, ruleset_fd: u64, rule_type, rule_attr: uintptr, flags);
return syscall_0_on_success(__NR_landlock_add_rule, ruleset_fd: u64, rule_type, rule_attr: uintptr, flags);
};
export fn landlock_restrict_self(
ruleset_fd: u64,
flags: u64 = 0,
) (rt::errno | u64) = {
return syscall(__NR_landlock_restrict_self, ruleset_fd: u64, flags);
) (rt::errno | void) = {
return syscall_0_on_success(__NR_landlock_restrict_self, ruleset_fd: u64, flags);
};

View File

@@ -60,12 +60,12 @@ export fn mount(source: str, target: str, fstype: str, mountflags: mount_flags,
let source_buf: [path::MAX]c::char = [0...];
let target_buf: [path::MAX]c::char = [0...];
let fstype_buf: [256]c::char = [0...];
syscall(
return syscall_0_on_success(
rt::SYS_mount,
make_cstr(&source_buf, source): uintptr: u64,
make_cstr(&target_buf, target): uintptr: u64,
make_cstr(&fstype_buf, fstype): uintptr: u64,
mountflags,
data: uintptr,
)?;
);
};

View File

@@ -6,10 +6,10 @@ use types::c;
export fn pivot_root(new_root: str, put_old: str) (rt::errno | void) = {
let new_root_buf: [path::MAX]c::char = [0...];
let put_old_buf: [path::MAX]c::char = [0...];
syscall(
return syscall_0_on_success(
rt::SYS_pivot_root,
make_cstr(&new_root_buf, new_root): uintptr: u64,
make_cstr(&put_old_buf, put_old): uintptr: u64,
)?;
);
};

View File

@@ -6,6 +6,15 @@ fn syscall(num: u64, args: u64...) (rt::errno | u64) = {
return wrap_return(rt::syscall(num, args...));
};
// for a syscall which only success exclusively returns 0, convert any non-zero
// into an error. stricter version of `syscall`
fn syscall_0_on_success(num: u64, args: u64...) (rt::errno | void) = {
let rc = rt::syscall(num, args...);
if (rc != 0) {
return (-(rc: i64)): rt::errno;
};
};
// checks the return value from a Linux syscall and, if found to be in error,
// returns the appropriate error. otherwise, returns the original value.
// borrowed from non-public hare internals: rt/+linux/errno.ha

View File

@@ -39,5 +39,5 @@ export type clone_flags = u64;
// };
export fn unshare(flags: clone_flags) (void | rt::errno) = {
syscall(rt::SYS_unshare, flags)?;
return syscall_0_on_success(rt::SYS_unshare, flags);
};