diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 40628a1d6d4..dd14033bbba 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -48,6 +48,7 @@ https://github.com/elastic/beats/compare/v8.8.1\...main[Check the HEAD diff] *Filebeat* - [threatintel] MISP pagination fixes {pull}37898[37898] +- Fix file handle leak when handling errors in filestream {pull}37973[37973] *Heartbeat* diff --git a/filebeat/input/filestream/input.go b/filebeat/input/filestream/input.go index b935161c126..90266b531bf 100644 --- a/filebeat/input/filestream/input.go +++ b/filebeat/input/filestream/input.go @@ -180,6 +180,9 @@ func (inp *filestream) open(log *logp.Logger, canceler input.Canceler, fs fileSo return nil, err } + ok := false // used for cleanup + defer cleanup.IfNot(&ok, cleanup.IgnoreError(f.Close)) + log.Debug("newLogFileReader with config.MaxBytes:", inp.readerConfig.MaxBytes) // if the file is archived, it means that it is not going to be updated in the future @@ -204,7 +207,6 @@ func (inp *filestream) open(log *logp.Logger, canceler input.Canceler, fs fileSo dbgReader, err := debug.AppendReaders(logReader) if err != nil { - f.Close() return nil, err } @@ -222,7 +224,6 @@ func (inp *filestream) open(log *logp.Logger, canceler input.Canceler, fs fileSo MaxBytes: encReaderMaxBytes, }) if err != nil { - f.Close() return nil, err } @@ -234,6 +235,7 @@ func (inp *filestream) open(log *logp.Logger, canceler input.Canceler, fs fileSo r = readfile.NewLimitReader(r, inp.readerConfig.MaxBytes) + ok = true // no need to close the file return r, nil } @@ -253,11 +255,11 @@ func (inp *filestream) openFile(log *logp.Logger, path string, offset int64) (*o return nil, fmt.Errorf("failed to open file %s, named pipes are not supported", fi.Name()) } - ok := false f, err := file.ReadOpen(path) if err != nil { return nil, fmt.Errorf("failed opening %s: %w", path, err) } + ok := false defer cleanup.IfNot(&ok, cleanup.IgnoreError(f.Close)) fi, err = f.Stat() @@ -281,14 +283,13 @@ func (inp *filestream) openFile(log *logp.Logger, path string, offset int64) (*o inp.encoding, err = inp.encodingFactory(f) if err != nil { - f.Close() if errors.Is(err, transform.ErrShortSrc) { return nil, fmt.Errorf("initialising encoding for '%v' failed due to file being too short", f) } return nil, fmt.Errorf("initialising encoding for '%v' failed: %w", f, err) } - ok = true + ok = true // no need to close the file return f, nil }