Serde, a popular Rust (de)serialization project, has decided to ship its serde_derive macro as a precompiled binary.
The move has generated a fair amount of push back among developers who worry about its future legal and technical implications, along with a potential for supply chain attacks, should the maintainer account publishing these binaries be compromised.
According to the Rust package registry, crates.io, serde has been downloaded over 196 million times over its lifetime, whereas the serde_derive macro has scored more than 171 million downloads, attesting to the project’s widespread circulation.
Serde macro goes precompiled: there’s no way to opt-out
About three weeks ago, a Rust programmer using the Serde project in their application noticed something odd.
“I’m working on packaging serde for Fedora Linux, and I noticed that recent versions of serde_derive ship a precompiled binary now,” wrote Fabio Valentini, a Fedora Packaging Committee member.
“This is problematic for us, since we cannot, under no circumstances (with only very few exceptions, for firmware or the like), redistribute precompiled binaries.”
Serde is a commonly used serialization and deserialization framework for Rust data structures that, according to its website, is designed to conduct these operations “efficiently and generically.”
“The Serde ecosystem consists of data structures that know how to serialize and deserialize themselves along with data formats that know how to serialize and deserialize other things,” states the project’s website. Whereas, “derive” is one of its macros.
Valentini further inquired to the project maintainers, how were these new binaries “actually produced,” and if it would be possible for him to recreate the binaries, as opposed to consuming precompiled versions.
David Tolnay, who is the primary Serde maintainer, responded with potential workarounds at the time. But, that’s not to say that everyone is pleased.
Following an influx of comments from developers as to why the decision wasn’t best suited for the project, Tolnay acknowledged the feedback, prior to closing the GitHub issue.
His justification for shipping precompiled binaries is reproduced in whole below.
“The precompiled implementation is the only supported way to use the macros that are published in serde_derive.
If there is implementation work needed in some build tools to accommodate it, someone should feel free to do that work (as I have done for Buck and Bazel, which are tools I use and contribute significantly to) or publish your own fork of the source code under a different name.
Separately, regarding the commentary above about security, the best path forward would be for one of the people who cares about this to invest in a Cargo or crates.io RFC around first-class precompiled macros so that there is an approach that would suit your preferences; serde_derive would adopt that when available.”
BleepingComputer has approached Tolnay with additional questions prior to publishing.
“First .NET’s Moq and now this.”
Some Rust developers request that precompiled binaries be kept optional and separate from the original “serde_derive” crate, while others have likened the move to the controversial code change to the Moq .NET project that sparked backlash.
“Please consider moving the precompiled serde_derive version to a different crate and default serde_derive to building from source so that users that want the benefit of precompiled binary can opt-in to use it,” requested one user.
“Or vice-versa. Or any other solution that allows building from source without having to patch serde_derive.”
“Having a binary shipped as part of the crate, while I understand the build time speed benefits, is for security reasons not a viable solution for some library users.”
Users pointed out how the change could impact entities that are “legally not allowed to redistribute pre-compiled binaries, by their own licenses,” specifically mentioning government-regulated environments.
“…First .NET’s Moq and now this,” said Jordan Singh, an Australia-based developer, in a comment that was later removed.
“If this is to force cargo devs to support a feature then this is terrible way around doing it. At-least give us reproducible binaries. I’m sick of devs of popular crates/libraries taking everyone hostage with absurd decisions.”
Philadelphia-based Donald Stufft cautioned against the risks of getting into the business of “shipping binaries” on social media:
Rust programmer Nathan West, who goes by Lucretiel, specifically highlighted the supply-chain risks posed by precompiled binaries, should the maintainer account get compromised:
“Is not this the exact way they’d go about it? Ship it silently as a semi-plausible change to how serde works, intransigently ignore all criticism of the decision,” wrote West.
“This is *exactly* the reason that everyone has such a reflexive opposition to moves like this.”
“Trust on the internet isn’t perfect; we *don’t* know that that’s really [the maintainer] posting in GitHub. That’s why we have layers and proxies of defense; sketchy sh*t is rejected because it’s not worth the risk.
Technologist Sanket Kanjalkar called the transition to ship binaries without a way of opting-out “a step backward.”
But, a security professional who goes by Lander, has a slightly different take:
“This Rust drama about serde_derive shipping a precompiled binary is kind of funny,” writes Lander.
“On one hand, I understand people’s concern. On the other hand, who cares? nobody’s reading proc macro code/build.rs code for every project they pull in anyways. An opt-out would be a good idea tho.”
Whether you agree with the project’s decision to serve its macros precompiled or not, it is a good practice to routinely inspect any source code and software binaries prior to incorporating these into your projects.
Thanks to Michael Kearns for the tip off.