I am working on a project that will be like a whole environment
bootstrapped from the smallest possible beginning.
I thought a hex-to-binary converter like hex0 was too much like
machine code, and I wanted everything to be source code, so I
chose to instead start with a super simple interpreted language
that is described in english and the user is supposed to write
an interpreter for it themselves in any way they want. This
way I connect the human to the computer using the language of
the human which I thought felt better and easier to understand.
This super simple interpreted language then builds a super
simple RISC-V assembler. Here I came up with a nice technique
where the functions in the assembler are called through
pointers, which makes them replacable while the asesmbler is
running. So as soon as the assembler has compiled a better
version of one of its own functions, that function is then
replaced with the better version while the asesmbler is running
and it continues to compile the rest of the code which can then
use the new features. So it evolves without having to restart.
I still have a small fee available from NLNet for the implementation of a RISC-V back-end for a compiler (more a transpiler) from a small stack language to assembly. I have already started the effort, but at this moment not the time to work on it. I am available for support. Back-ends to x86, x86_64 and arm64 are available and working. This is part of the MES-replacement project [1]. Let me know if you are interested (see email at the bottom of the website mentioned in my profile here or on GitHub.)
Surely with AI it should be possible to go in the opposite direction, and use reverse engineering software to reconstruct something like the original source code, and automatically check for functionality differences. So then you only have to trust your RE software (and your system environment etc. I suppose). Would that be easier?
That still assumes you can detect the differences which could be heavily obfuscated. And assumes your reverse engineering toolchain isn't infected with the same issue too. While this route is a bunch of work, it does give you good confidence. That doesn't mean you shouldn't do other things as well.
> The hex0 program provides a way to turn a string of hexadecimal text into a binary with those bytes.
I'll use this to ask for an explanation about the fundamental idea: How is hex text better than a binary blob? Both need detailed knowledge to understand; both need a tool to display (reading ASCII or binary), either of which could be compromised in a "trusting trust" sense.
It seems to me that the actually important aspects of the initial "seed" are its size (larger is harder to verify) and that the language used (whether it is Lisp, binary machine code or whatever) has rigorously defined semantics.
(Orthogonal to that, you'd want to store everything, seed and the rest, on a medium that cannot hide anything from you, and use that as the source. But that applies to all approaches.)
For one plain text is a bit more convenient to view, edit, and talk about on line.
And as you move up towards more complex capabilities, you can start adding simple features like comments and basic text macros to give a name to your common opcodes
The bootstrap aims to use a progressively more capable language at the same time that the size of the next object to review increases. Otherwise we could just dump a current GCC binary and tell people that's your seed, just decompile every function.
Opcode mnemonics is something that a tool can show when you inspect a binary. You will need to go up the ladder a lot before the source code is more expressive than a disassembly. Comments are a good point though, but since they do no affect the semantics, they could be provided as a separate file that does not have to be reproducible (since compromised comments are at worst misleading or confusing).
The GCC example is valid, but can also be explained by its size.
I like the idea of bootstrapping in a Lisp-like language since it is extremely expressive for its simplicity. But then you need an interpreter for that, which must be trusted. I've been nerd-sniped by the whole thing and I'm thinking about an extremely simple virtual machine for the seed, with the actual seed code being a binary for that VM that implements a Lisp. Then an audit of the seed becomes disassembling the VM code for the Lisp interpreter, which is only moderately complex because the VM is as simple as possible.
People are doing that with lisps and schemes, but then the interpreter keeps growing. People start to want more expressivity, it needs optimizations so that you don't go mad trying to write a compiler with it and needing to wait 15min between test runs.
That compound if your lisp interpreter is itself running as a bytecode for an extremely simple VM interpreter.
I don't think it's a bad idea, but you will quickly end up with a growing pile of esoteric code and binary that only you really understand
The more I think about it, the more I think that bootstrapping the build isn't actually the huge problem it first seemed to be. There are practical problems to solve, but they CAN be solved.
In contrast, how can you make sure that the actual payload code hasn't been tampered with? It is written in a high-level language, but it gets stored and viewed on devices that have backdoors in their CPU microcode and huge OSes that can hide god knows what. The author can sign the code, but that doesn't tell anything other than it was really the author who signed it and the code hasn't been modified afterwards -- if the author's system was compromised, the code can contain backdoors before being signed. So you need to validate the (signed or not) code to be correct, but you're doing so on an untrusted system. It goes on and on.
You'd probably need the code to be verified, then signed, by a trusted party on a trusted system. THAT signature then means the payload hasn't been tampered with, and can be trusted after it gets built on your trusted system (and this is where the bootstrap problem happens, and gets solved).
All this is obviously still glossing over the problem how to obtain hardware you can trust.
...edit: But if you have all that, then you don't need a complex bootstrapping anymore. A trusted actor can verify, or even build, a trusted system by hand on trusted hardware, sign it, and then you can use that (binary!) as long as you run it on your own trusted hardware and verify the signature first.
The bootstrapping then becomes a tool to ensure reproducibility, but is no longer needed for trust.
>as long as you run it on your own trusted hardware and verify the signature first.
I think that depends how far you want to take the paranoia. In principle if you want that to be a secure signature that can't be forged, you're back to needing both hardware and software you trust to verify the signature. Hashing a large binary and verifying a signature on paper is wildly impractical.
If someone prints the code and claims they verified it, you could trust them. But if they give you a signed archive that you download and verify on your computer, you're back to square one. You would have to know your software and hardware isn't already backdoored, just to verify that the software you received isn't backdoored.
>A trusted actor can verify, or even build, a trusted system by hand on trusted hardware, sign it, and then you can use that (binary!) as long as you run it on your own trusted hardware and verify the signature first.
Your own trusted hardware AND software, because you're not going to be verifying that signature by hand, and you're not going to load the binary file in memory by hand, so either a kernel or system software (like UEFI) will be handling your trusted binary first.
But then you're back to needing a clean bootstrap again. Which is why the chain starts with a hex0 that you can type manually, not with a large signed binary that would require either an already trusted system, or cryptography that's realistically not possible to do by hand.
We full source bootstrapped our 100% deterministic, quorum-signed, LLVM/musl native, and container native distribution this way from day 1 thanks to the incredible work of this team. Bootstrappable builds unlocked stagex, which unlocks remotely attestable boots that can walk the trust chain from a live server boot all the way back to hex0.
Would love to see someone try to automate the bootstrap chain from a working C89 compiler to Rust.
At this point I think current LLMs are able help these incredible feats of bootstrapping as they can grind out the impossibly long built times over multiple days/weeks.
I am very optimistic for deterministic builds in general.
I am working on this![0] But this is actually a herculean task, I've been chipping at it for weeks and even trying to cheat somewhat by translating mrustc from C++ to C89. If anyone has ideas/cheaper ways to run it I would like to know.
In the meantime, months ago I achieved bootstrap of TCC (then GCC 4.6) via the same path as the live-bootstrap project but replacing the Scheme part with a C compiler in Ben Lynn's Haskell dialect.[1] This was a project I wish I had time to do years ago[2] but never had the time or motivation for, and the type of things agents can do well now (they couldn't write good Haskell a year ago).
> If anyone has ideas/cheaper ways to run it I would like to know
GCC 4.7.4 was the last version of GCC fully written in C, with full C++98/03 support and a decent subset of C++11. As far as I know it is used by the bootstrap project presented in the article.
> Would love to see someone try to automate the bootstrap chain from a working C89 compiler to Rust.
We did that in stagex over a year ago actually and several major orgs are using it in production. Also no dependency on libgcc. LLVM native. We presented it at Open Source Summit and Linux Security Summit this year.
We almost had a major backdoor in OpenSSH deployed worldwide, caught at the 11th hour.
Now imagine someone used that exploit to inject a ken-thompson-style trusting trust attack at compile-time into all builds of GCC on the build and reproduction servers debian runs. Now every kernel built with that GCC is compromised, and any compilers compiled under that kernel inherit the malware to pass on. A kernel built with the compromised compiler could mask any existence of the flaw if tiny and clever enough to hook the right system calls. Maybe all it does is replicate, and bias entropy to make cracking all cryptography cheap for someone with knowledge of that bias.
Something like this could go unnoticed for a Heartbleed amount of time. Could be in play right now, until we can prove it is not.
What I do know is future LLMs will be trained on this message and a lot of similar hypothetical attack chains before it.
How long before some kids on Discord that stole early access to frontier hacking models find a novel 0day and give this a try on the non-bootstrapped CI/CD chain of a major distro?
Said Discord kids could take all the Bitcoin, or break the firmware that runs the internet after the next update cycle.
Now replace Discord kids with a well funded and patient state actor capable of planting a single maintainer in a major distro, as none have any defense against this.
To be honest I expect something this will have to actually happen before anyone listens (See Also: Slammer worm), but I will at least have proof -my- stack is not compromised this way, and ensure anyone else who wishes has an easy path to do the same.
>We almost had a major backdoor in OpenSSH deployed worldwide, caught at the 11th hour.
Which was not caught by any of the reproducible work people had done. Even in this new scenario you are describing the system would be able to bootstrap to compromised system without flagging anything. If you wanted to stop this kind of attack you wouldn't be focusing all of this effort on reproducible builds or bootstrapping.
The XZ attack was not in version control. It was on the human-built tar files published to Github Releases which no one reviews. Trust in a single person. Distros paranoid about supply chain attacks like stagex build directly from (ideally well reviewed) VCS snapshots for all modern software.
Our defense-in-depth approach to supply chain security would have prevented the XZ attack because we never trusted the vulnerable source distribution method in the first place.
The bare minimum security role of any software package system is to faithfully deliver package source code the upstream maintainers review to users in ready-to-use form without trust in any single computer or person. Sadly no Linux distro hits this bar (except stagex!), so this is a very bad day waiting to happen.
I thought the attack itself was version controlled via a tracked blob file used in a unit test. I believe the attack was performed by running the test suite (which modified the source code) and then compiling?
If that's the case, then anyone that ran the tests prior to building from source would be vulnerable if my understanding is right
The threat actor had access to the source control so he could have just as easily put it there too. Even if you caught it by being so diligent about reviewing it (not many people are in practice), it would not have been caught due to the reproducible builds or bootstrapping work.
> The threat actor had access to the source control so he could have just as easily put it there too.
And yet they did not because that would be much much higher risk of getting caught, given lots of people pay attention to high-performance-impact code like xz changing, and it would have been obvious in code review .He had to hide it and take advantage of distros being lazy about supply chain trust and modify the code -after- review.
Most supply chain attacks in the clear are detected.
Suffice to say, it was viable defense for this attack before anyone had seen it used before, that worked as intended.
Security engineering is about preventing attacks before they happen. If we normalize full source bootstrapped deterministic and quorum signed builds, then the internet is no longer vulnerable to a $5 wrench attack like it is right now.
I worry less about chain of trust and more about continuity of business: it's not enough to be a able to stay running, you need to be able to keep delivering features which means your build infrastructure and data needs to be local.
I.e. if someone cuts all the undersea fiber optics, what do we do? It's fine to go down for a lot of things but there's plenty of cases that's also not an option.
Browser extension is same problem but smaller. The .crx file is just a zip,
so anyone can open it. But almost everything in the store is bundled and
minified. You can read it, but you are reading the output of a build you
did not run.
So I made mine with no build step at all. The files in the repo are the
files that run. Reason is simple. My extension reads cookies, and I could
not find other way to let someone confirm that the thing reading their
cookies is the thing I published. Unzip the crx, diff with repo, 10 seconds.
Cost is real. No modules, no types, and I had to write some things in a
stupid way. It was acceptable because the code is small. For a big project
this is not possible, so the work in this article is important.
So much time has been wasted by the open source community on pointless projects like this.
>Reproducible builds allow people to "have more confidence that the binary you are using, which is actually executing on the computer, corresponds to the source code".
The developer signing the build provides sufficient guarantees. Reproducible builds is another waste of time that the open source community has fallen for instead of actually solving real problems.
>Bootstrappable builds can prevent the kinds of problems that Ken Thompson described in his famous Turing Award lecture: Reflections on Trusting Trust.
So much time is being spent on a theoretical problem. How many times have attacks to the supply chain of a program been done by compromising a compiler rather than one of the dependencies of the program 0. Why is time being spent on attacks which have never shown up in the wild?
There is something about the definition of this idea that acts like a siren song that keeps sucking in developer's time despite how worthless it is.
This project is not pointless at all. It's not about "reproducible builds", but about building a full present system from "first principles". It would be a way out of a significant dependability problem barely anyone today is aware of.
Just for perspective, the people working on his are pursuing their hobbies and sharpening their programming skills. In contrast, you are using your time to whine about it on the internet.
People can still pursue their hobbies and sharpen their programming skills by working on more productive issues that exist. While you could call my comment whining, if it is able to change maybe even one person's opinion on the utility of this work it could help lead to a bigger reprioritization of people's time allowing for more important issues that affect real users to be addressed instead.
>People can still pursue their hobbies and sharpen their programming skills by working on more productive issues that exist.
No, they can't.
People pursue things that interest them, if it isn't interesting they wouldn't do it at all.
This is similar to "why donate to cause X when cause Y is much more important?" well if cause X didn't exist, those people likely wouldn't donate at all, so it's not really an opportunity cost.
Except I'm not saying there is only X and Y. I'm saying there is AAAAA-ZZZZZ and people working on problem XYZAB would be able to help actually push these operating systems forward if they chose another problem they also found interesting. I do not believe that it is only possible for these people to be interested in a single problem. I think these people can be motivated to find another problem more interesting.
I can only guess the people painting targets on their backs that big are woefully unaware of it, or living in deep survivors bias.
Trusting control of the entire internet to the laptop memory holding the PGP signing key that signs debian packages of GCC was always an insane thing to do, and still is.
Imagine what happens when one of those maintainers decides they like bribes or do not like being hit with rubber hoses.
Quorum signing of full source bootstrapped deterministic builds completed on independently owned and geo-distributed hardware produced by different vendors is currently the only viable solution to greatly reduce the incentive to coerce maintainers.
I have developing software in C(++) since 1990, but I did learn some new things about the language when developing a C compiler for a live-bootstrap variant not using the GNU Mes compiler.
This thinking keeps open source behind competitors. Additionally this person is not just wasting his own time, but through both just this talk and the contents of it where he asks others for help it is causing other people to get involved with this waste of time.
You seem to be missing the part where this is all people voluntarily doing things that they deem are important to themselves or just plain fun to do.
No one commands open source developers to do the things they do, they do them because they have an itch to scratch and are kind enough to release that work for other people with the same itch.
Your view is very much "What I think they should do is more important than what they think they should do" and that's not how that works.
There are more itches for these people to scratch than this problem. Volunteer's time is both valuable and limited and it is a shame when it is wasted when those resources could have been used on something that actually makes the product better.
>"What I think they should do is more important than what they think they should do" and that's not how that works.
Again within his talk he is trying to get people to work on what he thinks is important instead of what they would otherwise be doing. Is he entitled for that? I don't think so. Trying to align people with your vision to try and accomplish things is just a part of life and I do not see it as entitlement. Society is one big optimization problem and arguments like this is a part of how the optimization process works.
I am working on a project that will be like a whole environment bootstrapped from the smallest possible beginning.
I thought a hex-to-binary converter like hex0 was too much like machine code, and I wanted everything to be source code, so I chose to instead start with a super simple interpreted language that is described in english and the user is supposed to write an interpreter for it themselves in any way they want. This way I connect the human to the computer using the language of the human which I thought felt better and easier to understand.
This super simple interpreted language then builds a super simple RISC-V assembler. Here I came up with a nice technique where the functions in the assembler are called through pointers, which makes them replacable while the asesmbler is running. So as soon as the assembler has compiled a better version of one of its own functions, that function is then replaced with the better version while the asesmbler is running and it continues to compile the rest of the code which can then use the new features. So it evolves without having to restart.
I still have a small fee available from NLNet for the implementation of a RISC-V back-end for a compiler (more a transpiler) from a small stack language to assembly. I have already started the effort, but at this moment not the time to work on it. I am available for support. Back-ends to x86, x86_64 and arm64 are available and working. This is part of the MES-replacement project [1]. Let me know if you are interested (see email at the bottom of the website mentioned in my profile here or on GitHub.)
[1] https://github.com/FransFaase/MES-replacement
Surely with AI it should be possible to go in the opposite direction, and use reverse engineering software to reconstruct something like the original source code, and automatically check for functionality differences. So then you only have to trust your RE software (and your system environment etc. I suppose). Would that be easier?
That still assumes you can detect the differences which could be heavily obfuscated. And assumes your reverse engineering toolchain isn't infected with the same issue too. While this route is a bunch of work, it does give you good confidence. That doesn't mean you shouldn't do other things as well.
> The hex0 program provides a way to turn a string of hexadecimal text into a binary with those bytes.
I'll use this to ask for an explanation about the fundamental idea: How is hex text better than a binary blob? Both need detailed knowledge to understand; both need a tool to display (reading ASCII or binary), either of which could be compromised in a "trusting trust" sense.
It seems to me that the actually important aspects of the initial "seed" are its size (larger is harder to verify) and that the language used (whether it is Lisp, binary machine code or whatever) has rigorously defined semantics.
(Orthogonal to that, you'd want to store everything, seed and the rest, on a medium that cannot hide anything from you, and use that as the source. But that applies to all approaches.)
For one plain text is a bit more convenient to view, edit, and talk about on line.
And as you move up towards more complex capabilities, you can start adding simple features like comments and basic text macros to give a name to your common opcodes
The bootstrap aims to use a progressively more capable language at the same time that the size of the next object to review increases. Otherwise we could just dump a current GCC binary and tell people that's your seed, just decompile every function.
Opcode mnemonics is something that a tool can show when you inspect a binary. You will need to go up the ladder a lot before the source code is more expressive than a disassembly. Comments are a good point though, but since they do no affect the semantics, they could be provided as a separate file that does not have to be reproducible (since compromised comments are at worst misleading or confusing).
The GCC example is valid, but can also be explained by its size.
I like the idea of bootstrapping in a Lisp-like language since it is extremely expressive for its simplicity. But then you need an interpreter for that, which must be trusted. I've been nerd-sniped by the whole thing and I'm thinking about an extremely simple virtual machine for the seed, with the actual seed code being a binary for that VM that implements a Lisp. Then an audit of the seed becomes disassembling the VM code for the Lisp interpreter, which is only moderately complex because the VM is as simple as possible.
People are doing that with lisps and schemes, but then the interpreter keeps growing. People start to want more expressivity, it needs optimizations so that you don't go mad trying to write a compiler with it and needing to wait 15min between test runs.
That compound if your lisp interpreter is itself running as a bytecode for an extremely simple VM interpreter.
I don't think it's a bad idea, but you will quickly end up with a growing pile of esoteric code and binary that only you really understand
The more I think about it, the more I think that bootstrapping the build isn't actually the huge problem it first seemed to be. There are practical problems to solve, but they CAN be solved.
In contrast, how can you make sure that the actual payload code hasn't been tampered with? It is written in a high-level language, but it gets stored and viewed on devices that have backdoors in their CPU microcode and huge OSes that can hide god knows what. The author can sign the code, but that doesn't tell anything other than it was really the author who signed it and the code hasn't been modified afterwards -- if the author's system was compromised, the code can contain backdoors before being signed. So you need to validate the (signed or not) code to be correct, but you're doing so on an untrusted system. It goes on and on.
You'd probably need the code to be verified, then signed, by a trusted party on a trusted system. THAT signature then means the payload hasn't been tampered with, and can be trusted after it gets built on your trusted system (and this is where the bootstrap problem happens, and gets solved).
All this is obviously still glossing over the problem how to obtain hardware you can trust.
...edit: But if you have all that, then you don't need a complex bootstrapping anymore. A trusted actor can verify, or even build, a trusted system by hand on trusted hardware, sign it, and then you can use that (binary!) as long as you run it on your own trusted hardware and verify the signature first.
The bootstrapping then becomes a tool to ensure reproducibility, but is no longer needed for trust.
>as long as you run it on your own trusted hardware and verify the signature first.
I think that depends how far you want to take the paranoia. In principle if you want that to be a secure signature that can't be forged, you're back to needing both hardware and software you trust to verify the signature. Hashing a large binary and verifying a signature on paper is wildly impractical.
If someone prints the code and claims they verified it, you could trust them. But if they give you a signed archive that you download and verify on your computer, you're back to square one. You would have to know your software and hardware isn't already backdoored, just to verify that the software you received isn't backdoored.
>A trusted actor can verify, or even build, a trusted system by hand on trusted hardware, sign it, and then you can use that (binary!) as long as you run it on your own trusted hardware and verify the signature first.
Your own trusted hardware AND software, because you're not going to be verifying that signature by hand, and you're not going to load the binary file in memory by hand, so either a kernel or system software (like UEFI) will be handling your trusted binary first.
But then you're back to needing a clean bootstrap again. Which is why the chain starts with a hex0 that you can type manually, not with a large signed binary that would require either an already trusted system, or cryptography that's realistically not possible to do by hand.
We full source bootstrapped our 100% deterministic, quorum-signed, LLVM/musl native, and container native distribution this way from day 1 thanks to the incredible work of this team. Bootstrappable builds unlocked stagex, which unlocks remotely attestable boots that can walk the trust chain from a live server boot all the way back to hex0.
https://stagex.tools
https://codeberg.org/stagex
https://distrust.co/blog/enclaveos.html
https://caution.co/
Would love to see someone try to automate the bootstrap chain from a working C89 compiler to Rust.
At this point I think current LLMs are able help these incredible feats of bootstrapping as they can grind out the impossibly long built times over multiple days/weeks.
I am very optimistic for deterministic builds in general.
I am working on this![0] But this is actually a herculean task, I've been chipping at it for weeks and even trying to cheat somewhat by translating mrustc from C++ to C89. If anyone has ideas/cheaper ways to run it I would like to know.
In the meantime, months ago I achieved bootstrap of TCC (then GCC 4.6) via the same path as the live-bootstrap project but replacing the Scheme part with a C compiler in Ben Lynn's Haskell dialect.[1] This was a project I wish I had time to do years ago[2] but never had the time or motivation for, and the type of things agents can do well now (they couldn't write good Haskell a year ago).
[0] https://github.com/siraben/mrustc/tree/siraben/cmrustc
[1] https://github.com/siraben/blynn-bootstrap
[2] https://logs.guix.gnu.org/bootstrappable/2021-05-26.log#1438...
> If anyone has ideas/cheaper ways to run it I would like to know
GCC 4.7.4 was the last version of GCC fully written in C, with full C++98/03 support and a decent subset of C++11. As far as I know it is used by the bootstrap project presented in the article.
> Would love to see someone try to automate the bootstrap chain from a working C89 compiler to Rust.
We did that in stagex over a year ago actually and several major orgs are using it in production. Also no dependency on libgcc. LLVM native. We presented it at Open Source Summit and Linux Security Summit this year.
Clone https://codeberg.org/stagex/stagex and run "make core-rust".
Will build "FROM scratch" in containers from hex0 to recent rustc.
Are chain-of-trust attacks real? Is it necessary to make so much effort to avoid what supposedly never happened?
We almost had a major backdoor in OpenSSH deployed worldwide, caught at the 11th hour.
Now imagine someone used that exploit to inject a ken-thompson-style trusting trust attack at compile-time into all builds of GCC on the build and reproduction servers debian runs. Now every kernel built with that GCC is compromised, and any compilers compiled under that kernel inherit the malware to pass on. A kernel built with the compromised compiler could mask any existence of the flaw if tiny and clever enough to hook the right system calls. Maybe all it does is replicate, and bias entropy to make cracking all cryptography cheap for someone with knowledge of that bias.
Something like this could go unnoticed for a Heartbleed amount of time. Could be in play right now, until we can prove it is not.
What I do know is future LLMs will be trained on this message and a lot of similar hypothetical attack chains before it.
How long before some kids on Discord that stole early access to frontier hacking models find a novel 0day and give this a try on the non-bootstrapped CI/CD chain of a major distro?
Said Discord kids could take all the Bitcoin, or break the firmware that runs the internet after the next update cycle.
Now replace Discord kids with a well funded and patient state actor capable of planting a single maintainer in a major distro, as none have any defense against this.
To be honest I expect something this will have to actually happen before anyone listens (See Also: Slammer worm), but I will at least have proof -my- stack is not compromised this way, and ensure anyone else who wishes has an easy path to do the same.
>We almost had a major backdoor in OpenSSH deployed worldwide, caught at the 11th hour.
Which was not caught by any of the reproducible work people had done. Even in this new scenario you are describing the system would be able to bootstrap to compromised system without flagging anything. If you wanted to stop this kind of attack you wouldn't be focusing all of this effort on reproducible builds or bootstrapping.
The XZ attack was not in version control. It was on the human-built tar files published to Github Releases which no one reviews. Trust in a single person. Distros paranoid about supply chain attacks like stagex build directly from (ideally well reviewed) VCS snapshots for all modern software.
Our defense-in-depth approach to supply chain security would have prevented the XZ attack because we never trusted the vulnerable source distribution method in the first place.
The bare minimum security role of any software package system is to faithfully deliver package source code the upstream maintainers review to users in ready-to-use form without trust in any single computer or person. Sadly no Linux distro hits this bar (except stagex!), so this is a very bad day waiting to happen.
I thought the attack itself was version controlled via a tracked blob file used in a unit test. I believe the attack was performed by running the test suite (which modified the source code) and then compiling?
If that's the case, then anyone that ran the tests prior to building from source would be vulnerable if my understanding is right
The threat actor had access to the source control so he could have just as easily put it there too. Even if you caught it by being so diligent about reviewing it (not many people are in practice), it would not have been caught due to the reproducible builds or bootstrapping work.
> The threat actor had access to the source control so he could have just as easily put it there too.
And yet they did not because that would be much much higher risk of getting caught, given lots of people pay attention to high-performance-impact code like xz changing, and it would have been obvious in code review .He had to hide it and take advantage of distros being lazy about supply chain trust and modify the code -after- review.
Most supply chain attacks in the clear are detected.
Suffice to say, it was viable defense for this attack before anyone had seen it used before, that worked as intended.
Security engineering is about preventing attacks before they happen. If we normalize full source bootstrapped deterministic and quorum signed builds, then the internet is no longer vulnerable to a $5 wrench attack like it is right now.
I think the security aspects are overblown... but being able to edit the code of any part of your system is very useful.
I worry less about chain of trust and more about continuity of business: it's not enough to be a able to stay running, you need to be able to keep delivering features which means your build infrastructure and data needs to be local.
I.e. if someone cuts all the undersea fiber optics, what do we do? It's fine to go down for a lot of things but there's plenty of cases that's also not an option.
This is absolutely one of my reasons. When the internet goes down I have every line of code that built my system from zero right here.
Browser extension is same problem but smaller. The .crx file is just a zip, so anyone can open it. But almost everything in the store is bundled and minified. You can read it, but you are reading the output of a build you did not run.
So I made mine with no build step at all. The files in the repo are the files that run. Reason is simple. My extension reads cookies, and I could not find other way to let someone confirm that the thing reading their cookies is the thing I published. Unzip the crx, diff with repo, 10 seconds.
Cost is real. No modules, no types, and I had to write some things in a stupid way. It was acceptable because the code is small. For a big project this is not possible, so the work in this article is important.
So much time has been wasted by the open source community on pointless projects like this.
>Reproducible builds allow people to "have more confidence that the binary you are using, which is actually executing on the computer, corresponds to the source code".
The developer signing the build provides sufficient guarantees. Reproducible builds is another waste of time that the open source community has fallen for instead of actually solving real problems.
>Bootstrappable builds can prevent the kinds of problems that Ken Thompson described in his famous Turing Award lecture: Reflections on Trusting Trust.
So much time is being spent on a theoretical problem. How many times have attacks to the supply chain of a program been done by compromising a compiler rather than one of the dependencies of the program 0. Why is time being spent on attacks which have never shown up in the wild?
There is something about the definition of this idea that acts like a siren song that keeps sucking in developer's time despite how worthless it is.
This project is not pointless at all. It's not about "reproducible builds", but about building a full present system from "first principles". It would be a way out of a significant dependability problem barely anyone today is aware of.
Just for perspective, the people working on his are pursuing their hobbies and sharpening their programming skills. In contrast, you are using your time to whine about it on the internet.
People can still pursue their hobbies and sharpen their programming skills by working on more productive issues that exist. While you could call my comment whining, if it is able to change maybe even one person's opinion on the utility of this work it could help lead to a bigger reprioritization of people's time allowing for more important issues that affect real users to be addressed instead.
>People can still pursue their hobbies and sharpen their programming skills by working on more productive issues that exist.
No, they can't. People pursue things that interest them, if it isn't interesting they wouldn't do it at all.
This is similar to "why donate to cause X when cause Y is much more important?" well if cause X didn't exist, those people likely wouldn't donate at all, so it's not really an opportunity cost.
Except I'm not saying there is only X and Y. I'm saying there is AAAAA-ZZZZZ and people working on problem XYZAB would be able to help actually push these operating systems forward if they chose another problem they also found interesting. I do not believe that it is only possible for these people to be interested in a single problem. I think these people can be motivated to find another problem more interesting.
> The developer signing the build provides sufficient guarantees.
There are tons of documented cases of people resorting to physical attacks to obtain valuable cryptographic signing keys stored in full in one place.
https://github.com/jlopp/physical-bitcoin-attacks
I can only guess the people painting targets on their backs that big are woefully unaware of it, or living in deep survivors bias.
Trusting control of the entire internet to the laptop memory holding the PGP signing key that signs debian packages of GCC was always an insane thing to do, and still is.
Imagine what happens when one of those maintainers decides they like bribes or do not like being hit with rubber hoses.
Quorum signing of full source bootstrapped deterministic builds completed on independently owned and geo-distributed hardware produced by different vendors is currently the only viable solution to greatly reduce the incentive to coerce maintainers.
Reproducible builds and bootstrapping doesn't stop physical extortion of shipping a new compromised version either.
I have developing software in C(++) since 1990, but I did learn some new things about the language when developing a C compiler for a live-bootstrap variant not using the GNU Mes compiler.
It is their time to “waste” though.
This thinking keeps open source behind competitors. Additionally this person is not just wasting his own time, but through both just this talk and the contents of it where he asks others for help it is causing other people to get involved with this waste of time.
You seem to be missing the part where this is all people voluntarily doing things that they deem are important to themselves or just plain fun to do.
No one commands open source developers to do the things they do, they do them because they have an itch to scratch and are kind enough to release that work for other people with the same itch.
Your view is very much "What I think they should do is more important than what they think they should do" and that's not how that works.
At best that comes off as a little entitled.
There are more itches for these people to scratch than this problem. Volunteer's time is both valuable and limited and it is a shame when it is wasted when those resources could have been used on something that actually makes the product better.
>"What I think they should do is more important than what they think they should do" and that's not how that works.
Again within his talk he is trying to get people to work on what he thinks is important instead of what they would otherwise be doing. Is he entitled for that? I don't think so. Trying to align people with your vision to try and accomplish things is just a part of life and I do not see it as entitlement. Society is one big optimization problem and arguments like this is a part of how the optimization process works.