From 15e5f5cff828c4726b65c9a3055690b8fda9d959 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Thu, 12 Aug 2021 19:15:27 -0700 Subject: [PATCH] Debug some horrifying permission errors --- Makefile | 6 ++--- docker/admin/install.bash | 1 + docker/shared/admin-pid1.bash | 8 +++--- supervisor/src/main.go | 2 +- system/res/sentinel.bash | 11 ++++++--- system/src/riju-pty.c | 4 +++ system/src/riju-system-privileged.c | 38 ++++++++++++++++++++++++----- 7 files changed, 52 insertions(+), 18 deletions(-) diff --git a/Makefile b/Makefile index 94e7932..f0ca2ee 100644 --- a/Makefile +++ b/Makefile @@ -88,16 +88,16 @@ shell: # I= [L=] [E[E]=1] [P1|P2=] [CMD="..."] : Launch @: $${I} ifneq (,$(filter $(I),admin ci)) @mkdir -p $(HOME)/.aws $(HOME)/.docker $(HOME)/.ssh $(HOME)/.terraform.d - docker run $(IT_ARG) --rm --hostname $(I) -v $(VOLUME_MOUNT):/src -v /var/run/riju:/var/run/riju -v /var/run/docker.sock:/var/run/docker.sock -v $(HOME)/.aws:/var/run/riju/.aws -v $(HOME)/.docker:/var/run/riju/.docker -v $(HOME)/.ssh:/var/run/riju/.ssh -v $(HOME)/.terraform.d:/var/run/riju/.terraform.d -e NI -e AWS_REGION -e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY -e DOCKER_REPO -e PUBLIC_DOCKER_REPO -e S3_BUCKET -e DOMAIN -e VOLUME_MOUNT=$(VOLUME_MOUNT) $(SHELL_PORTS) $(SHELL_ENV) $(WITH_IMAGE_HASH) --network host riju:$(I) $(BASH_CMD) + docker run $(IT_ARG) --rm --hostname $(I) -v $(VOLUME_MOUNT):/src -v /var/cache/riju:/var/cache/riju -v /var/run/docker.sock:/var/run/docker.sock -v $(HOME)/.aws:/var/cache/riju/.aws -v $(HOME)/.docker:/var/cache/riju/.docker -v $(HOME)/.ssh:/var/cache/riju/.ssh -v $(HOME)/.terraform.d:/var/cache/riju/.terraform.d -e NI -e AWS_REGION -e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY -e DOCKER_REPO -e PUBLIC_DOCKER_REPO -e S3_BUCKET -e DOMAIN -e VOLUME_MOUNT=$(VOLUME_MOUNT) $(SHELL_PORTS) $(SHELL_ENV) $(WITH_IMAGE_HASH) --network host riju:$(I) $(BASH_CMD) else ifeq ($(I),app) - docker run $(IT_ARG) --rm --hostname $(I) -v /var/run/riju:/var/run/riju -v /var/run/docker.sock:/var/run/docker.sock $(SHELL_PORTS) $(SHELL_ENV) $(WITH_IMAGE_HASH) riju:$(I) $(BASH_CMD) + docker run $(IT_ARG) --rm --hostname $(I) -v /var/cache/riju:/var/cache/riju -v /var/run/docker.sock:/var/run/docker.sock $(SHELL_PORTS) $(SHELL_ENV) $(WITH_IMAGE_HASH) riju:$(I) $(BASH_CMD) else ifneq (,$(filter $(I),base lang)) ifeq ($(I),lang) @: $${L} endif docker run $(IT_ARG) --rm --hostname $(LANG_TAG) -v $(VOLUME_MOUNT):/src $(SHELL_PORTS) $(SHELL_ENV) $(WITH_IMAGE_HASH) riju:$(LANG_TAG) $(BASH_CMD) else ifeq ($(I),runtime) - docker run $(IT_ARG) --rm --hostname $(I) -v $(VOLUME_MOUNT):/src -v /var/run/riju:/var/run/riju -v /var/run/docker.sock:/var/run/docker.sock $(SHELL_PORTS) $(SHELL_ENV) $(WITH_IMAGE_HASH) riju:$(I) $(BASH_CMD) + docker run $(IT_ARG) --rm --hostname $(I) -v $(VOLUME_MOUNT):/src -v /var/cache/riju:/var/cache/riju -v /var/run/docker.sock:/var/run/docker.sock $(SHELL_PORTS) $(SHELL_ENV) $(WITH_IMAGE_HASH) riju:$(I) $(BASH_CMD) else docker run $(IT_ARG) --rm --hostname $(I) -v $(VOLUME_MOUNT):/src $(SHELL_PORTS) $(SHELL_ENV) $(WITH_IMAGE_HASH) riju:$(I) $(BASH_CMD) endif diff --git a/docker/admin/install.bash b/docker/admin/install.bash index b06e6fc..cb8251b 100755 --- a/docker/admin/install.bash +++ b/docker/admin/install.bash @@ -37,6 +37,7 @@ clang clang-format dctrl-tools docker-ce-cli +file g++ git golang diff --git a/docker/shared/admin-pid1.bash b/docker/shared/admin-pid1.bash index e126a75..d6431c6 100755 --- a/docker/shared/admin-pid1.bash +++ b/docker/shared/admin-pid1.bash @@ -7,10 +7,10 @@ tee -a /etc/hosts >/dev/null <<< "127.0.0.1 $(hostname)" groupadd -g "$(stat -c %g "$PWD")" -o -p '!' -r riju useradd -u "$(stat -c %u "$PWD")" -g "$(stat -c %g "$PWD")" -o -p '!' -m -N -l -s /usr/bin/bash -G sudo riju -runuser -u riju -- ln -sT /var/run/riju/.aws /home/riju/.aws -runuser -u riju -- ln -sT /var/run/riju/.docker /home/riju/.docker -runuser -u riju -- ln -sT /var/run/riju/.ssh /home/riju/.ssh -runuser -u riju -- ln -sT /var/run/riju/.terraform.d /home/riju/.terraform.d +runuser -u riju -- ln -sT /var/cache/riju/.aws /home/riju/.aws +runuser -u riju -- ln -sT /var/cache/riju/.docker /home/riju/.docker +runuser -u riju -- ln -sT /var/cache/riju/.ssh /home/riju/.ssh +runuser -u riju -- ln -sT /var/cache/riju/.terraform.d /home/riju/.terraform.d runuser -u riju -- touch /home/riju/.sudo_as_admin_successful runuser -u riju -- tee -a /home/riju/.bashrc >/dev/null <<"EOF" diff --git a/supervisor/src/main.go b/supervisor/src/main.go index 336c0be..354de66 100644 --- a/supervisor/src/main.go +++ b/supervisor/src/main.go @@ -344,7 +344,7 @@ func (sv *supervisor) reload() error { sv.status("starting container " + name) dockerRun := exec.Command( "docker", "run", "-d", - "-v", "/var/run/riju:/var/run/riju", + "-v", "/var/cache/riju:/var/cache/riju", "-v", "/var/run/docker.sock:/var/run/docker.sock", "-p", fmt.Sprintf("127.0.0.1:%d:6119", port), "-e", "FATHOM_SITE_ID", diff --git a/system/res/sentinel.bash b/system/res/sentinel.bash index 39623f6..6fedfc0 100755 --- a/system/res/sentinel.bash +++ b/system/res/sentinel.bash @@ -10,13 +10,16 @@ while read -t2 -a cmd; do if (( "${#cmd[@]}" < 3 )); then echo >&2 "usage: (exec|pty) UUID ARG..." else + if [[ "${cmd[0]}" == pty ]]; then + maybe_pty=/var/cache/riju/share/riju-pty + fi uuid="${cmd[1]}" args=("${cmd[@]:2}") echo >&2 "${cmd[0]} ${args[0]} with UUID ${uuid}" - input="/var/run/riju/share/cmd-${uuid}-input" - output="/var/run/riju/share/cmd-${uuid}-output" + input="/var/cache/riju/share/cmd-${uuid}-input" + output="/var/cache/riju/share/cmd-${uuid}-output" mkfifo "${input}" "${output}" - runuser -u riju -- bash -c 'exec "$@"' sentinel "${args[@]}" < "${input}" &> "${output}" & + ${maybe_pty:-} runuser -u riju -- bash -c 'exec "$@"' sentinel "${args[@]}" < "${input}" &> "${output}" & fi ;; *) @@ -24,4 +27,4 @@ while read -t2 -a cmd; do ;; esac fi -done < /var/run/riju/share/control +done < /var/cache/riju/share/control diff --git a/system/src/riju-pty.c b/system/src/riju-pty.c index 685fd49..8160fe1 100644 --- a/system/src/riju-pty.c +++ b/system/src/riju-pty.c @@ -119,6 +119,8 @@ int main(int argc, char **argv) ptr += len_written; } } + if (len < 0) + die("read failed"); } else { if (setvbuf(stdout, NULL, _IONBF, 0) != 0) die("setvbuf failed"); @@ -129,6 +131,8 @@ int main(int argc, char **argv) if (feof(stdout)) break; } + if (len < 0) + die("read failed"); } return 0; } diff --git a/system/src/riju-system-privileged.c b/system/src/riju-system-privileged.c index 92372cb..c018f19 100644 --- a/system/src/riju-system-privileged.c +++ b/system/src/riju-system-privileged.c @@ -134,7 +134,7 @@ void wait_alarm(int signum) void session(char *uuid, char *lang, char *imageHash) { - char *image, *container, *hostname, *share, *volume, *fifo; + char *image, *container, *hostname, *share, *volume, *fifo, *rijuPtyPath; if ((imageHash != NULL ? asprintf(&image, "riju:lang-%s-%s", lang, imageHash) : asprintf(&image, "riju:lang-%s", lang)) < 0) die("asprintf failed"); @@ -142,15 +142,41 @@ void session(char *uuid, char *lang, char *imageHash) die("asprintf failed"); if (asprintf(&hostname, "HOSTNAME=%s", lang) < 0) die("asprintf failed"); - if (asprintf(&share, "/var/run/riju/shares/%s", uuid) < 0) + if (asprintf(&share, "/var/cache/riju/shares/%s", uuid) < 0) die("asprintf failed"); - int rv = mkdir("/var/run/riju/shares", 0700); + int rv = mkdir("/var/cache/riju/shares", 0700); if (rv < 0 && errno != EEXIST) die("mkdir failed"); rv = mkdir(share, 0700); - if (rv < 0 && errno != EEXIST) + if (rv < 0) die("mkdir failed"); - if (asprintf(&volume, "%s:/var/run/riju/share", share) < 0) + if (asprintf(&rijuPtyPath, "%s/riju-pty", share) < 0) + die("asprintf failed"); + int fdFrom = open("/src/system/out/riju-pty", O_RDONLY); + if (fdFrom < 0) + die("open failed"); + int fdTo = open(rijuPtyPath, O_WRONLY | O_CREAT | O_EXCL, 0700); + if (fdTo < 0) + die("open failed"); + char buf[1024]; + int len, len_written; + while ((len = read(fdFrom, buf, 1024)) > 0) { + char *ptr = buf; + while (len > 0) { + len_written = write(fdTo, ptr, len); + if (len_written < 0) + die("write failed"); + len -= len_written; + ptr += len_written; + } + } + if (close(fdFrom) < 0) + die("close failed"); + if (close(fdTo) < 0) + die("close failed"); + if (len < 0) + die("read failed"); + if (asprintf(&volume, "%s:/var/cache/riju/share", share) < 0) die("asprintf failed"); if (asprintf(&fifo, "%s/control", share) < 0) die("asprintf failed"); @@ -261,7 +287,7 @@ void exec(char *uuid, int argc, char **cmdline, bool pty) if (setvbuf(stdout, NULL, _IONBF, 0) != 0) die("setvbuf failed"); char *share, *ctlFIFO, *inputFIFO, *outputFIFO, *ctlCmd, *dataFIFO; - if (asprintf(&share, "/var/run/riju/shares/%s", uuid) < 0) + if (asprintf(&share, "/var/cache/riju/shares/%s", uuid) < 0) die("asprintf failed"); if (asprintf(&ctlFIFO, "%s/control", share) < 0) die("asprintf failed");