-
Notifications
You must be signed in to change notification settings - Fork 238
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
provide an option to set argv[0] #91
Labels
Comments
(I hit this when porting rpm-ostree code to use bwrap that had an API that took argv0 and char **argv separately, and while I think we can just conflate them, there's no reason not to support this) |
Sounds reasonable. |
quag
added a commit
to quag/bubblewrap
that referenced
this issue
Sep 27, 2023
Fixes containers#91 I realise that an initial Github issue was created for this feature in 2016 and it doesn't appear to have come up again since. However, NixOS is weird and creates a usecase for separating the executable path in the container from the command name. The nix-bubblewrap project also ran into the same issue, and has a note about it in their README: https://github.com/fgaz/nix-bubblewrap#troubeshooting Explanation NixOS doesn't install executable binaries into /usr/bin, and instead installs each package into it's own immutable folder under /nix/store/${hash}-${package}-${version}/bin. NixOS also provides a command to list the packages a given package depends on. This makes it trivial to use bwrap to only --ro-bind the packages required for a given executable. This all works wonderfully, except for two complications. To create a $PATH for a user's shell to use, NixOS creates folders of symlinks (often to other symlinks) for $PATH to reference. These folders of symlinks to executables could be --ro-bind into the container, but they're only needed to locate the initial executable for the command. We can just $(realpath $(which command)) and pass that to bwrap, except that fails for executables that change their behavior based on the command name used (say, bash behaving as sh, xz behaving as unxz, or coreutils behaving as date, df, cat, ...). We could also have NixOS build a $PATH for just the packages needed, and use that when running bwrap, but we've already located the binary, and have the command name, we just need to have bwrap use the executable path and the argv[0] provided. Concrete example The $PATH points to a folder of symlinks to symlinks to symlinks. The two levels of symlink folders don't need to be in the container, they're just needed to locate the executable for the command. In this case, date command is actually a symlink to the coreutils executable. % which date /home/quag/.nix-profile/bin/date % readlink $(which date) /nix/store/8nzn8ghzknqgjsg1iv124qy0fjli3dwn-home-manager-path/bin/date % readlink $(readlink $(which date)) /nix/store/apn3p2b40xvirn7w740wv2gy330ppib5-coreutils-9.3/bin/date % readlink $(readlink $(readlink $(which date))) /nix/store/apn3p2b40xvirn7w740wv2gy330ppib5-coreutils-9.3/bin/coreutils Coreutils only needs the following file system to be able to execute. % nix-store --query --requisites $(realpath $(which coreutils)) /nix/store/3wwfqhdym0sbis4bad1may3ll8rki8y1-gcc-12.3.0-libgcc /nix/store/jbwb8d8l28lg9z0xzl784wyb9vlbwss6-xgcc-12.3.0-libgcc /nix/store/s2gi8pfjszy6rq3ydx0z1vwbbskw994i-libunistring-1.1 /nix/store/k8ivghpggjrq1n49xp8sj116i4sh8lia-libidn2-2.3.4 /nix/store/aw2fw9ag10wr9pf0qk4nk5sxi0q0bn56-glibc-2.37-8 /nix/store/srrs7gn04rwa4f6zhsjkdacxydwrmzhj-attr-2.5.1 /nix/store/aj6gbshd8hvifpa1d8vy0iv688sm81wp-acl-2.3.1 /nix/store/xpxln7rqi3pq4m0xpnawhxb2gs0mn1s0-gcc-12.3.0-lib /nix/store/yqa5m326a0ynn4whm4fikyjfljfc6i3q-gmp-with-cxx-6.3.0 /nix/store/apn3p2b40xvirn7w740wv2gy330ppib5-coreutils-9.3 These ten directories can be --ro-bind into the container and the --ro-binds can be generated with sed. % function nix-bwrap-args() { nix-store --query --requisites $(realpath $(which $1)) \ | sed 's/.*/--ro-bind & &/' \ | tr '\n' ' ' } However, despite having all the files needed in the container, bwrap resolves date using $PATH to /home/quag/.nix-profile/bin/date which isn't in the container. % bwrap $(nix-bwrap-args date) date bwrap: execvp date: No such file or directory If we resolve the date command to the executable in the container (the coreutils binary), then that fails, as it doesn't know which command it is meant to be impersonating. % bwrap $(nix-bwrap-args date) $(realpath $(which date)) Try '/nix/store/apn3p2b40xvirn7w740wv2gy330ppib5-coreutils-9.3/bin/coreutils --help' for more information. If we add an --exec command that takes the executable within the container to run, and then passes through the command without resolving it, everything works. A minimal container, with executable resolution happening before entering the container while retaining the command name. % bwrap $(nix-bwrap-args date) --exec $(realpath $(which date)) date Wed Sep 27 05:50:49 UTC 2023 FAQ Q1. Doesn't the running process need a valid $PATH to locate other commands it depends on? Surprisingly no. To support installing multiple versions of the same package, all references to other packages (including executables) are compiled into the binaries as paths into /nix/store/*/*. This means that after the program starts, $PATH is not needed again.
quag
added a commit
to quag/bubblewrap
that referenced
this issue
Sep 27, 2023
…v[0] Fixes containers#91 Some tools change their behavior based on the value of argv[0], for example bash behaves as sh when argv[0] is "sh", xz behaves as unxz, and coreutils behaves as date, df, cat and so on.
quag
added a commit
to quag/bubblewrap
that referenced
this issue
Sep 28, 2023
Fixes containers#91 Add the ability to overwrite argv[0] when starting a process in a container. Using --argv0 to be consistent with ld.so --argv0. Overwriting argv[0] is useful as some tools change their behavior based on the value of argv[0]. For example, when bash is symlinked to sh it behaves as sh. Similarly, unxz is a symlink to xz and changes the default from compressing to decompressing. An extreme example is on many systems, date, df, cat and so on are all symlinks to the coreutils binary. Example usage: bwrap --bind / / --argv0 sh bash Signed-off-by: Jonathan Wright <[email protected]>
Merged
quag
added a commit
to quag/bubblewrap
that referenced
this issue
Sep 28, 2023
Fixes containers#91 Add the ability to overwrite argv[0] when starting a process in a container. Using --argv0 to be consistent with ld.so --argv0. Overwriting argv[0] is useful as some tools change their behavior based on the value of argv[0]. For example, when bash is symlinked to sh it behaves as sh. Similarly, unxz is a symlink to xz and changes the default from compressing to decompressing. An extreme example is on many systems, date, df, cat and so on are all symlinks to the coreutils binary. Example usage: bwrap --bind / / --argv0 sh bash Signed-off-by: Jonathan Wright <[email protected]>
quag
added a commit
to quag/bubblewrap
that referenced
this issue
Sep 30, 2023
Fixes containers#91 Add the ability to overwrite argv[0] when starting a process in a container. Using --argv0 to be consistent with ld.so --argv0. Overwriting argv[0] is useful as some tools change their behavior based on the value of argv[0]. For example, when bash is symlinked to sh it behaves as sh. Similarly, unxz is a symlink to xz and changes the default from compressing to decompressing. An extreme example is on many systems, date, df, cat and so on are all symlinks to the coreutils binary. Example usage: bwrap --bind / / --argv0 sh bash Signed-off-by: Jonathan Wright <[email protected]>
quag
added a commit
to quag/nix-bubblewrap
that referenced
this issue
Oct 2, 2023
Bubblewrap is adding a new --argv0 option. This means that the command name can remain unchanged, while the exe to execute can have realpath applied to it. Test-1: nix-bwrap date # coreutils provided on NixOS Test-2: nix-bwrap find / # /run/current-system/sw/bin/find on NixOS Note that --argv0 was only merged into bubblewrap today and there has not been an offical release. See: containers/bubblewrap#91
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
In some cases, programs vary behavior based on
argv[0]
, but we currently do:requiring them to be the same. We should add
--argv0 /usr/bin/blah
or so.The text was updated successfully, but these errors were encountered: