Tukaaani xz_util vulnerability

Latest version has vulnerable version.

Latest version coming in next release

should include 5.6.2 or later version of library file

Are you saying the latest version of graphviz has a vulnerable xz version? Which graphviz version?

Yes Hanson,

I am on Graphviz 16.1.0, I see xz_util version 5.4.4. While the vulnerability is fixed in 5.6.2 or higher library.

@magjac this appears to be coming from the Windows dependencies repo, added in b38f14949fdef376c690cb0abfad9120ea21a15d.

5.6.2 is not the latest version of XZ Utils, so I assume what you’re referring to here is the infamous backdoor fixed in 5.6.2. Note that this was introduced in 5.6.0, so the liblzma 5.4.4 bundled here is not affected. Having said that, there appear to have been numerous other CVEs fixed in the range (5.4.4, 5.8.4].

I know 5.8.2 is the latest one, but lower version are impacted, i can see them in defender as vulnerable. Can you share artifact where it says not vulnerable for 5.4.x?

I no longer have access to a Windows development environment.

Can you share what defender is saying?

So I guess the conclusion is, yes, this is a problem, but there are no remaining Graphviz maintainers with the capability to fix it.

This (outdated libraries being bundled in the Graphviz installers) would also explain why these installers are regularly flagged as malware on Virus Total.


For anyone wanting to attempt a fix… my suggested solution would be to stop bundling libraries and instead rely on a packaging ecosystem. This would involve, in order:

  1. Package Graphviz’s dependencies for some Windows ecosystem. Chocolatey/WinGet/vcpkg/NuGet/… I don’t know what the flavour of the month is right now.
  2. Modify the way Graphviz’s Windows installers are constructed in CI to have them require the dependencies created in (1).
  3. Modify Graphviz CI to no longer retrieve our mirrored (outdated) dependencies.
  4. Drop the windows/dependencies/libraries submodule from the Graphviz repository.

I’m willing to guide someone through this. But I have no Windows machines and know little about Windows. Anyone attempting this will also have to confront the slowness of Gitlab’s Windows runners – a naive attempt to do the above will most likely hit timeouts in CI.

Not sure I can help much with Windows, but wondering where the graphviz dependency on xz is defined, and why we can’t ā€œjustā€ move to a newer version of xz, instead of having to overhaul the build process. Or, can we just drop our Windows packaging, and send people to Chocolatey? They are on Graphviz 16.1.0.

It appears to be a transitive dependency of libgd, https://gitlab.com/graphviz/graphviz/-/blob/1fb95e4d0fd8f26bca5be54ecc83602bafcdfb2c/cmake/FindGD.cmake#L17. Though I can’t say I understand exactly why or how, given our libgd comes from vcpkg and liblzma is not listed as a dependency of it there, https://vcpkg.io/en/package/libgd

I will quote the message of one of the commits that added libgd:

Installed with:

./vcpkg/vcpkg.exe install --recurse --clean-after-build --host-triplet=x64-windows libgd
./vcpkg/vcpkg.exe export --raw --output=libgd-x64-vcpkg-export --host-triplet=x64-windows libgd
cp -rp vcpkg/libgd-x64-vcpkg-export/* ~/graphviz/windows/dependencies/libraries/vcpkg

So I think only someone with a Windows machine can replicate these steps to overwrite it with an updated copy.

I don’t think so, because they just run our CMake installer. I.e. The Chocolatey Graphviz package is actually relying on us for packaging right now. I would love to reverse this situation, but AFAIK none of our dependencies are packaged in Chocolatey.

I’ve managed to spin up a windows VM in Google Cloud and I think I’ve got enough of a tool chain setup to rerun the vcpkg tool above (it’s churning away at least). This is the first time I’ve run windows in 15 years, so it’s been quite a journey already. I doubt I’m in a position to ā€˜support’ graphviz on Windows.

It appears to be a transitive dependency of libgd, https://gitlab.com/graphviz/graphviz/-/blob/1fb95e4d0fd8f26bca5be54ecc83602bafcdfb2c/cmake/FindGD.cmake#L17. Though I can’t say I understand exactly why or how, given our libgd comes from vcpkg and liblzma is not listed as a dependency of it there, vcpkg package - libgd

If I’m reading the output of vcpkg correctly, then libgd depends on tiff and tiff depends on liblzma (which makes some kind of sense):

PS C:\Users\robhart\Repos\libgd> vcpkg install --recurse --clean-after-build --host-triplet=x64-windows libgd
Computing installation plan...
The following packages will be built and installed:
  * brotli:x64-windows@1.2.0
  * bzip2[core,tool]:x64-windows@1.0.8#6
  * dirent:x64-windows@1.26
  * expat:x64-windows@2.8.4
  * fontconfig:x64-windows@2.17.1#2
  * freetype[brotli,bzip2,core,png,zlib]:x64-windows@2.14.3
  * gperf:x64-windows@3.3
    libgd[core,fontconfig,freetype,jpeg,png,tiff,webp]:x64-windows@2.3.3#3
  * libjpeg-turbo:x64-windows@3.2.0
  * liblzma:x64-windows@5.8.4
  * libpng:x64-windows@1.6.58
  * libwebp[core,libwebpmux,nearlossless,simd,unicode]:x64-windows@1.6.0#3
  * tiff[core,jpeg,lzma,zip]:x64-windows@4.7.2
  * vcpkg-cmake:x64-windows@2025-08-07
  * vcpkg-cmake-config:x64-windows@2026-07-21
  * vcpkg-cmake-get-vars:x64-windows@2025-05-29
  * vcpkg-make:x64-windows@2026-07-09
  * vcpkg-tool-meson:x64-windows@1.9.0#10
  * zlib:x64-windows@1.3.2#2

Here is a rendering of your output generated using Copilot.

So I think only someone with a Windows machine can replicate these steps to overwrite it with an updated copy

If it’s any help to anybody, I’ve run those commands and dumped it all into a commit. I notice that some of the filenames contain version strings, and so there are still files left from older runs. I don’t know if there’s any easy way to clean this up without also rerunning the vcpkg for Tcl, pango, etc

I also don’t know how to validate if any of this has actually ā€˜worked’

I appreciate the initiative shown here.

I humbly admit I don’t understand a lot of things about this. From the above, I don’t understand why we would have a problem with a compromised version of liblzma when the above shows liblzma:x64-windows@5.8.4 which according to the internet was just released?

If there’s a problem because of a dependency through libgd, why does that arise two years after the back door problem and is that even something we can fix on our own?

How does fixing a local build then help fix the issue in Graphviz CI or downstream installers like vcpkg? I’m really confused.

Thanks, Rob! I’ll take a look if no one beats me to it.

What Rob has quoted is the dependency tree from an install of libgd today. What’s committed to the Graphviz dependency repo is the dependency tree of libgd from 2024-07-14.

As I said above, the version in the Graphviz dependency repo is prior to the backdoor. I do not believe it is affected by this problem. What it is affected by is every other CVE from this era fixed since then.

As I said above, only really by someone with a Windows machine.

Because the Graphviz installers are how users are acquiring liblzma. At a high-level:

  • Linux users apt install graphviz (or dnf install graphviz or …). The Graphviz package they get this way contains Graphviz and nothing more. It is the job of apt to retrieve libgd, and then transitively liblzma. When there is a security issue in liblzma, Linux users acquire the fix by the liblzma package getting an update.
  • macOS users brew install graphviz or port install graphviz. The Graphviz package they get this way contains Graphviz and nothing more. It is the job of Homebrew/Macports to retrieve libgd, and then transitively liblzma. When there is a security issue in liblzma, macOS users acquire the fix by the liblzma package getting an update.
  • Windows users choco install graphviz. The Graphviz package they get this way contains Graphviz and all its transitive dependencies. When there is a security issue in liblzma, the only way Windows users can get the fix is by us updating the Graphviz installer.

(There are other paths to install with other trade offs, but the above documents the most common path on each supported OS as far as I am aware)

Thank you for explaining. I sort of understand. I took at look at graphviz-windows-dependencies and see how the transitive dependency arises, also why it would need to be sorted out locally and then merged.

I’m confused why this is all different from what CI does. Looking at recent CI runs from windows, they appear to run pacman from msys2 to install libraries. Is that picking them up from the graphviz-windows-dependencies repo, or from some other upstream? I’m not familiar with how gitlab CI works or is configured.