The Brotli decoder out-of-bounds write (Brotli 1.0.3–1.2.0, fixed 1.2.1) was checked against every deployed image on 2026-10-25. No decoder is on any attacker-reachable path: Gitea's Go binary has no Brotli, vav and korban carry no libbrotli and no Python Brotli module, ingress-nginx has the module unloaded and only ever encodes. Three dormant copies remain: Gitea's Alpine brotli-libs 1.2.0 (no rebuilt image on Docker Hub yet), ingress-nginx's brotli-libs 1.1.0, and this image's libbrotli1 1.0.9-2 from the swipl:9.2.2 base, linked only by libcurl3-gnutls which nothing here calls. This one is ours to close. bookworm-security has 1.0.9-2+deb12u1; the runtime stage now upgrades that single package and nothing else, so the SWI-Prolog 9.2.2 pin (Construction §1.1) stands. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
77 lines
3.2 KiB
Docker
77 lines
3.2 KiB
Docker
# check=skip=FromPlatformFlagConstDisallowed
|
|
# ^ The --platform=linux/amd64 pins below are DELIBERATE (Exoscale SKS
|
|
# nodes are amd64). BuildKit lints a constant --platform as a smell;
|
|
# here it is the fix. Silenced so a real warning is not lost in noise.
|
|
# Bikoret Talmudic Engine — SWI-Prolog dialectical reasoning
|
|
# Construction spec §1.1: SWI-Prolog 9.2.2
|
|
# Communicates with vav_pipeline via Unix domain socket
|
|
#
|
|
# PLATFORM PIN: see Dockerfile.vav_pipeline for the rationale.
|
|
# Exoscale SKS = amd64; arm64 images cannot exec on the cluster.
|
|
|
|
# === BUILD STAGE ===
|
|
FROM --platform=linux/amd64 swipl:9.2.2 AS build
|
|
|
|
WORKDIR /app
|
|
COPY talmudic_engine/ ./
|
|
|
|
# Verify Prolog loads without errors
|
|
RUN swipl -g "consult('src/main'),halt(0)" -t "halt(1)"
|
|
|
|
# === RUNTIME STAGE ===
|
|
FROM --platform=linux/amd64 swipl:9.2.2
|
|
|
|
# CVE-2026-111497 (Brotli decoder out-of-bounds write, October 2026).
|
|
# The swipl:9.2.2 base carries Debian bookworm's libbrotli1 1.0.9-2,
|
|
# pulled in by libcurl3-gnutls. Nothing in this image decodes Brotli:
|
|
# swipl does not link it, there is no curl binary, and the engine reads
|
|
# JSON from vav over a Unix socket. The copy was dormant, not a path.
|
|
# Debian fixed it in 1.0.9-2+deb12u1 (bookworm-security); take that one
|
|
# package without moving the pinned base. The pin on SWI-Prolog 9.2.2
|
|
# (Construction §1.1) is the point of the base image, so this is
|
|
# --only-upgrade of the one library, not a general upgrade.
|
|
RUN apt-get update \
|
|
&& apt-get install -y --no-install-recommends --only-upgrade libbrotli1 \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
RUN useradd --create-home --shell /bin/bash bikoret
|
|
USER bikoret
|
|
|
|
WORKDIR /home/bikoret/talmudic_engine
|
|
|
|
COPY --from=build --chown=bikoret:bikoret /app/ ./
|
|
|
|
# L1 Torah filesystem — baked into the image
|
|
# L1 is read-only in fact, not only in name. Until 2026-10-04 the scroll
|
|
# was copied in owned by the service user with its write bits on: the
|
|
# process that reads Torah could also have rewritten it, and only the
|
|
# SHA-256 check would have noticed afterwards. Owned by root, no write
|
|
# bit for anyone; the service user can read and traverse, nothing more.
|
|
USER root
|
|
COPY --chown=root:root l1/ /mnt/torah/
|
|
RUN chmod -R a-w,a+rX /mnt/torah
|
|
USER bikoret
|
|
|
|
# L1 mount point
|
|
ENV L1_MOUNT_POINT=/mnt/torah
|
|
|
|
# Socket path for communication with vav_pipeline
|
|
ENV TALMUDIC_SOCKET_PATH=/tmp/bikoret/talmudic.sock
|
|
|
|
# Start the Prolog socket server.
|
|
#
|
|
# The predicate is serve/0 and serve/1 (exported by
|
|
# src/interface/socket_server.pl). The previous CMD called
|
|
# start_socket_server/0, which is not defined anywhere in the engine —
|
|
# the container exited 2 on every start:
|
|
# ERROR: -g consult('src/main'),start_socket_server:
|
|
# '<meta-call>'/1: Unknown procedure: start_socket_server/0
|
|
#
|
|
# serve/1 is used when TALMUDIC_SOCKET_PATH is set so the env var above
|
|
# is actually honoured; serve/0 falls back to the same path hardcoded
|
|
# as default_socket_path/1. vav_pipeline dials the socket at
|
|
# :talmudic_socket_path (config/config.exs), and deployment.yaml mounts
|
|
# the shared talmudic-socket volume at /tmp/bikoret in both
|
|
# containers, so the two ends must agree on this path.
|
|
CMD ["swipl", "-g", "consult('src/main'), (getenv('TALMUDIC_SOCKET_PATH', P) -> serve(P) ; serve)", "-t", "halt(1)"]
|