All Projects → gch1p → voidnsrun

gch1p / voidnsrun

Licence: BSD-2-Clause License
Run glibc binaries in musl libc Void Linux environment

Programming Languages

c
50402 projects - #5 most used programming language
Makefile
30231 projects

Projects that are alternatives of or similar to voidnsrun

linux-installer
Universal GNU+Linux installer script
Stars: ✭ 16 (-48.39%)
Mutual labels:  void, voidlinux
octoxbps
A Qt-based XBPS front end
Stars: ✭ 45 (+45.16%)
Mutual labels:  voidlinux
ghc-alt-libc
GHC compiled against musl & uClibc
Stars: ✭ 41 (+32.26%)
Mutual labels:  musl
semagrow
A SPARQL query federator of heterogeneous data sources
Stars: ✭ 27 (-12.9%)
Mutual labels:  void
html-void-elements
List of known void HTML elements
Stars: ✭ 23 (-25.81%)
Mutual labels:  void
void-runit
runit init scripts for Void
Stars: ✭ 118 (+280.65%)
Mutual labels:  voidlinux
VoidMuslWSL
Install Void Linux (with musl-libc) as a WSL Instance (for Windows 10 1803 64bit or later)
Stars: ✭ 30 (-3.23%)
Mutual labels:  voidlinux
Microdot
The Microdot Project guides you to create a fully functional but compact Linux system from scratch
Stars: ✭ 41 (+32.26%)
Mutual labels:  musl
detect-libc
Node.js module to detect details of the C standard library (libc) implementation provided by a given Linux system
Stars: ✭ 33 (+6.45%)
Mutual labels:  musl
docker-rustup
Automated builded images for rust-lang with rustup, "the ultimate way to install RUST"
Stars: ✭ 78 (+151.61%)
Mutual labels:  musl
void-infrastructure
Infrastructure configuration data for Void systems
Stars: ✭ 49 (+58.06%)
Mutual labels:  voidlinux
merelinux
A lightweight Linux distribution using musl libc, pacman and s6
Stars: ✭ 68 (+119.35%)
Mutual labels:  musl
void
Single player Runescape 634 server with a focus on knowledge representation and ai architecture.
Stars: ✭ 15 (-51.61%)
Mutual labels:  void
void-updates
Update check system for void-packages
Stars: ✭ 25 (-19.35%)
Mutual labels:  voidlinux
sabotage
a radical and experimental distribution based on musl libc and busybox
Stars: ✭ 502 (+1519.35%)
Mutual labels:  musl
stasis
build static rust position-independant-executables without any runtime requirements (no libc or ldso)
Stars: ✭ 40 (+29.03%)
Mutual labels:  musl
dots
Use chezmoi to install my dotfiles easily on Gentoo, Arch, Void and Debian.
Stars: ✭ 70 (+125.81%)
Mutual labels:  void
CMLFS
Clang-Built Musl Linux From Scratch
Stars: ✭ 51 (+64.52%)
Mutual labels:  musl
void-pine64
Build scripts for void linux images on Pine64 boards.
Stars: ✭ 14 (-54.84%)
Mutual labels:  voidlinux
crosware
Tools, things, stuff, miscellaneous, etc., for Chrome OS / Chromium OS
Stars: ✭ 36 (+16.13%)
Mutual labels:  musl

voidnsrun

voidnsrun is utility for launching programs in an isolated mount namespace with alternative /usr tree. Its primary goal is to run glibc programs in musl-libc Void Linux environments (or vice-versa, but who needs that?).

It creates a new private mount namespace, transparently substitutes /usr and some other directories with directories from your glibc container using bind mounts, and launches your program.

voidnsundo, to the contrary, is utility for launching programs in the parent mount namespace from within the mount namespace created by voidnsrun.

Installation

Creating glibc container

As per the Void documentation, perform glibc base system installation to a separate new directory:

# mkdir /glibc
# XBPS_ARCH=x86_64 xbps-install --repository=http://alpha.de.repo.voidlinux.org/current -r /glibc -S base-voidstrap

Installing voidnsrun

Clone the repo, and then:

make run
sudo make install-run

This will install voidnsrun to /usr/local/bin.

Export path to the container:

export VOIDNSRUN_DIR=/glibc

Also export path to voidnsundo:

export VOIDNSUNDO_BIN=/usr/local/bin/voidnsundo

You may want to add these exports to your ~/.bashrc or similar script.

Installing voidnsundo

voidnsundo is supposed to be used from within the glibc container, so it has to be linked with glibc. First, let's use just installed voidnsrun to install build dependencies into the container:

sudo voidnsrun -r /glibc xbps-install -Su
sudo voidnsrun -r /glibc xbps-install make gcc

Then enter the container (the current working directory will be preserved by voidnsrun 1.2 or higher) and build, then install voidnsundo:

voidnsrun bash
make clean
make undo
sudo make install-undo

This will install voidnsundo to /usr/local/bin in the container (which is /glibc/usr/local/bin in reality).

Type exit or Ctrl+D to exit the container.

Usage

voidnsrun

Usage: voidnsrun [OPTIONS] PROGRAM [ARGS]

Options:
    -r <path>: Container path. When this option is not present,
               VOIDNSRUN_DIR environment variable is used.
    -m <path>: Add bind mount. You can add up to 50 paths.
    -u <path>: Add undo bind mount. You can add up to 50 paths.
    -d <path>: Add /usr subdirectory bind mount.
    -U <path>: Path to voidnsundo. When this option is not present,
               VOIDNSUNDO_BIN environment variable is used.
    -i:        Don't treat missing source or target for added mounts as error.
    -V:        Enable verbose output.
    -h:        Print this help.
    -v:        Print version.

voidnsrun needs to know the path to your glibc installation directory (or "container"), it can read it from the VOIDNSRUN_DIR environment variable or you can use -r argument to specify it.

By default, voidnsrun binds only /usr from the container. But if you're launching xbps-install, xbps-remove or xbps-reconfigureand using voidnsrun version 1.1 or higher, it will bind /usr, /var and /etc.

To bind something else, use the -m option. You can add up to 50 binds as of version 1.2.

To bind a subdirectory from the host /usr, use the -d option (available since version 1.3). For example, instead of installing fonts into the container and therefore duplicating them and wasting your disk space, you can bind-mount /usr/share/fonts from the host. The rest of /usr/ will be from the glibc container.

There's also the -u option. It adds bind mounts of the voidnsundo binary inside the namespace. See more about this below in the voidnsundo bind mode section. Just like with the -m option, you can add up to 50 binds as of version 1.2.

To bind the voidnsundo binary, voidnsrun has to know its path, and, like with the container's path, it reads it from the VOIDNSUNDO_BIN environment variable and from the -U option.

voidnsundo

Usage: voidnsundo [OPTIONS] PROGRAM [ARGS]

Options:
    -V:  Enable verbose output.
    -h:  Print this help.
    -v:  Print version.

voidnsundo can be used in two modes.

One is the "normal" node, when you invoke it like voidnsundo <PROGRAM> [ARGS] and your PROGRAM will be launched from and in the original mount namespace.

For example, if you don't have a glibc version of firefox installed (so there's no /usr/bin/firefox in the container), but you want to launch the "real" (the one installed in your root musl system) firefox while being in the mount namespace, just do voidnsundo /usr/bin/firefox.

The other mode is the "bind" mode. While in the container, and therefore in the new mount namespace, you can bind mount voidnsundo to any path (don't worry: it won't be visible outside the namespace), and, when invoked by that path, it will launch the corresponding executable in your parent (root) namespace.

For example, being in the container, you can do this:

touch /usr/bin/firefox
mount --bind /usr/local/bin/voidnsundo /usr/bin/firefox

and while there was no /usr/bin/firefox in the glibc container, after this, when you'll launch /usr/bin/firefox, the "real" firefox from the root musl system will be launched.

The creation of this bind mounts of voidnsundo can be automated by using -u option of voidnsrun.

Examples

This section contains some real examples of how to use some proprietary glibc apps on your musl-libc Void Linux box.

Vivaldi

The first example is the Vivaldi browser. Let's assume you unpacked it to /opt/vivaldi (from rpm or deb package) and, obviously, it doesn't work.

Try launching it with voidnsrun:

$ voidnsrun /opt/vivaldi/vivaldi

It won't work just yet, but it's a start:

/opt/vivaldi/vivaldi: error while loading shared libraries: libgobject-2.0.so.0: cannot open shared object file: No such file or directory

Now you need to install all its dependencies into your glibc installation. Use xlocate from xtools package to find a package responsible for a file (or just guess it):

$ xlocate libgobject-2.0.so.0
Signal-Desktop-1.38.1_1	/usr/lib/signal-desktop/resources/app.asar.unpacked/node_modules/sharp/vendor/lib/libgobject-2.0.so -> /usr/lib/signal-desktop/resources/app.asar.unpacked/node_modules/sharp/vendor/lib/libgobject-2.0.so.0.5600.4
Signal-Desktop-1.38.1_1	/usr/lib/signal-desktop/resources/app.asar.unpacked/node_modules/sharp/vendor/lib/libgobject-2.0.so.0 -> /usr/lib/signal-desktop/resources/app.asar.unpacked/node_modules/sharp/vendor/lib/libgobject-2.0.so.0.5600.4
Signal-Desktop-1.38.1_1	/usr/lib/signal-desktop/resources/app.asar.unpacked/node_modules/sharp/vendor/lib/libgobject-2.0.so.0.5600.4
glib-2.66.2_1	/usr/lib/libgobject-2.0.so.0 -> /usr/lib/libgobject-2.0.so.0.6600.2
glib-2.66.2_1	/usr/lib/libgobject-2.0.so.0.6600.2
glib-devel-2.66.2_1	/usr/share/gdb/auto-load/usr/lib/libgobject-2.0.so.0.6600.2-gdb.py
libglib-devel-2.66.2_1	/usr/lib/libgobject-2.0.so -> /usr/lib/libgobject-2.0.so.0

Sync repos and install glib:

$ sudo voidnsrun -r /glibc xbps-install -Su
$ sudo voidnsrun -r /glibc xbps-install glib

Try launching vivaldi again:

$ voidnsrun /opt/vivaldi/vivaldi
/opt/vivaldi/vivaldi: error while loading shared libraries: libnss3.so: cannot open shared object file: No such file or directory

As you can see, it no longer complains about missing libgobject-2.0.so.0, now it's libnss3.so. Repeat steps above for all missing dependencies, and in the end, it will work.

Note that, for some reason, it doesn't complain about missing font related libraries, such as freetype, so make sure to install them too, as well as some base fonts:

$ sudo voidnsrun -r /glibc xbps-install freetype fontconfig libXft xorg-fonts

If you're noticing performance issues with Vivaldi, check the vivaldi://gpu page. If it turns out that hardware acceleration is unavailable, you're missing some packages again. I don't know which ones exactly, but installing xorg-minimal should fix it.

PhpStorm

PhpStorm and other JetBrains IDEs should just work like this (of course, replace /opt/PhpStorm with real path on your machine):

voidnsrun /opt/PhpStorm/bin/phpstorm.sh

But it is only at first glance, everything works. After some time you may notice all kinds of weird stuff caused by the fact that it runs inside the "container" with different /usr. For instance, if you open built-in terminal window, it will work, but... it will not be the shell you expect, it will be glibc-linked shell from the container. Some programs that you have installed on your root musl system will not be available there (like, it won't be able to launch a browser because there's no browser), other may not work as expected.

In general, all programs that launch other programs will suffer from this. To overcome this, the voidnsundo utility has been written and -u option added to voidnsrun.

To fix the built-in PhpStorm's terminal and the ability to launch browser as shown in the above example, launch it like so:

voidnsrun -u /bin/bash -u /usr/bin/firefox /opt/PhpStorm/bin/phpstorm.sh

FAQ

Q: sudo voidnsrun xbps-install exits with "environment variable VOIDNSRUN_DIR not found" error

A: Add this line to /etc/sudoers:

Defaults env_keep += "VOIDNSRUN_DIR"

Q: Why applications launched with voidnsrun do not see my fonts?

A: If you installed fonts on your main system, applications that run in the mount namespace can't see them because of custom /usr directory. You need to install them again into the container directory.

Since 1.3, it's possible to bind-mount /usr/share/fonts or other directorires from the host to the mount namespace. Use the -d option for that.

Security

voidnsrun and voidnsundo are setuid applications, meaning they are actually started as root and then dropping privileges when they can. setuid is generally bad, it's a common attack vector that allows local privilege escalation by exploiting unsafe code of setuid programs.

While these utilities have been written with this thought in mind, don't trust me. Read the code, it's not too big and it's commented. Place yourself in attacker's shoes and try to find a hole. For every new discovered vulnerability in these utilities that would allow privilege escalation or something similar I promise to pay $100 in Bitcoin. Contact me if you find something.

Changelog

1.3.1

  • Bug fixes.

1.3

  • Added the -d option to bind mount subdirectories from the host /usr.

1.2.1

  • Minor code fixes, nothing serious.

1.2

  • Added voidnsundo utility for spawning programs in the parent mount namespace from within the namespace created by voidnsrun.
  • Restore current working directory after changing namespace.

1.1

  • Bind whole /etc and /var when launching xbps-install, xbps-remove or xbps-reconfigure.

1.0

  • Initial release.

License

BSD-2c

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].