From 6d28a75a59433762329266c2fd063333ad179a7b Mon Sep 17 00:00:00 2001 From: Anatoly Trosinenko Date: Sat, 7 Mar 2026 12:47:48 +0300 Subject: [PATCH 1/3] Build as non-privileged user inside the container This fixes the contents of ./ccache and ./output directories being owned by `root`. --- Dockerfile.builder | 3 +++ README.md | 6 ++++++ build.sh | 12 ++++++++++++ scripts/build-in-docker.sh | 4 ++++ 4 files changed, 25 insertions(+) diff --git a/Dockerfile.builder b/Dockerfile.builder index cb8eaa9..587adb4 100644 --- a/Dockerfile.builder +++ b/Dockerfile.builder @@ -22,6 +22,9 @@ RUN apt-get update \ ARG REPO_ROOT +ARG UID=1000 +RUN useradd -u ${UID} builder + COPY cmake /${REPO_ROOT}/cmake COPY scripts /${REPO_ROOT}/scripts COPY config /${REPO_ROOT} diff --git a/README.md b/README.md index 03e556b..7444ce8 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,12 @@ Then build the toolchain by running The build artifact is `./output/llvm-pauth.squashfs` file. +The build scripts try to detect the UID of the real user running `./build.sh` +in case this script is executed with `sudo` to make the contents of `./output` +and `./ccache` directories writable without `sudo` by the host user. This is +especially useful to prevent the `host-build` performed with the same `./ccache` +directory from silently falling back to non-cached build. + # Using the toolchain Mount the produced SquashFS image at `/opt/llvm-pauth`: diff --git a/build.sh b/build.sh index bd60348..d98f03d 100755 --- a/build.sh +++ b/build.sh @@ -95,10 +95,22 @@ build_in_docker() { check_repo_sha "$ROOT/src/llvm" "$LLVM_SHA" check_repo_sha "$ROOT/src/musl" "$MUSL_SHA" + # Try creating a non-privileged user inside the container with the same UID + # as the UID of the real user to ensure ./ccache and ./output are writable + # without sudo on the host - this is useful to make sure ccache does not + # silently fall back to non-cached rebuilds in the 'host-build' mode of build.sh. + local UID + if [ "x$SUDO_USER" != "x" ]; then + UID="$(id -u "$SUDO_USER")" + else + UID="$(id -u)" + fi + $DOCKER_CMD build \ -t "$DOCKER_IMAGE_NAME" \ -f Dockerfile.builder \ --build-arg REPO_ROOT="$REPO_ROOT" \ + --build-arg UID="$UID" \ "$ROOT" $DOCKER_CMD run -ti --rm \ --volume "$ROOT/output:$OUTPUT_DIR:rw" \ diff --git a/scripts/build-in-docker.sh b/scripts/build-in-docker.sh index fb76200..377c260 100755 --- a/scripts/build-in-docker.sh +++ b/scripts/build-in-docker.sh @@ -2,6 +2,10 @@ set -xe cd "$(dirname "$0")" +if [ "$1" != "no-switch-user" ]; then + exec su builder -c "$0 no-switch-user" +fi + # This script is an entry point inside the Docker container. # Its location is expected to be $REPO_ROOT/scripts/build-in-docker.sh. From 0d5b83eef74ea57b1130e9c0a996182af691e6f5 Mon Sep 17 00:00:00 2001 From: Anatoly Trosinenko Date: Wed, 29 Jul 2026 15:52:48 +0300 Subject: [PATCH 2/3] Fix ownership of Docker volume dirs --- build.sh | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/build.sh b/build.sh index d98f03d..cddad99 100755 --- a/build.sh +++ b/build.sh @@ -106,6 +106,19 @@ build_in_docker() { UID="$(id -u)" fi + local rw_dir + for rw_dir in "$ROOT/output" "$ROOT/ccache" "$ROOT/tmp"; do + # Make sure $rw_dir is not created by `docker run`, otherwise it may + # end up being only writable by the root user. + mkdir -p "$rw_dir" + # Ignore "Permission denied" errors if our non-privileged user is allowed + # to execute `docker` without sudo - in that case `./build.sh build` does + # not otherwise require elevating its privileges explicitly, but `chown` + # may fail. Assuming that the $rw_dir was created by the above `mkdir` + # command, the ownership is already correct, thus ignore failed `chown`. + chown $UID:$UID "$rw_dir" || true + done + $DOCKER_CMD build \ -t "$DOCKER_IMAGE_NAME" \ -f Dockerfile.builder \ From 03a97e7188fd5822a0c9767e9d0d61c0847fc3d4 Mon Sep 17 00:00:00 2001 From: Anatoly Trosinenko Date: Thu, 30 Jul 2026 22:30:39 +0300 Subject: [PATCH 3/3] Add a note on SUDO_USER environment variable --- build.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/build.sh b/build.sh index cddad99..6d08709 100755 --- a/build.sh +++ b/build.sh @@ -101,6 +101,7 @@ build_in_docker() { # silently fall back to non-cached rebuilds in the 'host-build' mode of build.sh. local UID if [ "x$SUDO_USER" != "x" ]; then + # SUDO_USER is set by `sudo` ("login name of the user who invoked sudo"). UID="$(id -u "$SUDO_USER")" else UID="$(id -u)"