Repository navigation
doc: document config_setting_t pointer invalidation on override and re-read (#298) - #300
Merged
hyperrealm merged 2 commits intoSep 28, 2026
Conversation
…VERRIDES) When CONFIG_OPTION_ALLOW_OVERRIDES is enabled, config_setting_add() with a duplicate name internally calls config_setting_remove(), which recursively destroys the pre-existing setting object before the replacement is created. Any config_setting_t pointer previously returned for the overridden setting or its children is left dangling, and its next use is a use-after-free. Document this invalidation rule in the CONFIG_OPTION_ALLOW_OVERRIDES and config_setting_add() manual entries. Refs hyperrealm#298
config_read(), config_read_file() and config_read_string() all route through __config_read(), which calls config_clear() before parsing, recursively destroying the entire existing setting tree. Any config_setting_t pointer obtained before a re-read (a common pattern in daemons reloading configuration on SIGHUP) is left dangling. Add the corresponding note to the three manual entries. Refs hyperrealm#298
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Documentation-only fix for #298, implementing the approach agreed upon in the issue discussion (documenting the invalidation rules; a behavioral reuse-in-place fix was considered and set aside because pointers to children of a replaced setting would dangle in the same way).
Two undocumented invalidation rules currently leave
config_setting_t *handles dangling:CONFIG_OPTION_ALLOW_OVERRIDESenabled,config_setting_add()with a duplicate name internally callsconfig_setting_remove(), which recursively destroys the pre-existing setting object (__config_setting_destroy()). Any pointer previously returned for that setting or its children is left dangling, and its next use is a heap-use-after-free (CWE-416) — see the ASan trace in heap-use-after-free: config_setting_add() with CONFIG_OPTION_ALLOW_OVERRIDES silently destroys the existing setting, leaving callers with dangling pointers #298.config_read*()entry points route through__config_read(), which callsconfig_clear()before parsing, recursively destroying the entire existing setting tree. Any pointer obtained before a re-read (the classic daemon-reload-on-SIGHUP pattern) silently dangles; none of the three manual entries mentioned this.Changes (
doc/libconfig.texionly, no code changes)CONFIG_OPTION_ALLOW_OVERRIDES: note that overriding destroys the previous setting object (recursively, including any children) and invalidates all pointers previously returned for it, e.g. byconfig_setting_add(),config_setting_get_member(), orconfig_lookup().config_setting_add(): clarify that the "already exists"NULLreturn applies whenCONFIG_OPTION_ALLOW_OVERRIDESis turned off, and that when it is on the existing child setting is destroyed and replaced, invalidating previously returned pointers.config_read(),config_read_file(),config_read_string(): note that reading into a configuration discards any previously read configuration — all settings are recursively destroyed first (as withconfig_clear()) — so previously returned pointers become invalid and must not be used.The wording follows the patches posted and discussed in #298, rebased onto current master (
277b960; context had shifted slightly after #297).Verification
lib/libconfig.con current master: the override path (config_setting_add()→config_setting_remove()→__config_setting_destroy()) and the re-read path (config_read*()→__config_read()→config_clear()).makeinfo --no-split doc/libconfig.texiandmakeinfo --html --no-split doc/libconfig.texiboth build cleanly: no errors and no new warnings (the only warning,node `Lookup Differences' unreferenced, already exists on master and was introduced by docs: document differences between config_lookup and typed lookups (#242) #297). All five added notes were confirmed present in the rendered info and HTML output.If you would like the same note added to the corresponding C++ API entries (
Config::OptionAllowOverrides,Setting::add(),Config::read()/readFile()/readString()), I'm happy to include it here or in a follow-up PR.Fixes #298
Discovered with DarwinFuzz — Sergio Atienza Pastor, R&D department of MTP (Métodos y Tecnología) and UPM (Universidad Politécnica de Madrid). Full report and ASan trace in #298.