Skip to content

Commit

Permalink
Dockerfiles: Properly set up non-root users (#1265)
Browse files Browse the repository at this point in the history
Previously, the `crux-{llvm,mir}` Docker images were set up to use `root`
accounts, and all files that were created in the Docker images were given
`root` permissions. This is impractical for running rootless container
environments, as noted in #1261.

This rewrites the images to set the default users to unprivileges
`crux-{llvm,mir}` users. This is surprisingly involved, and it requires a fair
bit of refactoring to accomplish:

1. We cannot easily base the `crux-mir` image on the official `rust` image,
   as the latter has `cargo`, `rustup`, and related tools installed under a
   `root` account. Instead, we change to an unprivileged user and install these
   Rust tools using rustup.sh's installer script.
2. Previously, the `crux-llvm` image was supporting Unicode character printing
   by changing the locale, which requires root access to accomplish. This is
   overkill, however, as it suffices to simply set the `LANG` and `LC_ALL`
   environment variables. I've opted for the latter approach, which is much
   simpler and avoids the need for root access.
3. I needed to reorganize the order of commands in the `base` layers of each
   image in order to ensure that the relevant files are `chown`ed from the
   unprivileged user accounts.

Fixes #1261.
  • Loading branch information
RyanGlScott authored Oct 28, 2024
1 parent 2fb1c26 commit d0c27a1
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 118 deletions.
117 changes: 60 additions & 57 deletions .github/Dockerfile-crux-llvm
Original file line number Diff line number Diff line change
Expand Up @@ -14,83 +14,86 @@ RUN apt-get update && \
# LLVM toolchain
clang-${LLVM_VER} llvm-${LLVM_VER}-tools \
# Miscellaneous
locales unzip wget
RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && \
locale-gen
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8
unzip wget

WORKDIR /usr/local/bin
ARG CRUX_BUILD_DIR=/crux-llvm/build
RUN mkdir -p ${CRUX_BUILD_DIR}
ADD crucible ${CRUX_BUILD_DIR}/crucible
ADD crucible-llvm ${CRUX_BUILD_DIR}/crucible-llvm
ADD crucible-symio ${CRUX_BUILD_DIR}/crucible-symio
ADD crux ${CRUX_BUILD_DIR}/crux
ADD crux-llvm ${CRUX_BUILD_DIR}/crux-llvm
ADD dependencies ${CRUX_BUILD_DIR}/dependencies
ADD .github/cabal.project.crux-llvm ${CRUX_BUILD_DIR}/cabal.project
ADD cabal.GHC-9.4.8.config ${CRUX_BUILD_DIR}/cabal.project.freeze
# Workaround until we have a more recent LLVM build available
RUN cp ${CRUX_BUILD_DIR}/crux-llvm/c-src/libcxx-7.1.0.bc ${CRUX_BUILD_DIR}/crux-llvm/c-src/libcxx-${LLVM_VER}.0.0.bc

RUN useradd -m crux-llvm && chown -R crux-llvm:crux-llvm /crux-llvm
USER crux-llvm
WORKDIR /crux-llvm

ENV CLANG=clang-${LLVM_VER} \
LLVM_LINK=llvm-link-${LLVM_VER} \
LANG=C.UTF-8 \
LC_ALL=C.UTF-8

RUN mkdir -p rootfs/usr/local/bin
WORKDIR rootfs/usr/local/bin
# The URL here is based on the same logic used to specify BUILD_TARGET_OS and
# BUILD_TARGET_ARCH in `.github/workflow/crux-llvm-build.yml`, but specialized
# to x86-64 Ubuntu.
RUN curl -o solvers.zip -sL "https://github.com/GaloisInc/what4-solvers/releases/download/snapshot-20240212/ubuntu-22.04-X64-bin.zip"
RUN unzip solvers.zip && rm solvers.zip && chmod +x *

ENV PATH=/root/ghcup-download/bin:/root/.ghcup/bin:$PATH
RUN mkdir -p /root/ghcup-download/bin && \
curl -L https://downloads.haskell.org/~ghcup/0.1.17.7/x86_64-linux-ghcup-0.1.17.7 -o /root/ghcup-download/bin/ghcup && \
chmod +x /root/ghcup-download/bin/ghcup
RUN mkdir -p /root/.ghcup && \
WORKDIR /crux-llvm
ENV PATH=/crux-llvm/rootfs/usr/local/bin:/home/crux-llvm/.local/bin:/home/crux-llvm/.ghcup/bin:$PATH
RUN mkdir -p /home/crux-llvm/.local/bin && \
curl -L https://downloads.haskell.org/~ghcup/0.1.17.7/x86_64-linux-ghcup-0.1.17.7 -o /home/crux-llvm/.local/bin/ghcup && \
chmod +x /home/crux-llvm/.local/bin/ghcup
RUN mkdir -p /home/crux-llvm/.ghcup && \
ghcup --version && \
ghcup install cabal 3.10.3.0 && \
ghcup install ghc 9.4.8 && \
ghcup set ghc 9.4.8
RUN cabal v2-update

ARG DIR=/crux-llvm
WORKDIR ${DIR}
RUN mkdir -p ${DIR}/build
ADD crucible ${DIR}/build/crucible
ADD crucible-llvm ${DIR}/build/crucible-llvm
ADD crucible-symio ${DIR}/build/crucible-symio
ADD crux ${DIR}/build/crux
ADD crux-llvm ${DIR}/build/crux-llvm
ADD dependencies ${DIR}/build/dependencies
ADD .github/cabal.project.crux-llvm ${DIR}/build/cabal.project
ADD cabal.GHC-9.4.8.config ${DIR}/build/cabal.project.freeze
# Workaround until we have a more recent LLVM build available
RUN cp $DIR/build/crux-llvm/c-src/libcxx-7.1.0.bc $DIR/build/crux-llvm/c-src/libcxx-${LLVM_VER}.0.0.bc

WORKDIR ${DIR}/build
RUN cabal v2-build --only-dependencies crux-llvm
RUN cabal v2-build crux-llvm
ENV CLANG=clang-${LLVM_VER}
ENV LLVM_LINK=llvm-link-${LLVM_VER}
RUN cabal v2-test crux-llvm
RUN cp `cabal v2-exec which crux-llvm` /usr/local/bin
RUN cp `cabal v2-exec which crux-llvm-svcomp` /usr/local/bin
WORKDIR ${CRUX_BUILD_DIR}
RUN cabal v2-update && \
cabal v2-build --only-dependencies crux-llvm && \
cabal v2-build crux-llvm && \
cabal v2-test crux-llvm && \
cp `cabal v2-exec which crux-llvm` /crux-llvm/rootfs/usr/local/bin && \
cp `cabal v2-exec which crux-llvm-svcomp` /crux-llvm/rootfs/usr/local/bin
USER root
RUN chown -R root:root /crux-llvm/rootfs

FROM ubuntu:22.04
ARG LLVM_VER

USER root
RUN apt-get update && \
apt-get install -y \
libgmp10 zlib1g clang-${LLVM_VER} llvm-${LLVM_VER}-tools unzip locales

COPY --from=build /usr/local/bin/* /usr/local/bin/
libgmp10 zlib1g clang-${LLVM_VER} llvm-${LLVM_VER}-tools unzip

ARG DIR=/crux-llvm
WORKDIR ${DIR}
COPY --from=build /crux-llvm/rootfs /
WORKDIR /crux-llvm
ADD crux-llvm/c-src c-src
# Use LLVM 7 bitcode file for libcxx until a more recent LLVM version is available
RUN cp c-src/libcxx-7.1.0.bc c-src/libcxx-${LLVM_VER}.0.0.bc
RUN \
# Use LLVM 7 bitcode file for libcxx until a more recent LLVM version is available
cp c-src/libcxx-7.1.0.bc c-src/libcxx-${LLVM_VER}.0.0.bc && \
# (Temporary) fix for
# https://github.com/galoisinc/crucible/issues/887: the libDir default
# is relative to the executable or failing that, the data dir as
# reported by the build process, but neither matches WORKDIR/c-src.
cp -r c-src /usr/local/

# (Temporary) fix for
# https://github.com/galoisinc/crucible/issues/887: the libDir default
# is relative to the executable or failing that, the data dir as
# reported by the build process, but neither matches WORKDIR/c-src.
RUN cp -r c-src /usr/local/

RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && \
locale-gen
RUN useradd -m crux-llvm && chown -R crux-llvm:crux-llvm /crux-llvm /home/crux-llvm
USER crux-llvm
ENV LD_LIBRARY_PATH=/usr/local/lib
ENV CLANG=clang-${LLVM_VER}
ENV LLVM_LINK=llvm-link-${LLVM_VER}
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8
WORKDIR /

ENV LD_LIBRARY_PATH=/usr/local/lib \
CLANG=clang-${LLVM_VER} \
LLVM_LINK=llvm-link-${LLVM_VER} \
LANG=C.UTF-8 \
LC_ALL=C.UTF-8

ENTRYPOINT ["/usr/local/bin/crux-llvm"]
115 changes: 54 additions & 61 deletions .github/Dockerfile-crux-mir
Original file line number Diff line number Diff line change
@@ -1,19 +1,11 @@
# If you update this, make sure to also update RUST_TOOLCHAIN in
# .github/workflows/crux-mir-build.yml
ARG RUST_TOOLCHAIN="nightly-2023-01-23"

FROM rust:1.46.0 AS mir_json
ARG RUST_TOOLCHAIN

ADD dependencies/mir-json /mir-json
WORKDIR /mir-json
RUN rustup toolchain install ${RUST_TOOLCHAIN} --force
RUN rustup component add --toolchain ${RUST_TOOLCHAIN} rustc-dev
RUN rustup default ${RUST_TOOLCHAIN}
RUN cargo install --locked
ARG CRUX_BUILD_DIR=/crux-mir/build

FROM ubuntu:22.04 AS build
ARG RUST_TOOLCHAIN
ARG CRUX_BUILD_DIR

RUN apt-get update && \
apt-get install -y \
Expand All @@ -24,78 +16,79 @@ RUN apt-get update && \
# Miscellaneous
unzip wget

COPY --from=mir_json /usr/local/cargo /usr/local/cargo
COPY --from=mir_json /usr/local/rustup /usr/local/rustup
WORKDIR /usr/local/bin
RUN mkdir -p ${CRUX_BUILD_DIR}
ADD crucible ${CRUX_BUILD_DIR}/crucible
ADD crucible-concurrency ${CRUX_BUILD_DIR}/crucible-concurrency
ADD crucible-mir ${CRUX_BUILD_DIR}/crucible-mir
ADD crucible-syntax ${CRUX_BUILD_DIR}/crucible-syntax
ADD crux ${CRUX_BUILD_DIR}/crux
ADD crux-mir ${CRUX_BUILD_DIR}/crux-mir
ADD dependencies ${CRUX_BUILD_DIR}/dependencies
ADD .github/cabal.project.crux-mir ${CRUX_BUILD_DIR}/cabal.project
ADD cabal.GHC-9.4.8.config ${CRUX_BUILD_DIR}/cabal.project.freeze

RUN useradd -m crux-mir && chown -R crux-mir:crux-mir /crux-mir
USER crux-mir
WORKDIR /crux-mir

ENV LANG=C.UTF-8 \
LC_ALL=C.UTF-8 \
PATH=/crux-mir/rootfs/usr/local/bin:/home/crux-mir/.cargo/bin:/home/crux-mir/.local/bin:/home/crux-mir/.ghcup/bin:$PATH

WORKDIR ${CRUX_BUILD_DIR}/dependencies/mir-json
RUN curl https://sh.rustup.rs -sSf | bash -s -- -y --profile minimal --default-toolchain ${RUST_TOOLCHAIN}
RUN rustup component add --toolchain ${RUST_TOOLCHAIN} rustc-dev
RUN cargo install --locked

RUN mkdir -p /crux-mir/rootfs/usr/local/bin
WORKDIR /crux-mir/rootfs/usr/local/bin
# The URL here is based on the same logic used to specify BUILD_TARGET_OS and
# BUILD_TARGET_ARCH in `.github/workflow/crux-mir-build.yml`, but specialized
# to x86-64 Ubuntu.
RUN curl -o solvers.zip -sL "https://github.com/GaloisInc/what4-solvers/releases/download/snapshot-20240212/ubuntu-22.04-X64-bin.zip"
RUN unzip solvers.zip && rm solvers.zip && chmod +x *

ENV CARGO_HOME=/usr/local/cargo
ENV RUSTUP_HOME=/usr/local/rustup
ENV LD_LIBRARY_PATH=/usr/local/lib:/usr/local/rustup/lib
ENV LANG=C.UTF-8 \
LC_ALL=C.UTF-8

ENV PATH=/root/ghcup-download/bin:/root/.ghcup/bin:$PATH
RUN mkdir -p /root/ghcup-download/bin && \
curl -L https://downloads.haskell.org/~ghcup/0.1.17.7/x86_64-linux-ghcup-0.1.17.7 -o /root/ghcup-download/bin/ghcup && \
chmod +x /root/ghcup-download/bin/ghcup
RUN mkdir -p /root/.ghcup && \
WORKDIR /crux-mir
RUN mkdir -p /home/crux-mir/.local/bin && \
curl -L https://downloads.haskell.org/~ghcup/0.1.17.7/x86_64-linux-ghcup-0.1.17.7 -o /home/crux-mir/.local/bin/ghcup && \
chmod +x /home/crux-mir/.local/bin/ghcup
RUN mkdir -p /home/crux-mir/.ghcup && \
ghcup --version && \
ghcup install cabal 3.10.3.0 && \
ghcup install ghc 9.4.8 && \
ghcup set ghc 9.4.8
RUN cabal v2-update

ARG DIR=/crux-mir
RUN mkdir -p ${DIR}/build
ADD crucible ${DIR}/build/crucible
ADD crucible-concurrency ${DIR}/build/crucible-concurrency
ADD crucible-mir ${DIR}/build/crucible-mir
ADD crucible-syntax ${DIR}/build/crucible-syntax
ADD crux ${DIR}/build/crux
ADD crux-mir ${DIR}/build/crux-mir
ADD dependencies ${DIR}/build/dependencies
ADD .github/cabal.project.crux-mir ${DIR}/build/cabal.project
ADD cabal.GHC-9.4.8.config ${DIR}/build/cabal.project.freeze

WORKDIR ${DIR}/build
RUN cabal v2-build --only-dependencies crux-mir
RUN cabal v2-build crux-mir
RUN cp `cabal v2-exec which crux-mir` /usr/local/bin
RUN cp /usr/local/cargo/bin/* /usr/local/bin/
RUN rustup default ${RUST_TOOLCHAIN}
WORKDIR ${DIR}/build/crux-mir
WORKDIR ${CRUX_BUILD_DIR}/crux-mir
RUN ./translate_libs.sh
WORKDIR ${DIR}/build
RUN cabal v2-test crux-mir
WORKDIR ${CRUX_BUILD_DIR}
RUN cabal v2-update && \
cabal v2-build --only-dependencies crux-mir && \
cabal v2-build crux-mir && \
cabal v2-test crux-mir && \
cp `cabal v2-exec which crux-mir` /crux-mir/rootfs/usr/local/bin
USER root
RUN chown -R root:root /crux-mir/rootfs

FROM ubuntu:22.04
ARG CRUX_BUILD_DIR

USER root
RUN apt-get update && \
apt-get install -y \
libgmp10 zlib1g libcurl4 \
# A C toolchain (needed to build crates that require a C compiler)
clang

ARG DIR=/crux-mir
COPY --from=mir_json /usr/local/cargo /usr/local/cargo
COPY --from=mir_json /usr/local/rustup /usr/local/rustup
COPY --from=build /usr/local/bin/* /usr/local/bin/
COPY --from=build /crux-mir/build/crux-mir/rlibs /crux-mir/rlibs
RUN mkdir -p ${DIR}/workspace

WORKDIR ${DIR}/workspace
COPY --from=build /home/crux-mir/.cargo/bin /home/crux-mir/.cargo/bin
COPY --from=build /home/crux-mir/.rustup /home/crux-mir/.rustup
COPY --from=build /crux-mir/rootfs /
COPY --from=build ${CRUX_BUILD_DIR}/crux-mir/rlibs /crux-mir/rlibs

RUN useradd -m crux-mir && chown -R crux-mir:crux-mir /crux-mir /home/crux-mir
USER crux-mir
ENV CARGO_HOME=/usr/local/cargo \
RUSTUP_HOME=/usr/local/rustup \
CRUX_RUST_LIBRARY_PATH=/crux-mir/rlibs \
LD_LIBRARY_PATH=/usr/local/lib:/usr/local/rustup/lib \
LANG=C.UTF-8 \
LC_ALL=C.UTF-8
WORKDIR /

ENV LANG=C.UTF-8 \
LC_ALL=C.UTF-8 \
PATH=/home/crux-mir/.cargo/bin:$PATH

ENTRYPOINT ["/usr/local/bin/cargo", "crux-test"]

0 comments on commit d0c27a1

Please sign in to comment.