InitPaths is not threadsafe

There is a race when using InitPaths during initial beat configuration if you initialize more than a single beat in parallel.

Calling InitPaths calls Path.InitPaths (code), where Path is a shared global pointer. That method in turn calls initPaths, which sets the global ptr to the Path ptr passed by the caller. This creates a race where, if InitPaths is called in parallel, the global Path ptr can be redirected before MkdirAll gets called, meaning that some paths are not properly created and that beat initialization will fail.

An easy fix to make this threadsafe would be to declare a global mutex corresponding to the Paths var and then to wrap the Paths.InitPaths call with it:

var pathsMutex sync.Mutex

...

func InitPaths(cfg *Path) error {
    pathsMutex.Lock()
    defer pathsMutex.Unlock()
	return Paths.InitPaths(cfg)
}

Callers can also do this on their side, but will generally not think to do so unless they're aware of this issue since this is pretty non-obvious without delving into the implementation, which is why I believe this should be fixed in the library itself.

Thanks for bringing this up @asanderson15 and welcome to the Elastic discussion forums :wave:

If you have a GitHub account, would you mind creating an issue in the Beats repository for this: https://github.com/elastic/beats/issues/new/choose? That would be a better place to get Beats' developers attention to this technical implementation issue. If you don't have a GitHub account let me know and I'll create the issue on your behalf.

Thanks,

Shaunak

Filed: https://github.com/elastic/beats/issues/11869.

Thanks.

1 Like

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.