Hacker News new | ask | show | jobs
by throwaway24006 1845 days ago
That's not the reality though. The current wisdom in security seems to be to follow reality. To eliminate shooting foots by both users and developers. See NaCl crypto library, libsodium, Noise protocol, Signal app, Tarsnap and restic, Brian Warner's magic-wormhole, Signify/Minisign, Filippo Valsorda's 'age', WireGuard.

Are there more?

1 comments

It's not just security. This applies generally where people will shoot at their own feet. In C++ I can apparently have an atomic integer and increment it:

  std::atomic<int> n = 0;
  n++;
Rust has atomics but they don't work that way.

  let n = std::sync::atomic::AtomicU32::new(0);
  n.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
Hmm. Why doesn't Rust's "AtomicU32" just implement AddAssign? If it implemented the AddAssign trait then you could at least write:

  n += 1
.. and that looks much nicer, it elides all that stuff about memory models, consistency, and... oh...

In the C++ code, the programmer thinks this variable n "is" atomic. It's an atomic integer right? But that's not a thing. C++ is mapping atomic integer operations, which are a thing, onto the type, and not making the integer itself magically atomic, it's just an ordinary (aligned) integer.

So if we tweak both examples to do some slightly trickier arithmetic...

  std::atomic<int> n = 0;
  std::atomic<int> m = 0;
  n++;
  m= m + n;

  use std::sync::atomic::{AtomicU32, Ordering};
  let n = AtomicU32::new(0);
  let m = AtomicU32::new(0);
  n.fetch_add(1, Ordering::SeqCst);
  m.fetch_add(n.load(Ordering::SeqCst), Ordering::SeqCst);
Once again, Rust seems much more verbose, but, wait, actually this isn't the same as the C++. This is probably what the C++ programmer intended but what they actually wrote means this:

  use std::sync::atomic::{AtomicU32, Ordering};
  let n = AtomicU32::new(0);
  let m = AtomicU32::new(0);
  n.fetch_add(1, Ordering::SeqCst);
  m.store(m.load(Ordering::SeqCst) + n.load(Ordering::SeqCst), Ordering::SeqCst);
Well that's just crazy. Now m can change between when we load from it, and when we add n to it, and then we store back this out-dated value. We definitely didn't want that. But it looked sane because C++ fools us into believing "Atomic integers" are a thing, which they actually aren't.