It's unfortunate that some platforms got dropped, but OTOH all these platforms seem to be 30 years old, niche, and discontinued by their original manufacturers.
If someone has antique computer that still works, that's great, but they shouldn't expect to have the latest software for it.
Rust supports musl and a bunch of BSDs, so if something broke with their packages, it should be only a matter of fixing the builds. That's a much smaller problem than adding a new old architecture to LLVM and rustc.
It's not just about adding new architectures to LLVM and rustc, it's also about bootstrapping supported architectures on all architectures supported by a distribution.
This isn't fully done in Alpine yet, and took a long time to do in Debian.
This is the sort of opinion that evaporates once you become the victim of what’s happening here.
IMO Rust should have a C backend, then the maintainers could drop it as a build dependency and not break existing platforms. Though I expect there to be political reasons for Rust’s conspicuous lack of a C backend.
There's mrustc which compiles Rust to C. Rustc itself supports two back-ends now (LLVM and cranelift), so more should be possible if someone wanted to contribute and maintain them.
I don't think there's any ideological opposition to having more back-ends. It's just a huge amount of work, and is lacking volunteers, especially for niche platforms.
The amount of work doesn’t seem to be the limiting factor. Rewriting large amounts of C code into Rust is a lot of work too but that doesn’t stop Rust justice warriors from doing that.
For one, respected community member pcwalton has argued against compiling to C, citing the difficulty in producing performant, memory-safe output.
For another, from personal experience, I can comment that compiling to C in such a way that doesn't leak abstractions left and right is quite challenging. It's pretty hard to produce memory-safe C, so it's a ton of work, and the payoff is pretty marginal, as the most important platforms already are supported by LLVM.
For the most part, that can be worked around as well, with careful use of unsigned arithmetic. See https://git.yzena.com/Yzena/Yc/src/branch/master/include/yc/... for some examples. All arithmetic is unsigned, but I use it to simulate 2's complement signed.
That is not difficult to avoid if you are generating short primitives. You can for the most part just convert the LLVM bitcode that the Rust compiler would output to the equivalent C snippet. Since each snippet is short, you can trivially check if it invokes undefined behavior. LLVM bitcode also can exhibit undefined behavior.
I think there are alternative implementations that are (much) less mature than rustc.
And I wonder if using those implementations would be good for a project, that requires security...
If you are using open source packages in a corporate setting you really should be
a) pinning versions
b) maintaining secure, internal mirrors instead of always pulling from Github etc.
That would prevent breaking your builds without being intentional about it, regardless of what changes upstream introduces.
There is a lot of "right side of history" / "get with the program" smugness coming from the Rust camp, this bug report and other discussions. Claims of improved security are used as an ultimate, unbeatable-by-definition, trump card.
This might prove right eventually - or might very well end up just like Java, for which similar claims were made. The smugness around Java was moderated a bit by the more corportey image of it, but the gist was quite similar nonetheless. Let's just say openly: the smugness is using up a lot of natural goodwill, and generating its own pushback. As there's no widely acknowledged "equal competitor" to Rust (why?), something feels "off" about the whole situation.
One of they devs did say "C is a bad language to implement parsers for e.g. ASN.1". Unfortunately, there are enough examples out there [0] to prove him right. Not all of them will be mitigated by Rust (e.g. something like CVE-2019-17359), but it's probably worth it long-term (idk, i don't feel the pain of security issues day-to-day, only occasionally).
there are a few Rust ASN implementations. They've been caught running out of memory and having arithmetic overflows, but no segfaults or use-after-frees. Rust doesn't prevent all problems, but things that slip through tend to be less severe.
Many users care much more about working software than they do secure software until suddenly they have a major live exploit on their stuff. This causes many people in the security world to get very tired of the whiplash cycle of "No we don't want to fix this issue it's probably minor" until "Oh my god, why didn't you fix this it caused us millions of dollars in losses" hits.
Especially in the security hardware world, getting customers to upgrade is like pulling teeth.
It would be hard to find a thing you can do in Rust that cannot be equally well or better done in C++.
Any safety that can be provided by a library+Rust can be provided by another library+C++, with only a different apportionment of responsibility between library and language.
pyca/cryptography replaced C code with Rust code without bumping the major semver. This broke people's CI because it removed support for certain platforms which Rust barely supports or doesn't support at all. People are arguing over this change in the github comments, but the problem from my perspective is just with semver. The maintainers didn't do semver right.
Edit: the maintainers didn't do semver right because the maintainers didn't do semver
Python is all over the place with versioning, making it hard to predict what scheme anyone is using. People either falsely assume semver or just don't do any version constraints, both leading to problems. Whats unfortunate, is the Poetry project is putting their head in the sand on this and not letting you patch transitive dependency versions [1]
Even if they did use semver, its still a contentious topic within projects using semver of what all is "included". Some people take an idealistic perspective of "if it might break me" but any change can break them [2], making it impractical. I've seen others take this as a sign that semver is impractical and shouldn't be used. I feel its a limited but useful communication tool; we have to accept imperfections in its use.
Yes; it’s particularly bad when you mix languages like this.
I maintain the nodejs foundationdb libraries. Fdb doesn’t have a published wire protocol - bindings are expected to wrap a dynamically linked C library which contains the protocol implementation and net code. And that library is very “clever” - it leans heavily on codegen (via mono) and hand written asm to support a high performance actor model internally. The downstream effect is that FreeBSD support for database clients has only been added recently. There’s no native Apple M1 client support. There’s been issues with code signing in Java ... and so on. Generally you can only talk to a foundationdb server from an x86_64 client that runs Linux/macos/windows. Which is arbitrary and frustrating.
I hope wasm/wasi eventually becomes the standard for libraries like this. Then the binaries/packages we distribute can work in different languages, different OSes and different architectures without needing all this drama. Wasm bundles fit perfectly in pip/npm/etc. Write them in any language you want and they run fast & run everywhere.
I'm torn on this, In the past, I've been broken by changes breaking me.
On the other hand, you have you have an open source project that has to deal with the schedule/quality/cost trade off and people are expecting support for particular platforms without there being funding coming in to support those efforts. How much free work do they do so other people's company's continue to function?
Yeahhh, I understand the frustration of a breaking change to the build system, but I don't understand the vitriol at the maintainers.
Ultimately, projects upgrade/move. If you are dependent, that's something you need to deal with. If you're not ready to deal with it, then pin your dependencies until you are.
Many of the issues in the thread aren't necessarily problems with cryptography - for example pip not being able to deliver wheels to Alpine.
.. and to pin dependencies, or expect the occasional CI breakage. (you could argue a major version bump would've been nice instead of a minor one. but i don't even want to open that can of worms.)
Honestly, even with minor versions, I'd prefer to use something like dependabot, or for a bot to open a pull request bumping versions. Tons of authors mess up semver in subtle ways, it's just much easier to avoid problems if you just pin dependencies.
I've started doing this with Nix for my own Rust projects, using the technique described here[1]. Planning on setting up a GitHub workflow to automatically open pull requests with bumped versions of nixpkgs/rust.
Its not clear cut what all is included with semver. Is switching from a C89 to a C99 a semver-breaking change? Is using a Python 3.1-specific function a semver-breaking change? Is fixing a bug or adding a new feature a semver breaking change [1]?
There is no clear cut answer in all of these situations and applying purity tests to semver instead just push another crowd of developers to abandon semver completely, making it hard to get any information communicated from your dependencies up to you.
I’m not discounting the pains that some people are going through because of this change, but this response [1] in the issue says
> The new Rust code adds exactly 0 (zero) runtime packages to Cryptography. Rust, Cargo, pyo3, its dependencies, and setuptools_rust are build-time dependencies only.
Aren’t there tools available to build this on a supported platform and integrate the binaries in the systems in use? It is a bit convoluted, but seems like a solution at least for some (?) cases at additional cost.
There is no standard in the Python community for versioning. From this, a lot of projects just never constrained their versions while a lot of other projects assume semver when specifying their version constraints, both wrong.
Then there is the problem of there not being a standard dependency management system. Your `setup.py` can specify version constraints. You either over-constrain in there or have to add a whole separate process for locking your constraint.
- You could use `pip-compile` to get a platform-specific locking of constraints, requiring you to run this for every platform and python version you support. At least, since you duplicate `setup.py` into a `requirements.in`, you can override transitive dependencies.
- You could use `pipenv` and just capture what you happened to install, from constraints or directly, from a specific machine
- You could use Poetry which solves most of these problems except they've put their heads in the sand regarding how bad versioning is within the Python ecosystem and refuse to support overriding transitive dependencies despite being modeled off of Rust's Cargo which does support it despite the Rust ecosystem being good with versioning [1]
It depends on how you want to pin. You probably always want the latest API compatible version for a package like cryptography. But as I read from that thread, it seems cryptography doesn't use semver, thus you doing something like `>=3,<4` is not really feasible. In addition, this change was introduced at 3.4.
I disagree. If the library follows semver, or has a predictable way of managing its versions, I would personally set it as broad as possible without breaking compatibility. Especially with something like cryptography. If a critical bug is found, you don't wanna be stuck at a version from a few years ago. Setting a broad pinned version allows you to update this as part of your day to day development.
If someone has antique computer that still works, that's great, but they shouldn't expect to have the latest software for it.