Hacker News new | ask | show | jobs
by coppsilgold 8 hours ago
The simplest worthwhile DIY sandbox you can have is to layer two tools: bwrap and gvisor.

    bwrap args -- gvisor args do args -- /path/sandboxee args

bwrap will set up the environment and then gvisor elevates it into a true sandbox.

Standalone gvisor (not the 'do' subcommand) used to be a mess with the OCI json requirement, but recently they began work on presenting their own bwrap interface (likely to pursue AI agent uses) though I wouldn't use it myself yet.

People often look down on gvisor because they think it's some kind of syscall filter, it is not. It can use one of ptrace, seccomp or even KVM to intercept ALL syscalls and service them with it's own logic (which is in Go). Basically it's a VMM and kernel in one.

1 comments

Any reason why you wouldn't use gVisor's bwrap interface yet? We're working on it precisely to make DIY sandboxing on Linux as easy as possible in order to get Linux-sandboxing-at-home to mature beyond the current syscall-filter-and-namespaces duct tape stage, so I'm curious to know what you'd like to see.
It just didn't seem fully baked yet, the 'do' subcommand works fine while the 'bwrap' alias has this problem: `bash: cannot set terminal process group (1): Not a tty`. When executing 'bash -li'. Also the EROFS feature of 'do' should probably be included in 'bwrap', it can be useful. Include overlay options.

Also some things you can do to make gvisor better are Wayland passthrough, vulkan support (or virtio native context). Being able to get gvisor to populate a network interface inside itself through a 'passt' (or 'containers/gvisor-tap-vsock') socket on the host would also be ergonomic. All of those are available on 'muvm' (based on libkrun) which if you have the time to set up is the next step in DIY sandboxing of graphical apps as well. See: <https://git.clan.lol/clan/munix>

Thanks. We're working on rootless network setup to make `runsc do --rootless` work with networking enabled when `passt` is installed right now. See issue #13337 (yes that's a cool issue number) which should unblock this.

The tty issue is known, should be fixed soon too, though contributions welcome as it sounds like it should be simple fix and we love more contributions :)

FWIW, X11 apps work well, I have a personal hacky project in which I've been running Librewolf in gVisor, with the window being reflected as a native Wayland window. It uses `Xvfb -fbdir` aimed at a bound tmpfs mount to get a shared memory region containing the window's pixel data which can be read directly from out of the sandbox, has Pulseaudio audio passthrough, and a socket server passing through mouse/keyboard events to make the window interactive. Works smoothly even for YouTube playback, and I successfully played a game of Unreal Tournament 2004 at 24fps in it, with no noticeable mouse/keyboard latency :) We're basically making baby steps to get there less hackily.

Thanks for the feedback!

That's good to hear! Hopefully the passt approach you are pursuing will include the ability to use an existing passt socket and not just launch one for you.

Wayland is tricky because there are memory buffers being shared between the compositor and the client. crosvm (also by google) adopted 2 custom solutions to it of which one got merged into mainline.

Achieving audio passthrough is trivial as it's just a unix socket. `-host-uds=all`

That's the approach I initially took, but experienced some combination of noticeable stuttering and latency regardless of which buffering strategy I tried... Had to switch to a shared memory ring buffer, along with some adaptive playback speed shenanigans (sometimes imperceptibly speeding up playback when falling behind production of audio samples, sometimes imperceptibly slowing down when there's less than a few milliseconds' worth of samples left in the ringbuffer), in order to achieve actually-gapless playback.
There is something wrong with your setup.

I just tried:

    bwrap ... --ro-bind /run/user/1000/pipewire-0 /run/user/1000/pipewire-0 ... -- runsc ... do ... -- mpv podcast.mp3
Flawless playback. I think it's a default pipewire configuration.