• 0 Posts
  • 17 Comments
Joined 3 months ago
cake
Cake day: August 9th, 2026

help-circle
  • I don’t think small is necessarily the target. It may be an aspect of the result, but only coincidentally.

    That is because even very, very small programs can have behavior that we cannot reason about. There exists a 6-state Turing Machine for which we don’t know whether it halts. On the other hand, there exist programs far larger than that for which we can formally prove either termination or nontermination and also other much more useful properties. seL4 is an example. So smallness is at best a really iffy proxy for how well we can reason about a program.

    Another problem with “small” is (as icefox points out) that it immediately leads to discussions around “well, how small?” and there is no good single answer. On the other hand, formal verification is pretty clear: Once you have a mechanized proof that checks, you’re done. Better yet, you’re allowed to add as many features and/or optimizations as you want as long as you can still prove their correctness.

    Now of course, you will instead invite discussion around “what properties to verify?”. I think that is more productive than “how small”, though.


    score 3 · canonical




  • compilers are totally allowed to refine the standard and define behavior that the standard leaves as UB. They don’t have to wait for the committee to force them to remove UB. However, to my knowledge, neither GCC nor clang do this.

    At least GCC lists a couple of these here: https://gcc.gnu.org/onlinedocs/gcc/Semantic-Extensions.html

    Not all of these are UB in standard C and are just ill-formed, but at least arithmetic on void* is UB, to my understanding. The C23 standard draft says in 6.5.7.2 (emphasis mine):

    For addition, either both operands shall have arithmetic type, or one operand shall be a pointer to a complete object type and the other shall have integer type

    Where 6.2.5.24 says:

    The void type comprises an empty set of values; it is an incomplete object type that cannot be completed.

    And then 4.2:

    If a “shall” or “shall not” requirement that appears outside of a constraint or runtime-constraint is violated, the behavior is undefined.

    Beyond these, both GCC and Clang document optional extensions that remove some UB if you turn them on, e.g. -wrapv and -ftrapv making signed integer overflow well-defined.


    score 1 · canonical





  • If anything, this vulnerability was more of a C one than a PHP one. As in, the problem was in the implementation of PHP itself, which is written in C. Of course, there are also tons of bugs in PHP code too, including your garden variety Wordpress CVEs. This is not that.

    This one is very characteristic of C vulnerabilities: Because of C’s lack of memory safety, it’s very hard to prevent memory corruption bugs. The conditions required to trigger these can be arbitrarily complex, making them hard to find (this one was hidden in plain sight for 20 years). They usually result in the most severe consequences, often remote code execution (as in this case). And because of C’s foundational role in the ecosystem, the affected components tend to be deep down in the stack and used very, very widely.

    Sure, you could respond that it’s not C’s problem, it’s just that the PHP developers (who are bad, because PHP is bad, unlike us, who are good) are just also bad at C. That might hold some water if nearly every other important C project wasn’t also running into these issues.


    score 1 · canonical




  • I think there’s a lot to love about the idea of C, but its reality is much messier and more annoying.

    Being around for fifty years doesn’t automatically mean it get polished to a sheen, because C is not one single artifact that one single group worked on for fifty years. Instead, it’s got fifty years of weird legacy cruft accumulated from divergence between various implementations, concessions to historical constraints that no longer apply and (yes!) human error.

    This is kind of by design. The process by which C is developed (including the ANSI/ISO standardization processes) is very focused on backwards compatibility. That makes it an amazingly stable environment, there is tons of decades-old C code being used unchanged in production with modern compilers. However, that also means that all the really bad parts can’t ever truly be fixed. If you want something that looks like a perfectly cut and polished gem after fifty years, you need a process that is able to sand off some rough edges once in a while. I think we can have a systems programming language designed through such a process, even for decades, but it can’t also simultaneously have the kingpin role that C plays for compatibility and interoperability.


    score 1 · canonical







  • In terms of user-control, I don’t think GrapheneOS is the best solution in the Android ecosystem. It may well be the best in terms of security, but that’s a different question.

    Just like Google’s Android, GrapheneOS does not allow the user arbitrary filesystem access under any circumstances. This means a few things:

    • You cannot take full backups of your phone or otherwise take out all your data. All you can do is ask each app kindly via a backup API for the things it’s willing to give you.

    • If you ever want to replace GrapheneOS, maybe because you’ve found something better or because the project stops supporting your device, you need to re-unlock the bootloader, wiping all your data.

    In essence, this means that replacing Google’s Android with GrapheneOS swaps out one gatekeeper for another. Your data is still not yours. The same is true for e.g. CalyxOS, which also insists on locking the bootloader (with a non-user-controlled key) and providing no arbitrary filesystem access.

    This is a definite degradation compared to the previous generation of Android distros such as Lineage OS, where users kept full control of their device and their data. Is it worth giving that up in exchange for stronger security? Maybe, maybe not. All I’m saying is that GrapheneOS does not represent the optimum in terms of user control.


    score 1 · canonical