xz-utils DSA-6549-1: Patch liblzma on Debian 13

8 min read

On 2026-10-07 Debian published DSA-6549-1 for xz-utils. It fixes an invalid memory write in the LZMA1 decoders of liblzma. The advisory says it can cause a denial of service and possibly arbitrary code execution. On Debian 13 (trixie) the fixed version is 5.8.1-1+deb13u2. After "xz" and 2024, the name alone is enough to make people nervous, so this post sticks to the facts: what the bug is, who is realistically exposed, how to patch, and how to prove that no running process still uses the old library.

What happened: DSA-6549-1 and the xz-utils LZMA1 bug

The timeline, from the primary sources:

  • 2026-09-09: upstream XZ Utils released 5.8.4 and published advisory GHSA-5qpq-xqfv-j9pg, "Invalid write if a decoder is reinitialized after allocation failure". Upstream says it affects 5.8.3 and older. The 5.8.4 release notes say every version since 5.0.0 is affected. The bug was found by Cantina with their AppSec agent Apex.
  • 2026-09-10: Salvatore Bonaccorso of the Debian Security Team filed Debian bug #1147318 with severity important. Unstable got 5.8.4-1 on 2026-09-12.
  • 2026-10-07: DSA-6549-1 shipped the backported fix for trixie as 5.8.1-1+deb13u2.

CVE and CVSS: no CVE had been assigned when the DSA was published. The DSA lists the CVE as "not yet available", and the GitHub advisory says "No known CVE". The Debian security tracker uses a temporary ID, TEMP-1147318-639065. GitHub rates the advisory "High” but publishes no CVSS score or vector, so this post doesn't give one. Don't confuse this bug with CVE-2026-34743, a different liblzma issue in the index decoder that upstream fixed in 5.8.3.

What the bug actually is

The flaw is in the decoder initialisers for the legacy formats:

  • lzma_alone_decoder(): the legacy .lzma format (LZMA1)
  • lzma_lzip_decoder(): .lz files
  • lzma_auto_decoder(), but only when the input is .lzma or .lz
  • lzma_microlzma_decoder(): MicroLZMA

Upstream states that the .xz decoder and the raw decoders are not affected. To trigger the bug, one process has to reuse the same lzma_stream in a specific sequence:

  1. Initialise the decoder and partially decode a file.
  2. Reinitialise it and decode another file, during which a real memory allocation fails with LZMA_MEM_ERROR. Hitting the memory limit (LZMA_MEMLIMIT_ERROR) does not trigger it.
  3. Reinitialise it again and decode a file whose header declares a matching dictionary size.

The result is an invalid write into heap memory. Upstream's 5.8.4 release notes say the bug could cause a crash; the advisory itself only describes an invalid memory write. Debian's wording, "possibly arbitrary code execution", is the usual cautious reading of a heap write. Nobody has published an exploit, and none of the sources I read show the bug being exploited in practice.

Who is affected on Debian 13

The xz-utils source package builds liblzma5, xz-utils, xzdec, liblzma-dev, liblzma-doc and liblzma5-udeb. The bug is in the library, so liblzma5 is the package that matters. Package status from the Debian security tracker for TEMP-1147318-639065:

ReleaseVersionStatus
trixie (13)5.8.1-1+deb13u1vulnerable
trixie-security (13)5.8.1-1+deb13u2fixed (DSA-6549-1)
bookworm (12)5.4.1-1+deb12u1vulnerable
bookworm-security (12)5.4.1-1+deb12u2fixed
forky, sid5.8.4-1fixed

One trap for scanners and dashboards: the Debian fix is a backport. After you patch, xz --version still reports 5.8.1. Only the Debian revision (+deb13u2) shows whether you are fixed.

Realistic exposure versus panic level

Almost every Debian system has liblzma loaded somewhere. In trixie, dpkg and libapt-pkg7.0 have a hard dependency on liblzma5. libsystemd0 only lists it under Suggests. Having the library installed is not the same as being exposed. For an attacker to hit this bug, all of the following must be true:

  • a process decodes attacker-controlled .lzma, .lz or MicroLZMA data, not .xz;
  • the process reuses one decoder stream for several inputs and reinitialises it between them;
  • a real allocation failure happens at the right moment.

In practice:

  • Highest priority: long-running services that unpack uploaded or fetched archives in-process through liblzma or a language binding. Examples are upload handlers, mail and attachment scanners, artifact or package mirrors, and backup or ingest daemons that accept third-party data. Patch these and restart them first.
  • Low: one-shot CLI runs (xz -d, unxz, tar -J) on your own files, and apt or dpkg handling signed packages from Debian mirrors. Each invocation is a fresh process with signed or trusted input.
  • Not affected by this bug: workloads that only ever decode .xz.

So this isn't a 2024-style emergency. It's a normal library update that you should apply this week and that needs restarts.

How to check your Debian 13 systems

List the installed versions of every binary package built from xz-utils:

dpkg-query -W -f='${Package}\t${Version}\n' liblzma5 xz-utils xzdec liblzma-dev 2>/dev/null
apt-cache policy liblzma5

An unpatched host looks like this:

liblzma5	5.8.1-1+deb13u1
xz-utils	5.8.1-1+deb13u1

If apt-cache policy doesn't offer 5.8.1-1+deb13u2 as the candidate, check that trixie-security is in your APT sources.

Patch xz-utils to 5.8.1-1+deb13u2

Update the index and upgrade only the affected packages. --only-upgrade skips packages that aren't installed:

apt update
apt install --only-upgrade liblzma5 xz-utils xzdec liblzma-dev

A full apt upgrade works too, but it pulls in everything else that's pending.

Find processes still mapping the old liblzma

Installing the package does nothing for processes that already have the library loaded. Because the upstream version didn't change, the new file has the same name as the old one. The kernel marks the replaced inode as (deleted) in each process's memory map, and that marker is what to look for. Run this as root:

for maps in /proc/[0-9]*/maps; do
  if grep -q 'liblzma\.so\.5.*(deleted)' "$maps" 2>/dev/null; then
    pid=${maps#/proc/}
    pid=${pid%/maps}
    ps -o pid=,unit=,comm= -p "$pid"
  fi
done

The unit column tells you which systemd service or user session to restart. If you prefer lsof, mapped files that have been deleted show up with DEL in the FD column:

lsof -nP 2>/dev/null | grep liblzma | grep -w DEL

needrestart runs the same check. -r l only lists services and restarts nothing:

needrestart -r l

Restart the affected services

Warning: restarting services interrupts them. Do it in a maintenance window, and when working over SSH, keep a second session or console access open. If needrestart is set to restart automatically (-r a), it doesn't ask first.

Restart each unit found above, for example:

systemctl restart example.service

If PID 1 is in the list, re-execute systemd instead of rebooting. Log out and back in, or end old sessions, for user processes. A reboot is the blunt but complete option. This is the same restart process as in the OpenSSL DSA-6531-1 libssl3t64 restart walkthrough, just for a different library.

systemctl daemon-reexec

Verify after the update

Check the package version again, then run the /proc loop again (it should print nothing), or check that needrestart -r l no longer lists any services:

dpkg-query -W -f='${Package}\t${Version}\n' liblzma5 xz-utils
needrestart -r l
liblzma5	5.8.1-1+deb13u2
xz-utils	5.8.1-1+deb13u2

Remember that xz --version still shows 5.8.1. That's expected, and it isn't a sign the update failed.

Mitigation if you can't patch yet

No upstream workaround exists. As a stopgap, a service that unpacks untrusted archives can refuse anything that isn't .xz before passing it to liblzma: reject .lzma and .lz uploads by magic bytes, not by file extension. Also run decoders in short-lived, sandboxed worker processes instead of one long-lived process that reuses its stream. The second measure is good practice anyway, and the systemd options in sandboxing systemd services on Debian 13 make it cheap.

What to watch next

  • CVE assignment: follow bug #1147318 and the tracker entry TEMP-1147318-639065. When a CVE is assigned, the tracker will swap the TEMP ID for it, and scanners that only match CVEs will start flagging unpatched hosts.
  • A DSA-6549-2: backports sometimes need a regression update. Watch debian-security-announce, as with the rsync DSA-6527-1 update.
  • Other 5.8.4 fixes: the upstream release also fixed a xz --list slowdown on crafted concatenated files, use-after-free bugs in the CLI, and an xzgrep option-parsing bug. The sources I read don't say whether Debian's trixie backport includes these. Check apt changelog liblzma5 before you assume it does.

Takeaways

  • DSA-6549-1 was published on 2026-10-07. No CVE has been assigned yet. The upstream advisory is GHSA-5qpq-xqfv-j9pg, and Debian tracks the bug as #1147318.
  • Debian 13 is fixed in 5.8.1-1+deb13u2. +deb13u1 is vulnerable.
  • Only the .lzma, .lz and MicroLZMA decoders are affected, and only when a process reuses a decoder after an allocation failure. .xz decoding is not affected.
  • Patch every host, but restart services that decode untrusted archives first.
  • Look for liblzma.so.5 marked (deleted) in /proc/*/maps and keep restarting until nothing shows up.
  • Check the version with dpkg-query, not xz --version.

Sources

Comments