Skip to content

Tools/build/regen-configure.sh leaves a root-owned autom4te.cache, breaking later autoconf runs in the same tree #159452

Open

Description

@sendaoYan

Bug report

Tools/build/regen-configure.sh runs the Autoconf container as root: the docker run invocation has no --user, and the image sets no USER. Because the source tree is bind-mounted, everything the container writes is owned by root — including the autom4te.cache/ directory that Autoconf leaves behind. That directory can then be neither written to nor removed by the invoking user, which breaks two things.

environment

CPython main (reproduced on ab9b474), image ghcr.io/python/autoconf:2025.01.02.12581854023
Ubuntu 22.04 host, rootful Docker 20.10
The user is in the docker group, but has no sudo

Steps to reproduce

$ make regen-configure          # or: ./Tools/build/regen-configure.sh
$ ls -ld autom4te.cache; ls -l configure aclocal.m4 pyconfig.h.in
drwxr-xr-x 2 root root     4096 autom4te.cache
-rwxr-xr-x 1 root root 1086804 configure
-rw-r--r-- 1 root root   29215 aclocal.m4
-rw-r--r-- 1 root root   63824 pyconfig.h.in

Actual behaviour

  1. The tree can no longer be cleaned. Any git command that removes ignored/untracked files trips over the cache (.gitignore lists /autom4te.cache, so -x is what reaches it):
$ git clean -xdf
warning: failed to remove autom4te.cache/traces.1: Permission denied
warning: failed to remove autom4te.cache/requests: Permission denied
... (7 files)

Unlinking needs write permission on the directory; autom4te.cache/ is root-owned 0755, so the 0644 modes on the files are irrelevant. sudo rm -rf is the only way out, and not every developer has sudo on the machine they build CPython on.

  1. make autoconf is broken for that same user.
$ make autoconf
(cd /path/to/cpython; autoconf -Wall)
autom4te: error: cannot open autom4te.cache/requests: Permission denied
make: *** [Makefile.pre.in:1895: autoconf] Error 1

This reproduces independently of the Autoconf version: create a root-owned autom4te.cache/ in a tree and run any Autoconf as an unprivileged user.

Expected behaviour

Regenerating configure and friends should not leave anything in the tree that the invoking user cannot write to or delete. Note that configure, aclocal.m4 and pyconfig.h.in being root-owned is less visible, because their parent directory stays user-writable and Git can replace them via unlink + create — but the same fix removes that too.

Root cause

Two separate problems, and fixing either one alone is not enough:

The container runs as root, so the generated files are root-owned.
autom4te.cache/ is a directory. Unlike a file, it cannot be replaced by unlink + create, so the invoking user loses write access to it entirely, and the next non-root Autoconf run fails before it even starts.

Suggested fix

Run the container as the invoking user, and drop the cache before and after the run, from inside the container, so leftovers owned by root from earlier runs are also removed without needing sudo:

purge_autom4te_cache() {
    "$RUNTIME" run --rm -v "$abs_srcdir:$WORK_DIR$PATH_OPT" \
        --entrypoint sh "$IMAGE" -c "rm -rf $WORK_DIR/autom4te.cache"
}

purge_autom4te_cache            # a stale root-owned cache would break the run below
trap purge_autom4te_cache EXIT

"$RUNTIME" run --rm -u "$(id -u):$(id -g)" -v "$abs_srcdir:$WORK_DIR$PATH_OPT" "$IMAGE"
-u alone is insufficient: with a root-owned cache left behind by a previous run, the non-root run aborts with the very same cannot open autom4te.cache/requests: Permission denied. The cleanup reuses the same image (no new dependency, and it is already pulled), autom4te.cache is a cache that is regenerated on demand, and a full autoreconf takes about 6 seconds. Only rootful-container users are affected — rootless Podman already maps the invoking user.

CPython versions tested on:

CPython main branch

Operating systems tested on:

Linux

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    buildThe build process and cross-buildtype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions