rust-lang/log

`AtomicUsize` has an unsound `Sync` impl

djkoloski opened this issue · 5 comments

The comment on the Sync impl for AtomicUsize is:

// Any platform without atomics is unlikely to have multiple cores, so
// writing via Cell will not be a race condition.

While this may be true in practice, it's still technically incorrect and could open the door for bad codegen. Is there some background on why this impl is required even for platforms that don't support atomics?

I believe this was added to support embedded system which don't support atomics (or threads). I don't even think it's possible to support threads without some of atomics, but I could be wrong here.

While embedded systems may not have threads, many of them still have interrupts. It is possible to start writing to an AtomicUsize, then have an interrupt, and then read that value inside of the interrupt handler, which leads to undefined behavior. The usual solution is to disable interrupts while you are writing to the AtomicUsize.

This is documented in set_logger_racy.

I see, I missed that. In that case it should be sound since it is only used when safety can be enforced.

Since MAX_LOG_LEVEL_FILTER is also an AtomicUsize, doesn't that mean that set_max_level should be set up the same way? i.e. set_max_level should be behind a #[cfg(atomic_cas)] and an unsafe set_max_level_racy should be available everywhere.

The potential for UB here is a similar setup where you start writing with set_max_level, have an interrupt, then read the value with max_level which transmutes the memory and may produce an invalid LevelFilter.