From 76a05323685afa2b5a34f5eb5e879e959e28bebe Mon Sep 17 00:00:00 2001 From: Nayana Bidari Date: Mon, 26 Jun 2023 13:39:05 -0700 Subject: [PATCH] Release the lock after reading all the fields from FileAsync in NotifyEvent. This CL makes changes to read all the fields from FAsync struct at once to avoid inconsistent results when FileAsync is changed. PiperOrigin-RevId: 543528321 --- pkg/sentry/kernel/fasync/fasync.go | 37 ++++++++++++++++-------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/pkg/sentry/kernel/fasync/fasync.go b/pkg/sentry/kernel/fasync/fasync.go index 0e6f4dc38..a4ae2f684 100644 --- a/pkg/sentry/kernel/fasync/fasync.go +++ b/pkg/sentry/kernel/fasync/fasync.go @@ -88,20 +88,21 @@ type FileAsync struct { // NotifyEvent implements waiter.EventListener.NotifyEvent. func (a *FileAsync) NotifyEvent(mask waiter.EventMask) { a.mu.Lock() - locked := true - defer func() { - if locked { - a.mu.Unlock() - } - }() if !a.registered { + a.mu.Unlock() return } + // Read all the required fields which are lock protected from FileAsync + // and release the lock. t := a.recipientT tg := a.recipientTG + creds := a.requester + sig := a.signal if a.recipientPG != nil { tg = a.recipientPG.Originator() } + a.mu.Unlock() + if tg != nil { t = tg.Leader() } @@ -109,13 +110,13 @@ func (a *FileAsync) NotifyEvent(mask waiter.EventMask) { // No recipient has been registered. return } - c := t.Credentials() + tCreds := t.Credentials() // Logic from sigio_perm in fs/fcntl.c. - permCheck := (a.requester.EffectiveKUID == 0 || - a.requester.EffectiveKUID == c.SavedKUID || - a.requester.EffectiveKUID == c.RealKUID || - a.requester.RealKUID == c.SavedKUID || - a.requester.RealKUID == c.RealKUID) + permCheck := (creds.EffectiveKUID == 0 || + creds.EffectiveKUID == tCreds.SavedKUID || + creds.EffectiveKUID == tCreds.RealKUID || + creds.RealKUID == tCreds.SavedKUID || + creds.RealKUID == tCreds.RealKUID) if !permCheck { return } @@ -123,8 +124,8 @@ func (a *FileAsync) NotifyEvent(mask waiter.EventMask) { Signo: int32(linux.SIGIO), Code: linux.SI_KERNEL, } - if a.signal != 0 { - signalInfo.Signo = int32(a.signal) + if sig != 0 { + signalInfo.Signo = int32(sig) signalInfo.SetFD(uint32(a.fd)) var band int64 for m, bandCode := range bandTable { @@ -134,9 +135,11 @@ func (a *FileAsync) NotifyEvent(mask waiter.EventMask) { } signalInfo.SetBand(band) } - a.mu.Unlock() - locked = false - t.SendSignal(signalInfo) + if tg != nil { + t.SendGroupSignal(signalInfo) + } else { + t.SendSignal(signalInfo) + } } // Register sets the file which will be monitored for IO events.