{"id":15573861,"url":"https://github.com/gch1p/voidnsrun","last_synced_at":"2025-04-24T02:07:52.845Z","repository":{"id":46675501,"uuid":"316849222","full_name":"gch1p/voidnsrun","owner":"gch1p","description":"Run glibc binaries in musl libc Void Linux environment","archived":false,"fork":false,"pushed_at":"2024-01-02T04:46:57.000Z","size":76,"stargazers_count":68,"open_issues_count":3,"forks_count":3,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-24T02:07:39.191Z","etag":null,"topics":["glibc","musl","void","voidlinux"],"latest_commit_sha":null,"homepage":"https://ch1p.io/void-linux-musl-glibc/","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gch1p.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2020-11-29T00:44:33.000Z","updated_at":"2025-04-23T14:49:24.000Z","dependencies_parsed_at":"2025-04-17T21:19:33.674Z","dependency_job_id":null,"html_url":"https://github.com/gch1p/voidnsrun","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gch1p%2Fvoidnsrun","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gch1p%2Fvoidnsrun/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gch1p%2Fvoidnsrun/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gch1p%2Fvoidnsrun/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gch1p","download_url":"https://codeload.github.com/gch1p/voidnsrun/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250546081,"owners_count":21448260,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["glibc","musl","void","voidlinux"],"created_at":"2024-10-02T18:14:37.306Z","updated_at":"2025-04-24T02:07:52.820Z","avatar_url":"https://github.com/gch1p.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# voidnsrun\n\n**voidnsrun** is utility for launching programs in an isolated mount namespace\nwith alternative `/usr` tree. Its primary goal is to run glibc programs in\nmusl-libc Void Linux environments (or vice-versa, but who needs that?).\n\nIt creates a new private mount namespace, transparently substitutes `/usr` and\nsome other directories with directories from your glibc container using bind\nmounts, and launches your program.\n\n**voidnsundo**, to the contrary, is utility for launching programs in the parent\nmount namespace from within the mount namespace created by **voidnsrun**.\n\n## Installation\n\n### Creating glibc container\n\nAs per the [Void documentation](https://docs.voidlinux.org/installation/musl.html#glibc-chroot),\nperform glibc base system installation to a separate new directory:\n```\n# mkdir /glibc\n# XBPS_ARCH=x86_64 xbps-install --repository=https://repo-default.voidlinux.org/current -r /glibc -S base-voidstrap\n```\n\n### Installing voidnsrun\n\nClone the repo, and then:\n\n```\nmake run\nsudo make install-run\n```\n\nThis will install **voidnsrun** to `/usr/local/bin`.\n\nExport path to the container:\n```\nexport VOIDNSRUN_DIR=/glibc\n```\n\nAlso export path to **voidnsundo**:\n```\nexport VOIDNSUNDO_BIN=/usr/local/bin/voidnsundo\n```\n\nYou may want to add these exports to your `~/.bashrc` or similar script.\n\n### Installing voidnsundo\n\n**voidnsundo** is supposed to be used from within the glibc container, so it has\nto be linked with glibc. First, let's use just installed **voidnsrun** to install\nbuild dependencies into the container:\n```\nsudo voidnsrun -r /glibc xbps-install -Su\nsudo voidnsrun -r /glibc xbps-install make gcc\n```\n\nThen enter the container (the current working directory will be preserved by\n**voidnsrun** 1.2 or higher) and build, then install **voidnsundo**:\n```\nvoidnsrun bash\nmake clean\nmake undo\nsudo make install-undo\n```\n\nThis will install **voidnsundo** to `/usr/local/bin` in the container (which is\n`/glibc/usr/local/bin` in reality).\n\nType `exit` or `Ctrl+D` to exit the container.\n\n## Usage\n\n### voidnsrun\n```\nUsage: voidnsrun [OPTIONS] PROGRAM [ARGS]\n\nOptions:\n    -r \u003cpath\u003e: Container path. When this option is not present,\n               VOIDNSRUN_DIR environment variable is used.\n    -m \u003cpath\u003e: Add bind mount. You can add up to 50 paths.\n    -u \u003cpath\u003e: Add undo bind mount. You can add up to 50 paths.\n    -d \u003cpath\u003e: Add /usr subdirectory bind mount.\n    -U \u003cpath\u003e: Path to voidnsundo. When this option is not present,\n               VOIDNSUNDO_BIN environment variable is used.\n    -i:        Don't treat missing source or target for added mounts as error.\n    -V:        Enable verbose output.\n    -h:        Print this help.\n    -v:        Print version.\n```\n\n**voidnsrun** needs to know the path to your glibc installation directory (or\n\"container\"), it can read it from the `VOIDNSRUN_DIR` environment variable or\nyou can use `-r` argument to specify it.\n\nBy default, **voidnsrun** binds only `/usr` from the container. But if you're\nlaunching `xbps-install`, `xbps-remove` or `xbps-reconfigure`and using\n**voidnsrun** version 1.1 or higher, it will bind `/usr`, `/var` and `/etc`.\n\nTo bind something else, use the `-m` option. You can add up to 50 binds as of\nversion 1.2.\n\nTo bind a subdirectory from the host `/usr`, use the `-d` option (available\nsince version 1.3). For example, instead of installing fonts into the container\nand therefore duplicating them and wasting your disk space, you can bind-mount\n`/usr/share/fonts` from the host. The rest of `/usr/` will be from the glibc\ncontainer.\n\nThere's also the `-u` option. It adds bind mounts of the **voidnsundo** binary\ninside the namespace. See more about this below in the **voidnsundo** bind mode\nsection. Just like with the `-m` option, you can add up to 50 binds as of version\n1.2.\n\nTo bind the **voidnsundo** binary, **voidnsrun** has to know its path, and, like\nwith the container's path, it reads it from the `VOIDNSUNDO_BIN` environment\nvariable and from the `-U` option.\n\n### voidnsundo\n\n```\nUsage: voidnsundo [OPTIONS] PROGRAM [ARGS]\n\nOptions:\n    -V:  Enable verbose output.\n    -h:  Print this help.\n    -v:  Print version.\n```\n\n**voidnsundo** can be used in two modes.\n\nOne is the **\"normal\" node**, when you invoke it like `voidnsundo \u003cPROGRAM\u003e [ARGS]`\nand your `PROGRAM` will be launched from and in the original mount namespace.\n\nFor example, if you don't have a glibc version of firefox installed (so there's\nno `/usr/bin/firefox` in the container), but you want to launch the \"real\" (the\none installed in your root musl system) firefox while being in the mount\nnamespace, just do `voidnsundo /usr/bin/firefox`.\n\nThe other mode is the **\"bind\" mode**. While in the container, and therefore in\nthe new mount namespace, you can bind mount **voidnsundo** to any path (don't\nworry: it won't be visible outside the namespace), and, when invoked by that\npath, it will launch the corresponding executable in your parent (root)\nnamespace.\n\nFor example, being in the container, you can do this:\n```\ntouch /usr/bin/firefox\nmount --bind /usr/local/bin/voidnsundo /usr/bin/firefox\n```\nand while there was no `/usr/bin/firefox` in the glibc container, after this,\nwhen you'll launch `/usr/bin/firefox`, the \"real\" firefox from the root musl\nsystem will be launched.\n\nThe creation of this bind mounts of **voidnsundo** can be automated by using\n`-u` option of **voidnsrun**.\n\n## Examples\n\nThis section contains some real examples of how to use some proprietary glibc\napps on your musl-libc Void Linux box.\n\n### Vivaldi\n\nThe first example is the Vivaldi browser. Let's assume you unpacked it to\n`/opt/vivaldi` (from rpm or deb package) and, obviously, it doesn't work.\n\nTry launching it with **voidnsrun**:\n```\n$ voidnsrun /opt/vivaldi/vivaldi\n```\n\nIt won't work just yet, but it's a start:\n```\n/opt/vivaldi/vivaldi: error while loading shared libraries: libgobject-2.0.so.0: cannot open shared object file: No such file or directory\n```\n\nNow you need to install all its dependencies into your glibc installation. Use\n`xlocate` from `xtools` package to find a package responsible for a file (or\njust guess it):\n```\n$ xlocate libgobject-2.0.so.0\nSignal-Desktop-1.38.1_1\t/usr/lib/signal-desktop/resources/app.asar.unpacked/node_modules/sharp/vendor/lib/libgobject-2.0.so -\u003e /usr/lib/signal-desktop/resources/app.asar.unpacked/node_modules/sharp/vendor/lib/libgobject-2.0.so.0.5600.4\nSignal-Desktop-1.38.1_1\t/usr/lib/signal-desktop/resources/app.asar.unpacked/node_modules/sharp/vendor/lib/libgobject-2.0.so.0 -\u003e /usr/lib/signal-desktop/resources/app.asar.unpacked/node_modules/sharp/vendor/lib/libgobject-2.0.so.0.5600.4\nSignal-Desktop-1.38.1_1\t/usr/lib/signal-desktop/resources/app.asar.unpacked/node_modules/sharp/vendor/lib/libgobject-2.0.so.0.5600.4\nglib-2.66.2_1\t/usr/lib/libgobject-2.0.so.0 -\u003e /usr/lib/libgobject-2.0.so.0.6600.2\nglib-2.66.2_1\t/usr/lib/libgobject-2.0.so.0.6600.2\nglib-devel-2.66.2_1\t/usr/share/gdb/auto-load/usr/lib/libgobject-2.0.so.0.6600.2-gdb.py\nlibglib-devel-2.66.2_1\t/usr/lib/libgobject-2.0.so -\u003e /usr/lib/libgobject-2.0.so.0\n```\n\nSync repos and install `glib`:\n```\n$ sudo voidnsrun -r /glibc xbps-install -Su\n$ sudo voidnsrun -r /glibc xbps-install glib\n```\n\nTry launching vivaldi again:\n```\n$ voidnsrun /opt/vivaldi/vivaldi\n/opt/vivaldi/vivaldi: error while loading shared libraries: libnss3.so: cannot open shared object file: No such file or directory\n```\n\nAs you can see, it no longer complains about missing `libgobject-2.0.so.0`, now\nit's `libnss3.so`. Repeat steps above for all missing dependencies, and in the\nend, it will work.\n\nNote that, for some reason, it doesn't complain about missing font related\nlibraries, such as freetype, so make sure to install them too, as well as some\nbase fonts:\n```\n$ sudo voidnsrun -r /glibc xbps-install freetype fontconfig libXft xorg-fonts\n```\n\nIf you're noticing performance issues with Vivaldi, check the `vivaldi://gpu`\npage. If it turns out that hardware acceleration is unavailable, you're missing\nsome packages again. I don't know which ones exactly, but installing `xorg-minimal`\nshould fix it.\n\n### PhpStorm\n\n**PhpStorm** and other JetBrains IDEs should just work like this (of course,\nreplace `/opt/PhpStorm` with real path on your machine):\n```\nvoidnsrun /opt/PhpStorm/bin/phpstorm.sh\n```\n\nBut it is only at first glance, everything works. After some time you may\nnotice all kinds of weird stuff caused by the fact that it runs inside the\n\"container\" with different `/usr`. For instance, if you open built-in terminal\nwindow, it will work, but... it will not be the shell you expect, it will be\nglibc-linked shell from the container. Some programs that you have\ninstalled on your root musl system will not be available there (like, it won't be\nable to launch a browser because there's no browser), other may not work as\nexpected.\n\nIn general, all programs that launch other programs will suffer from this. To\novercome this, the **voidnsundo** utility has been written and `-u` option added\nto **voidnsrun**.\n\nTo fix the built-in PhpStorm's terminal and the ability to launch browser as shown\nin the above example, launch it like so:\n```\nvoidnsrun -u /bin/bash -u /usr/bin/firefox /opt/PhpStorm/bin/phpstorm.sh\n```\n\n## FAQ\n\n#### Q: `sudo voidnsrun xbps-install` exits with \"environment variable VOIDNSRUN_DIR not found\" error\n\nA: Add this line to `/etc/sudoers`:\n```\nDefaults env_keep += \"VOIDNSRUN_DIR\"\n```\n\n#### Q: Why applications launched with voidnsrun do not see my fonts?\n\nA: If you installed fonts on your main system, applications that run in the mount\nnamespace can't see them because of custom `/usr` directory. You need to install\nthem again into the container directory.\n\nSince 1.3, it's possible to bind-mount `/usr/share/fonts` or other directorires\nfrom the host to the mount namespace. Use the `-d` option for that.\n\n## Security\n\n**voidnsrun** and **voidnsundo** are setuid applications, meaning they are\nactually started as root and then dropping privileges when they can. setuid is\ngenerally bad, it's a common attack vector that allows local privilege\nescalation by exploiting unsafe code of setuid programs.\n\nWhile these utilities have been written with this thought in mind, don't trust\nme. Read the code, it's not too big and it's commented. Place yourself in\nattacker's shoes and try to find a hole. For every new discovered vulnerability\nin these utilities that would allow privilege escalation or something similar I\npromise to pay $100 in Bitcoin. Contact me if you find something.\n\n## Changelog\n\n#### 1.3.1\n\n- Bug fixes.\n\n#### 1.3\n\n- Added the `-d` option to bind mount subdirectories from the host `/usr`.\n\n#### 1.2.1\n\n- Minor code fixes, nothing serious.\n\n#### 1.2\n\n- Added **voidnsundo** utility for spawning programs in the parent mount\n  namespace from within the namespace created by **voidnsrun**.\n- Restore current working directory after changing namespace.\n\n#### 1.1\n\n- Bind whole `/etc` and `/var` when launching `xbps-install`, `xbps-remove` or\n  `xbps-reconfigure`.\n\n#### 1.0\n\n- Initial release.\n\n## License\n\nBSD-2c\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgch1p%2Fvoidnsrun","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgch1p%2Fvoidnsrun","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgch1p%2Fvoidnsrun/lists"}