mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Fix fdnotifier.AddFD() to handle the case when queue already has events.
`notifier.addFD()` was simply updating the FD map, assuming that the queue is new and has no events registered. However, this assumption may not hold for some callers of fdnotifier.AddFD(), notably transport.connectionedEndpoint.SetBoundSocketFD(). This situation can arise if the application does socket(2) -> epoll_ctl(EPOLL_CTL_ADD) -> bind(2). This change gets rid of the said assumption. Fixes #9848 PiperOrigin-RevId: 595171718
This commit is contained in:
@@ -96,7 +96,7 @@ func (n *notifier) waitFD(fd int32, fi *fdInfo, mask waiter.EventMask) error {
|
||||
}
|
||||
|
||||
// addFD adds an FD to the list of FDs observed by n.
|
||||
func (n *notifier) addFD(fd int32, queue *waiter.Queue) {
|
||||
func (n *notifier) addFD(fd int32, queue *waiter.Queue) error {
|
||||
n.mu.Lock()
|
||||
defer n.mu.Unlock()
|
||||
|
||||
@@ -105,8 +105,14 @@ func (n *notifier) addFD(fd int32, queue *waiter.Queue) {
|
||||
panic(fmt.Sprintf("File descriptor %v added twice", fd))
|
||||
}
|
||||
|
||||
// We have nothing to wait for at the moment. Just add it to the map.
|
||||
n.fdMap[fd] = &fdInfo{queue: queue}
|
||||
info := &fdInfo{queue: queue}
|
||||
// We might already have something in queue to wait for.
|
||||
if err := n.waitFD(fd, info, queue.Events()); err != nil {
|
||||
return err
|
||||
}
|
||||
// Add it to the map.
|
||||
n.fdMap[fd] = info
|
||||
return nil
|
||||
}
|
||||
|
||||
// updateFD updates the set of events the fd needs to be notified on.
|
||||
@@ -188,8 +194,7 @@ func AddFD(fd int32, queue *waiter.Queue) error {
|
||||
return shared.initErr
|
||||
}
|
||||
|
||||
shared.notifier.addFD(fd, queue)
|
||||
return nil
|
||||
return shared.notifier.addFD(fd, queue)
|
||||
}
|
||||
|
||||
// UpdateFD updates the set of events the fd needs to be notified on.
|
||||
|
||||
Reference in New Issue
Block a user