Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Catch metadata realm decryption. #4285

Merged
merged 18 commits into from
May 11, 2021
Merged

Catch metadata realm decryption. #4285

merged 18 commits into from
May 11, 2021

Conversation

ejm01
Copy link
Contributor

@ejm01 ejm01 commented Jan 13, 2021

Related to RCOCOA-1035

What, How & Why?

What: Opening a metadata realm with the wrong encryption key or should_encrypt property will now remove the metadata realm and create a new realm using the new key or configuration option.

How: Catch opening the metadata realm when the SyncMetadataManager is being constructed. If caught exception, remove metadata realm, open a new one in its place.

Why: Realm-core creates an encryption key for devices if one does not exist. It's possible for a device to lose its encryption key, but retain the sync metadata realm (for example, via a backup). Previously, the newly created key couldn't open the realm and an exception could be thrown each time the app is started.

☑️ ToDos

  • 📝 Changelog update
  • 🚦 Tests (or not relevant)

@ejm01
Copy link
Contributor Author

ejm01 commented Jan 15, 2021

This line is necessary in the test to produce a RealmFileException. Without it, the test raises a MismatchedConfiguration which doesn't reflect the decryption failure expected in production.

Screen Shot 2021-01-14 at 3 55 58 PM

@ejm01 ejm01 requested a review from tgoyne January 15, 2021 20:30
@tgoyne
Copy link
Member

tgoyne commented Jan 15, 2021

That indicates that there's something still holding onto the RealmCoordinator after failing to open the Realm. Clearing the cache works around one specific symptom of that without fixing the problem, and will break things if there are any other Realms open.

realm = get_realm();
}
catch (const RealmFileException&) {
if (!should_encrypt)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should check the error code from the exception rather than should_encrypt.

Copy link
Contributor Author

@ejm01 ejm01 Jan 19, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Opening with the wrong key and opening when should_encrypt configuration doesn't match the original configuration are both RealmFileException::Kind::AccessError and have the same error message. What other ways are there to differentiate?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In both of those cases we want to delete the Realm and recreate it. Currently this code will delete the Realm when any error occurs if we want to encrypt the Realm even if it's an unrelated error, and will fail to delete the Realm in a case where we want to (disabling encryption when the existing file is encrypted).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I understand. I previously was trying to retain the response of throwing an error when should_encrypt == false was applied to a path that was encrypted.

@ejm01
Copy link
Contributor Author

ejm01 commented Jan 21, 2021

Clearing the cache works around one specific symptom of that without fixing the problem, and will break things if there are any other Realms open.

The usage of this realm_coordinate->clear_cache() is only used in the test. I couldn't find another way to close the metadata realm in order to attempt opening with the wrong key. I tried with other methods on RealmCoordinator and FileManager. I think the problem is that using get_or_make_user_metadata still holds the realm open. I looked through other tests that use this method but none of them require closing the realm immediately after using the method.

Do you also mean that using clear cache is dangerous in a testing context?

CHECK(user_metadata->is_valid());

// Close realm
_impl::RealmCoordinator::get_coordinator(metadata_path)->clear_cache();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tgoyne Is clearing the cache here bad? I couldn't figure any other way to successfully close the realm. I understand there are dangers for doing this normally, but would it be suitable for a test context?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The above code needs to be wrapped in another scope. The metadata realm will be closed when everything using it goes out of scope (in this case, just user_metadata as the manager itself doesn't keep the Realm open).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me know if 8317f78 is what you mean.

@ejm01 ejm01 requested a review from tgoyne May 11, 2021 16:26
@ejm01
Copy link
Contributor Author

ejm01 commented May 11, 2021

I'm going to retry build because the CI error looks like a server connectivity thing. Then I'll merge.

@ejm01 ejm01 merged commit 3b747b1 into master May 11, 2021
@ejm01 ejm01 deleted the em/metadata-encrypt-failure branch May 11, 2021 19:01
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 22, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants