Skip to content

Possible atomicity violation in reseeding register_fork_handler #911

@Chain-Fox

Description

@Chain-Fox

pub fn register_fork_handler() {
if !FORK_HANDLER_REGISTERED.load(Ordering::Relaxed) {
unsafe { libc::pthread_atfork(None, None, Some(fork_handler)) };
FORK_HANDLER_REGISTERED.store(true, Ordering::Relaxed);
}
}
}

In function register_fork_handler:

  1. load and check the atomic variable FORK_HANDLER_REGISTERED.
  2. if not, call the C library function.
  3. set the atomic variable so that the next call of the same function will not execute the C library function again.

It seems to me that atomic FORK_HANDLER_REGISTERED is utilized to guarantee that libc::pthread_at_fork is only called once.

However, if the function is called by two threads, a possible atomicity violation may happen:

  1. Th1: load and check
  2. Th2: load and check; call C function; set the value
  3. Th1: call C function again

The fix is simple: use one compare_and_swap() to replace the two separate atomic load and store.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions