TL;DR

  • redis 8.10.1 fixes nine issues. None is reachable here: redis runs with port 0 on a group-restricted unix socket, and ss -lntp shows no listener.
  • nginx 1.31.4 and BoringSSL went in as one rebuild, under a live socket. Our QUIC report #1616 and its one-line fix #1617 are both still open.
  • The AdGuard Home advisory was already answered in this fork on 31 July, eighteen days before it published. By reading upstream's own fix, not by finding it ourselves.
  • The item that mattered was in neither headline: a Go toolchain bump, answered by rebuilding rather than merging.
  • One upstream fix had to be rewritten before we could take it. It echoes the client's EDNS buffer size; this resolver clamps it to 1,232 bytes.

The checker could only report clean

The update checker's Go row read go 1.26.5 · current. That was not a measurement.

The watcher runs from a systemd timer, and that timer's PATH does not contain /usr/local/go/bin. Its go version call resolved to nothing, so the check was skipped rather than failed. The row kept whatever an earlier interactive run had left behind. Go had been at 1.26.6 since 13 August.

A second fault sat beside it. The marker for which upstream release had been reviewed read the newest local v*.*.* git tag, and those tags arrive from upstream on an ordinary fetch. Fetching alone would have declared a release reviewed before anyone had read it.

Neither cost anything this time. Neither was found by the check - both were found while updating. The Go probe now tries absolute paths before falling back to the PATH, and upstream's tags are kept under upstream-v*, separate from the fork's own.

What moved on 21 August

Four components: redis 8.10.0 to 8.10.1, nginx 1.31.3 to 1.31.4, nginx's copy of BoringSSL from 0.20260803.0 to 0.20260813.0, and the AdGuard Home fork from v0.107.78-edge to v0.107.79-edge.

Two of those releases carried a security label. A label is a claim about upstream's code, not about a deployment. Reading was the only way to find out which claim applied here.

redis 8.10.1: nine fixes, no listener to reach them

Upstream ships nine security fixes. Three are worth naming:

  • CVE-2026-62356, a miscalculated buffer size in CMSketch RDB loading that can write past the end of the heap.
  • An out-of-range SLOT_INFO slot id in a malicious RDB payload, which upstream describes as possibly leading to remote code execution.
  • A TLS client-certificate authentication bypass: a Common Name containing an embedded NUL byte is truncated, letting a client authenticate as a different, possibly privileged, ACL user.

On this box redis runs with port 0 and a unix socket with group-restricted permissions. ss -lntp shows no redis listener at all. The certificate bypass has nothing to reach, and the RDB paths are not fed by anything remote.

The update was taken the same day because it was cheap, not because there was an exposure to close.

The reusable part is the gate rather than the patch. The build refuses to proceed unless the tarball from download.redis.io matches the digest published in the redis-hashes repository. Two different origins is the only reason that check is worth anything.

nginx and BoringSSL: one rebuild, live socket

nginx 1.31.4 is not a security release. The security fixes were in 1.31.3.

It carries three QUIC commits, and none of them is ours. Our report of an Initial CRYPTO deadlock is still open as nginx/nginx#1616, and the one-line fix proposed for it, #1617, is open and unmerged. Both re-checked on 23 August. The failure itself is written up in the handshake that failed one time in twenty.

Two BoringSSL changes were checked before the rebuild rather than discovered after it:

  • SSL_GROUP_X25519_KYBER768_DRAFT00 was removed in the new tag. This site offers X25519MLKEM768:X25519:prime256v1:secp384r1, which never referenced it.
  • BORINGSSL_API_VERSION went from 42 to 43. The ECH patch applied to a fresh 1.31.4 tree with one hunk offset by two lines.

Measured at 22:27 that evening: the running master process had been started at 18:34, while the service unit had not restarted since 11 August. The binary was replaced under a live socket.

The AdGuard Home advisory was already answered

GHSA-w6v6-f44j-3rj2, published 18 August, is a dnsproxy advisory. A client opens the highest-numbered unidirectional QUIC stream. Stream-ID semantics implicitly open all 65,535 below it. dnsproxy never reads or cancels them, so receive-stream state stays pinned for the life of the connection.

This fork has capped that number at 64 since 24 May. Since 31 July it refuses unidirectional streams outright on DoQ, which reads none. The HTTP/3 control and QPACK streams that DoH3 does need are configured separately.

To be exact about the credit: that was a review of upstream's own dnsproxy v0.83.1, taken three days after it shipped and eighteen days before the advisory published. Upstream wrote the fix. We read it early. There was nothing left to port.

The security item nobody headlined

The binary in production had been built with Go 1.26.5. Go 1.26.6, released 13 August, carries security fixes to the go command and to crypto/tls, encoding/asn1, encoding/xml, html/template, net, net/http and net/url.

The answer was a rebuild, not a merge. Read back from the preserved binaries: the build replaced at 18:47 reports go1.26.5, and the one that replaced it reports go1.26.6. A second rebuild at 20:44 the same evening moved the deployed binary to Go 1.27.0, released 19 August. That is what it reports now.

The one fix we could not copy as written

Upstream closed issue #8183. Responses the server generates itself - blocked answers, NXDOMAIN, REFUSED, SERVFAIL and NODATA - did not echo the request's EDNS(0) state. That breaks systemd-resolved.

Upstream's fix echoes the buffer size the client advertised, unchanged. That is reasonable for a general resolver. It is wrong here.

This stack clamps that number to 1,232 bytes. The clamp covers both the buffer it honours and the point at which it truncates, because amplification floods advertise large buffers on purpose. Echoing the raw value would advertise a size this resolver never honours, on exactly the responses cheapest for a reflector to trigger.

So the fork echoes the smaller of the two instead, and its own test fails against upstream's version on that number. The same clamp is what exposed a TCP bug when we first turned it on. Re-run on the resolver on 23 August:

$ dig @127.0.0.1 +dnssec doubleclick.net A
; EDNS: version: 0, flags: do; udp: 1232

$ dig @127.0.0.1 +dnssec +bufsize=10000 doubleclick.net A
; EDNS: version: 0, flags: do; udp: 1232

$ dig @127.0.0.1 +noedns doubleclick.net A
(no OPT PSEUDOSECTION)

The DO bit and the buffer size come back on a generated answer. The clamp holds against a client asking for 10,000 bytes. A request that carried no OPT record still gets a reply with none, as RFC 6891 requires.

Why we read releases instead of merging them

Two security labels on the day, and neither described what actually needed doing. One names code this deployment does not expose. The other names code this fork had already replaced in May, and again in July.

What needed doing was a rebuild against a newer compiler, and a one-line upstream fix that had to be rewritten before it could be taken. Neither was in a headline. Both were in the diff.

The next update pass, two weeks later, is nginx 1.31.5, Go 1.27.1, and a month of BoringSSL not taken.