The final image is scratch, which has no C library. The builder compiled mfer with cgo on, which is the default in the golang image, and because the binary imports net (mfer's own HTTP code does, and so does google/uuid), it was dynamically linked against the C library. The image could not start: exec /mfer: no such file or directory.
The go build that produces the image's binary now sets CGO_ENABLED=0. Nothing in mfer uses cgo.
A new builder step fails the build unless ldd reports that the binary is not a dynamic executable. If ldd were missing, the check would also fail, not pass silently.
Not visible in the diff:
make test in the builder stage still runs with cgo on. Only the binary that ships in the image changed.
Host builds (make bin/mfer) are unchanged.
Judgement call: the check uses ldd, because the builder image has no file command.
The final image is `scratch`, which has no C library. The builder compiled `mfer` with cgo on, which is the default in the `golang` image, and because the binary imports `net` (mfer's own HTTP code does, and so does `google/uuid`), it was dynamically linked against the C library. The image could not start: `exec /mfer: no such file or directory`.
- The `go build` that produces the image's binary now sets `CGO_ENABLED=0`. Nothing in mfer uses cgo.
- A new builder step fails the build unless `ldd` reports that the binary is not a dynamic executable. If `ldd` were missing, the check would also fail, not pass silently.
Not visible in the diff:
- `make test` in the builder stage still runs with cgo on. Only the binary that ships in the image changed.
- Host builds (`make bin/mfer`) are unchanged.
Judgement call: the check uses `ldd`, because the builder image has no `file` command.
Closes https://git.eeqj.de/sneak/mfer/issues/126
Model: opus-5-5
Commit message of c45310d and the PR body, cause of the dynamic linking: both say the binary was dynamically linked because google/uuid imports net. mfer's own fetch code (internal/cli/fetch.go, internal/cli/manifest_loader.go) imports net/http, which imports net, so the binary links the C library with cgo on even without google/uuid. As written, the planned move to the standard library UUID (#102) reads as if it would remove the cause. Acceptable: say the binary imports net (mfer's own HTTP code does, and so does google/uuid), or state the cause without naming a single package.
Disclosures:
#127 also changes the Dockerfile (lint stage); the two merge without conflict.
Judgement call, not a finding: fetch over HTTPS fails in the image because scratch has no CA certificates. That is outside #126 and belongs in its own issue.
Model: opus-5-5
Review failed.
1. Commit message of `c45310d` and the PR body, cause of the dynamic linking: both say the binary was dynamically linked because `google/uuid` imports `net`. mfer's own fetch code (`internal/cli/fetch.go`, `internal/cli/manifest_loader.go`) imports `net/http`, which imports `net`, so the binary links the C library with cgo on even without `google/uuid`. As written, the planned move to the standard library UUID (https://git.eeqj.de/sneak/mfer/issues/102) reads as if it would remove the cause. Acceptable: say the binary imports `net` (mfer's own HTTP code does, and so does `google/uuid`), or state the cause without naming a single package.
Disclosures:
- https://git.eeqj.de/sneak/mfer/pulls/127 also changes the `Dockerfile` (lint stage); the two merge without conflict.
- Judgement call, not a finding: `fetch` over HTTPS fails in the image because `scratch` has no CA certificates. That is outside https://git.eeqj.de/sneak/mfer/issues/126 and belongs in its own issue.
Model: opus-5-5
The final stage is scratch, which has no C library, but the builder
compiled mfer with cgo on (the golang image's default). The binary
imports net (mfer's own HTTP code does, and so does google/uuid), so
with cgo on it came out dynamically linked and the image could not
start. The image's go build now sets CGO_ENABLED=0; nothing in mfer
needs cgo. A new builder step runs ldd on the binary and fails the
build unless it reports a static executable.
Model: opus-5-5
Disclosure: #127 also changes the Dockerfile (lint stage); the two merge without conflict.
Judgement call, not a finding: the ldd check would also accept a file that is not a program at all, since ldd says "not a dynamic executable" for that too; /mfer always comes from go build, so this cannot happen in practice.
Model: opus-5-5
Review passed.
Gated on `next` at `a2732cf`.
- Disclosure: https://git.eeqj.de/sneak/mfer/pulls/127 also changes the `Dockerfile` (lint stage); the two merge without conflict.
- Judgement call, not a finding: the `ldd` check would also accept a file that is not a program at all, since `ldd` says "not a dynamic executable" for that too; `/mfer` always comes from `go build`, so this cannot happen in practice.
Model: opus-5-5
clawbot
merged commit b91e92b070 into next2026-10-04 08:48:53 +02:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
The final image is
scratch, which has no C library. The builder compiledmferwith cgo on, which is the default in thegolangimage, and because the binary importsnet(mfer's own HTTP code does, and so doesgoogle/uuid), it was dynamically linked against the C library. The image could not start:exec /mfer: no such file or directory.go buildthat produces the image's binary now setsCGO_ENABLED=0. Nothing in mfer uses cgo.lddreports that the binary is not a dynamic executable. Iflddwere missing, the check would also fail, not pass silently.Not visible in the diff:
make testin the builder stage still runs with cgo on. Only the binary that ships in the image changed.make bin/mfer) are unchanged.Judgement call: the check uses
ldd, because the builder image has nofilecommand.Closes #126
Model: opus-5-5
Review failed.
c45310dand the PR body, cause of the dynamic linking: both say the binary was dynamically linked becausegoogle/uuidimportsnet. mfer's own fetch code (internal/cli/fetch.go,internal/cli/manifest_loader.go) importsnet/http, which importsnet, so the binary links the C library with cgo on even withoutgoogle/uuid. As written, the planned move to the standard library UUID (#102) reads as if it would remove the cause. Acceptable: say the binary importsnet(mfer's own HTTP code does, and so doesgoogle/uuid), or state the cause without naming a single package.Disclosures:
Dockerfile(lint stage); the two merge without conflict.fetchover HTTPS fails in the image becausescratchhas no CA certificates. That is outside #126 and belongs in its own issue.Model: opus-5-5
c45310dc9eto17d2631984net(mfer's own HTTP code does, and so doesgoogle/uuid); code unchanged.Model: opus-5-5
Review passed.
Gated on
nextata2732cf.Dockerfile(lint stage); the two merge without conflict.lddcheck would also accept a file that is not a program at all, sincelddsays "not a dynamic executable" for that too;/mferalways comes fromgo build, so this cannot happen in practice.Model: opus-5-5