bunpen: finish wiring the xdg-dbus-proxy instance

this isn't tested, except to see that it doesn't interfere with the *existing* bunpen use
This commit is contained in:
2025-01-03 11:55:46 +00:00
parent 66103854fa
commit 22f3a19165
2 changed files with 44 additions and 9 deletions

View File

@@ -61,24 +61,33 @@
use config;
use errors;
use errors::ext;
use strings;
use io;
use os;
use os::exec;
use path;
use ps;
use resources;
use rt;
use rt::ext;
use strings;
// given an existing, unfiltered bus at the fs path `upstream`,
// proxy the bus into the fs path indicated by `downstream`.
// clients attaching to the `downstream` path are provided access only to the
// resources indicated by `dbus`.
fn dbus_restrict(dbus: resources::dbus_subset, upstream: str, downstream: str) void = {
fn dbus_restrict(dbus: resources::dbus_subset, upstream_fd: io::file, downstream_path: path::buffer) void = {
// TODO: restrict resources to the xdg-dbus-proxy instance
match (ps::fork_and_die_with_parent()) {
case let child_pid: os::exec::process =>
// dup the upstream to give it a predictable fd
rt::dup2(upstream_fd, 0)!;
io::close(upstream_fd)!;
os::setenv("DBUS_SESSION_BUS_ADDRES", "path:unix=/proc/self/fd/0")!; // TODO: pass this to execvpe's env instead of setenv'ing it here
let proxy_args: []str = [
"xdg-dbus-proxy",
"--filter",
path::string(&downstream_path),
];
for (let spec .. dbus.talk) {
append(proxy_args, "--talk");

View File

@@ -1,9 +1,12 @@
// vim: set shiftwidth=2 :
use errors;
use errors::ext;
use io;
use log;
use path;
use resources;
use restrict::ns;
use rt;
export fn restrict(what: *resources::resources) void = {
// map the user-requested networking into internal mechanisms:
@@ -18,14 +21,26 @@ export fn restrict(what: *resources::resources) void = {
yield (true, void);
};
let (any_dbus, dbus_session_path, dbus_resources): (bool, path::buffer, resources::dbus_subset) = match (what.dbus) {
case let d: resources::dbus_subset => yield match (get_dbus_session_path()) {
case let s: path::buffer => yield (true, s, d);
// map the user-requested dbus settings into internal mechanisms:
// also, obtain a handle to the bus *before* entering the outer sandbox,
// so that we can proxy it into the main sandbox.
let dbus_proxy: (void | dbus_details) = match (what.dbus) {
case let res: resources::dbus_subset => yield match (get_dbus_session_path()) {
case let session: path::buffer =>
yield match (rt::open(path::string(&session), rt::O_RDONLY, 0o400)) { //< TODO: correct mode?
case let outer_fd: int => yield dbus_details {
outer_fd = outer_fd,
session_path = session,
resources = res,
};
case let err: rt::errno =>
errors::ext::swallow("restrict: open(DBUS_SESSION_BUS_ADDRESS)", err);
};
case =>
log::println("restrict: dbus requested, but failed to parse dbus session path");
yield (false, path::init("")!, resources::dbus_subset { ... });
yield void;
};
case void => yield (false, path::init("")!, resources::dbus_subset { ... });
case void => yield void;
};
// sandbox the entire process early, now, before any forking/exec'ing.
@@ -40,8 +55,6 @@ export fn restrict(what: *resources::resources) void = {
append(outer_paths, p);
if (outer_pid)
append(outer_paths, path::init("/proc")!);
if (any_dbus)
append(outer_paths, dbus_session_path);
let outer_ns_resources = ns::ns_resources {
paths = outer_paths,
ipc = what.ipc,
@@ -58,6 +71,13 @@ export fn restrict(what: *resources::resources) void = {
};
// sandbox the user process
match (dbus_proxy) {
case void => void;
case let details: dbus_details =>
dbus_restrict(details.resources, details.outer_fd, details.session_path);
// the bus at this path is now proxied, so grant access to the user
append(what.paths, details.session_path);
};
let user_ns_resources = ns::ns_resources {
paths = what.paths,
ipc = what.ipc,
@@ -68,3 +88,9 @@ export fn restrict(what: *resources::resources) void = {
ns::namespace_restrict(&user_ns_resources);
capability_restrict(what.caps);
};
type dbus_details = struct {
outer_fd: io::file,
session_path: path::buffer,
resources: resources::dbus_subset,
};