Bootstrapping GCC in RISC-V: Milestone: MesCC builds TinyCC and fun C errors
ekaitz.elenq.tech
ekaitz.elenq.tech
It was surprising that the OP calls C's shift operators (<< and >>) rotate, especially surprising in the context of low-level/assembly programming where rotate is very often a separate instruction. A rotate will bring bits "around", while a shift just inserts 0s or sign bit copies.
The difference to the approach referenced here is that build-many-glibcs.py and similar efforts start out from a native GNU toolchain (contemporary GCC with the C and C++ front ends, binutils, GNU make, and so on) plus some extensions (such as Python). Most people already have such an environment and trust it to some degree, so there is no need to bootstrap off some minimal seed.
To a lesser extend, letting the army of gcc extensions being required to compile a linux kernel is not that far away...
The opinion of us, non-paying users, is irrelevant.
Lack of interest in evolving C at a reasonable pace has left the standard catching up to the implementations where there is no such ideological battle to implement a feature. The attribute situation in C is a great example of this.
And I agree on the fact that C is bad, but much less worse than c++ and similar, plain and simple C (without the latest ISO tantrums) is still the less worse compromise.
And if something had to be done with C, it was the "other way around": only 1 loop statement (loop{}), no integer promotion, no switch enum typedef (and the filthy _generic and typeof), no implicit cast except from literals (see rust and others) and void*, hard compiler constant declarations, fix for good the variable argument list macro, no anonymous code block (but ok for union and struct), only sized primary types (u8/s8...u64/s64...f32...), and all those pesky little things I forget.
We did reach a state in our domain where "innovation" is actually not "adding and complexifying" (unless Big Tech, since this is their bread and butter), but "removing", and the really hard part, then, to keep it that way.
You still have to trust the original compiler, and you still can't rely on reading the source.
You just have to hope that the simple compiler is simple enough to read at the machine code level, and trust your file system / hex viewer / text editor.
lets say gcc is compromised.
if it detects its compiling a compiler it inserts a back door routine, if it detects it's compiling an os, it inserts a backdoor, if it detects its compiling a file system it inserts code to hide that back door and prevent it being shown to the user, when a user accesses those files.
if you compile tinycc with gcc, youve lost. if you compile tinycc with anything thats been compiled by gcc youve lost.
you arent going to detect it by looking at the source code, you arent going to detect it looking at the binary, you would have to look at the running executable, and hope that the attackers didn't take my example one step further.
you basically need to make your own trusted stack. but then anyone else that uses that stack has to trust you.
You can't fully mitigate it, all you can do is trust that all the people building their own trusted stacks aren't in on it, and are competent. But then we're back to trust again.
That's going to be hard.
If you're compiling yourself, sure, you know how the compiler is structured and what the source code looks like, so it's easy to spot the point to add the hidden backdoors to.
But inserting the backdoors into an arbitrary compiler? That may be structured differently, or use a completely different set of intermediate representations? Or even just uses `camelCase()` instead of `lower_underscores()` for function naming?
I'm not sure a generic backdoored compiler would be an option. I think you'd need separate payloads for, say, gcc and tinycc. But then the problem becomes, how do you add a new backdoor for a compiler that was released after yours, without anyone noticing? If you do a 3-stage bootstrap of GCC, the end result will be noticeably different if someone started with a pre-new-backdoor binary compiler than with a post-new-backdoor binary compiler.