diff --git a/doc/16-upgrading-icinga-2.md b/doc/16-upgrading-icinga-2.md index 6eaec877d..5ffbc7fce 100644 --- a/doc/16-upgrading-icinga-2.md +++ b/doc/16-upgrading-icinga-2.md @@ -172,6 +172,15 @@ Since the config sync change detection now uses checksums, this may fail with anything else than syncing configuration text files. Syncing binary files were never supported, but rumors say that some users do so. +This is now prohibited and logged. + +``` +[2019-08-02 16:03:19 +0200] critical/ApiListener: Ignoring file '/etc/icinga2/zones.d/global-templates/forbidden.exe' for cluster config sync: Does not contain valid UTF8. Binary files are not supported. +Context: + (0) Creating config update for file '/etc/icinga2/zones.d/global-templates/forbidden.exe' + (1) Activating object 'api' of type 'ApiListener' +``` + Such binaries wrapped into JSON-RPC cluster messages may always cause changes and trigger reload loops. In order to prevent such harm in production, use infrastructure tools such as Foreman, Puppet, Ansible, etc. to install diff --git a/lib/remote/apilistener-filesync.cpp b/lib/remote/apilistener-filesync.cpp index 79fa55b55..4aa381c43 100644 --- a/lib/remote/apilistener-filesync.cpp +++ b/lib/remote/apilistener-filesync.cpp @@ -794,12 +794,29 @@ void ApiListener::ConfigGlobHandler(ConfigDirInformation& config, const String& * * **Keep this intact to stay compatible with older clients.** */ - if (Utility::Match("*.conf", file)) + String sanitizedContent = Utility::ValidateUTF8(content); + + if (Utility::Match("*.conf", file)) { update = config.UpdateV1; - else + + // Configuration files should be automatically sanitized with UTF8. + update->Set(relativePath, sanitizedContent); + } else { update = config.UpdateV2; - update->Set(relativePath, content); + /* + * Ensure that only valid UTF8 content is being read for the cluster config sync. + * Binary files are not supported when wrapped into JSON encoded messages. + * Rationale: https://github.com/Icinga/icinga2/issues/7382 + */ + if (content != sanitizedContent) { + Log(LogCritical, "ApiListener") + << "Ignoring file '" << file << "' for cluster config sync: Does not contain valid UTF8. Binary files are not supported."; + return; + } + + update->Set(relativePath, content); + } /* Calculate a checksum for each file (and a global one later). *