Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Matomo configuration reset due to race condition #23067

Open
Bacto opened this issue Feb 24, 2025 · 0 comments
Open

Matomo configuration reset due to race condition #23067

Bacto opened this issue Feb 24, 2025 · 0 comments

Comments

@Bacto
Copy link

Bacto commented Feb 24, 2025

Hello,

I've encountered a bug where, at random times, Matomo resets to an unconfigured state, displaying the installation phase in the web UI.

In these cases, the config/config.ini.php file contains only the following:

[General]
installation_first_accessed = 1740328930

After extensive investigation, I identified the root cause: a race condition triggered by using the config:set CLI command (or any other action that writes to the configuration file).

How to reproduce

Run config:set commands in a loop:

while true; do php console config:set --section General --key test --value 1; done

In my case, running this loop in four different terminals caused config/config.ini.php to be erased within seconds, leaving only:

; <?php exit; ?> DO NOT REMOVE THIS LINE
; file automatically generated or modified by Matomo; you can manually override default values in global.ini.php by redefining them in this file.
[global]
test = "1"

When accessing the Matomo web UI, the installation process is triggered, and config/config.ini.php is rewritten as follows:

; <?php exit; ?> DO NOT REMOVE THIS LINE
; file automatically generated or modified by Matomo; you can manually override default values in global.ini.php by redefining them in this file.
[General]
installation_first_accessed = 1740329172

[global]
test = 1

Root causes

1. The configuration reader does not handle locks

When writing the configuration, file_put_contents is used with LOCK_EX, which is good. However, the reader does not support locks.

This creates a race condition when the configuration file is being written while another process reads it. If the file is truncated during reading, Matomo may interpret it as missing installation details and re-trigger the installation process, adding installation_first_accessed to the configuration file.

2. The sanityCheck function doesn't handle locks and is unnecessary

The sequence of events in Matomo's configuration process is problematic:

  1. The configuration file is first written to disk.
  2. The sanityCheck function is then called.
  3. This function reads the configuration file (without locking) and verifies its contents. If there is a difference, the file is rewritten.

This introduces two issues:

  1. The lack of locking in the sanityCheck function leads to the same race condition as with the reader.
  2. The logic itself is questionable. If a write operation is performed, we should assume the OS did it. There is no apparent reason to re-read the file, and even less reason to rewrite it.

Solutions

1. Implement lock handling in the configuration reader

Matomo's configuration reader is handled by the ini component. I have patched it to support file locking and wait for the lock to be released before reading.
See matomo-org/component-ini#28

2. Remove the sanityCheck function

I have patched Matomo's Config class to remove the sanityCheck function, as it introduces a race condition and serves no useful purpose.
See #23066

I'm running these two patches and they totally solved the problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant