Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

preload: fix sigmask block and restore race #253

Merged
merged 1 commit into from
Jul 22, 2024

Conversation

barathrm
Copy link

@barathrm barathrm commented Jul 20, 2024

Related to and discussed more at #252


To avoid clobbering a threads signal mask with that of another thread, take locks before storing a thread's signal mask in case another thread has already stored its own signal mask in the trap_path_sig_restore variable, but has not yet restored it.

Without this change, the following could happen:

If umockdev-run is used to run a process which spawns multiple threads, and each of those threads writes to a file, and has specific signal mask requirements, the following may happen

  • Thread A:

    • store thread A's sigmask in trap_path_sig_restore and block all signals for thread A
    • acquire trap_path_lock
  • Thread B:

    • store thread B's sigmask in trap_path_sig_restore and block all signals for thread B. Thread A's original signal mask is lost.
    • wait on acquiring trap_path_lock
  • Thread A:

    • "restore" thread A's sigmask using trap_path_sig_restore, which now contains thread B's sigmask, thus clobbering thread A's original sigmask with that of thread B.

To avoid clobbering a threads signal mask with that of another thread,
take locks before storing a thread's signal mask in case another thread
has already stored its own signal mask in the trap_path_sig_restore
variable, but has not yet restored it.

Without this change, the following could happen:

If umockdev-run is used to run a process which spawns multiple threads, and
each of those threads writes to a file, and has specific signal mask
requirements, the following may happen

- Thread A:
    - store thread A's sigmask in trap_path_sig_restore and block all
      signals for thread A
    - acquire trap_path_lock

- Thread B:
    - store thread B's sigmask in trap_path_sig_restore and block all
      signals for thread B. Thread A's original signal mask is lost.
    - wait on acquiring trap_path_lock

- Thread A:
    - "restore" thread A's sigmask using trap_path_sig_restore, which
      now contains thread B's sigmask, thus clobbering thread A's
      original sigmask with that of thread B.
@martinpitt
Copy link
Owner

Hello @barathrm ! Oh dear, you clearly win my "bug report and analysis of the year" trophy! 🏆 Thanks so much for tracking this down!

The fix is straightforward, as usual in these cases (where there's a ton of work in debugging and understanding the problem).

Unfortunately meson is making a boo-boo in Debian testing. That has nothing to do with your fix, it just broke independently. I'll investigate this, and then rebase/queue your PR after that fix.

Cheers!

Copy link
Owner

@martinpitt martinpitt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reported the meson bug here: mesonbuild/meson#13461

Not sure how to work around this, I don't want to block on this, so I'll ignore the Debian-testing failure. It's tested on all the other OSes.

Thanks again!

@martinpitt martinpitt merged commit 284dcf1 into martinpitt:main Jul 22, 2024
20 of 23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants