5 ms·
> There are many good "better C" alternatives already. Rust, zig, D. All of these are very different from C. What I'm proposing is just one small change to th
by lisper 2y ago
> There are many good "better C" alternatives already. Rust, zig, D.
All of these are very different from C. What I'm proposing is just one small change to the existing C language.
> If you can come up with a way to add these guarantees to C without needing significant rewriting, I can assure you that most C programmers would be very interested.
I can pretty much guarantee that they would not because this is easy: phase in the changes. Start by turning array-pointer conflation into a mandatory warning rather than undefined behavior or whatever it is now. Then wait a few years. Then turn it into an error that you can muffle using -C2024 or whatever.
I actually don't know whether array-pointer conflation is required by the standard or if it's undefined behavior (I'm pretty sure it's one or the other). But if it's the latter then you don't actually have to change the standard to make this happen, all you need to do is write a compiler that does the Right Thing. AFAIK no such compiler exists. But there is just no excuse for this:
% gcc -v
Apple clang version 14.0.0 (clang-1400.0.29.202)
...
% more test.c
int main () {
int x[10];
return *(x+20);
}
% gcc -Wall test.c
%
- retrac 2y agoIn assembly, arrays and structs reduce to base address, plus offset times scaling factor. C provides a thin veneer over that. Scaling derived from size of type. Offset is the array index. The basic programming model of C is to view memory as an array.
- lisper 2y agoYes, I understand that. But the topic at hand is a compiler whose "intended use is the compilation of life-critical and mission-critical software written in C". The idea of using C in life-critical and mission-critical software is risible as long as the language definition requires it to have gaping security holes, especially when the single biggest contributor to this problem is fairly easy to fix, at least from a technological point of view if not a political and sociological one.
- nequo 2y agoMy understanding is that the primary purpose of CompCert is to make formally verified code that is extracted into C also get compiled by a compiler that is formally verified to preserve the intended semantics. So CompCert seems to me to aim to help mission-critical software to move away from C, and possibly into Coq/Isabelle/etc., except for the purposes of compilation to machine code.
- lisper 2y agoThat is a noble goal, but I don't see how it can possibly achieve the intended result as long as the C standard is a fundamentally borken as it is. I tried to download CompCert so I could try it out, but they only have a source distribution and to build it you need Coq and OCaml and a few other things because of course CompCert is not written in C. No one in their right mind would write mission-critical software in C.
- seabird 2y agoIf your original source is provably transpilable to C with no UB, and your compiler provably compiles that C without any bungling, then you've made it. The standard is bad and I want to see the end of C before I'm dead, but this isn't a stretch, and C is just a detail in the process.
- LeFantome 2y agoI am mostly in the other side of this argument. C is an insane language in my view ( in a modern context ). That said, what “mission critical software” are you using that is not running on an OS written in C?
- eru 2y ago> > No one in their right mind would write mission-critical software in C. > That said, what “mission critical software” are you using that is not running on an OS written in C? I'm not sure that's relevant? If you have a piece of mission critical software, almost all the time you run it on an existing OS like Windows or Linux. You don't _write_ a new OS just for your one piece of software. Of course, that OS had to be written at some point in the past (and is still being worked on). Presumably that writing was (and is) being done by people not 'in their right mind'. But that shouldn't concern you. The problem with C is not that you can't write secure-ish software at all; the problem is that this is insanely difficult, and that the trade-offs aren't worth it. Especially for new software. For software that I get from some third-party, like the OS, I only care about its quality (and price); I don't care about the trade-offs and pains the authors had to endure. If they want to use C in the privacy of their own bedroom, that's up to them. Of course, Linux in 2024 is written in C, mostly because Linux in 2023 was written in C, then 2022, etc all the way back to the 1990s. There's a lot of path dependence. Back in the 1990s C was a more reasonable choice to write your new OS in. Especially if it was a clone of Unix, C's original home and killer app.
- eru 2y agoIt's tempting to view C as a thin veneer over assembly. Alas going there ignores all the nice undefined behaviour landmines the standard has buried for you.
- rfoo 2y agoThere are more than one billion lines of C code which hasn't been updated in the last decade and is still in use. Who is going to update these code once the "do the right thing"-compiler become available? Oh, and the worst part: some of them may already be bug-free due to 15 years (if not more) of people trying to make money by selling exploits to surveillance vendors or who knows. But there's certainly high-impact bugs left. Now what, refactor the code to use the fancy eliminate-spatial-memory-corruption C variant and introduce a few UAF by the way?
- lisper 2y agoThe authors and maintainers of that code. Any error or warning flagged by this change is something that really ought to be changed anyway because any unchecked array or pointer dereference is a potential security risk.
- rfoo 2y agoHave you read the source code of Xpdf (the thing being exploited in the famous NSO Apple iMessage 0-click blah blah)? I did (because I wrote an exploit for the bug after the Google blogpost, for curiosity), the code looks disgusting. The author (one poor guy) does not have the code in an online VCS and instead dump a source tarball every few months (or years). The upstream vulnerable code was fixed months after news outbreak. My conclusion is if Apple had a choice it won't end up in iOS at all. Clearly, Apple already paid a lot of maintaining cost in this case (fixing bugs before upstream did), but what you asked for is a whole new level.
- LukeShu 2y agoThere is a well-maintained in-VCS less-disgusting version of Xpdf. It's called Poppler, and Apple chooses to not use it.
- deleted 2y ago[deleted]
- 2y ago
- pyrolistical 2y agoYou should take a closer look at zig. While superficially the syntax is very different, what zig really is, c but more specific
- lisper 2y agoNo, I get that. I was referring to the syntax. Syntax matters. Zig is hands-down a better language than C, and (I'll take your word that) it fills the same niche as C, but it is still a different language with its own idioms and lore and conventions. It is not C-with-tweaks. It cannot be compiled by an extant C compiler. Code written under my proposal would be legal C code under the current standard (but not the other way around). [EDIT] Actually, that turns out not to be true. You'd need to change the behavior of SIZEOF or provide some other way of getting the size of dynamically allocated arrays at run time, since this information would now be maintained by the compiler.
- unwind 2y agoOf course sizeof already has that capability since C has variable length arrays. They are kind of being phased out, but they are there. You can do this: #include <stdio.h> int main(int argc, char *argv[]) { unsigned int lens[argc]; for (int i = 0; i < argc; ++i) lens[i] = (int) strlen(argv[i]); printf("Computed %d lens into %zu bytes of array\n", argc, sizeof lens); return 0; } Very contrived pointless example, but still.
- flohofwoe 2y ago> All of these are very different from C. With the changes you have in mind, that new "C+" would be much closer to Zig than C. For a backward compatible bounds-checking proposal see: https://discourse.llvm.org/t/rfc-enforcing-bounds-safety-in-c-fbounds-safety/70854 https://discourse.llvm.org/t/rfc-enforcing-bounds-safety-in-... This basically just associates a pointer and a length via new (and optional) annotations.
- pjmlp 2y agoThat is what Microsoft is already doing since the Windows XP SP2 security task force, Apple came a bit late into the game. The void foo(int *__counted_by(N) ptr, size_t N); with SAL void foo(_In_reads_bytes_(N) int *ptr, size_t N); https://learn.microsoft.com/en-us/cpp/code-quality/understanding-sal?view=msvc-170 https://learn.microsoft.com/en-us/cpp/code-quality/understan... But given how much long time ago XP SP 2 was, and how many people actually use them, unless forced at their job, that is quite telling how much people care.
- Gibbon1 2y agoWhat bothers me is a function that takes both a ptr and a length is taking a phat pointer. What feels bad is you could add standard phat_ptr_t to the C library. But they refuse to do even that.
- flohofwoe 2y agoSuch a bounds-checking language extension needs to be able to annotate existing libraries without changing their API, otherwise it's not all that useful.
- flohofwoe 2y agoPS (too late for edit so I'm replying to myself): with the above Clang extension you can also define your own phat_ptr_t struct and still associate the length with the pointer. Not sure if that's also possible with the Microsoft extension, for instance this is copied from the proposal text: typedef struct { int *__counted_by(count) buf; size_t count; } sized_buf_t;
- colonwqbang 2y agoYou are just not using the correct compiler flags. Compile with gcc -O2 -Wall -Werror, and you will see that GCC rejects this program due to the out of bounds condition. No need to trash talk GCC when it already does what you want it to.
- lisper 2y agoI'm actually running clang (look at the second line of the transcript). I just invoke it with gcc out of thirty years of habit.
- colonwqbang 2y agoI see! For recent clang, the flag -Warray-bounds-pointer-arithmetic did the same thing for me. So if missing bounds checking for static arrays was your main gripe with C, you can rejoice.
- balnaphone 2y agoPerhaps that is inexcusable. GNU gcc version 13.2.0 (with -O2, as documented) does report a problem. $ cat tst.c int main () { int x[10]; return *(x+20); } $ gcc -Wall -O2 tst.c tst.c: In function ‘main’: tst.c:3:10: warning: array subscript 20 is outside array bounds of ‘int[10]’ [-Warray-bounds=] 3 | return *(x+20); | ^~~~~~~ tst.c:2:7: note: at offset 80 into object ‘x’ of size 40 2 | int x[10]; | ^
- HelloNurse 2y agoThese are easy mode arrays, with size and offset known at compile time. Receiving x as an int* parameter to a function, with no way to know its length automatically, would be more realistic.