Original release notes
Read this first
- The ask callback allows a connection only with
true. A callback that resolved to another truthy value (1, a string, an object) allowed in 0.0.79 and now denies. It may also resolve to{ allow: false, reason }. (#591) - Linux: a sandboxed command stays in the namespaces made for it. It can no longer create a user namespace, or a mount namespace of its own. Whatever sandboxes itself that way stops working inside the sandbox by default: the namespace sandbox of Chromium and Electron, rootless podman or buildah, a nested bubblewrap,
unshare -r.allowNestedUserNamespaces: truelifts it, for the configuration or for a single wrap. An embedder that compiles the seccomp helper into its own binary has to rebuild it. (#588, #617) - Linux:
denyWritetakes precedence overallowWritehowever the two are nested. A write path beneath adenyWritedirectory is now read-only, as on macOS. (#684) - With a
filterRequest, a request target that names another path once normalised is answered 400.network.ambiguousRequestTargetchooses between"refuse"(the default),"asSpelled"(what 0.0.79 sent) and"normalize". (#698)
Fixed: denies that did not apply
- Linux, glob denies on some file systems. A
denyReadpattern covers what lies beneath a directory whose listing gives no entry types (some NFS and FUSE mounts, XFS withftype=0). (#672) - Glob walk. A directory that cannot be read is denied whole, and a directory that answers
ENOENTunder one of its names is asked for under its others. A matching link kept under its own spelling stays in the deny list. On Windows a drive root or a share root is a base like any other:C:/Users*/id.pemand//server/share/x*/y.keymatch. (#575, #690) - Linux, a file above a write deny. Where a file lies above a write-denied path, in a directory the command may write, the file is kept there read-only. In a worktree or a submodule that is its
.gitfile. (#705) - Linux: the mounts of a deny set do not depend on the order it was written in. (#585)
- Linux: VM sockets (
AF_VSOCK) are refused withEPERMwherever the seccomp filter runs. (#691) - Credential files. A
credentials.filesentry takes precedence overallowReadandallowWriteon every platform: nothing at or beneath it is bound back or granted. (#680, #686) - Windows: a path in both
denyReadanddenyWritekeeps the read deny, and deny entries rank against allow entries as on the other platforms. (#656, #686; #650) - Names that hold a backslash. Off Windows the real path of such a name is asked of the file system, the same on every runtime. (#683, #689)
Fixed: sandboxes that did not start
- A folder named like
[user-id]orbackup[2024-01-15]. Brackets that spell no set of characters are read as text, so no path entry, and no working directory, keeps a sandbox from starting. (#687, #718) - Linux without IPv6. The relays inside the sandbox name the family they listen on, and fall back to IPv4. With some socat versions nothing listened and every proxied command was refused. (#719; #706)
- Linux, a mount point that cannot be made. An absent
denyWritepath where bubblewrap cannot create a mount point (a protected folder of a Windows drive under WSL 2, a path under/usr) no longer keeps every command from starting. (#688) - Linux: a fifo or a socket above a write deny no longer keeps a command from starting. (#705)
- macOS: git over SSH works through the sandbox's proxy. Every fetch or push was refused. (#681)
Fixed: other
Linux: an empty read-only file of the caller's own at a denyWrite path is no longer removed from the host after a command. (#673) Linux: the mount points made for absent deny paths are removed when the last sandbox is done, also after a wrap that fails or overlaps another. (#671) Temp files. A process that ends with process.exit(), or whose initialize() fails, leaves none of the library's objects in the temp directory. A generated CA's key was among them. (#670) TLS termination: a certificate's serial number never begins with a zero byte. About one certificate in 65,000 was refused by strict parsers. (#685) Proxy: an upstream that sends more than its Content-Length no longer loses its whole answer. (#717) Proxy: in a tunnel, the 502 for a backend that failed is written only where nothing has gone back to the client yet. (#702) Linux: the two relays inside the sandbox take a burst of connections. Of 128 made at once, about 20 used to fail. (#701) Linux: a bwrap --version probe that gets no answer is not repeated at every ask. (#674) Linux: wraps walk their patterns one at a time, which bounds memory and the time the event loop is held. (#679) Linux: the refusal at 9,000 bubblewrap arguments says how many come from built-in write protection and what lowers each share. (#675) Linux: getLinuxGlobPatternWarnings() also names a credentials.files deny whose pattern is skipped. (#669) getFsWriteConfig() compiles a read rule once and reads brackets in linear time. ( #718</

