Validate every singleton Domain Store row

This commit is contained in:
ms2k 2026-07-15 14:22:43 +09:00
commit 1fd87ba1bd
2 changed files with 36 additions and 11 deletions

View file

@ -167,13 +167,7 @@ impl HostCoordinatorDomainStore {
pub fn snapshot(&self) -> Result<DomainStore, DomainStoreError> {
self.validate_metadata()?;
let read = self.database.begin_read()?;
let domain = {
let table = read.open_table(DOMAINS)?;
let value = table
.get(SINGLETON_KEY)?
.ok_or(DomainStoreError::MissingRow("Domain"))?;
decode(value.value())?
};
let domain = read_domain(&read.open_table(DOMAINS)?)?;
let generations = read_generations(&read.open_table(GENERATIONS)?)?;
let participants = read_participants(&read.open_table(PARTICIPANTS)?)?;
let sessions = read_sessions(&read.open_table(SESSIONS)?)?;
@ -309,6 +303,21 @@ fn read_generations(
Ok(records)
}
fn read_domain(table: &redb::ReadOnlyTable<u8, &[u8]>) -> Result<Domain, DomainStoreError> {
let mut domain = None;
for entry in table.iter()? {
let (key, value) = entry?;
let record: Domain = decode(value.value())?;
if key.value() != SINGLETON_KEY {
return Err(DomainStoreError::InvalidRow("Domain key"));
}
if domain.replace(record).is_some() {
return Err(DomainStoreError::DuplicateRow("Domain"));
}
}
domain.ok_or(DomainStoreError::MissingRow("Domain"))
}
fn read_participants(
table: &redb::ReadOnlyTable<&[u8; 9], &[u8]>,
) -> Result<Vec<Participant>, DomainStoreError> {

View file

@ -248,6 +248,22 @@ fn metadata_and_typed_row_validation_fail_closed() {
HostCoordinatorDomainStore::open(lock, &row_directory.path("domain.redb"), &domain()),
Err(DomainStoreError::InvalidRow("Generation key"))
));
let domain_directory = TestDirectory::new("extra-domain-row");
drop(open_store(&domain_directory));
let database = Database::open(domain_directory.path("domain.redb")).unwrap();
let write = database.begin_write().unwrap();
{
let mut table = write.open_table(DOMAINS).unwrap();
table.insert(1, &[0xff, 0xff][..]).unwrap();
}
write.commit().unwrap();
drop(database);
let lock = try_exclusive_flock(lock_file(&domain_directory.path("domain.lock"))).unwrap();
assert!(matches!(
HostCoordinatorDomainStore::open(lock, &domain_directory.path("domain.redb"), &domain()),
Err(DomainStoreError::Codec(_))
));
}
#[test]