Am I a Good C Programmer?
gavinhoward.com
gavinhoward.com
This is my experience, though I started in Java and transitioned to C.
My C code also does not need to be updated for language changes and such.
[1] Linux syzkaller bug tracker https://groups.google.com/g/syzkaller-bugs
My bc does use fuzzing. [1]
I love fuzzing. In my new project, fuzzing generates my test suite that I then go through by hand and verify.
In bc, if I change the source code before a release, I run a fuzzer for two weeks on both bc and dc.
[2] and [3] are directories of error tests, almost all of which were found by AFL(++).
If you run the following on my bc repo:
commits1=$(git log --oneline --grep=afl)
commits2=$(git log --oneline --grep=AFL)
printf '%s\n%s\n' "$commits1" "$commits2" | uniq | wc -l
You will get 148 as of 53832b884b5c. Not all of those are bugs found by AFL(++) because some are tending to my fuzzing infrastructure, but at least 2/3 probably are.[1]: https://git.gavinhoward.com/gavin/bc/src/branch/master/tests...
[2]: https://git.gavinhoward.com/gavin/bc/src/branch/master/tests...
[3]: https://git.gavinhoward.com/gavin/bc/src/branch/master/tests...
Additionally people have died due to software bugs, Therac-25 being quite famous, with its Assembly optimization tricks.
The reason people like you are not listened to is that you're so unreasonable.
It's not an accident that ada was designed years ago for software that IS critical in this manner, because different decisions get made. But the vast majority of software is not going to end up with people dead, hence why arguments comparing life-or-death situations with your run-of-the-mill C code is assinine.
Yes, it's true that GCC code will never live under the same level of scrutiny as NASA code, nor should it.
Moreover, it is untenable to maintain a small island of "secure software" for "important things" in a vast ocean of careless and vulnerable code. Inevitably, the island gets infected, and not even air-gaps can save it, as stuxnet showed.
This idea that all code must be treated equally wrt security is why security people are oddly never effective.
Why is it inevitable? As long as it doesn't connect to other software (via internet or other means), isn't it possible to formally verify one critical software component, e.g. in pacemakers?
I'm not saying that C would necessarily be the best choice for formally verifying it, though.
perfect is the enemy of good, "security" people act as if all breaches are equally relevant.
When your surface area is everything you're more likely to have holes, that's just a law of nature. Limit your surface area and suddenly you can be more thorough.
Unlike what your sibling comment claims, I'm not saying all software is equally important, or must have equal effort invested in securing it. But insecurity absolutely is infectious, and the more insecure the general environment is, the harder it is to secure a small part of it.
For example, you'll want a compiler. How secure is the web stack of the page that delivers your gcc/clang? How secure is its host's infrastructure, and of the DNS provider? The browser you're downloading it with? Did you ever visit any other page that might have compromised it? What about your text editor, your OS, the SDK you're using to flash code onto the pacemaker.. And all of them have vast supply-chain networks.
I think you need to read to the end of the post. And then read the one it links to because that one says that I will rewrite all of my new project in a memory-safe language. (bc, unfortunately, needs to stay in C because it needs to have zero dependencies.)
I'm not making the argument that C is good, or that I am good at C. I'm comparing myself against the average.
Couldn't you write it in Golang? That's also popular for creating standalone executables (ignoring the dynamically linked libc when necessary).
I'm not saying you're obligated to switch. I just assume you wrote bc in C because you find it fun, based on your "Why I write C when I care about memory safety" post.
And that was part of my original requirements because I knew that fact at the time I started.
Edit: In fact, there's really a dependency on POSIX sh and various standard POSIX utilities, but Linux also requires those to build, so those are also "free."
Those links say 70% of all security bugs, but since my bc/dc does not have the ! command (to spawn processes) and only reads files, not writes them (except stdout), it’s hard to actually turn a memory safety issue into a security bug, even if it’s possible.
Is this quote assuming ASLR, non-executable stack, stack canaries?I don't really understand what writing files and forking have to do with the security of system? Unless you mean it limits the attack surface from a ROP gadget?
It means that you have to find input that triggers a memory bug to do something malicious.
If my dc had the `!` command, then you, as an attacker with low privileges, might be able to modify a dc script to spawn another command that you know can be exploited to get root. Without it, you have to exploit my dc for ROP or some other attack.
Of course, then you would just target a shell, right? And that's the point: I've put in enough work, and my bc/dc are locked down enough, that attackers would probably find other ways in.
This and the Curl article make me wonder what factors impact the proportion of security bugs which are memory safety bugs. The most obvious variable is codebase size - Microsoft/Chromium both are huge codebases, with multiple millions (billions?) of lines of code each. Curl appears to clock in closer to 100k, and Daniel states "51% (22 of 43) of the issues rated high or critical was due to C mistakes." bc appears to have ~20k lines of code, and this article gives C bug rate closer to 10%. Feature set/attack surface area feels like another important variable, though I'm sure there are arguments for others as well.
I'd be nice if we had more directly comparable numbers as well. The denominator for Microsoft's 70% number is "number of CVEs". The denominator for Chromium's number is "high severity security bugs". Curl's 51% number uses a similar metric, and I think the denominator for bc's ~10% number is just "bugs" (though to be fair, OP does discuss this in the post).
All that being said, I still think the data point introduced by this article is better to have than not.
Thank you. :)
One thing I am going to do in my new project is catalog all bugs fixed after first release with the following data points:
* Is it a C bug?
* Is it in a stable module of the monorepo? (I will mark things stable after they have been tested.)
* Is the bug in a release, even if it's in an unstable module?
* Is it a build bug?
* Is it a test bug?
* Etc.
I'll keep the catalog in a human- and machine-readable format. This should provide a good set of data.
I would be thrilled if people downloaded my code for human study, analysis, and code archeology.
Until I build my VCS, which will be like Fossil and have an integrated issue tracker that gets cloned with the repo.
Then I'll put the catalog into my VCS by hand and track issues normally; the catalog will build itself as people report bugs.
I'm currently inclined to think that:
1. Yes, it should
2. The OP of the linked issue may be mistaking a tools / social conventions issue for an error by the author
I'm in love with "bc", I don't know if I use your version or not, but well... it's a calculator... It's well written, it does the job, but come on...
I'm currently making a build system and a VCS with a server that will be exposed 24/7/365 with HTTP, authentication, authorization RBAC, a database, connection encryption, randomness, hashing, compression, caching, and streaming of large files.
bc is my only current data point since this project is not finished, but once it is, we'll start to get real data about what I can do.
Just pathetically good at seeking out some ego stroking
I hate posts like this one.
They always start off with a banal post heading
Then becomes a way of arguing the posters hiden agenda