Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

47 changes: 39 additions & 8 deletions polkadot/node/core/pvf/common/src/worker/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ use std::{
/// spawning the desired worker.
#[macro_export]
macro_rules! decl_worker_main {
($expected_command:expr, $entrypoint:expr, $worker_version:expr, $worker_version_hash:expr $(,)*) => {
($worker_kind:expr, $expected_command:expr, $entrypoint:expr, $worker_version:expr, $worker_version_hash:expr $(,)*) => {
fn get_full_version() -> String {
format!("{}-{}", $worker_version, $worker_version_hash)
}
Expand All @@ -67,6 +67,7 @@ macro_rules! decl_worker_main {
return
}

let mut do_security_checks = false;
match args[1].as_ref() {
"--help" | "-h" => {
print_help($expected_command);
Expand All @@ -81,7 +82,9 @@ macro_rules! decl_worker_main {
println!("{}", get_full_version());
return
},

"--check-all" => {
do_security_checks = true;
},
"--check-can-enable-landlock" => {
#[cfg(target_os = "linux")]
let status = if let Err(err) = security::landlock::check_can_fully_enable() {
Expand Down Expand Up @@ -187,6 +190,16 @@ macro_rules! decl_worker_main {
let socket_path = std::path::Path::new(socket_path).to_owned();
let worker_dir_path = std::path::Path::new(worker_dir_path).to_owned();

if do_security_checks {
$crate::worker::do_security_checks(
$worker_kind,
socket_path.clone(),
worker_dir_path.clone(),
node_version,
None
);
}

$entrypoint(socket_path, worker_dir_path, node_version, Some($worker_version));
}
};
Expand Down Expand Up @@ -317,6 +330,29 @@ pub fn run_worker<F>(
) where
F: FnMut(UnixStream, &WorkerInfo, SecurityStatus) -> io::Result<Never>,
{
let ( stream, worker_info, security_status ) = do_security_checks(
worker_kind,
socket_path,
worker_dir_path.clone(),
node_version,
worker_version,
);

// Run the main worker loop.
let err = event_loop(stream, &worker_info, security_status)
// It's never `Ok` because it's `Ok(Never)`.
.unwrap_err();

worker_shutdown(worker_info, &err.to_string());
}

pub fn do_security_checks(
worker_kind: WorkerKind,
socket_path: PathBuf,
worker_dir_path: PathBuf,
node_version: Option<&str>,
worker_version: Option<&str>,
) -> (UnixStream, WorkerInfo, SecurityStatus) {
#[cfg_attr(not(target_os = "linux"), allow(unused_mut))]
let mut worker_info = WorkerInfo {
pid: std::process::id(),
Expand Down Expand Up @@ -449,12 +485,7 @@ pub fn run_worker<F>(
}
}

// Run the main worker loop.
let err = event_loop(stream, &worker_info, security_status)
// It's never `Ok` because it's `Ok(Never)`.
.unwrap_err();

worker_shutdown(worker_info, &err.to_string());
( stream, worker_info, security_status )
}

/// Provide a consistent message on unexpected worker shutdown.
Expand Down
1 change: 1 addition & 0 deletions polkadot/node/service/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ thiserror = { workspace = true }
# Polkadot
polkadot-core-primitives = { workspace = true, default-features = true }
polkadot-node-core-parachains-inherent = { workspace = true, default-features = true }
polkadot-node-core-pvf-common = { workspace = true, default-features = true }
polkadot-node-network-protocol = { workspace = true, default-features = true }
polkadot-node-primitives = { workspace = true, default-features = true }
polkadot-node-subsystem = { workspace = true, default-features = true }
Expand Down
14 changes: 14 additions & 0 deletions polkadot/node/service/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,20 @@ pub enum Error {
node_version: String,
worker_path: PathBuf,
},

#[cfg(feature = "full-node")]
#[error("Execute binary failed security checks, execute binary: {exec_worker_path:?}, directory path: {exec_worker_dir_path:?}")]
ExecuteWorkerFailedSecurityChecks {
exec_worker_path: PathBuf,
exec_worker_dir_path: PathBuf,
},

#[cfg(feature = "full-node")]
#[error("Prepare binary failed security checks, prepare binary: {prep_worker_path:?}, path: {prep_worker_dir_path:?}")]
PrepareWorkerFailedSecurityChecks {
prep_worker_path: PathBuf,
prep_worker_dir_path: PathBuf,
},
}

/// Identifies the variant of the chain.
Expand Down
37 changes: 37 additions & 0 deletions polkadot/node/service/src/workers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
use super::Error;
use is_executable::IsExecutable;
use std::path::PathBuf;
use std::process::Command;

#[cfg(test)]
thread_local! {
Expand Down Expand Up @@ -97,6 +98,42 @@ pub fn determine_workers_paths(
log::warn!("Skipping node/worker version checks. This could result in incorrect behavior in PVF workers.");
}

let mut exec_worker_dir_path = exec_worker_path.clone();
let _ = exec_worker_dir_path.pop();
let exit_status = Command::new(&exec_worker_path)
// .arg("--socket-path")
// .arg(socket_path.as_ref().as_os_str())
.arg("--worker-dir-path")
.arg(exec_worker_dir_path.as_os_str())
.arg("--check-all")
.status()
.unwrap();

if exit_status.success() == false {
return Err(Error::ExecuteWorkerFailedSecurityChecks {
exec_worker_path,
exec_worker_dir_path }
);
}

let mut prep_worker_dir_path = prep_worker_path.clone();
let _ = prep_worker_dir_path.pop();
let exit_status = Command::new(&prep_worker_path)
// .arg("--socket-path")
// .arg(socket_path.as_ref().as_os_str())
.arg("--worker-dir-path")
.arg(prep_worker_dir_path.as_os_str())
.arg("--check-all")
.status()
.unwrap();

if exit_status.success() == false {
return Err(Error::PrepareWorkerFailedSecurityChecks {
prep_worker_path,
prep_worker_dir_path
});
}

Ok((prep_worker_path, exec_worker_path))
}

Expand Down
1 change: 1 addition & 0 deletions polkadot/src/bin/execute-worker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
//! Execute worker.

polkadot_node_core_pvf_common::decl_worker_main!(
polkadot_node_core_pvf_common::worker::WorkerKind::Execute,
"execute-worker",
polkadot_node_core_pvf_execute_worker::worker_entrypoint,
polkadot_cli::NODE_VERSION,
Expand Down
1 change: 1 addition & 0 deletions polkadot/src/bin/prepare-worker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
//! Prepare worker.

polkadot_node_core_pvf_common::decl_worker_main!(
polkadot_node_core_pvf_common::worker::WorkerKind::Prepare,
"prepare-worker",
polkadot_node_core_pvf_prepare_worker::worker_entrypoint,
polkadot_cli::NODE_VERSION,
Expand Down