July 10th, 2024

At the Mountains of Madness

The blog discusses challenges in building executables for NixOS and Linux, focusing on ELF interpretation, glibc versions, and dynamic linking. It explores container use, NixOS dependency management, and proposes patchelf for cross-compatibility.

Read original articleLink Icon
At the Mountains of Madness

The blog post titled "At the Mountains of Madness" by Will Wilson, CEO of a company, discusses the challenges faced when building native executables and shared libraries for both NixOS and other Linux distributions. The post delves into the complexities of ELF program interpretation and loading, highlighting issues with glibc versions and dynamic linking. It explores the use of containers and the unique approach of NixOS in managing dependencies. The author shares insights on resolving conflicts between different Linux environments and the limitations of static linking glibc. The post concludes with a proposed solution involving the use of a utility called patchelf to modify ELF headers for cross-compatibility. Overall, the narrative provides a detailed account of the technical intricacies encountered in software packaging and deployment across diverse Linux platforms.

Related

Nickel Modules

Nickel Modules

Nickel, a programming language inspired by NixOS modules, introduces a merge system for defining complex configurations modularly. It addresses NixOS module system limitations, offering enhanced error handling and consistency for structured configurations.

Mix-testing: revealing a new class of compiler bugs

Mix-testing: revealing a new class of compiler bugs

A new "mix testing" approach uncovers compiler bugs by compiling test fragments with different compilers. Examples show issues in x86 and Arm architectures, emphasizing the importance of maintaining instruction ordering. Luke Geeson developed a tool to explore compiler combinations, identifying bugs and highlighting the need for clearer guidelines.

Parallel Nix Evaluation

Parallel Nix Evaluation

The blog post discusses Nix's speed impact on user experience due to Nixpkgs and NixOS growth. Determinate Systems' parallel evaluator boosts performance 3-4 times, addressing immutability challenges for faster evaluations. Ongoing work targets concurrency bugs.

The weirdest QNX bug I've ever encountered

The weirdest QNX bug I've ever encountered

The author encountered a CPU usage bug in a QNX system's 'ps' utility due to a 15-year-old bug. Debugging revealed a race condition, leading to code modifications and a shift towards open-source solutions.

Booting Linux Off of Google Drive

Booting Linux Off of Google Drive

A programmer's competitiveness leads to booting Linux from Google Drive, facing challenges like networking setup and mounting an Arch Linux root from an S3 bucket. Despite setbacks, Linux boots successfully, integrating Google Drive but facing performance issues and complexities.

Link Icon 13 comments
By @dreamcompiler - 4 months
I once had a robotic cat litter box that cleaned itself. Except once a week it would get clogged and I would have to spend a quality hour disassembling it, scrubbing off the feces embedded on the delicate parts, and reassembling it. Every two weeks when it heated up its artificial litter to dry, it would have missed a small piece of cat shit that when baked, filled my house with an aroma that I would not recommend you even try to imagine.

And of course it needed special, expensive supplies that you had to buy from the manufacturer because the bottles had numbered chips.

I eventually threw the damn thing out and now I just use a manual litter box. Takes 15 seconds a day to clean. It's a chore but it's a small predictable chore.

When I read about NixOS I remember that robot litter box. It seems like it solves a real problem of difficulty X but it brings five brand new problems from a parallel universe you didn't know existed and they're all written in an indecipherable language and have difficulty 10X.

By @finnh - 5 months
Every time I look at NixOS, I think that it perfectly solves a problem that I only have once every 5 years, when buying a new computer. I think I even looked into it once to automate that exact process, but that idea fell apart at the first line of Nix syntax. I'll stick with OSX and `brew bundle` I guess...

But then I read a piece like this and remember that some people do have to plumb the depths of C/C++ linkers, and I'm glad I'm not one of them.

Great post! FWIW I always want to know the prompt text when seeing an AI-generated image, I wish there were a convention around that.

By @sjburt - 5 months
It seems like every article about nix goes on and on about DLL hell. I've been using Debian/Ubuntu for 15+ years and never really experienced dependency hell. I guess maybe this is thanks to hard work by Debian maintainers and rarely needing to run a bleeding edge library, but also, why do we need to run bleeding edge versions of everything and then invent an incredibly complicated scheme to keep multiple copies of each library, most of which are completely compatible with each other?

And then when there's a security problem, who goes and checks that every version of every dependency of every application has actually been patched and updated? Why would I want to roll a system back to an (definitely insecure) state of a few months ago?

What problem does Nix solve that SO numbers (properly used) doesn't?

I have many of the same questions about Snap and even Docker.

By @klodolph - 5 months
> No such file or directory

Anyone who’s run into this problem remembers it! (This isn’t a Nix problem—this is just the baffling errors you get because a.out exists, but one of the libraries it needs does not, and the error message doesn’t distinguish that case.)

Anyway, Nix.

Nix has the Nix way of building things. Nix doesn’t give you standard tools. It gives you wrappers around the standard tools that force you to do things a certain way. Part of that is futzing around with RPATH—because Nix stores everything in an unusual location. The user experience around this is awful, if you ever run into a case where Nix’s tooling doesn’t automatically do the right thing for you. It’s not just RPATH, but also other paths.

What’s the solution?

Honestly—I think it would make sense for Nix to have a “cross compilation” mode where you tell it to cross-compile for other Linuxes. You know, something like pkgsCross.x86_64-generic-linux. This comes with all the cross-compilation headaches, but you know what? You are cross-compiling.

By @wwilson - 5 months
Post author here. Feel free to ask me any questions about the piece of software that I most regret having had to write.
By @georgewsinger - 5 months
=======Technical Summary========

Here's a problem with NixOS:

1. Suppose we have a `./nixos_binary_program_with_glibc-newer` compiled on a NixOS machine against bleeding edge `glibc-newer`.

2. `./nixos_binary_program_with_glibc-newer` will have `/nix/store/glibc-newer/linux-ld.so` path hardcoded into its ELF header which will be used when the program launches to find all of the program's shared libraries, and so forth. (And this is a fact that `ldd` will obfuscate!).

3. When `./nixos_binary_program_with_glibc-newer` is distributed to machines which use `glibc-older` instead of `glibc-newer`, the hardcoded `linux-ld.so` from (2) will fail to be found, leading to a launch error.

4. (3) will also happen on machines which don't use nix in the first place.

=======Will's Solution========

1. Use `patchelf` to hardcode a standard FHS `ld-linux.so` location into `nixos_binary_program_with_glibc-newer`'s ELF header (using e.g. `/lib64/ld-linux-x86-64.so.2` as the path)

2. Use a metaloader to launch `nixos_binary_program_with_glibc-newer` with an augmented `RPATH` which has a bunch of different `/nix/store/glibc-newer` paths, so that nix machines can find a suitable `ld-linux.so` to launch the program with.

This will make `nixos_binary_program_with_glibc-newer` work on any machine, including both non-nix machines and nix machines (which might be running older versions of glibc by default)!

By @AdamH12113 - 5 months
I'm still confused why static linking isn't a more common solution to versioning issues. Software developers normally have no problem using an order of magnitude more resources to solve organizational problems. Is there any technical advantage to dynamic linking other than smaller binaries and maybe slightly faster load times from disk?
By @banish-m4 - 4 months
Completely missed that Nix solves RPM dependency hell, which is a superset of the shared library hell.

Another problem not solved by NixOS and most other distros is conflating and mixing dependencies in a messy, fragile way rather than having a clear separation between the OS and add-ons that FreeBSD and others have. Congruent with this is proper configuration and lifecycle management.

I'm also wondering about the security of this RPATH approach, if it does or doesn't introduce vulnerabilities.

By @bbor - 5 months
I love what they’re going for, but I couldn’t help but react negatively at finding out that I had been hyped up for a post on some small technical topic for an OS I don’t know of. Maybe title it “At the Mountains of NIXos Madness”? But then again I’m just a grouch! Well written article regardless, from what I was able to get out of it
By @pizzalife - 5 months
Calling binaries using ld-linux used to be a popular way to get around noexec on filesystems, since the libraries are usually in a place that is executable..
By @NoraCodes - 5 months
What is that abominable diffusion output doing at the top of an otherwise interesting article?
By @dhash - 5 months
I loved this post, and patchelf is a real gem of a utility.
By @DoreenMichele - 5 months
tl;dr: we are open-sourcing an internal tool that solves a problem that we think many NixOS shops are likely to run into. The rest of this post is just the story of how we came to write this tool, which is totally a skippable story.

The tool happens to be called Madness, thus the Lovecraftian reference in this piece.

Madness enables you to easily run the same binary on NixOS and non-NixOS systems

https://github.com/antithesishq/madness