From d00e68e55069216cd1022d1f304d24db379607ca Mon Sep 17 00:00:00 2001 From: Paul Holzinger Date: Wed, 3 Jul 2024 11:11:51 +0200 Subject: [PATCH] podman events: fix error race The events code makes use of two channels, one for the events and one for the resulting error. Then in the main file we have a loop reading from both channels that should exit on first error it gets. However in case the event channel is closed before the error channel cotains the error it could caused an early exit as it looked like all events were done. Commit c46884aa93 fixed that somewhat by checking for an error in the error channel before exiting. This however was still racy as it added a default case in the select which means the channel check is non blocking. Thus the error was not yet send into the channel. To fix this we should make it a blocking read to wait for the error in the channel. Also the err != nil check can be removed as we either return err or nil anyway. And as last step make sure the error channel is closed, that prevents us from blocking forever in case the main select already processed the nil error. Fixes #23165 Signed-off-by: Paul Holzinger --- cmd/podman/system/events.go | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/cmd/podman/system/events.go b/cmd/podman/system/events.go index 44b24319c0..b4e1317d9e 100644 --- a/cmd/podman/system/events.go +++ b/cmd/podman/system/events.go @@ -163,6 +163,7 @@ func eventsCmd(cmd *cobra.Command, _ []string) error { go func() { errChannel <- registry.ContainerEngine().Events(context.Background(), eventOptions) + close(errChannel) }() for { @@ -170,14 +171,8 @@ func eventsCmd(cmd *cobra.Command, _ []string) error { case event, ok := <-eventChannel: if !ok { // channel was closed we can exit - select { - case err := <-errChannel: - if err != nil { - return err - } - default: - } - return nil + // read the error channel blocking to make sure we are not missing any errors (#23165) + return <-errChannel } switch { case doJSON: