This material is work-in-progress ...
The reasoning is most likely wrong for why to do some stuff. Someone more experienced needs to look it over.(Last edited by
Encode on 27 Jan 2023.)
Bubblewrap is an
unprivileged sandboxing tool. Kernel features it also has:
User/IPC/PID/Network/UTS/cgroup
namespaces and
Seccomp filters.
How bubblewrap works, as stated in the
README.md :
bubblewrap works by creating a new, completely empty, mount namespace where the root is on a tmpfs that is invisible from the host, and will be automatically cleaned up when the last process exits. You can then use commandline options to construct the root filesystem and process environment and command to run in the namespace.
Installation
Install bubblewrap :
# apk add bubblewrap
Note: The package is bubblewrap
but the command to
manage it is bwrap
.
How to workout what a program needs
Look at Bubblewrap/Examples to see various ways bubblewrap can be used.
Prerequisites
First make sure to have a user editable directory in $PATH
. This
page will use "${HOME}"/.local/bin , create it if it does not
exist:
$ mkdir -p ~/.local/bin
Add it to ~/.profile :
Contents of ~/.profile
...
export PATH="${PATH}":"${HOME}"/.local/bin
...
Will need to relog for this to apply.
Basic bwrap setup
Note: With how we will be sandboxing everything that doesn't match our owner/group will show as nobody
.
Lets assume you want to sandbox imv and are using Wayland
only. Here is how you might go about that.
Create bwrap-imv
inside "${HOME}"/.local/bin and make it
executable:
$ touch ~/.local/bin/bwrap-imv
$ chmod 0700 ~/.local/bin/bwrap-imv
Use file
to determine the file type of /usr/bin/imv :
$ file /usr/bin/imv
/usr/bin/imv: POSIX shell script, ASCII text executable
Use less
to view it:
$ less /usr/bin/imv
Contents of /usr/bin/imv
#!/bin/sh
if [ -n "${WAYLAND_DISPLAY}" ]; then
exec /usr/libexec/imv-wayland "$@"
else
exec /usr/libexec/imv-x11 "$@"
fi
Since we are assuming Wayland only we can just skip to
/usr/libexec/imv-wayland . Run file
on it:
$ file /usr/libexec/imv-wayland
/usr/libexec/imv-wayland: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-musl-x86_64.so.1, stripped
It is an
Executable and Linkable Format (ELF)
file. So we know we need the ELF interpreter
/lib/ld-musl-x86_64.so.1 . We also know we need
/usr/libexec/imv-wayland , since it has to know where the command
is located. As the argument to /usr/libexec/imv-wayland
, put
"${@:-./}"
, this will generate a separate word for each
positional parameter and if you didn't have any parameters it will
default to current directory.
Running ldd
to find all necessary libs, except ones loaded at
runtime, on /usr/libexec/imv-wayland , outputs a lot of things but
for the moment all we care about are the directory paths. Specifically
the starting directories, which are /lib/*
and /usr/lib/*
.
Warning: The
ldd
manpage talks about some security implications. It may not apply since they seem to be talking about glibc and
musl-utils makes
/lib/ld-musl-x86_64.so.1 ldd
[1] . Is this something to worry about?
Since this is for Wayland lets also add some prerequisites:
--setenv XDG_RUNTIME_DIR "${XDG_RUNTIME_DIR}" \
for determining the directory for the wayland socket;
--setenv WAYLAND_DISPLAY "${WAYLAND_DISPLAY}" \
for determining the socket;
--ro-bind "${XDG_RUNTIME_DIR}/${WAYLAND_DISPLAY}" "${XDG_RUNTIME_DIR}/${WAYLAND_DISPLAY}" \
mount readonly.
Lets also add some nice to haves:
--unshare-all \
will create a new user/ipc/pid/net/utc namespaces and try to create a
new cgroup namespace if possible;
--new-session
will create a new terminal session for the sandbox, disconnecting from
the controlling terminal so for example it can't inject input into the
terminal;
--die-with-parent
will ensure child process (imv-wayland
in this case) dies when
bwrap
parent dies.
Since we are not passing the whole filesystem, we need a way to pass the
arguments given:
--ro-bind "${@:-./}" "$(realpath "${@:-./}")" \
this will take all arguments or the current directory and mount to the
absolute path.
Warning: This will have everything under the current directory available to imv
if you don't specify an argument. I don't know how to limit it so you can specify 2+ and not have everything .
We might also have a config file:
--ro-bind-try "${XDG_CONFIG_HOME}"/imv "${XDG_CONFIG_HOME}"/imv \
this will add your local config to imv
if you have one and if not
will still continue. Add:
--setenv XDG_CONFIG_HOME "${XDG_CONFIG_HOME}" \
for later.
Note: If you have your imv config as a symbolic link, where it points to will also need to be added. Lets say you had a symbolic link that points to ~/src/dots/imv/config , you would do:
--ro-bind-try "${HOME}/src/dots/imv/config" "${HOME}/src/dots/imv/config" \
--ro-bind-try "${XDG_CONFIG_HOME}"/imv "${XDG_CONFIG_HOME}"/imv \
Also need:
--dev-bind /dev/null /dev/null \
and
--ro-bind /bin/sh /bin/sh \
to make use of your config .
We should also wrap the whole thing in (exec ...)
. This will
replace the shell process; no new process is created. Any changes to
variables are not seen by stuff outside the subshell.
~/.local/bin/bwrap-imv looks like:
Contents of ~/.local/bin/bwrap-imv
#!/usr/bin/env sh
# imv wrapped in bwrap.
(exec /usr/bin/bwrap \
--unshare-all \
--new-session \
--die-with-parent \
--setenv XDG_RUNTIME_DIR "${XDG_RUNTIME_DIR}" \
--setenv WAYLAND_DISPLAY "${WAYLAND_DISPLAY}" \
--setenv XDG_CONFIG_HOME "${XDG_CONFIG_HOME}" \
--dev-bind /dev/null /dev/null \
--ro-bind-try "${XDG_CONFIG_HOME}"/imv "${XDG_CONFIG_HOME}"/imv \
--ro-bind "${XDG_RUNTIME_DIR}/${WAYLAND_DISPLAY}" "${XDG_RUNTIME_DIR}/${WAYLAND_DISPLAY}" \
--ro-bind /bin/sh /bin/sh \
--ro-bind /lib /lib \
--ro-bind /usr/lib /usr/lib \
--ro-bind /usr/libexec/imv-wayland /usr/libexec/imv-wayland \
--ro-bind "${@:-./}" "$(realpath "${@:-./}")" \
/usr/libexec/imv-wayland "${@:-./}")
Now lets run bwrap-imv
; go into a directory with an image:
$ bwrap-imv IMAGE
xkbcommon: ERROR: failed to add default include path /usr/share/X11/xkb
Assertion failed: keyboard->context (../src/keyboard.c: imv_keyboard_create: 20)
Add:
--ro-bind /usr/share/X11/xkb /usr/share/X11/xkb \
to bwrap-imv
. XKB
is a keyboard keymap support library.
After adding the above, run it again:
$ bwrap-imv IMAGE
libEGL warning: wayland-egl: could not open /dev/dri/renderD128 (No such file or directory)
Add:
--dev-bind /dev/dri/renderD128 /dev/dri/renderD128 \
and run again:
$ bwrap-imv IMAGE
libEGL warning: wayland-egl: drmGetMagic failed
If you follow Bubblewrap#Can't_find_what_path_is_missing , you will
eventually get down to:
--ro-bind /sys/dev/char /sys/dev/char \}}
and
--ro-bind /sys/devices/pci0000:00 /sys/devices/pci0000:00 \
--clearenv \
can also be added now. This will unset all environment variables,
except for $PWD
and any we set with --setenv
.
Now imv
should show images and your config file should
work. If you do not use commands, the finished
~/.local/bin/bwrap-imv should look like:
Contents of ~/.local/bin/bwrap-imv
#!/usr/bin/env sh
# imv wrapped in bwrap.
(exec /usr/bin/bwrap \
--unshare-all \
--new-session \
--die-with-parent \
--clearenv \
--setenv XDG_RUNTIME_DIR "${XDG_RUNTIME_DIR}" \
--setenv WAYLAND_DISPLAY "${WAYLAND_DISPLAY}" \
--setenv XDG_CONFIG_HOME "${XDG_CONFIG_HOME}" \
--dev-bind /dev/dri/renderD128 /dev/dri/renderD128 \
--dev-bind /dev/null /dev/null \
--ro-bind-try "${XDG_CONFIG_HOME}"/imv "${XDG_CONFIG_HOME}"/imv \
--ro-bind "${XDG_RUNTIME_DIR}/${WAYLAND_DISPLAY}" "${XDG_RUNTIME_DIR}/${WAYLAND_DISPLAY}" \
--ro-bind /bin/sh /bin/sh \
--ro-bind /lib /lib \
--ro-bind /sys/dev/char /sys/dev/char \
--ro-bind /sys/devices/pci0000:00 /sys/devices/pci0000:00 \
--ro-bind /usr/lib /usr/lib \
--ro-bind /usr/libexec/imv-wayland /usr/libexec/imv-wayland \
--ro-bind /usr/share/X11/xkb /usr/share/X11/xkb \
--ro-bind "${@:-./}" "$(realpath "${@:-./}")" \
/usr/libexec/imv-wayland "${@:-./}")
If you do use commands however, you will notice it is only showing
substitute characters .
Tip: Commands in imv
can be entered by pressing :
.
If you try to use a command it will say:
Fontconfig error: Cannot load default config file: No such file: (null)
Look at the fonts-conf
manpage (which is from
fontconfig-doc ) we see that /etc/fonts is the system
font configuration directory and
"${XDG_CONFIG_HOME}"/fontconfig is the per-user configuration
directory. Add "${XDG_CONFIG_HOME}"/fontconfig/ with
--ro-bind-try
so it doesn't have to exist:
--ro-bind /etc/fonts /etc/fonts \
--ro-bind-try "${XDG_CONFIG_HOME}"/fontconfig "${XDG_CONFIG_HOME}"/fontconfig \
The default directories scanned for font files are
/usr/share/fonts/ and "${XDG_DATA_HOME}"/fonts . Add
"${XDG_DATA_HOME}"/fonts with --ro-bind-try
:
--ro-bind /usr/share/fonts /usr/share/fonts \
--ro-bind-try "${XDG_DATA_HOME}"/fonts "${XDG_DATA_HOME}"/fonts \
Also need:
--setenv XDG_DATA_HOME "${XDG_DATA_HOME}" \
The user cache of font information is also needed, by default
"${XDG_CACHE_HOME}"/fontconfig :
--bind-try "${XDG_CACHE_HOME}"/fontconfig "${XDG_CACHE_HOME}"/fontconfig \
Note: It seems to still work with --ro-bind-try
, does it not need to write to it?
Also need:
--setenv XDG_CACHE_HOME "${XDG_CACHE_HOME}" \
--ro-bind /usr/share/icu /usr/share/icu \
Is also needed or when you do :<backspace>
it will terminate the
process. ICU provides Unicode and Globalization support.
The updated ~/.local/bin/bwrap-imv should look like this:
Contents of ~/.local/bin/bwrap-imv
#!/usr/bin/env sh
# imv wrapped in bwrap.
(exec /usr/bin/bwrap \
--unshare-all \
--new-session \
--die-with-parent \
--clearenv \
--setenv XDG_RUNTIME_DIR "${XDG_RUNTIME_DIR}" \
--setenv WAYLAND_DISPLAY "${WAYLAND_DISPLAY}" \
--setenv XDG_CACHE_HOME "${XDG_CACHE_HOME}" \
--setenv XDG_CONFIG_HOME "${XDG_CONFIG_HOME}" \
--setenv XDG_DATA_HOME "${XDG_DATA_HOME}" \
--dev-bind /dev/dri/renderD128 /dev/dri/renderD128 \
--dev-bind /dev/null /dev/null \
--bind-try "${XDG_CACHE_HOME}"/fontconfig "${XDG_CACHE_HOME}"/fontconfig \
--ro-bind-try "${XDG_CONFIG_HOME}"/fontconfig "${XDG_CONFIG_HOME}"/fontconfig \
--ro-bind-try "${XDG_CONFIG_HOME}"/imv "${XDG_CONFIG_HOME}"/imv \
--ro-bind-try "${XDG_DATA_HOME}"/fonts "${XDG_DATA_HOME}"/fonts \
--ro-bind /bin/sh /bin/sh \
--ro-bind /etc/fonts /etc/fonts \
--ro-bind /lib /lib \
--ro-bind /sys/dev/char /sys/dev/char \
--ro-bind /sys/devices/pci0000:00 /sys/devices/pci0000:00 \
--ro-bind "${XDG_RUNTIME_DIR}/${WAYLAND_DISPLAY}" "${XDG_RUNTIME_DIR}/${WAYLAND_DISPLAY}" \
--ro-bind /usr/lib /usr/lib \
--ro-bind /usr/libexec/imv-wayland /usr/libexec/imv-wayland \
--ro-bind /usr/share/X11/xkb /usr/share/X11/xkb \
--ro-bind /usr/share/fonts /usr/share/fonts \
--ro-bind /usr/share/icu /usr/share/icu \
--ro-bind "${@:-./}" "$(realpath "${@:-./}")" \
/usr/libexec/imv-wayland "${@:-./}")
Finally test what all is allowed by replacing
/usr/libexec/imv-wayland "${@:-./}")
with /bin/sh
and
adding --ro-bind /bin /bin \
. Check around and see what the
filesystem is like:
Contents of ~/.local/bin/bwrap-imv
...
--ro-bind "${@:-./}" "$(realpath "${@:-./}")" \
--ro-bind /bin /bin \
/bin/sh)
Invoke bwrap-imv
:
$ bwrap-imv
Show what environment variables are active:
$ printenv
See what directories are at root:
$ ls -la /
... bin
... dev
... etc
... home
... lib
... sys
... tmp
... usr
exit
when done:
$ exit
Do not forget to change it back:
Contents of ~/.local/bin/bwrap-imv
...
--ro-bind "${@:-./}" "$(realpath "${@:-./}")" \
/usr/libexec/imv-wayland "${@:-./}")
All done with a basic bubblewrap wrapper.
Seccomp
This material needs expanding ...
Limiting shared objects
Earlier we didn't care about limiting the shared objects but now we do.
In the spirit of
Principle of least privilege ,
what is not needed should not exist. Use the output of
$ ldd /usr/libexec/imv-wayland
to the find necessary libs.
Contents of ~/.local/bin/bwrap-imv
...
--ro-bind /etc/fonts /etc/fonts \
--ro-bind /lib/ld-musl-x86_64.so.1 /lib/ld-musl-x86_64.so.1 \
--ro-bind /lib/libblkid.so.1 /lib/libblkid.so.1 \
--ro-bind /lib/libmount.so.1 /lib/libmount.so.1 \
--ro-bind /lib/libz.so.1 /lib/libz.so.1 \
--ro-bind /sys/dev/char /sys/dev/char \
...
--ro-bind "${XDG_RUNTIME_DIR}/${WAYLAND_DISPLAY}" "${XDG_RUNTIME_DIR}/${WAYLAND_DISPLAY}" \
--ro-bind /usr/lib/libEGL.so.1 /usr/lib/libEGL.so.1 \
--ro-bind /usr/lib/libGL.so.1 /usr/lib/libGL.so.1 \
--ro-bind /usr/lib/libX11-xcb.so.1 /usr/lib/libX11-xcb.so.1 \
--ro-bind /usr/lib/libX11.so.6 /usr/lib/libX11.so.6 \
--ro-bind /usr/lib/libXau.so.6 /usr/lib/libXau.so.6 \
--ro-bind /usr/lib/libXdmcp.so.6 /usr/lib/libXdmcp.so.6 \
--ro-bind /usr/lib/libXext.so.6 /usr/lib/libXext.so.6 \
--ro-bind /usr/lib/libXfixes.so.3 /usr/lib/libXfixes.so.3 \
--ro-bind /usr/lib/libXrender.so.1 /usr/lib/libXrender.so.1 \
--ro-bind /usr/lib/libXxf86vm.so.1 /usr/lib/libXxf86vm.so.1 \
--ro-bind /usr/lib/libbrotlicommon.so.1 /usr/lib/libbrotlicommon.so.1 \
--ro-bind /usr/lib/libbrotlidec.so.1 /usr/lib/libbrotlidec.so.1 \
--ro-bind /usr/lib/libbsd.so.0 /usr/lib/libbsd.so.0 \
--ro-bind /usr/lib/libbz2.so.1 /usr/lib/libbz2.so.1 \
--ro-bind /usr/lib/libcairo-gobject.so.2 /usr/lib/libcairo-gobject.so.2 \
--ro-bind /usr/lib/libcairo.so.2 /usr/lib/libcairo.so.2 \
--ro-bind /usr/lib/libdrm.so.2 /usr/lib/libdrm.so.2 \
--ro-bind /usr/lib/libexpat.so.1 /usr/lib/libexpat.so.1 \
--ro-bind /usr/lib/libffi.so.8 /usr/lib/libffi.so.8 \
--ro-bind /usr/lib/libfontconfig.so.1 /usr/lib/libfontconfig.so.1 \
--ro-bind /usr/lib/libfreeimage.so.3 /usr/lib/libfreeimage.so.3 \
--ro-bind /usr/lib/libfreetype.so.6 /usr/lib/libfreetype.so.6 \
--ro-bind /usr/lib/libfribidi.so.0 /usr/lib/libfribidi.so.0 \
--ro-bind /usr/lib/libgbm.so.1 /usr/lib/libgbm.so.1 \
--ro-bind /usr/lib/libgcc_s.so.1 /usr/lib/libgcc_s.so.1 \
--ro-bind /usr/lib/libgdk_pixbuf-2.0.so.0 /usr/lib/libgdk_pixbuf-2.0.so.0 \
--ro-bind /usr/lib/libgio-2.0.so.0 /usr/lib/libgio-2.0.so.0 \
--ro-bind /usr/lib/libglapi.so.0 /usr/lib/libglapi.so.0 \
--ro-bind /usr/lib/libglib-2.0.so.0 /usr/lib/libglib-2.0.so.0 \
--ro-bind /usr/lib/libgmodule-2.0.so.0 /usr/lib/libgmodule-2.0.so.0 \
--ro-bind /usr/lib/libgobject-2.0.so.0 /usr/lib/libgobject-2.0.so.0 \
--ro-bind /usr/lib/libgraphite2.so.3 /usr/lib/libgraphite2.so.3 \
--ro-bind /usr/lib/libharfbuzz.so.0 /usr/lib/libharfbuzz.so.0 \
--ro-bind /usr/lib/libicudata.so.72 /usr/lib/libicudata.so.72 \
--ro-bind /usr/lib/libicuuc.so.72 /usr/lib/libicuuc.so.72 \
--ro-bind /usr/lib/libinih.so.0 /usr/lib/libinih.so.0 \
--ro-bind /usr/lib/libintl.so.8 /usr/lib/libintl.so.8 \
--ro-bind /usr/lib/libjpeg.so.8 /usr/lib/libjpeg.so.8 \
--ro-bind /usr/lib/liblzma.so.5 /usr/lib/liblzma.so.5 \
--ro-bind /usr/lib/libmd.so.0 /usr/lib/libmd.so.0 \
--ro-bind /usr/lib/libpango-1.0.so.0 /usr/lib/libpango-1.0.so.0 \
--ro-bind /usr/lib/libpangocairo-1.0.so.0 /usr/lib/libpangocairo-1.0.so.0 \
--ro-bind /usr/lib/libpangoft2-1.0.so.0 /usr/lib/libpangoft2-1.0.so.0 \
--ro-bind /usr/lib/libpcre2-8.so.0 /usr/lib/libpcre2-8.so.0 \
--ro-bind /usr/lib/libpixman-1.so.0 /usr/lib/libpixman-1.so.0 \
--ro-bind /usr/lib/libpng16.so.16 /usr/lib/libpng16.so.16 \
--ro-bind /usr/lib/librsvg-2.so.2 /usr/lib/librsvg-2.so.2 \
--ro-bind /usr/lib/libstdc++.so.6 /usr/lib/libstdc++.so.6 \
--ro-bind /usr/lib/libwayland-client.so.0 /usr/lib/libwayland-client.so.0 \
--ro-bind /usr/lib/libwayland-egl.so.1 /usr/lib/libwayland-egl.so.1 \
--ro-bind /usr/lib/libwayland-server.so.0 /usr/lib/libwayland-server.so.0 \
--ro-bind /usr/lib/libxcb-dri2.so.0 /usr/lib/libxcb-dri2.so.0 \
--ro-bind /usr/lib/libxcb-dri3.so.0 /usr/lib/libxcb-dri3.so.0 \
--ro-bind /usr/lib/libxcb-glx.so.0 /usr/lib/libxcb-glx.so.0 \
--ro-bind /usr/lib/libxcb-present.so.0 /usr/lib/libxcb-present.so.0 \
--ro-bind /usr/lib/libxcb-randr.so.0 /usr/lib/libxcb-randr.so.0 \
--ro-bind /usr/lib/libxcb-render.so.0 /usr/lib/libxcb-render.so.0 \
--ro-bind /usr/lib/libxcb-shm.so.0 /usr/lib/libxcb-shm.so.0 \
--ro-bind /usr/lib/libxcb-sync.so.1 /usr/lib/libxcb-sync.so.1 \
--ro-bind /usr/lib/libxcb-xfixes.so.0 /usr/lib/libxcb-xfixes.so.0 \
--ro-bind /usr/lib/libxcb.so.1 /usr/lib/libxcb.so.1 \
--ro-bind /usr/lib/libxkbcommon.so.0 /usr/lib/libxkbcommon.so.0 \
--ro-bind /usr/lib/libxml2.so.2 /usr/lib/libxml2.so.2 \
--ro-bind /usr/lib/libxshmfence.so.1 /usr/lib/libxshmfence.so.1 \
--ro-bind /usr/libexec/imv-wayland /usr/libexec/imv-wayland \
...
Running that, $ bwrap-imv IMAGE
, we see an error:
lebEGL warning.../usr/lib/xorg/modules/dri/crocus_dri.so
lebEGL warning.../usr/lib/xorg/modules/dri/swrast_dri.so
Running ldd
on both and see they both have the same
shared objects. Insert them in the above, will look like:
Contents of ~/.local/bin/bwrap-imv
...
--ro-bind "${XDG_RUNTIME_DIR}/${WAYLAND_DISPLAY}" "${XDG_RUNTIME_DIR}/${WAYLAND_DISPLAY}" \
--ro-bind /usr/lib/libEGL.so.1 /usr/lib/libEGL.so.1 \
--ro-bind /usr/lib/libGL.so.1 /usr/lib/libGL.so.1 \
--ro-bind /usr/lib/libLLVM-15.so /usr/lib/libLLVM-15.so \
--ro-bind /usr/lib/libX11-xcb.so.1 /usr/lib/libX11-xcb.so.1 \
--ro-bind /usr/lib/libX11.so.6 /usr/lib/libX11.so.6 \
--ro-bind /usr/lib/libXau.so.6 /usr/lib/libXau.so.6 \
--ro-bind /usr/lib/libXdmcp.so.6 /usr/lib/libXdmcp.so.6 \
--ro-bind /usr/lib/libXext.so.6 /usr/lib/libXext.so.6 \
--ro-bind /usr/lib/libXfixes.so.3 /usr/lib/libXfixes.so.3 \
--ro-bind /usr/lib/libXrender.so.1 /usr/lib/libXrender.so.1 \
--ro-bind /usr/lib/libXxf86vm.so.1 /usr/lib/libXxf86vm.so.1 \
--ro-bind /usr/lib/libbrotlicommon.so.1 /usr/lib/libbrotlicommon.so.1 \
--ro-bind /usr/lib/libbrotlidec.so.1 /usr/lib/libbrotlidec.so.1 \
--ro-bind /usr/lib/libbsd.so.0 /usr/lib/libbsd.so.0 \
--ro-bind /usr/lib/libbz2.so.1 /usr/lib/libbz2.so.1 \
--ro-bind /usr/lib/libcairo-gobject.so.2 /usr/lib/libcairo-gobject.so.2 \
--ro-bind /usr/lib/libcairo.so.2 /usr/lib/libcairo.so.2 \
--ro-bind /usr/lib/libdrm.so.2 /usr/lib/libdrm.so.2 \
--ro-bind /usr/lib/libdrm_amdgpu.so.1 /usr/lib/libdrm_amdgpu.so.1 \
--ro-bind /usr/lib/libdrm_intel.so.1 /usr/lib/libdrm_intel.so.1 \
--ro-bind /usr/lib/libdrm_nouveau.so.2 /usr/lib/libdrm_nouveau.so.2 \
--ro-bind /usr/lib/libdrm_radeon.so.1 /usr/lib/libdrm_radeon.so.1 \
--ro-bind /usr/lib/libelf.so.1 /usr/lib/libelf.so.1 \
--ro-bind /usr/lib/libexpat.so.1 /usr/lib/libexpat.so.1 \
--ro-bind /usr/lib/libffi.so.8 /usr/lib/libffi.so.8 \
--ro-bind /usr/lib/libfontconfig.so.1 /usr/lib/libfontconfig.so.1 \
--ro-bind /usr/lib/libfreeimage.so.3 /usr/lib/libfreeimage.so.3 \
--ro-bind /usr/lib/libfreetype.so.6 /usr/lib/libfreetype.so.6 \
--ro-bind /usr/lib/libfribidi.so.0 /usr/lib/libfribidi.so.0 \
--ro-bind /usr/lib/libgbm.so.1 /usr/lib/libgbm.so.1 \
--ro-bind /usr/lib/libgcc_s.so.1 /usr/lib/libgcc_s.so.1 \
--ro-bind /usr/lib/libgdk_pixbuf-2.0.so.0 /usr/lib/libgdk_pixbuf-2.0.so.0 \
--ro-bind /usr/lib/libgio-2.0.so.0 /usr/lib/libgio-2.0.so.0 \
--ro-bind /usr/lib/libglapi.so.0 /usr/lib/libglapi.so.0 \
--ro-bind /usr/lib/libglib-2.0.so.0 /usr/lib/libglib-2.0.so.0 \
--ro-bind /usr/lib/libgmodule-2.0.so.0 /usr/lib/libgmodule-2.0.so.0 \
--ro-bind /usr/lib/libgobject-2.0.so.0 /usr/lib/libgobject-2.0.so.0 \
--ro-bind /usr/lib/libgraphite2.so.3 /usr/lib/libgraphite2.so.3 \
--ro-bind /usr/lib/libharfbuzz.so.0 /usr/lib/libharfbuzz.so.0 \
--ro-bind /usr/lib/libicudata.so.72 /usr/lib/libicudata.so.72 \
--ro-bind /usr/lib/libicuuc.so.72 /usr/lib/libicuuc.so.72 \
--ro-bind /usr/lib/libinih.so.0 /usr/lib/libinih.so.0 \
--ro-bind /usr/lib/libintl.so.8 /usr/lib/libintl.so.8 \
--ro-bind /usr/lib/libjpeg.so.8 /usr/lib/libjpeg.so.8 \
--ro-bind /usr/lib/liblzma.so.5 /usr/lib/liblzma.so.5 \
--ro-bind /usr/lib/libmd.so.0 /usr/lib/libmd.so.0 \
--ro-bind /usr/lib/libpango-1.0.so.0 /usr/lib/libpango-1.0.so.0 \
--ro-bind /usr/lib/libpangocairo-1.0.so.0 /usr/lib/libpangocairo-1.0.so.0 \
--ro-bind /usr/lib/libpangoft2-1.0.so.0 /usr/lib/libpangoft2-1.0.so.0 \
--ro-bind /usr/lib/libpciaccess.so.0 /usr/lib/libpciaccess.so.0 \
--ro-bind /usr/lib/libpcre2-8.so.0 /usr/lib/libpcre2-8.so.0 \
--ro-bind /usr/lib/libpixman-1.so.0 /usr/lib/libpixman-1.so.0 \
--ro-bind /usr/lib/libpng16.so.16 /usr/lib/libpng16.so.16 \
--ro-bind /usr/lib/librsvg-2.so.2 /usr/lib/librsvg-2.so.2 \
--ro-bind /usr/lib/libstdc++.so.6 /usr/lib/libstdc++.so.6 \
--ro-bind /usr/lib/libwayland-client.so.0 /usr/lib/libwayland-client.so.0 \
--ro-bind /usr/lib/libwayland-egl.so.1 /usr/lib/libwayland-egl.so.1 \
--ro-bind /usr/lib/libwayland-server.so.0 /usr/lib/libwayland-server.so.0 \
--ro-bind /usr/lib/libxcb-dri2.so.0 /usr/lib/libxcb-dri2.so.0 \
--ro-bind /usr/lib/libxcb-dri3.so.0 /usr/lib/libxcb-dri3.so.0 \
--ro-bind /usr/lib/libxcb-glx.so.0 /usr/lib/libxcb-glx.so.0 \
--ro-bind /usr/lib/libxcb-present.so.0 /usr/lib/libxcb-present.so.0 \
--ro-bind /usr/lib/libxcb-randr.so.0 /usr/lib/libxcb-randr.so.0 \
--ro-bind /usr/lib/libxcb-render.so.0 /usr/lib/libxcb-render.so.0 \
--ro-bind /usr/lib/libxcb-shm.so.0 /usr/lib/libxcb-shm.so.0 \
--ro-bind /usr/lib/libxcb-sync.so.1 /usr/lib/libxcb-sync.so.1 \
--ro-bind /usr/lib/libxcb-xfixes.so.0 /usr/lib/libxcb-xfixes.so.0 \
--ro-bind /usr/lib/libxcb.so.1 /usr/lib/libxcb.so.1 \
--ro-bind /usr/lib/libxkbcommon.so.0 /usr/lib/libxkbcommon.so.0 \
--ro-bind /usr/lib/libxml2.so.2 /usr/lib/libxml2.so.2 \
--ro-bind /usr/lib/libxshmfence.so.1 /usr/lib/libxshmfence.so.1 \
--ro-bind /usr/lib/libzstd.so.1 /usr/lib/libzstd.so.1 \
--ro-bind /usr/lib/xorg/modules/dri/crocus_dri.so /usr/lib/xorg/modules/dri/crocus_dri.so \
--ro-bind /usr/lib/xorg/modules/dri/swrast_dri.so /usr/lib/xorg/modules/dri/swrast_dri.so \
--ro-bind /usr/libexec/imv-wayland /usr/libexec/imv-wayland \
...
Now it should work as before.
.desktop integration
This material is obsolete ...
This should probably be documented in Default_applications and linked here. Nothing is unique in using with bwrap
.
(Discuss )
Note: This section is also using imv as the example.
XDG Desktop Entry Specification
are a set of standards describing how a particular program is to be
launched, how it appears in menus, etc.
The default .desktop file for imv
is at
/usr/share/applications/imv.desktop . Move it to
"${XDG_DATA_HOME}"/applications/bwrap-imv.desktop .
Only 3 options will need to be changed: Name/Name[en_US], what shows up
in the application menu in a graphical file manager (if you have one
installed); Exec, program to execute:
Contents of "${XDG_DATA_HOME}"/applications/bwrap-imv.desktop
...
Name=bwrap-imv
Name[en_US]=bwrap-imv
Exec=bwrap-imv %F
...
The program xdg-open
(from the xdg-utils package) can be
used to open files based on the MIME
type + corresponding entry in $"{XDG_CONFIG_HOME}"/mimeapps.list and
"${XDG_DATA_HOME}"/applications/mimeinfo.cache .
Install desktop-file-utils if it is not installed already, it
comes with two commands that are needed desktop-file-validate
and
update-desktop-database
:
# apk add desktop-file-utils
Validate
It is a good idea to validate imv.desktop
using
desktop-file-validate
:
$ desktop-file-validate "${XDG_DATA_HOME}"/applications/bwrap-imv.desktop
Update database
This will make entries in "${XDG_DATA_HOME}"/applications/ take
precedence over system-wide files (/usr/share/applications/ ).
However "${XDG_CONFIG_HOME}"/mimeapps.list has precedence over
both.
Updating the database, will create
"${XDG_DATA_HOME}"/applications/mimeinfo.cache :
$ update-desktop-database "${XDG_DATA_HOME}"/applications
Troubleshooting
Can't find what path is missing
If all else fails start broad and work toward narrowing. See if
bwrap
works with the program at all:
$ bwrap \
--dev-bind / / PROGRAM
If that works start to narrow:
$ bwrap \
--ro-bind /bin /bin \
--dev-bind /dev /dev \
--ro-bind /lib /lib \
--ro-bind /sys /sys \
--ro-bind /usr /usr \
PROGRAM
Keep going till you have narrowed as much as possible.
See also