diff options
| author | David Bremner <david@tethera.net> | 2019-11-24 22:31:34 -0400 |
|---|---|---|
| committer | David Bremner <david@tethera.net> | 2019-11-27 07:58:09 -0400 |
| commit | 8e2251484214d39bdb4872216239bd38eb7729ab (patch) | |
| tree | 8b0816b68ecee50b0b8e1469d4f92f9430280bfa /lib | |
| parent | 2a003f0f503b1e7a15b01664cf8217a4762d95cc (diff) | |
lib: fix memory error in notmuch_config_list_value
The documentation for notmuch_config_list_key warns that that the
returned value will be destroyed by the next call to
notmuch_config_list_key, but it neglected to mention that calling
notmuch_config_list_value would also destroy it (by calling
notmuch_config_list_key). This is surprising, and caused a use after
free bug in _setup_user_query_fields (first noticed by an OpenBSD
porter, so kudos to the OpenBSD malloc implementation). This change
fixes that use-after-free bug.
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/config.cc | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/lib/config.cc b/lib/config.cc index da71c16e..a8bcdf83 100644 --- a/lib/config.cc +++ b/lib/config.cc @@ -150,13 +150,17 @@ notmuch_config_list_valid (notmuch_config_list_t *metadata) return true; } +static inline char * _key_from_iterator (notmuch_config_list_t *list) { + return talloc_strdup (list, (*list->iterator).c_str () + CONFIG_PREFIX.length ()); +} + const char * notmuch_config_list_key (notmuch_config_list_t *list) { if (list->current_key) talloc_free (list->current_key); - list->current_key = talloc_strdup (list, (*list->iterator).c_str () + CONFIG_PREFIX.length ()); + list->current_key = _key_from_iterator (list); return list->current_key; } @@ -166,7 +170,7 @@ notmuch_config_list_value (notmuch_config_list_t *list) { std::string strval; notmuch_status_t status; - const char *key = notmuch_config_list_key (list); + char *key = _key_from_iterator (list); /* TODO: better error reporting?? */ status = _metadata_value (list->notmuch, key, strval); @@ -177,6 +181,7 @@ notmuch_config_list_value (notmuch_config_list_t *list) talloc_free (list->current_val); list->current_val = talloc_strdup (list, strval.c_str ()); + talloc_free (key); return list->current_val; } |
