Discussion:
Generating wrappers for execution in non-root non-Guix contexts
Ludovic Courtès
2018-04-25 09:14:05 UTC
Permalink
Hello Guix!

The hack below allows ‘guix pack’ to produce wrappers that allow,
through user namespaces, programs to automatically relocate themselves
when you run them unprivileged on a machine that lacks Guix. In the
example below, I run ‘sed’ from a pack on a machine that lacks Guix:

--8<---------------cut here---------------start------------->8---
***@fencepost:~/tmp$ tar xf ../pack.tgz
***@fencepost:~/tmp$ echo hello > foo
***@fencepost:~/tmp$ gnu/store/ffdzkyi23n8xh3n6vfqpa1lzg3xx9jpj-sed-4.4/bin/sed -i foo -es/hello/bye/g
***@fencepost:~/tmp$ cat foo
bye
***@fencepost:~/tmp$ ls /gnu/store
ls: cannot access '/gnu/store': No such file or directory
--8<---------------cut here---------------end--------------->8---

Pretty cool no?

What I imagine is that we could make this an option of ‘guix pack’, such
that ‘guix pack -w’ would produce such binaries.

This relies on the same approach as ‘call-with-container’
 except it’s
written in C and statically-linked to avoid bootstrapping issues. Doing
that in Scheme would be a bit involved because a shebang like
#!/gnu/store/
-guile/bin/guile wouldn’t work; the wrappers have to be
statically-linked executables.

There are (minor) issues to be solved: symlinks created by ‘guix pack
-S’ should be relative instead of absolute, and same for symlinks in the
profile. This would allow users to directly type ./bin/sed instead of
having to find out which directory is the right one as in the example
above.

We could also have wrappers fall back to PRoot when unshare(2) fails.

What do people think?

Cheers,
Ludo’.
Pierre Neidhardt
2018-04-25 09:19:53 UTC
Permalink
Brilliant!

Would this only work for C-based programs?
What about other languages, shared libaries, external resources, etc.?
--
Pierre Neidhardt

The only "ism" Hollywood believes in is plagiarism.
-- Dorothy Parker
Ludovic Courtès
2018-04-25 12:44:12 UTC
Permalink
Post by Pierre Neidhardt
Brilliant!
Would this only work for C-based programs?
No, it works for everything. It’s brute-force I must say. :-)

Ludo’.
Ricardo Wurmus
2018-04-26 13:39:21 UTC
Permalink
Hi Ludo,
The hack below allows ‘guix pack’ to produce wrappers that allow,
through user namespaces, programs to automatically relocate themselves
when you run them unprivileged on a machine that lacks Guix.
This is very cool and very useful! It would make “guix pack” much more
useful than it already is. Using a pack like that would require little
more than unpacking it and running the application — that’s much less
work than setting up Docker, Singularity or Guix itself, which may be
impossible in an environment where user privileges are severely
restricted.
We could also have wrappers fall back to PRoot when unshare(2) fails.
Good idea. Could we use ptrace directly and optimize it for the case of
“/gnu/store” paths? I’m just guessing that PRoot may incur a higher
performance penalty because it’s so generic compared to a compile-time
deterministic use of ptrace – after all, we know all /gnu/store
locations in advance.

--
Ricardo
Ludovic Courtès
2018-04-26 14:58:59 UTC
Permalink
Hey!
Post by Ricardo Wurmus
Post by Ludovic Courtès
We could also have wrappers fall back to PRoot when unshare(2) fails.
Good idea. Could we use ptrace directly and optimize it for the case of
“/gnu/store” paths? I’m just guessing that PRoot may incur a higher
performance penalty because it’s so generic compared to a compile-time
deterministic use of ptrace – after all, we know all /gnu/store
locations in advance.
IWBN, but that’s a project in its own. ptrace(2) requires knowledge
about the architecture’s ABI so that you know what registers to look at
when a syscall happens, and so on. So for now it’ll have to be PRoot.

I’ll try to come up with a patch set without PRoot support to begin
with.

Thanks for your feedback,
Ludo’.
Chris Marusich
2018-04-27 03:21:08 UTC
Permalink
Post by Ludovic Courtès
Hello Guix!
The hack below allows ‘guix pack’ to produce wrappers that allow,
through user namespaces, programs to automatically relocate themselves
when you run them unprivileged on a machine that lacks Guix.
That's really cool!

I've noticed that when running in a chroot-like environment, sometimes
programs expect certain files to exist that don't - for example, device
files in /dev, procfs files in /proc, or even things like
/etc/resolv.conf. Does this wrapper automatically create those kinds of
files, or would programs that want to access those kinds of files still
need some special love on an case-by-case basis?
--
Chris
Ludovic Courtès
2018-04-27 16:38:36 UTC
Permalink
Hello!
Post by Chris Marusich
Post by Ludovic Courtès
Hello Guix!
The hack below allows ‘guix pack’ to produce wrappers that allow,
through user namespaces, programs to automatically relocate themselves
when you run them unprivileged on a machine that lacks Guix.
That's really cool!
I've noticed that when running in a chroot-like environment, sometimes
programs expect certain files to exist that don't - for example, device
files in /dev, procfs files in /proc, or even things like
/etc/resolv.conf. Does this wrapper automatically create those kinds of
files, or would programs that want to access those kinds of files still
need some special love on an case-by-case basis?
The wrapper automatically bind-mounts every entry in /, such that the
only difference compared to the “real” system is the extra /gnu/store.


Note: we had this discussion about ‘guix run’ with Mike Gerwitz and
Rutger not long ago (to run applications in isolated environments). In
a pretty similar way, we could generate least-authority wrappers for
what you install with ‘guix package’. Like, one could write:

guix package -i icecat --least-authority

or something like that. Food for thought…

Ludo’.
Ludovic Courtès
2018-05-03 20:51:19 UTC
Permalink
The hack below allows ‘guix pack’ to produce wrappers that allow,
through user namespaces, programs to automatically relocate themselves
when you run them unprivileged on a machine that lacks Guix. In the
bye
ls: cannot access '/gnu/store': No such file or directory
You can watch the next episode of this season (and be part of it!)
at <https://bugs.gnu.org/31360>.

Ludo’.

Loading...