diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 9459628c..b1d29e70 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -28,9 +28,7 @@ jobs: - name: Run tests run: | - cd .. - cp -r try ~ - cd ~/try + sudo ./setup.sh scripts/run_tests.sh - name: Upload script diff --git a/.github/workflows/vagrant.yaml b/.github/workflows/vagrant.yaml index 08321aac..b02d7cc3 100644 --- a/.github/workflows/vagrant.yaml +++ b/.github/workflows/vagrant.yaml @@ -4,6 +4,7 @@ on: push: branches: - main + - future pull_request: jobs: diff --git a/.gitignore b/.gitignore index 9f29bbef..3c85c2a7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +gidmapper test/bash_workspace/ test/results/ test/try_workspace/ diff --git a/README.md b/README.md index a749b1cd..a69b34fd 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,8 @@ disks. ### Dependencies +Requires `netcat-openbsd` and `procps`. +======= `try` relies on the following dependencies * `util-linux` @@ -56,6 +58,8 @@ You only need the [`try` script](https://raw.githubusercontent.com/binpash/try/m $ git clone https://github.com/binpash/try.git ``` +You would also want to install the `gidmapper`, simply run `sh setup.sh`. +======= #### Arch Linux `try` is present in [AUR](https://aur.archlinux.org/packages/try), you can install it with your preferred AUR helper: diff --git a/Vagrantfile b/Vagrantfile index fcf46c04..bc376810 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -14,6 +14,7 @@ Vagrant.configure("2") do |config| sudo apt-get install -y git expect sudo chown -R vagrant:vagrant try cd try + sudo ./setup.sh scripts/run_tests.sh " end @@ -27,6 +28,7 @@ Vagrant.configure("2") do |config| sudo apt-get install -y curl sudo chown -R vagrant:vagrant try cd try + sudo ./setup.sh mkdir rustup ./try -D rustup \"curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y\" ls -lah rustup/upperdir/home/vagrant/.cargo/bin @@ -65,6 +67,7 @@ Vagrant.configure("2") do |config| sudo chown -R vagrant:vagrant /mnt/lv0/try cd /mnt/lv0/try + sudo ./setup.sh scripts/run_tests.sh " end @@ -77,6 +80,7 @@ Vagrant.configure("2") do |config| sudo yum install -y git expect sudo chown -R vagrant:vagrant try cd try + sudo ./setup.sh TRY_TOP=$(pwd) scripts/run_tests.sh " end @@ -89,6 +93,7 @@ Vagrant.configure("2") do |config| sudo yum install -y git expect sudo chown -R vagrant:vagrant try cd try + sudo ./setup.sh TRY_TOP=$(pwd) scripts/run_tests.sh " end diff --git a/setup.sh b/setup.sh new file mode 100755 index 00000000..5777fdf3 --- /dev/null +++ b/setup.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +wget https://github.com/ericzty/gidmapper/releases/download/0.0.3/gidmapper -O /usr/local/bin/gidmapper +chmod +x /usr/local/bin/gidmapper +setcap 'CAP_SETGID=ep' /usr/local/bin/gidmapper diff --git a/try b/try index 610d9561..cd3a6110 100755 --- a/try +++ b/try @@ -161,6 +161,17 @@ autodetect_union_helper() { fi } +# start gid mapping +# -U: use unix domain socket +# -q0: don't wait after EOF on stdin +# Sometimes this will run first before the other nc starts listening, so we will retry +while ! echo a | nc -Uq0 "$socket1" 2> /dev/null; do sleep 0.25 ; done + +# Wait for gid to be mapped +# -l: listen +# -U: use unix socket +nc -lU "$socket2" > /dev/null + # Detect if union_helper is set, if not, we try to autodetect them if [ -z "$UNION_HELPER" ] then @@ -260,13 +271,22 @@ EOF # enable job control so interactive commands will play nicely with try asking for user input later(for committing). #5 [ -t 0 ] && set -m + # TZ: Does this adhere to the styleguide? + # TZ: TODO: un-export them later + socket1="$(mktemp)" + socket2="$(mktemp)" + export socket1 + export socket2 + + # Running mapper in a subshell to suppress job control [1] + Done message + (mapper&) + # --mount: mounting and unmounting filesystems will not affect the rest of the system outside the unshare - # --map-root-user: map to the superuser UID and GID in the newly created user namespace. # --user: the process will have a distinct set of UIDs, GIDs and capabilities. # --pid: create a new process namespace (needed fr procfs to work right) # --fork: necessary if we do --pid # "Creation of a persistent PID namespace will fail if the --fork option is not also specified." - unshare --mount --map-root-user --user --pid --fork "$mount_and_execute" + unshare --mount --user --pid --fork "$mount_and_execute" TRY_EXIT_STATUS=$? ################################################################################ @@ -503,6 +523,36 @@ error() { exit "$exit_status" } +################################################################################ +# Change uid/gid mapping +################################################################################ + +mapper() { + # TZ: TODO: fix check whether gidmapper exists + # Wait for unshare process to start + # -U: use unix domain socket + # -l: listen + nc -Ul "$socket1" > /dev/null + # Get the pid of the unshare process with current pid as parent + pid=$(pgrep -P $$ -f unshare) + + # Map root user to current user, and all groups + if [ "$(id -u)" = 0 ] + then + # If we're running as root, we can map all the users + gidmapper "$pid" 0 0 65535 0 0 65535 + else + # If not running as root, we can only mount the caller user + gidmapper "$pid" 0 "$(id -u)" 1 0 0 65535 + fi + + # Notify the unshare process that we have finished + # -U: use unix domain socket + # -q0: don't wait after EOF + echo a | nc -Uq0 "$socket2" +} + + ################################################################################ # Argument parsing ################################################################################