News for hackers. Stuff that matters.
Re:Security Issues with LastPass on Android by d7duhsebh on Saturday May 29, 2021 @08:21AM (#27324795)
Most people realize they can hurt themselves if they use a hammer wrong. If someone can be expected to put four years of their life into a degree or prepatory trade training they can be held accountable for not caring enough to spend 10 minutes reading about effective use of their password manager.
Re:Security Issues with LastPass on Android by throwaway24006 on Saturday May 29, 2021 @09:23AM (#27325048)
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?

Re:Security Issues with LastPass on Android by tialaramex on Saturday May 29, 2021 @12:39PM (#27326397)
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.