winapi-rs is a Rust crate that provides raw foreign function interface (FFI) bindings to the entire Windows API from Rust. This gives Rust applications on Windows direct access to the Windows API. This dramatically improves the functionality and performance of Rust on Windows. The developer, Peter Atashian, gathered each API call by hand from the Windows 10 SDK.

winapi-rs is packaged into the GNU/Linux distribution Debian by the Debian Rust Maintainers as librust-winapi-dev. The Debian Rust Maintainers, among them Ximin Luo, built custom tools, such as debcargo, to package Rust crates for Debian. There was a proposal to patch the low-level Debian packaging tool dpkg to accommodate two-sided version constraint ranges to properly translate Cargo dependencies. This was marked as a wishlist item due to the task's complexity.

The Debian Rust Maintainers began pushing Rust crate Debian packages as librust-*-dev to Sid, the unstable bleeding-edge branch of Debian, in the middle of 2018.

As a temporary workaround to the two-sided version constraint issue, multiple version numbers of the modules inside each Rust crate are listed in each crate Debian package. The policy and implementation are documented in the Debian Wiki.

This, however, resulted librust-winapi-dev having 1336 packages, which is a 57kB string, in the 'Provided' field in its Debian package Control file, the main configuration file of a Debian .deb package:

Meanwhile, cdebootstrap, is a utility for bootstrapping images of Debian from Debian. It is a tool used in the process of building Pengwin, custom Debian images, and other Debian derivatives. It is a higher performance rewrite in C of an older collection of scripts for the same purpose, debootstrap. When generating bootstrap images of Debian cdebootstrap relies on the library libdebian-installer4 which provides various useful functions for installing packages Debian.

The problem arose when libdebian-installer4 went to parse all available apt packages to check dependencies on Sid and hit librust-winapi-dev.

Why? The parsing function, parser_rfc822.c in libdebian-installer4, had set:

#define READSIZE 16384

Yes, just 16,384 bytes.

The string of "Provides" in the librust-winapi-dev Debian package control file could not fit in the pre-defined memory constraints of libdebian-installer4, because it has 74,885 bytes of data, and it broke cdebootstrap.

This bug made it into Debian testing and then into Buster when it reached stable status. It was patched in libdebian-installer 0.119.

For about six months we patched around the bug by providing our own libdebian-installer4 for Pengwin. We later dropped that on our development branch, which allowed us to unify our x64 and arm64 build scripts and was used to build Pengwin 1.3 images.

But that is how the Windows API (and Rust!) ended up temporarily breaking Debian Stable.

  • Use Rust on Windows? Peter's Patreon is here.
  • Thank you to everyone who works on Debian and maintains the low-level tooling to build and adapt the Debian Universal Operating System.