[BUG] 2.4.3 SIGSEGV in fts_solr
Nick O'Connor via dovecot <[email protected]> Tue, 31 Mar 2026 23:47:18 -0700
| Newsgroups | gmane.mail.imap.dovecot |
|---|---|
| Message-ID | <[email protected]> |
Dovecot 2.4.3 crashes with SIGSEGV in indexer-worker and lmtp during FTS
Solr indexing. The crash is a use-after-free triggered when the HTTP
client does a DNS lookup for the Solr host.
Environment:
- Dovecot 2.4.3 (Alpine 3.23 / musl)
- Linux x86_64
- Filesystem: maildir on ZFS
- Solr 10.0.0
- fts_solr plugin with DNS-based Solr URL
dovecot -n:
# 2.4.3 (e278b1e09b): /etc/dovecot/dovecot.conf
# Pigeonhole version 2.4.3 (0bf9ee48)
# OS: Linux 6.12.74+deb13+1-amd64 x86_64
dovecot_config_version = 2.4.0
auth_mechanisms = oauthbearer xoauth2
dovecot_storage_version = 2.4.0
fts_autoindex = yes
fts_search_add_missing = yes
mail_always_cache_fields = date.save
mail_driver = maildir
mail_plugins {
fts = yes
fts_solr = yes
}
protocols = imap lmtp sieve
ssl = required
fts solr {
url = http://solr.example.com/solr/dovecot
}
(LDAP userdb/passdb, pigeonhole sieve, imapsieve for spam learning, and
oauth2 passdb omitted)
How to reproduce:
The crash occurs in the indexer-worker when processing multiple user
mailboxes sequentially for FTS indexing, using a DNS hostname for the
Solr URL.
Steps:
1. Configure fts_solr with a DNS-based URL (not an IP address)
2. Have the indexer-worker process mailboxes for more than one user
(e.g. fts_autoindex = yes with multiple users, or manual doveadm index
-A)
3. The first user session completes successfully. On the second user
session, the indexer-worker crashes with SIGSEGV during the DNS lookup
for the Solr host.
Reproduces reliably on musl (Alpine) due to aggressive memory reuse.
Likely also affects glibc but may not crash immediately due to delayed
reuse of freed memory.
Root cause:
The solr_http_client singleton outlives the user session that created
it. Its event chain holds a ref on the mail_storage_service_user event,
keeping it alive after the user is freed. The SETTINGS_EVENT_INSTANCE on
that event still points to the already-freed settings_instance. On the
next user session, dns_lookup() walks the stale event chain and
dereferences the dangling pointer in settings_instance_get().
Stack trace (from core dump, debug build with musl-dbg):
#0 strlen(s=0x415641d189485741) -- SIGSEGV, freed/reused
memory
#1 p_strdup() strfuncs.c:56
#2 event_add_str(key="protocol", value=...) lib-event.c:1099
#3 settings_instance_get() settings.c:2521
#4 settings_get_real() settings.c:2706
#5 settings_get_full() settings.c:2915
#6 settings_get(dns_client_setting_parser_info) settings.c:2976
#7 dns_client_init() dns-lookup.c:465
#8 dns_client_init_handle_failure() dns-lookup.c:317
#9 dns_lookup("solr.example.com") dns-lookup.c:337
#10 http_client_host_shared_lookup() http-client-host.c:166
#11 http_client_host_shared_refresh() http-client-host.c:195
#12-#19 http_client queue/host/request submit chain
#20 http_client_request_continue_payload()
http-client-request.c:1170
#21 http_client_request_send_payload()
http-client-request.c:1261
#22 solr_connection_post_more() solr-connection.c:269
Proposed fix:
Destroy solr_http_client in solr_connection_deinit() so it is recreated
with a fresh event chain on the next user session:
--- a/src/plugins/fts-solr/solr-connection.c
+++ b/src/plugins/fts-solr/solr-connection.c
@@ -117,6 +117,8 @@ void solr_connection_deinit(struct solr_connection
**_conn)
*_conn = NULL;
event_unref(&conn->event);
+ if (solr_http_client != NULL)
+ http_client_deinit(&solr_http_client);
i_free(conn->http_host);
i_free(conn->http_base_url);
I've been running for few days with the patch applied. FTS indexing
across multiple user sessions completes without crashes using a
DNS-based Solr URL.
Please let me know if there's anything else that would be helpful. The
core files have sensitive information so I've omitted them from the
report.
-Nick
_______________________________________________
dovecot mailing list -- [email protected]
To unsubscribe send an email to [email protected]