Skip to content

Commit a5b3288

Browse files
committed
Add prechecks for all key description-related operations
1 parent b7f74d4 commit a5b3288

File tree

5 files changed

+87
-2
lines changed

5 files changed

+87
-2
lines changed

src/engine/strat_engine/engine.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use crate::{
2727
backstore::ProcessedPathInfos,
2828
cmd::verify_executables,
2929
dm::get_dm,
30-
keys::StratKeyActions,
30+
keys::{validate_key_descs, StratKeyActions},
3131
liminal::{find_all, DeviceSet, LiminalDevices},
3232
names::KeyDescription,
3333
ns::MemoryFilesystem,
@@ -108,6 +108,10 @@ impl StratEngine {
108108
blockdev_paths: &[&Path],
109109
encryption_info: Option<&InputEncryptionInfo>,
110110
) -> StratisResult<CreateAction<PoolUuid>> {
111+
if let Some(ei) = encryption_info {
112+
validate_key_descs(ei.key_descs())?;
113+
}
114+
111115
validate_name(name)?;
112116
let name = Name::new(name.to_owned());
113117

@@ -526,6 +530,10 @@ impl Engine for StratEngine {
526530
encryption_info: Option<&InputEncryptionInfo>,
527531
integrity_spec: IntegritySpec,
528532
) -> StratisResult<CreateAction<PoolUuid>> {
533+
if let Some(ei) = encryption_info {
534+
validate_key_descs(ei.key_descs())?;
535+
}
536+
529537
validate_name(name)?;
530538
let name = Name::new(name.to_owned());
531539
let integrity_spec = ValidatedIntegritySpec::try_from(integrity_spec)?;

src/engine/strat_engine/keys.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,14 @@ pub(super) fn search_key_persistent(key_desc: &KeyDescription) -> StratisResult<
3232
search_key(keyring_id, key_desc.to_system_string())
3333
}
3434

35+
/// Validate that all key descriptions
36+
pub fn validate_key_descs<'a>(iter: impl Iterator<Item = &'a KeyDescription>) -> StratisResult<()> {
37+
for key_desc in iter {
38+
search_key_persistent(key_desc)?;
39+
}
40+
Ok(())
41+
}
42+
3543
/// Search the process keyring for the given key description.
3644
pub(super) fn search_key_process(
3745
key_desc: &VolumeKeyKeyDescription,

src/engine/strat_engine/pool/v1.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use stratisd_proc_macros::strat_pool_impl_gen;
2020
#[cfg(any(test, feature = "extras"))]
2121
use crate::engine::strat_engine::{
2222
backstore::UnownedDevices,
23+
keys::validate_key_descs,
2324
metadata::MDADataSize,
2425
thinpool::{ThinPoolSizeParams, DATA_BLOCK_SIZE},
2526
};
@@ -37,6 +38,7 @@ use crate::{
3738
ProcessedPathInfos,
3839
},
3940
crypt::{handle::v1::CryptHandle, CLEVIS_LUKS_TOKEN_ID, LUKS2_TOKEN_ID},
41+
keys::search_key_persistent,
4042
liminal::DeviceSet,
4143
metadata::disown_device,
4244
serde_structs::{FlexDevsSave, PoolSave, Recordable},
@@ -189,6 +191,10 @@ impl StratPool {
189191
devices: UnownedDevices,
190192
encryption_info: Option<&InputEncryptionInfo>,
191193
) -> StratisResult<(PoolUuid, StratPool)> {
194+
if let Some(ei) = encryption_info {
195+
validate_key_descs(ei.key_descs())?;
196+
}
197+
192198
let pool_uuid = PoolUuid::new_v4();
193199

194200
// FIXME: Initializing with the minimum MDA size is not necessarily
@@ -769,6 +775,8 @@ impl Pool for StratPool {
769775
return Err(StratisError::Msg("Specifying the token slot for binding is not supported in V1 pools; please migrate to V2 pools to use this feature".to_string()));
770776
}
771777

778+
search_key_persistent(key_description)?;
779+
772780
let changed = self.backstore.bind_keyring(key_description)?;
773781
if changed {
774782
Ok(CreateAction::Created((Key, LUKS2_TOKEN_ID)))
@@ -788,6 +796,13 @@ impl Pool for StratPool {
788796
return Err(StratisError::Msg("Specifying the token slot for rebinding is not supported in V1 pools; please migrate to V2 pools to use this feature".to_string()));
789797
}
790798

799+
if let Some(ei) = self.encryption_info_legacy() {
800+
if let Some(kd) = ei.key_description()? {
801+
search_key_persistent(kd)?;
802+
}
803+
}
804+
search_key_persistent(new_key_desc)?;
805+
791806
match self.backstore.rebind_keyring(new_key_desc)? {
792807
Some(true) => Ok(RenameAction::Renamed(Key)),
793808
Some(false) => Ok(RenameAction::Identity),

src/engine/strat_engine/pool/v2.rs

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ use crate::{
3030
ProcessedPathInfos, UnownedDevices,
3131
},
3232
crypt::DEFAULT_CRYPT_DATA_OFFSET_V2,
33+
keys::{search_key_persistent, validate_key_descs},
3334
liminal::DeviceSet,
3435
metadata::{disown_device, MDADataSize},
3536
serde_structs::{FlexDevsSave, PoolFeatures, PoolSave, Recordable},
@@ -41,7 +42,8 @@ use crate::{
4142
Key, KeyDescription, Name, OffsetDirection, OptionalTokenSlotInput, PoolDiff,
4243
PoolEncryptionInfo, PoolUuid, PropChangeAction, ReencryptedDevice, RegenAction,
4344
RenameAction, SetCreateAction, SetDeleteAction, SizedKeyMemory, StratFilesystemDiff,
44-
StratPoolDiff, StratSigblockVersion, TokenUnlockMethod, ValidatedIntegritySpec,
45+
StratPoolDiff, StratSigblockVersion, TokenUnlockMethod, UnlockMechanism,
46+
ValidatedIntegritySpec,
4547
},
4648
},
4749
stratis::{StratisError, StratisResult},
@@ -158,6 +160,10 @@ impl StratPool {
158160
encryption_info: Option<&InputEncryptionInfo>,
159161
integrity_spec: ValidatedIntegritySpec,
160162
) -> StratisResult<(PoolUuid, StratPool)> {
163+
if let Some(ei) = encryption_info {
164+
validate_key_descs(ei.key_descs())?;
165+
}
166+
161167
let pool_uuid = PoolUuid::new_v4();
162168

163169
// FIXME: Initializing with the minimum MDA size is not necessarily
@@ -692,6 +698,8 @@ impl Pool for StratPool {
692698
token_slot: OptionalTokenSlotInput,
693699
key_description: &KeyDescription,
694700
) -> StratisResult<CreateAction<(Key, u32)>> {
701+
search_key_persistent(key_description)?;
702+
695703
let changed = self.backstore.bind_keyring(token_slot, key_description)?;
696704
match changed {
697705
Some(t) => {
@@ -708,6 +716,41 @@ impl Pool for StratPool {
708716
token_slot: Option<u32>,
709717
new_key_desc: &KeyDescription,
710718
) -> StratisResult<RenameAction<Key>> {
719+
if let Some(e) = self.encryption_info() {
720+
match e {
721+
Either::Left(ei) => match token_slot {
722+
Some(t) => {
723+
let info = ei.get_info(t).ok_or_else(|| {
724+
StratisError::Msg(format!(
725+
"Failed to find key description for token slot {t}"
726+
))
727+
})?;
728+
match info {
729+
UnlockMechanism::KeyDesc(kd) => {
730+
search_key_persistent(kd)?;
731+
}
732+
_ => {
733+
return Err(StratisError::Msg(format!(
734+
"Token slot {t} is associated with a Clevis binding"
735+
)));
736+
}
737+
}
738+
}
739+
None => {
740+
if let Some((_, kd)) = ei.single_key_description() {
741+
search_key_persistent(kd)?;
742+
}
743+
}
744+
},
745+
Either::Right(pei) => {
746+
if let Some(kd) = pei.key_description()? {
747+
search_key_persistent(kd)?;
748+
}
749+
}
750+
}
751+
}
752+
search_key_persistent(new_key_desc)?;
753+
711754
match self.backstore.rebind_keyring(token_slot, new_key_desc)? {
712755
Some(true) => Ok(RenameAction::Renamed(Key)),
713756
Some(false) => Ok(RenameAction::Identity),
@@ -1216,6 +1259,8 @@ impl Pool for StratPool {
12161259
pool_uuid: PoolUuid,
12171260
encryption_info: &InputEncryptionInfo,
12181261
) -> StratisResult<CreateAction<(u32, (u32, SizedKeyMemory))>> {
1262+
validate_key_descs(encryption_info.key_descs())?;
1263+
12191264
match self.backstore.encryption_info() {
12201265
Some(_) => Ok(CreateAction::Identity),
12211266
None => {

src/engine/types/keys.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,15 @@ impl InputEncryptionInfo {
245245
clevis_infos_with_token_id,
246246
))
247247
}
248+
249+
pub fn key_descs(&self) -> impl Iterator<Item = &KeyDescription> {
250+
self.encryption_infos
251+
.iter()
252+
.filter_map(|(_, enc)| match enc {
253+
UnlockMechanism::KeyDesc(k) => Some(k),
254+
_ => None,
255+
})
256+
}
248257
}
249258

250259
impl From<EncryptionInfo> for InputEncryptionInfo {

0 commit comments

Comments
 (0)