OpenSSL DSA-6531-1: Patch 13 CVEs on Debian 13

10 min read

On 2026-09-30 Debian published DSA-6531-1 for OpenSSL. It fixes 13 CVEs in Debian 13 (trixie). The advisory warns of denial of service, information disclosure and possible private key recovery. The fix ships as 3.5.7-1~deb13u3. Running apt upgrade is only half the job, though. Every daemon that loaded libssl.so.3 or libcrypto.so.3 before the upgrade keeps the old, vulnerable copy in memory until you restart it. The DSA says nothing about restarts, so this post covers that part: check the package, find the stale processes, restart them, and confirm from /proc that they now map the patched library.

What happened: the OpenSSL advisory and DSA-6531-1

OpenSSL published a security advisory on 2026-09-29 listing 14 CVEs. Thirteen of them affect the 3.5 branch, which is what trixie ships. The fourteenth, CVE-2026-84783, only affects OpenSSL 4.0. Upstream fixed the 3.5 issues in 3.5.9. Debian stays on 3.5.7 and backported the fixes, which is why the fixed version is 3.5.7-1~deb13u3 and not 3.5.9. Upstream says none of the 14 CVEs affect the FIPS module.

The CVEs listed in DSA-6531-1 are: CVE-2026-35189, CVE-2026-35191, CVE-2026-42772, CVE-2026-54872, CVE-2026-54873, CVE-2026-54875, CVE-2026-72897, CVE-2026-75804, CVE-2026-75805, CVE-2026-75806, CVE-2026-77696, CVE-2026-84782 and CVE-2026-84784.

Only one of them is rated High by OpenSSL: CVE-2026-84782, an out-of-bounds read in DTLS handshake retransmission. OpenSSL acts as CNA and does not publish CVSS scores. CISA's ADP entry in the CVE record gives it CVSS 3.1 base score 8.2 (AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:H). The CVE was published 2026-09-29. OpenSSL rates the other twelve as Low.

Who is affected

Any Debian 13 host with libssl3t64 older than 3.5.7-1~deb13u3 is affected. The t64 suffix comes from the 64-bit time_t transition that ran during the trixie cycle. On trixie the runtime library package is libssl3t64, not libssl3, so commands copied from bookworm-era guides can come back empty. The openssl source package builds libssl3t64, openssl, libssl-dev, libssl-doc, openssl-provider-legacy and openssl-provider-fips, plus installer udebs.

ReleaseVulnerable versionFixed versionStatus (Debian security tracker)
Debian 13 trixie3.5.7-1~deb13u23.5.7-1~deb13u3 (trixie-security)Fixed by DSA-6531-1
Debian 12 bookworm3.0.22-1~deb12u1 (bookworm-security)none listed when checkedSix of these CVEs are marked vulnerable, including CVE-2026-84782
forky, sidn/a3.6.5-1Fixed

On bookworm, keep watching the tracker. Upstream only provides 3.0 branch fixes to premium support customers, so a Debian fix depends on backporting.

Which CVEs matter on a typical server

Thirteen CVEs sounds bad. Read by feature, most of them only hit code paths that a normal web or mail server never runs:

ClassCVEsWhen it matters
DTLSCVE-2026-84782 (High), CVE-2026-75806Anything that speaks DTLS, such as UDP-based VPNs and media servers. 84782 can leak heap memory to the peer or crash the process. 75806 lets an unauthenticated datagram tear down a DTLS 1.2 association.
TLS handshakeCVE-2026-35189, CVE-2026-7289735189: TLS clients, and servers that request client certificates (mTLS), can be pushed into allocating hundreds of MiB. 72897: servers that call SSL_set_SSL_CTX() mid-handshake (for example in an SNI callback), with contexts that differ in provider signature algorithms.
Key recovery (timing side channels)CVE-2026-54872, CVE-2026-77696, CVE-2026-5487554872: ECDSA/SM2 signing on generic curves such as Brainpool. P-256, P-384 and P-521 are not affected. 77696: SM2 signing on all platforms. 54875: SM2 on AArch64 and RISC-V only.
OpenSSL's QUIC stackCVE-2026-35191, CVE-2026-42772, CVE-2026-54873, CVE-2026-75804, CVE-2026-84784Only applications that use OpenSSL's own QUIC implementation. Covers amplification, CPU and memory exhaustion.
CMP clientCVE-2026-75805A CMP client revoking by CSR against a malicious or compromised CMP server.

If your keys are RSA, Ed25519 or NIST P-curves, the key-recovery CVEs mostly don't apply to you. Here is how to check which curve a certificate uses:

openssl x509 -in /etc/ssl/certs/example.pem -noout -text | grep -E 'Public Key Algorithm|ASN1 OID'

Patch anyway. The point of the table is to help you decide whether something deserves closer attention afterwards, such as a DTLS VPN endpoint or Brainpool keys you might want to rotate.

How to check your Debian 13 systems

Don't rely on openssl version here. It prints the upstream version (3.5.7) both before and after the fix. The Debian revision is what changes, so query dpkg:

dpkg-query -W -f='${Package} ${Version}\n' libssl3t64 openssl openssl-provider-legacy libssl-dev 2>/dev/null
apt-cache policy libssl3t64

A patched host shows:

libssl3t64 3.5.7-1~deb13u3
openssl 3.5.7-1~deb13u3
openssl-provider-legacy 3.5.7-1~deb13u3

You can also confirm that the installed changelog mentions the advisory:

apt changelog libssl3t64 2>/dev/null | head -n 30

Patch OpenSSL on Debian 13

sudo apt update
sudo apt install --only-upgrade libssl3t64 openssl openssl-provider-legacy

If libssl-dev, libssl-doc or openssl-provider-fips are installed, add them to the same command so every binary package from the source ends up on the same version. Mixed versions from one source package are a common leftover on build hosts. If you already use unattended-upgrades with the security origin, the package is probably updated. The restarts below are still your job. The same workflow applied to the recent rsync DSA-6527-1 update on Debian 13.

Find daemons still running the old libssl

When dpkg replaces a shared library, it unlinks the old file. Processes that already mapped it keep using the deleted inode. The kernel marks such mappings in /proc/PID/maps by appending (deleted) to the path. Check both libssl and libcrypto. Some programs, OpenSSH for example, only link libcrypto.

Option 1: needrestart

sudo apt install needrestart
sudo needrestart -r l -l

-r l only lists and restarts nothing. -l limits the check to outdated libraries. For scripts or monitoring, -b gives machine-readable batch output.

Option 2: /proc/PID/maps directly

This needs no extra packages and, for libssl and libcrypto specifically, gives the same answer as needrestart:

for m in /proc/[0-9]*/maps; do
  if sudo grep -qE 'lib(ssl|crypto)\.so\.3 \(deleted\)' "$m" 2>/dev/null; then
    pid=${m#/proc/}
    pid=${pid%/maps}
    printf '%s\t%s\n' "$pid" "$(cat "/proc/$pid/comm" 2>/dev/null)"
  fi
done

Example output on an unrestarted web and mail host:

812	nginx
813	nginx
1044	master
1190	dovecot
1377	haproxy
2210	sshd-session

The lsof version: mappings of deleted files show DEL in the FD column.

sudo lsof -n 2>/dev/null | grep -E 'lib(ssl|crypto)\.so\.3' | grep -w DEL

To get the systemd unit for a PID, run systemctl status with the PID as its argument:

systemctl status 1044 --no-pager | head -n 1

Restart the affected services

Warning: the commands below restart services and drop active connections. Do this in a maintenance window. On remote hosts, keep a second SSH session open while restarting ssh.

Use a full restart, not a reload. On nginx and apache2 a reload keeps the master process and forks new workers from it. Forked children inherit the master's mappings, old libssl included. Restart only the units that showed up in the check. A typical trixie server ends up with something like this:

sudo systemctl restart nginx
sudo systemctl restart apache2
sudo systemctl restart php8.4-fpm
sudo systemctl restart postfix
sudo systemctl restart dovecot
sudo systemctl restart haproxy
sudo systemctl restart ssh

Restarting ssh.service does not kill existing sessions. Trixie ships OpenSSH 10.0, where each connection runs in a separate sshd-session process. Those processes keep the old libcrypto until the session ends, so log out and back in, then check again. PHP-FPM workers count too. If you run several pools or PHP versions, restart each FPM unit, as in the PHP 8.4 DSA-6514-1 PHP-FPM patch guide. If PID 1, your desktop session or a long list of unrelated processes still show up afterwards, a reboot is the cleanest fix.

Verify the fix in running processes

A new package version doesn't prove anything about running processes. Compare the inode a process actually maps with the inode of the file on disk. First find the library paths from the package:

dpkg -L libssl3t64 | grep -E 'lib(ssl|crypto)\.so\.3$'

Then compare, here using nginx's main PID:

pid=$(systemctl show -p MainPID --value nginx)
sudo awk '/lib(ssl|crypto)\.so\.3/ {print $5, $6, $7}' "/proc/$pid/maps" | sort -u
lib=$(dpkg -L libssl3t64 | grep -E 'libssl\.so\.3$')
stat -L -c '%i %n' "$lib"

The inode from maps must match the one from stat, and no line may end in (deleted). Finish by running the loop from the previous section again. It should print nothing. Add it to your post-patch runbook so the same check happens after every library DSA.

Bundled OpenSSL: containers, wheels and static binaries

DSA-6531-1 fixes the system library and nothing else. Copies of OpenSSL elsewhere on the box are still vulnerable until their own vendors ship fixes.

Docker images

Each image has its own libssl. A debian:trixie-based image needs a rebuild with apt-get upgrade or a refreshed base image, followed by a container restart. Check what running containers actually contain:

for c in $(docker ps -q); do
  name=$(docker inspect -f '{{.Name}}' "$c")
  ver=$(docker exec "$c" dpkg-query -W -f='${Version}' libssl3t64 2>/dev/null || echo 'no libssl3t64 (non-Debian base?)')
  printf '%s\t%s\n' "$name" "$ver"
done

Containers built on Alpine, Ubuntu or distroless bases get their OpenSSL fixes from those distributions, on their own schedule. Containers share the host kernel but not its libraries. The isolation model is covered in how container escapes work.

Python wheels, vendored libraries, static binaries

Debian's python3 uses the system library. Binary wheels installed with pip into virtualenvs often bundle their own libssl or libcrypto, usually in a .libs directory next to the package. The same goes for vendor tarballs under /opt. This command finds shared copies outside the system path:

sudo find / -xdev \( -name 'libssl*.so*' -o -name 'libcrypto*.so*' \) -not -path '/usr/lib/*' 2>/dev/null

Statically linked binaries such as some Go and Rust tools, or self-contained agents, won't turn up there. As a rough heuristic, look for an embedded version string:

strings -a /opt/vendor/bin/agent | grep -m1 -E '^OpenSSL [0-9]+\.[0-9]+\.[0-9]+'

Anything older than the upstream fixed releases (3.5.9, 3.6.5, 3.4.8 or 4.0.3) needs an update from whoever ships it. For pip packages that usually means pip install --upgrade once the project publishes new wheels.

What to watch next

  • The Debian security tracker page for openssl, for a bookworm fix to the six CVEs still marked vulnerable there.
  • A possible DSA-6531-2 if a regression turns up. Watch debian-security-announce.
  • New images for your container base and new wheels for vendored crypto (cryptography, database drivers).
  • DTLS endpoints you run. CVE-2026-84782 is the one with a High rating and network reach.

Takeaways

  • Debian 13 is fixed in libssl3t64 and openssl 3.5.7-1~deb13u3. Check with dpkg-query, not openssl version.
  • Upgrade every binary package from the openssl source, including the providers and libssl-dev.
  • Find stale processes with needrestart -r l -l or by grepping /proc/*/maps for (deleted) libssl and libcrypto mappings.
  • Fully restart nginx, apache2, PHP-FPM, postfix, dovecot, haproxy, ssh and anything else listed. A reload is not enough.
  • Prove the fix: mapped inode matches the file on disk, and the deleted-mapping check comes back empty.
  • Rebuild containers and update bundled OpenSSL copies separately. The DSA doesn't reach them.
  • Outside of DTLS, mTLS and Brainpool/SM2 keys, most of the 13 CVEs need features a typical server doesn't use. Patch anyway.

Sources

Comments