Neat article, always interesting to take a peak at some ones highly idiosyncratic process.
Neat article, always interesting to take a peak at some ones highly idiosyncratic process.
More importantly, it goes against the cargo cult narrative that the choice of programming language is the one and only factor determining memory safety, and consequently any use of languages such as C automatically leads to security issues.
It's not a coincidence that we have people in this discussion coping with that concept by spinning the use of frameworks focused on memory safety in C applications as somehow representing writing code in an entirely different programming language.
Despite the authors borderline obsessive efforts to write memory safe C code, it's interesting to note that his implementation of "bc" prominently contains a file documenting memory issues in previous versions. If that's what borderline obsessive gets you, how are us normies who are only programming to pay the bills, who have to work with other people who also just want to finish what they are doing or interact with blobs of code written by other people with less exacting standards supposed to write memory safe code?
It's a framework. It's a set of C macros and C code. It's not a new language. Please stop.
> The final reason is the only one that justifies my decision: my code will be rewritten in a memory-safe language.
> No, it won’t be Rust. It’s my own language. It’s called Yao.
If you wanna write your hobby programs in C because you think it's fun, then fine, you do you. But this seems like a pretty good indication that basically no C written by anyone can realistically be truly safe.
If the author's reason is "because I can get the same features as Rust with much more effort" they've failed to justify it and thus that reading.
Not really. The author describes he put together a framework for C that implements memory safety features.
Isn't it intellectually dishonest to criticize the adoption of libraries that provide features that other languages may or may not have built in?
What's the end goal exactly? Use safety features to write safer software, or attack anyone that hasn't mindlessly jumped onto a particular bandwagon?
Of course you can augment a language with libraries. But you are one developer and everyone else will make different choices.
Sure, you are free to make this sort of claims. But they are besides the point, aren't they?
The cliche being discussed here is C's hypothetical ties with memory safety issues, and here we are commenting on a discussion on how someone writes C using a framework focused on memory safety and thus providing "some guarantees" about their whole ecosystem. Yet, we're still seeing comments mindlessly parotting myths in spite of the facts that are being dangled right in front of their nose.
Even malloc | free aren't vital as memory is preplanned and can be retrieved from an RTOS in a single block at startup.
> Using glibc in avionics software is insane,
As I said above .. there's no need for glibc et al.
> I feel like you are missing the point.
We seem to be in agreement here.
> In other words, it’s asinine to pretend C is somehow more reliable because ...
What most people call "C" is (preprocessor) + (actual language) + (stdc function library).
What I call C (and hey, maybe that's just me) is just the language component, the "below the fold" library spec in the ANSI Std is easily disregarded .. it's more of a dated "proof of concept" of (for example) one of many ways of handling strings.
C is a nice language - the preprocessor and stdlib have issues.
Christ, I wrote it as an absurd notion in the first place. This is honestly like writing “go ahead and wear underwear on your head” only to have someone tell repeated tell you that isn’t necessary. Well, no shit.
Language doesn't matter.
> "The next reason is that during my time with C, I have developed a custom software stack designed around memory safety."
Oh ok then. Again goes to show how C is deficient in some areas
I get something being fun, but C ends up needing to worry about a lot of details where you could be actually improving the code in other languages
Also if he already has a framework that solves that problem for him, then it's not deficient in that areas, for him, right?
Also to gp, title perfectly matches, pointing out why he believes in memory safety when using C, everytime also pointing out the flaws with his thinking, and why this only applies to him in his completely owned projects. Not sure what's wrong with the critics here.
It's also fun to write data-structures yourself instead of being a mere user all the time. In C you can tell yourself that your take on how to do datastructures is worthwhile and unique (might be a slight stretch) but in other languages almost anything you can do is redundant.
Only if you manage simple buffers and do shallow processing with them
String management, network connections, data structures, this is simpler literally everywhere else
> It's also fun to write data-structures yourself instead
True, but it's more fun in C++, warts and all. And not when time is money
There is no theory.
It's really simple, actually:
If you have a mine-field with an uncountable number of mines, knowing the locations of 200 mines won't help you cross the mine-field safely. If, instead, you learn how to spot areas which are known to be safe, you can, assuming you don't make a mistake, at least attempt to cross it safely (and if you fail to cross it, you can go back and learn how to spot other areas which are known to be safe).
That is the difference between your claim that you need to know all the documented instances of UB and my claim that you just need to know enough defined behaviour to write your program.
It has nothing to do with security assessments or pentests.
It's not just the API either. So once you've got your "nice" error handling API, you have to manually handle resource clean up - no branches that exit for you; every function call is accompanied by a result check and a goto to cleanup code (so your pointers need to be defined properly prior to any calls and initialised to null). Honestly, I don't know I ever lived with this mess. It was a painful and laborious experience to get to something that was just about ok.
> So once you've got your "nice" error handling API, you have to manually handle resource clean up - no branches that exit for you; every function call is accompanied by a result check and a goto to cleanup code (so your pointers need to be defined properly prior to any calls and initialised to null).
I have a stack allocator that will release everything allocated in the function on exit, and I have macros to replace my use of the return keyword that also deallocate everything in the stack allocator before returning.
So my code actually has code cleanup on return.
C does not have to be laborious. Maybe the fact that I have done things like that is part of why I like C?
Basically, you tell the stack allocator to store a jmp_buf, then you setjmp() on it. Then keep going.
For a function, a special destructor is used as a marker. Same with scopes.
The same is also true of a setjmp() destructor, which is actually what activates longjmp().
The stack allocator should have three functions to unwind itself until it reaches the end of the next scope, function, or jmp, respectively.
Then, when you need an exception, or to exit a function or scope, you call the correct stack allocator function to clean up everything to that point. Then you return or whatever.
This can run arbitrary code on cleanup for an item if you write a "destructor" with that arbitrary code. For example, one idea I had was to use the stack allocator to ensure a mutex or other lock was always released. This would be done by storing a pointer to the mutex and writing a "destructor" that unlocks the mutex when given a pointer to the mutex. Boom. Scope-based mutex unlocking.
Makes sense?