[HN Gopher] PRoot: User-space implementation of chroot, mount -b...
       ___________________________________________________________________
        
       PRoot: User-space implementation of chroot, mount -bind, and
       binfmt_misc
        
       Author : nateb2022
       Score  : 112 points
       Date   : 2024-11-28 03:58 UTC (19 hours ago)
        
 (HTM) web link (proot-me.github.io)
 (TXT) w3m dump (proot-me.github.io)
        
       | nine_k wrote:
       | Ah! Finally I see a way to try nix (the package manager) on my
       | existing installation without it requiring access to the root
       | directory and other such stuff!
        
         | yjftsjthsd-h wrote:
         | https://nixos.wiki/wiki/Nix_Installation_Guide discusses that a
         | bit more (also other solutions)
        
           | lostmsu wrote:
           | Unrelated, but does anyone know what's the deal between
           | wiki.nixos.org and nixos.wiki? The former appears to be
           | actually functional, but the latter ranks much higher in
           | search engines and seems to be incorrectly treated by them as
           | the primary source.
        
             | Reventlov wrote:
             | Because nixos.wiki was the primary source, until very
             | recently. Then, wiki.nixos.org was introduced, and mass
             | edits were made (without the owner of nixos.wiki being ok
             | with that) trying to redirect people from nixos.wiki to
             | wiki.nixos.org, and now both co-exist.
             | 
             | Reminds me a bit the archlinux.fr vs wiki.archlinux.org fr
             | wiki situation from 10 years ago.
        
             | Voklen wrote:
             | nixos.wiki was the primary wiki before NixOS really had an
             | official one. Now there is the official wiki.nixos.org and
             | the NixOS foundation asked the nixos.wiki maintainer to
             | cooperate on the new wiki but they refused. Now there are
             | multiple problems[1] with nixos.wiki and the maintainer in
             | unresponsive so although unfortunately it's ranked higher
             | in search results, in my experience you'll get better
             | information on the official wiki.
             | 
             | [1] https://wiki.nixos.org/wiki/FAQ#Why_is_there_a_new_wiki
             | ?_Wha...?
        
               | lostmsu wrote:
               | Ah, too bad the maintainer is unresponsive. If they don't
               | plan to work on it, they'd do a huge service to community
               | by adding permanent redirects to wiki.nixos.org and maybe
               | canonical links.
        
         | kokada wrote:
         | I don't recommend using Nix inside PRoot unless this is your
         | only option (e.g.: Android, since there are no user
         | namespaces). The reason for that is that Nix is syscall heavy
         | and using it in PRoot will be slow, really slow.
         | 
         | As someone said, the wiki [1] has some interesting options.
         | From the options I used nix-user-chroot [2] with great success,
         | and while the tool is unmaintained it should still work. It
         | uses Linux's user namespaces instead of intercepting syscalls,
         | and this makes the performance pretty much identical to native.
         | 
         | If you want more control like PRoot offers, I recommend
         | bubblewrap instead [2].
         | 
         | Another option undocumented is to just grab a recent nix binary
         | somewhere and run. It will automatically create the Nix store
         | inside `$HOME/.local/share/nix` (if I am not mistaken) and use
         | user namespaces to mount to it. However the last time I tried
         | this didn't work well for a few things (e.g.: Home-Manager), so
         | in general I still think nix-user-chroot is a better choice.
         | 
         | [1]: https://wiki.nixos.org/wiki/Nix_Installation_Guide,
         | linking to the official one
         | 
         | [2]: https://github.com/containers/bubblewrap
         | 
         | [3]: https://wiki.nixos.org/wiki/Nix_Installation_Guide#nix-
         | user-...
        
       | ggm wrote:
       | Unless I am mistaken this cannot elide over the fundamental
       | protections Android enforce which make it impossible to do cross-
       | device symlinks to external SD cards in a non-rooted Android: the
       | outer kernel blocks this, even though you can cd into the paths.
       | 
       | If (for example) you can overlay/union mount and have a synthetic
       | upper layer FS which manages things, I could use this.
        
         | hks0 wrote:
         | proot works by hijacking and altering syscalls. So maybe you
         | could emulate the symlink yourself, by altering the file paths
         | at ptrace level?
         | 
         | Thinking more, maybe it works out of the box? Just mount the
         | overlays (there's a cli flag IIRC) and proot takes care of
         | syscalls by definition.
        
       | CaliforniaKarl wrote:
       | Here's an example of how we've used this.
       | 
       | RStudio Server[0] 1.3 and older hard-coded a number of paths,
       | such as the path for storing temporary files: Instead of looking
       | for the TMPDIR environment variable (as specified by POSIX[1]), R
       | Studio Server would always use /tmp. That is extremely annoying,
       | because we set TMPDIR to a path on fast local storage (SATA or
       | NVMe SSDs) that the job scheduler cleans up at the end of the
       | compute job.
       | 
       | We do have a last-resort mechanism using pam_namespace[2], such
       | that a user going to `/tmp` actually takes them to
       | `/namespace/tmp/${username}`, but that is per-user, not per-job.
       | If a user has two R Studio jobs, and those two jobs landed on the
       | same host, there would be trouble.
       | 
       | So, we used PRoot to wrap R Studio, with /tmp bind-mounted to a
       | directory under TMPDIR.
       | 
       | [0]: https://www.rstudio.com/products/rstudio/download-server/
       | 
       | [1]:
       | https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1...
       | 
       | [2]: https://linux.die.net/man/8/pam_namespace
        
         | godelski wrote:
         | For those that don't know, you shouldn't blindly let programs
         | have access to tmp. They can get access to sockets and stuff.
         | If you're running with systemd there's a private tmp option for
         | this reason.
         | 
         | It's always best to sandbox programs when you can. Linux has
         | been making this much easier but it's still non trivial
         | 
         | https://salvatoresecurity.com/the-many-perils-of-tmp/
        
           | westurner wrote:
           | From the systemd.exec man page: https://www.freedesktop.org/s
           | oftware/systemd/man/systemd.exe... :
           | PrivateTmp=true       #JoinsNamespaceOf=
           | 
           | `unshare -m` and then bind-mounting a private /tmp at
           | /tmp/systemd-private-/ does the same thing; `systemd-tmpfiles
           | --help`: https://serverfault.com/questions/1010339/how-
           | exactly-to-use...
        
             | mikepurvis wrote:
             | "`unshare -m` and then bind-mounting a private /tmp at
             | /tmp/systemd-private-/ does the same thing"
             | 
             | As an intermediate level user and sysadmin, this kind of
             | thing underscores the good work systemd is doing making it
             | easy to get sane and safe defaults for things otherwise
             | fiddly enough that many normal people wouldn't bother.
        
         | paulyy_y wrote:
         | Please don't use zero-based footnote citations, people will
         | assume 1 is the first one (because that is the standard in
         | like, all of literature) and muscle-memory click the first link
         | when reading and have to then figure out that you are doing a
         | non-standard thing.
        
           | yjftsjthsd-h wrote:
           | I disagree; this is Hacker News, and the cultural background
           | favors zero indexing.
        
           | JonChesterfield wrote:
           | The natural numbers start from zero.
        
             | zamadatix wrote:
             | Funnily enough, that's exactly the debate (whether or not
             | natural numbers start at 0 or 1). There is no universally
             | right or wrong answer, is comp sci nerds just tend to like
             | 0 :p.
        
           | malkia wrote:
           | This ain't Lua, Pascal, Basic or Real Life :)
        
       | hks0 wrote:
       | Termux has now a nice wrapper (manager?) for proot [1]. I once
       | wanted to submit a wrapper but got an angry response as the first
       | comment to my PR and it was closed. Guess enough people did that
       | until they decided maybe it's not a bad idea after all.
       | 
       | [1]: https://github.com/termux/proot-distro
        
         | yjftsjthsd-h wrote:
         | > I once wanted to submit a wrapper but got an angry response
         | as the first comment to my PR and it was closed.
         | 
         | I don't follow; you made a PR to add this functionality to
         | proot itself?
        
           | hks0 wrote:
           | Ah no, sorry I was so lost in my thoughts and explained
           | badly.
           | 
           | I was taking in the context of Termux app for Android,
           | nothing to do with proot itself. Termux uses apt and deb
           | repos, and provides a patched proot. I wanted to add a
           | package similar to one I linked.
        
         | jillyboel wrote:
         | > I once wanted to submit a wrapper but got an angry response
         | 
         | link?
        
       | albertzeyer wrote:
       | A similar tool for this user-space bind-mount is
       | https://github.com/fritzw/ld-preload-open, which relies on
       | LD_PRELOAD to overwrite common libc functions. Thus this is less
       | reliable as the presented tool which uses ptrace, but it still
       | works reasonably well (I run e.g. PyCharm with it).
        
         | jeduardo wrote:
         | Thanks for sharing this! I had to do exactly the same thing
         | some 10 years ago to get an Oracle instance up and running
         | again. Oracle insisted on using the /tmp location, despite
         | being installed on a different drive, and the disk was full. As
         | I had access to the Oracle system user, but not to the DBA user
         | to change any configuration, I built a similar shared lib and
         | preloaded it to the script. Worked like a charm! Happy to know
         | that there is something _slightly more streamlined_ to do that
         | now.
        
         | AshamedCaptain wrote:
         | There is also Scratchbox, which was used (and probably is still
         | used) to cross-build embedded Linux distributions.
         | https://github.com/sailfishos/scratchbox2
         | 
         | It also offers CPU transparency and was able to run almost
         | arbitrary desktop software, but specializes in build
         | toolchains.
        
       | aloisdg wrote:
       | Great name in french
        
         | QuiDortDine wrote:
         | Means "fart" for the curious.
        
       | Voklen wrote:
       | Can anyone explain why chroot requires root privileges in the
       | first place? Because from my understanding it seems like it
       | should only restrict what you can do rather than grant any new
       | abilities.
        
         | badmintonbaseba wrote:
         | Nowadays you have unprivileged options with mount namespaces.
         | And from an unprivileged user namespace you can probably invoke
         | chroot just fine as "root".
         | 
         | `chroot`, the function, has probably some baggage that makes it
         | impossible to enable straight from an unprivileged program?
         | Anyway, a chroot-like program seems to be implementable on top
         | of user namespaces. Rootless docker is mostly that, with more
         | namespace and cgroup isolation.
        
         | Teongot wrote:
         | If you can get a suid root binary into the chroot, then you can
         | control its configuration files to bypass security
         | restrictions.                  $ ln /usr/bin/sudo ./my-chroot
         | $ echo "$USER ALL=(ALL) NOPASSWD: ALL" > ./my-
         | chroot/etc/sudoers.d/01-oops        $ chroot ./my-chroot
         | $ sudo bash
         | 
         | modern Linux distributions prevent creation of hard links to
         | suid binaries, but the restrictions on chroot came years before
         | that.
        
           | cedws wrote:
           | Can't SUID binaries in chroots be ignored, like the nosuid
           | mount flag?
        
             | blueflow wrote:
             | Linux namespaces can do that, with a UID namespace, you
             | drop the ability to do SUID, and then you can open a mount
             | namespace and bind-mount and chroot as you like.
        
         | vifon wrote:
         | chroot doesn't nest, there is only one chroot active for a
         | given process at a given moment. If you're inside a chrooted
         | environment and call chroot on a subdirectory without entering
         | it, you regain the access to the parent directories.
        
           | compsciphd wrote:
           | which is why before fs namespaces, as part of security
           | research prototype work I did, I created a "chroot aware"
           | (not quite, but close enough for this context to use that
           | term), that wouldn't let one walk past certain directories
           | (i.e. lookup() would fail for them, no matter what
           | permissions the user had once one entered "pseudo namespace"
           | mode via this chroot mechanism). Was very easy to accomplish,
           | but also very much a hack that fs namespaces are much better
           | for.
        
       | rekado wrote:
       | `guix pack` can create bundles that use a static proot to make
       | them relocatable:
       | 
       | https://hpc.guix.info/blog/2017/10/using-guix-without-being-...
       | 
       | It also supports other more performant ways, but in some
       | situations proot is the best choice.
        
       | randomtoast wrote:
       | If I shell script something together that executes a process in a
       | PRoot environment, would that be similar to Docker?
        
       | badmintonbaseba wrote:
       | So this works by intercepting file-related syscalls. Does it
       | intercept io_uring?
        
       | bieganski wrote:
       | related url, for syscall intercepting made easy:
       | https://github.com/bieganski/asstrace/
       | 
       | see `pathsubst` example.
       | 
       | unfortunately set of use cases for `ptrace`-based solution is
       | limited, due to high performance overhead.
        
       | animesh10k wrote:
       | this is epic stuff
        
       | molticrystal wrote:
       | Does this support using gdb to debug a program, because I vaguely
       | remember years ago using a simulated root to install a linux
       | distro on android to compile and test certain ideas while
       | traveling and due to the nature of ptrace , they couldn't be
       | loaded into a debugger.
        
       ___________________________________________________________________
       (page generated 2024-11-28 23:01 UTC)