bubblewrap icon indicating copy to clipboard operation
bubblewrap copied to clipboard

Have a specific exit code for when sandboxing is not possible

Open sophie-h opened this issue 4 months ago • 2 comments

Since there are a bunch of environments where sandboxing doesn't work like in a libgnome-desktop sandbox or some CIs, we want to do opportunistic sandboxing. We are now doing this in glycin by testing if bwrap was called with SIGSYS (happens in CIs) or if it's STDERR contains a string indicating that spawning failed due to failing to create namespace glycin!295.

While there is no clear answer to what "sandboxing not being available" means, at least for the failed clone syscalls it would be good to have a more specific exit code than just 1. Following the 128+n convention would be one option.

sophie-h avatar Sep 16 '25 12:09 sophie-h

Alternative suggestion: use --json-status-fd to communicate such errors. It does not have the usual ambiguity of exit codes.

rusty-snake avatar Sep 16 '25 14:09 rusty-snake

Changing the exit status would technically be a backward-compatibility break, so I think #455 would be a prerequisite.

With hindsight, I agree that exit status 1 is not a great choice (I didn't choose it), although it is consistent with, e.g., sudo. But, no other exit status is a great choice either: there are only 256 exit statuses, and whichever one bubblewrap uses to indicate internal errors, bubblewrap users cannot distinguish between bubblewrap itself exiting with that status and the "payload" command exiting with the same status.

The least-bad exit status if we didn't have backward-compatibility to worry about would probably be the env(1), nice(1), etc. convention of exit status 125 for an error in the adverb, but that would mean that if bwrap ... env ... nice ... mycommand exits with status 125, you can't tell whether it was bwrap, env, nice or some other thing in the exec chain that failed.

As @rusty-snake said, the way to get more than 8 bits of information out of bubblewrap is with --json-status-fd or a similar option, which tells the caller what is going on in a machine-readable and extensible way. I don't know whether it already provides enough information, but if not, I'd consider merge requests (with the usual warning that I have too many responsibilities and not enough time, so if you are relying on me personally, it could take a while for me to get to them).

The other option here is what Steam does: during startup, run bwrap ... true, and see what happens; and then use that to decide what to do for the commands that you actually wanted to wrap.

if it's STDERR contains a string indicating that spawning failed due to failing to create namespace

As you've seen, this is not a great choice for robustness, because stderr contains human-readable diagnostic information which can contain typos, be re-worded, get patched by distros to show distro-appropriate advice and so on.

Following the 128+n convention would be one option.

Those are reserved for "killed by signal n", and have the same problem as any other exit status that it is not possible to distinguish between getting them for one reason or another reason.

smcv avatar Sep 25 '25 09:09 smcv