From ec4538c6f7b892a775fea2e2eadecb95c138cfbb Mon Sep 17 00:00:00 2001 From: Marius Vollmer Date: Wed, 6 Mar 2024 18:21:16 +0200 Subject: [PATCH] storage: Always set config on cleartext block during mounting UDisks2 allows any block object to be used to update configuration items for any other block, and the mounting dialog was abusing that when mounting an encrypted filesystem: It would use the backing block to update the fstab entries of the cleartext block. This works perfectly fine, except that UDisks2 only guarantees proper notification ordering for the block used to make the method call. Thus, when calling UpdateConfiguration on the backing block, the "Configuration" property of the cleartext block would not necessarily be up-to-date yet when mount_at accesses it. --- pkg/storaged/filesystem/mounting-dialog.jsx | 24 +++++++++++---------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/pkg/storaged/filesystem/mounting-dialog.jsx b/pkg/storaged/filesystem/mounting-dialog.jsx index ae58ebad3226..b0ebb9f8a58a 100644 --- a/pkg/storaged/filesystem/mounting-dialog.jsx +++ b/pkg/storaged/filesystem/mounting-dialog.jsx @@ -243,16 +243,18 @@ export function mounting_dialog(client, block, mode, forced_options, subvol) { return Promise.resolve(); } - function maybe_unlock() { + async function maybe_unlock() { const crypto = client.blocks_crypto[block.path]; if (mode == "mount" && crypto) { - return (unlock_with_type(client, block, passphrase, passphrase_type) - .catch(error => { - dlg.set_values({ needs_explicit_passphrase: true }); - return Promise.reject(error); - })); + try { + await unlock_with_type(client, block, passphrase, passphrase_type); + return await client.wait_for(() => client.blocks_cleartext[block.path]); + } catch (error) { + dlg.set_values({ needs_explicit_passphrase: true }); + throw error; + } } else - return Promise.resolve(); + return block; } function maybe_lock() { @@ -275,14 +277,14 @@ export function mounting_dialog(client, block, mode, forced_options, subvol) { return (reload_systemd() .then(() => teardown_active_usage(client, usage)) .then(maybe_unlock) - .then(() => { + .then(content_block => { if (!old_config && new_config) - return (block.AddConfigurationItem(new_config, {}) + return (content_block.AddConfigurationItem(new_config, {}) .then(maybe_mount)); else if (old_config && !new_config) - return block.RemoveConfigurationItem(old_config, {}); + return content_block.RemoveConfigurationItem(old_config, {}); else if (old_config && new_config) - return (block.UpdateConfigurationItem(old_config, new_config, {}) + return (content_block.UpdateConfigurationItem(old_config, new_config, {}) .then(maybe_mount)); else if (new_config && !is_mounted(client, block)) return maybe_mount();