diff options
author | Ian Gudger <igudger@google.com> | 2019-06-13 17:24:58 -0700 |
---|---|---|
committer | Shentubot <shentubot@google.com> | 2019-06-13 17:26:22 -0700 |
commit | 0a5ee6f7b20ef4f5533766d753b85005f79ae613 (patch) | |
tree | 3ffc2f9ad60ab4ba97e9a924d925f3ff00fd8f5a /pkg/sentry/fs/ramfs/dir.go | |
parent | 05ff1ffaadaa0ac370365eb14febc761506735ce (diff) |
Fix deadlock in fasync.
The deadlock can occur when both ends of a connected Unix socket which has
FIOASYNC enabled on at least one end are closed at the same time. One end
notifies that it is closing, calling (*waiter.Queue).Notify which takes
waiter.Queue.mu (as a read lock) and then calls (*FileAsync).Callback, which
takes FileAsync.mu. The other end tries to unregister for notifications by
calling (*FileAsync).Unregister, which takes FileAsync.mu and calls
(*waiter.Queue).EventUnregister which takes waiter.Queue.mu.
This is fixed by moving the calls to waiter.Waitable.EventRegister and
waiter.Waitable.EventUnregister outside of the protection of any mutex used
in (*FileAsync).Callback.
The new test is related, but does not cover this particular situation.
Also fix a data race on FileAsync.e.Callback. (*FileAsync).Callback checked
FileAsync.e.Callback under the protection of FileAsync.mu, but the waiter
calling (*FileAsync).Callback could not and did not. This is fixed by making
FileAsync.e.Callback immutable before passing it to the waiter for the first
time.
Fixes #346
PiperOrigin-RevId: 253138340
Diffstat (limited to 'pkg/sentry/fs/ramfs/dir.go')
0 files changed, 0 insertions, 0 deletions