← Back to context

Comment by tux3

10 hours ago

Advisories with the details are public:

https://github.com/php/php-src/security/advisories/GHSA-w8hw...

https://github.com/php/php-src/security/advisories/GHSA-6wmf...

>PHP uses longjmp()

Well off to a good start here.

  • It's not exactly uncommon, it's basically C's equivalent to exceptions. It lets you avoid having to do an extra error checking branch after every fallible operation and can quite significantly speed up the happy path of a language VM.

    • I know but I don't think the risks justify using this, as demonstrated here. "It's fine when it's used correctly" except it's so hard to use correctly. It completely messes up any analysis of codepaths because you have this "time travel" footgun that can bypass everything.

      Exceptions aren't great for that either, but languages that feature them at least have the tooling and support features to make them work. C has no destructors or anything to handle exception unwinding cleanly. Scheme has call/cc, but scheme has a big runtime and garbage collector to deal with the fallout.

      Let the branch predictor do its job and implement error checking properly, I say. If performance matters so much that you worry about pipeline flushes and icache thrashing, surely you wouldn't be using PHP anyway.

      setjmp, longjmp and gets are 3 function I would absolutely ban in any C codebase I would be responsible for. Maybe strncpy too. and strtok. C is fun.

    • > It's not exactly uncommon, it's basically C's equivalent to exceptions.

      longjmp is very uncommon, I don't recall seeing any high-quality C codebase using it, and if you want exceptions, you should pick a different language because longjmp doesn't really give you comparable semantics. It's basically saying "ok, computer, f--k my s--t up".

      The fact that OOM conditions are an enduring source of exploitable vulnerabilities in PHP really should give everyone a pause. Like, that's not a thing in any sane project.

      1 reply →

    • It's C's equivalent to exceptions, except without any of the stuff that might actually make exceptions safe and reasonable to use in other languages.

      There's no automatic cleanup of anything, no built-in way to even register things for manual cleanup, and it doesn't even consistently save/restore the values of your local variables. A local variable that was mutated between the setjmp and longjmp may end up with the old value or the new value depending on where the compiler decided to store it. The documentation does mention this and says that you need to use the volatile keyword to avoid it, but in typical C fashion there's nothing to enforce this, it's just up to the programmer to remember it.

      It is extremely uncommon in C codebases because it is extremely dangerous. It makes hazards like pointer arithmetic and manually-terminated strings look like a walk in the park by comparison.

  • Not that uncommon for a language interpreter? Pretty sure MicroPython does some setjmp/longjmp for non-local returns.

did I skim this correctly that with the mitigation shared this does not (yet) impact fpm-usage and classic CGI (vs. mod_php) is not impacted either?