The NX bit is not just about security

(purplesyringa.moe)

27 points | by torutofu 2 days ago

6 comments

  • asveikau 48 minutes ago
    On this theme of it not being just about security: if you have a bug like a use after free and it happens to cover a function pointer, the nx bit can ensure that when you follow that pointer through a call, you get a clean trap as close to the failure point as possible. If it blindly executed stale bytes as code, maybe the crash and stack trace doesn't look as nice.

    But then, a lot of correctness bugs like that are also security problems.

  • mubbicles 24 minutes ago
    I appreciated this article. I've asked our CSP guy the difference, but this helps me better understand device vs ns. I also appreciate that this doesn't appear AI written.
  • eqvinox 13 minutes ago
    Honestly feels like a misdesign in ARM. Where does it ever make sense for Device memory to not be data prefetchable, but allow instruction prefetch? It should IMHO disable all prefetch…
  • tripdout 59 minutes ago
    I really wish I understood this, it hits a bunch of topics that I've heard of and are/sound interesting, but I don't know enough to follow it.
    • RiverCrochet 22 minutes ago
      Basically, the NX bit prevents CPU behavior (speculative fetches) that had a hand in Spectre-type vulnerabilities. That's surprising because that's not its purpose. This is for ARM CPUs.
      • jnwatson 13 minutes ago
        No, NX precedes Spectre by a long shot. It was originally intended so an attacker couldn't use a buffer overflow to change the PC and execute directly out of the attacker-controlled buffer.
    • zephen 26 minutes ago
      In an attempt to go fast and beat benchmarks and other computers, CPUs attempt to speculatively execute code, and then later undo the results of the speculation if it turns out it was wrong. This causes all sorts of security issues (spectre, meltdown, and friends et al.) even when it's done relatively competently.

      When it's done incompetently as on this ARM implementation, then you can't even run perfectly good and correct code, because the CPU will attempt speculative execution on a location that you never asked it to execute code at, and then bork itself when it realizes that can't possibly work.

      Naturally, this is the sort of problem that requires tedious dissection of what exactly happened, and copious amounts of alcohol.

  • crazy1_ 53 minutes ago
    this is so amazing
  • Nail2680 56 minutes ago
    Hot take: NX bit is shit W^X is shit. proper JIT is having objects written as needed, and cache line flushing is full bullshit, we need self modifying code as a first class citizen and with modern techiques we can have it work and not be crazy slow, it is currently cuz shits fucked, but we can do better.
    • neerajsi 13 minutes ago
      Disallowing smc is a significant perf/power win. For cpus that run a large variety of large code (e.g. a web browser or ux stack), being able to cache a large instruction footprint and fetch/decode it quickly is important. Having to have the icache snoop data writes and entangle the i-fetch with the store buffer machinery would be a huge penalty to pay for a niche use case. Unlike loads, which are a small fraction of instructions to disambiguate with stores, you'd have to disambiguate every single instruction.

      JIT is important to Apple platforms, and they seem to manage to make it work well enough even with the need for explicit invalidation.

      • Nail2680 8 minutes ago
        So that is only true because we do it, there is a world where we optimize differently and that self modifying version works better, reread the synthesis kernel thesis(one, it is super easy, two they did this), we could have hardware that does this. Because we don't have hardware that does this we don't
    • RiverCrochet 20 minutes ago
      L take. RAM is too slow for self-modifying code to be anywhere but F tier. This isn't 6502 land.
      • Nail2680 15 minutes ago
        But it could be, there are bits about doing computation in RAM, self modifying code could work.
    • Nail2680 28 minutes ago
      Well it was a hot take.
      • eqvinox 17 minutes ago
        Are you unaware that you can write code to RW memory, remap it to RX and then run it? That's how all JIT works these days.

        (Or did you confuse cache flushing with TLB flushing? The remap does the latter, not the former.)

        • Nail2680 12 minutes ago
          Yeah, that works okay, but really is a you shouldn't, with pipelining you lose all the predictive decoding. The Synthesis kernel did some cool ass shit with this, but failed in other architectures due to pipelining, which speeds up shit, but change the opcodes(with other instructions(ie selfmodyfing code)) and shit gets flushed.