[Fix] Bound Iota storage, relay and transport resources

This commit is contained in:
Alex Emmet 2026-09-24 18:37:28 +02:00
commit e19c3c3d12
19 changed files with 609 additions and 48 deletions

View file

@ -4,6 +4,7 @@ version = "0.1.0"
edition = "2024"
[dependencies]
libc = "0.2"
async-trait = "0.1.89"
base64 = "0.22.1"
mtp = { git = "https://git.methanium.net/Methanium/mtp.git", rev = "bb0f682b735de5ebb36bb41dc699260578341828", features = ["crypto", "files", "raw"] }

View file

@ -179,6 +179,34 @@ impl fmt::Display for LocalNodeIdentityError {
impl std::error::Error for LocalNodeIdentityError {}
#[cfg(unix)]
fn verify_private_keyring(path: &Path) -> std::io::Result<()> {
use std::os::unix::fs::MetadataExt;
let metadata = match fs::symlink_metadata(path) {
Ok(metadata) => metadata,
Err(error) if error.kind() == std::io::ErrorKind::NotFound => return Ok(()),
Err(error) => return Err(error),
};
if !metadata.file_type().is_file()
|| metadata.mode() & 0o077 != 0
|| metadata.uid() != unsafe { libc::geteuid() }
{
return Err(std::io::Error::new(
std::io::ErrorKind::PermissionDenied,
"keyring must be a regular owner-only file owned by the service user",
));
}
Ok(())
}
#[cfg(not(unix))]
fn verify_private_keyring(_: &Path) -> std::io::Result<()> {
Err(std::io::Error::new(
std::io::ErrorKind::Unsupported,
"keyring permissions cannot be verified on this platform",
))
}
#[derive(Clone)]
pub struct LocalNodeIdentity {
keyring: Arc<mtp::crypto::Keyring>,
@ -210,6 +238,10 @@ impl LocalNodeIdentity {
source,
})?;
}
verify_private_keyring(path).map_err(|error| LocalNodeIdentityError::Storage {
path: path.display().to_string(),
source: error.to_string(),
})?;
let keyring = match mtp::files::load_keyring_raw(path) {
Ok(keyring) => keyring,
Err(mtp::files::FileError::Io(error))
@ -250,6 +282,10 @@ impl LocalNodeIdentity {
source: error.to_string(),
}
})?;
verify_private_keyring(path).map_err(|error| LocalNodeIdentityError::Storage {
path: path.display().to_string(),
source: error.to_string(),
})?;
let persisted = mtp::files::load_keyring_raw(path).map_err(|error| {
LocalNodeIdentityError::Storage {
path: path.display().to_string(),