Skip to content

fix(cli): start lifetime modules before use in CLI commands#818

Open
A386official wants to merge 1 commit intofoxcpp:masterfrom
A386official:fix/cli-nil-pointer-crash
Open

fix(cli): start lifetime modules before use in CLI commands#818
A386official wants to merge 1 commit intofoxcpp:masterfrom
A386official:fix/cli-nil-pointer-crash

Conversation

@A386official
Copy link

Bug

maddy imap-acct and maddy creds CLI subcommands crash with a nil pointer dereference (SIGSEGV) when used with storage.imapsql:

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x38 pc=0xeb5430]

goroutine 1 [running]:
github.com/foxcpp/go-imap-sql.(*Backend).UpdateManager(...)
        github.com/foxcpp/go-imap-sql@v0.5.1-0.20250124140007-8da5567429d5/backend.go:343
github.com/foxcpp/maddy/internal/storage/imapsql.(*Storage).EnableUpdatePipe(...)
        internal/storage/imapsql/imapsql.go:348
github.com/foxcpp/maddy/internal/cli/ctl.openStorage(...)
        internal/cli/ctl/moduleinit.go:96

Root Cause

getCfgBlockModule() calls RegisterModules() then c.Modules.Get(), which triggers lazy Configure() on the target module. However, it never calls Start().

For storage.imapsql, Start() is what initializes the Back field (the go-imap-sql backend). Without it, Back is nil. When openStorage() then calls EnableUpdatePipe(), it dereferences store.Back.UpdateManager() on a nil Back, causing the SIGSEGV.

The server path works correctly because moduleMain() calls c.Lifetime.StartAll() after configuration, which invokes Start() on all LifetimeModule instances. The CLI path was missing this step.

Fix

Call c.Lifetime.StartAll() in getCfgBlockModule() after the module is retrieved from the registry. This ensures all lifetime modules (including the storage backend and its dependencies) are fully started before the CLI tries to use them.

Also wire up c.Lifetime.StopAll() on error paths in openStorage() and openUserDB() so that started modules are cleaned up when the type assertion fails.

Closes #815

The CLI subcommands (imap-acct, creds) load and configure modules from
the config file but never call Start() on them. For storage.imapsql
this leaves the Back field nil, so EnableUpdatePipe() dereferences a
nil UpdateManager and panics with SIGSEGV.

Call c.Lifetime.StartAll() in getCfgBlockModule() after module lookup
so that backends are fully initialized before the CLI uses them. Also
wire up c.Lifetime.StopAll() on error paths so modules are cleaned up
properly when the type assertion fails.

Fixes foxcpp#815
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

Successfully merging this pull request may close these issues.

imap-acct (and creds) CLI crashes with nil pointer when storage modules aren’t started

1 participant