Live data from Hacker News

NixOS Reproducible Builds: minimal ISO successfully independently rebuilt

discourse.nixos.org

101–110 of 179 posts

Re: NixOS Reproducible Builds: minimal ISO successfully independently rebuilt

#101
post #80

Earlier quoted context omitted.

I can see why devs would want "This Software was built on 10/10/2007 by bob7 from git hash aaffaaff" to appear on the splash screen of software. How do you get similar behaviour while having a reproducible build? Can you, for example, have the final binary contain a reproducible part, and another section of the elf file for deliberately non-reproducible info?

if you have a reproducible build, then the notion of "software was built on date by user " is kind of useless information, no? Because it does not matter - if you can verify that a specific git hash of a codebase results in a particular binary through reproducible builds, a malicious adversary could have built it yesterday and given it to me and i can be almost surely confident (barring hash-collisions...) it's ident…

The usecase is: user wants an easy way to know, from the GUI of some running software, exactly what build/version/git commit/branch/date they're running - perhaps to file a bug report for example.

The actual build date doesn't matter if the software is reproducible - but its a proxy for 'how out of date is this software'.

Re: NixOS Reproducible Builds: minimal ISO successfully independently rebuilt

#102
post #30

Earlier quoted context omitted.

This[0] is basically the hand-documentation of those bytes then. Handwritten ELF header and assembly code. [0] https://github.com/oriansj/bootstrap-seeds/blob/master/POSIX...

Just had a read of this to see what it did... And I must admit, I don't understand what purpose this is supposed to serve. All it seems to do is convert hex into binary and dump it to a file. Not sure how that's any more useful than just copying the binary for next stage directly, after all this binary had to get on the system somehow.

The program does also dispose of comment lines.

One could argue that this is just a kind of trick so they can say the next "binary" is actually a "source" file because it happens to be written by a human in ASCII.

Still the phase distinction between what is a source and what is a binary becomes blurry at this low level. I believe the next stage of compiling is to, writing in ASCII represented machine code with comments, to allow for the existence of labels and then compute offsets for jumps to labels. And then more and more features are added until you have a minimal assembler letting you write somewhat machine independent code, and then continuing to work you way up the toolchain.

So at which point does the translation from "source" to "binary" become a real thing and not just a trick of semantics? Is it when we have a machine independent assembly code? Is it when we computed offsets for labelled jumps? It is when we started stripping comments out of the source code?

Re: NixOS Reproducible Builds: minimal ISO successfully independently rebuilt

#103
post #89

Earlier quoted context omitted.

I think they meant if you cast a pointer to an integer, do some math on that and then store that. Then you will a stored result that will likely differ from run to run

That sounds like runtime differences not a difference between two binaries

The difference in binaries must be caused by some runtime difference of a compiler.

Re: NixOS Reproducible Builds: minimal ISO successfully independently rebuilt

#104

Earlier quoted context omitted.

I can see why devs would want "This Software was built on 10/10/2007 by bob7 from git hash aaffaaff" to appear on the splash screen of software. How do you get similar behaviour while having a reproducible build? Can you, for example, have the final binary contain a reproducible part, and another section of the elf file for deliberately non-reproducible info?

Yeah, "who built this" information belongs in a signing certificate that accompanies the build artefact, not in the artefact itself. The Git hash can certainly appear in the binary (it's a reproducible part of the build input), and the date can instead be e.g. the commit date, which is probably more relevant to a user anyway.

Much as I like Git, I'm not sure I like the idea of the artefacts depending on the git commit and therefore on the entire git history. I rather feel the artefacts should only depend on the actual source and not on a particular version control system used for storing the source.

Re: NixOS Reproducible Builds: minimal ISO successfully independently rebuilt

#105
post #81

Earlier quoted context omitted.

a very common one is pointer values being different from run to run and across different operating systems. Any code that intentionally or accidentally relies on pointer values will be non-deterministic

Would be nice if you could explain how/why this happens, given that normally, pointers aren't persisted.

Languages such as Standard ML and others (Scheme? Lisp? Not sure...) have implementations that can save the current state of the heap into a binary.

This is used in theorem provers, for example, so that you don't have to verify proofs of theorems over and over again (which can be very slow).

Instead, you verify them once, save the state of the heap to disk (as a binary ELF, for instance) and then you can run the binary to continue exactly where you left off (i.e. with all the interesting theorems already in memory, in a proved state).

This is what the HOL4 theorem prover's main `hol` script does, i.e. it runs HOL4 by loading such a memory state from disk, with the core theories and theorems already loaded.

Presumably, to make this reproducible you'd need to make sure that all the memory objects are saved to disk in a deterministic order somehow (e.g. not in memory address order, as it can change from run to run, especially when using multiple threads).

Edit: Presumably you'd also need to make sure that you persist the heap when all threads are idle and in a known state (e.g. with all timers stopped), to avoid random stack states and extraneous temporary allocations from being persisted, which would also affect the resulting binary.

Re: NixOS Reproducible Builds: minimal ISO successfully independently rebuilt

#106

Stupid question as I never worked on something like this before: why isn't reproducibility the default behavior? I mean if 2 copies of a piece of software were compiled from the same source, what stops them from being identical each and every time? I know there are so many moving parts, but I still can't understand how discrepancies can manifest themselves.

A surprising amount of compiler and program behavior depends on how pointer values compare.

These comparisons don't have to go the same way for everything to be correct.

Re: NixOS Reproducible Builds: minimal ISO successfully independently rebuilt

#107

Earlier quoted context omitted.

Would be nice if you could explain how/why this happens, given that normally, pointers aren't persisted.

Languages such as Standard ML and others (Scheme? Lisp? Not sure...) have implementations that can save the current state of the heap into a binary. This is used in theorem provers, for example, so that you don't have to verify proofs of theorems over and over again (which can be very slow). Instead, you verify them once, save the state of the heap to disk (as a binary ELF, for instance) and then you can run the bina…

Thanks, yeah. So I guess the concrete example I would cite here is that the most natural (and most efficient?) way of persisting std::map would introduce pointer ordering into the output.

Re: NixOS Reproducible Builds: minimal ISO successfully independently rebuilt

#108
post #34

Earlier quoted context omitted.

Parallelism. There might be actions that are not order-independent, and the state of the CPU might result in slightly different binaries, but all are correct.

Why does this matter though? Why does order of compilation result in a different binary?

Because order of completion of the parallel tasks is not guaranteed, if all tasks write to the same file you might get a different result each time.

Re: NixOS Reproducible Builds: minimal ISO successfully independently rebuilt

#109

Earlier quoted context omitted.

> but it is not a question of the reproducibility of the binaries (which can change at each build). This binary reproducibility of Nix / NixOS / Nixpkgs is indeed not really tested, at least not systematically. Isn't that exactly what your first source and OP are about? They check that the binaries are the same when built from the same sources on different machines. The point is exactly that the binaries don't change…

Yeah, that represent maybe 1% of the packages in nixpkgs (only the installation iso).

Sure but the goal is the same, binary reproducibility, and it is systematic. It's just less far along than Debian.

Also I'm pretty sure a big percent of nixpkgs is already reproducible, we just don't know for sure.

They say the next step might be the GNOME-based ISO, which would be a big achievement because it's basically a full-featured system.

Re: NixOS Reproducible Builds: minimal ISO successfully independently rebuilt

#110

Earlier quoted context omitted.

Just had a read of this to see what it did... And I must admit, I don't understand what purpose this is supposed to serve. All it seems to do is convert hex into binary and dump it to a file. Not sure how that's any more useful than just copying the binary for next stage directly, after all this binary had to get on the system somehow.

The program does also dispose of comment lines. One could argue that this is just a kind of trick so they can say the next "binary" is actually a "source" file because it happens to be written by a human in ASCII. Still the phase distinction between what is a source and what is a binary becomes blurry at this low level. I believe the next stage of compiling is to, writing in ASCII represented machine code with commen…

Yeah, I kind of agree, but my issue is kind of with this statement (in the link from the peer post):

> What if we could bootstrap our entire system from only this one hex0 assembler binary seed? We would only ever need to inspect these 500 bytes of computer codes. Every later program is written in a more friendly programming language: Assembly, C, … Scheme.

And my issue is that this isn't true. hex1 isn't written in assembler any more than hex0 is. Both of those bootstrap files can get onto the system simply by ignoring whitespace and anything after #, converting the hex into binary and writing it to a file.

Having hex0 doesn't add anything to the mix, other than being shorter than hex1, because you still have the same initial bootstrap problem of how you can prove that the hex0 binary represents the hex in its source vs the hex1 binary and its source and both have the same problem of needing to prove the hex in the source matches the assembly (and that the program even does what the comments claim).

hex1 is a more useful bootstrap point, because you can use standard system tools to create the binary from the source (e.g. sed) and also compile itself and verify that the files are the same.

Having hex0 and hex1 just means you need to manually verify both rather than just hex1.

I guess my point is that if you have insufficient trust in your system that you can't e.g. trust "sed" to create the original binary files, or trust the output of "dd -x" or "md5sum" to verify the binary files, you also can't trust it enough to verify that the hex in those source files is correct or that the binary files match.

Post reply on HN