Skip to content

Unreadable custom datadir can cause and exception #775

Description

@johnny9

Still finishing the rest of my review but I did find a blocker so posting it now.

On Linux, if the saved GUI-selected custom datadir still exists but is no longer readable, the app aborts at launch with an unhandled exception instead of re-showing the datadir chooser:

terminate called after throwing an instance of 'std::filesystem::__cxx11::filesystem_error'
what(): filesystem error: status: Permission denied [/bitcoin.conf]
Aborted (core dumped)

Repro:

  1. Fresh config dir, onboard choosing a custom data directory.
  2. chmod 000 (or any state where the directory exists but cannot be traversed, for example an external drive that remounts root-owned).
  3. Relaunch. Expected: the storage location chooser reappears. Actual: abort before any window, on every launch, until the user fixes permissions by hand or passes -choosedatadir.

Root cause: ResolveOnboardingStartupStatus correctly computes force_show_onboarding (ShouldShowDataDirChooser flags the directory as not writable), but then still reads the profile from it, because the gate is custom_datadir_exists = QFileInfo::exists(...) (qml/onboarding_settings.cpp, around line 406), and a mode-000 directory exists. It applies the datadir to the preview args and calls ReadConfigFiles, where fs::is_directory(conf_path) (src/common/config.cpp:134) stats /bitcoin.conf, gets EACCES, and throws. Nothing on the QML startup path catches std::filesystem_error, so the process terminates.

Suggested fix, two parts:

  1. Gate the profile read on the datadir being usable, not merely existing: the ValidateCustomDataDir result is already computed for force_show_onboarding two lines above, so can_read_profile should exclude a custom datadir that failed validation.
  2. Wrap the preview's config/settings read in a try/catch that turns fs::filesystem_error into status.error, so any remaining gap of this kind degrades to the onboarding error path instead of std::terminate.

The existing unit test covers the unwritable case (guiDataDirChooserShowsForUnwritableConfiguredDir) but not the unreadable one, which is why this survives a green suite; a sibling test with a mode-000 directory would pin the fix.

Originally posted by @epicleafies in #742 (comment)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    Status
    Open

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions