Skip to content

Commit 14cb346

Browse files
ShadowCursepb8o
andcommitted
feat(seccomp): update seccompiler to use libseccomp
libseccomp provides a better quality compiler for BPF seccomp programs than our current implementation. In our testing it produces BPF code with ~65% less instructions which makes final binaries smaller which in turn makes Firecracker binary smaller because we include them into Firecracker at build time. For this transition we create a minimal set of bindings for `libseccomp` in order to simplify maintenance and avoid adding additional dependencies. The only tricky issue with this transition is the way `ioctl` and other syscalls are checked with libseccomp. It always adds a check for the high bits of the request to be 0. Unfortunately when we build with `musl`, some syscalls like `ioctl` have upper bits set to 1. Because of this, we replace `Eq` with `MaskedEq` with mask `0x00000000FFFFFFFF` when the argument is 32bits. This commit also removes dependency of firecracker and vmm crates on the seccompiler crate. Co-authored-by: Pablo Barbáchano <[email protected]> Signed-off-by: Egor Lazarchuk <[email protected]>
1 parent 9ac6f3a commit 14cb346

34 files changed

+835
-4162
lines changed

Cargo.lock

Lines changed: 2 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/cpu-template-helper/src/utils/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use std::sync::{Arc, Mutex};
1212
use vmm::builder::{build_microvm_for_boot, StartMicrovmError};
1313
use vmm::cpu_config::templates::{CustomCpuTemplate, Numeric};
1414
use vmm::resources::VmResources;
15-
use vmm::seccomp_filters::get_empty_filters;
15+
use vmm::seccomp::get_empty_filters;
1616
use vmm::vmm_config::instance_info::{InstanceInfo, VmState};
1717
use vmm::{EventManager, Vmm, HTTP_MAX_PAYLOAD_SIZE};
1818
use vmm_sys_util::tempfile::TempFile;

src/firecracker/Cargo.toml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ libc = "0.2.169"
2222
log-instrument = { path = "../log-instrument", optional = true }
2323
micro_http = { git = "https://github.com/firecracker-microvm/micro-http" }
2424

25-
seccompiler = { path = "../seccompiler" }
2625
serde = { version = "1.0.217", features = ["derive"] }
2726
serde_derive = "1.0.136"
2827
serde_json = "1.0.135"
@@ -42,13 +41,12 @@ serde = { version = "1.0.217", features = ["derive"] }
4241
userfaultfd = "0.8.1"
4342

4443
[build-dependencies]
45-
bincode = "1.2.1"
4644
seccompiler = { path = "../seccompiler" }
4745
serde = { version = "1.0.217" }
4846
serde_json = "1.0.135"
4947

5048
[features]
51-
tracing = ["log-instrument", "seccompiler/tracing", "utils/tracing", "vmm/tracing"]
49+
tracing = ["log-instrument", "utils/tracing", "vmm/tracing"]
5250
gdb = ["vmm/gdb"]
5351

5452
[lints]

src/firecracker/build.rs

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,8 @@
11
// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
22
// SPDX-License-Identifier: Apache-2.0
33

4-
use std::collections::BTreeMap;
5-
use std::fs::File;
64
use std::path::Path;
75

8-
use seccompiler::common::BpfProgram;
9-
use seccompiler::compiler::{Compiler, JsonFile};
10-
116
const ADVANCED_BINARY_FILTER_FILE_NAME: &str = "seccomp_filter.bpf";
127

138
const JSON_DIR: &str = "../../resources/seccomp";
@@ -44,19 +39,7 @@ fn main() {
4439
// Also retrigger the build script on any seccompiler source code change.
4540
println!("cargo:rerun-if-changed={}", SECCOMPILER_SRC_DIR);
4641

47-
let input = std::fs::read_to_string(seccomp_json_path).expect("Correct input file");
48-
let filters: JsonFile = serde_json::from_str(&input).expect("Input read");
49-
50-
let arch = target_arch.as_str().try_into().expect("Target");
51-
let compiler = Compiler::new(arch);
52-
53-
// transform the IR into a Map of BPFPrograms
54-
let bpf_data: BTreeMap<String, BpfProgram> = compiler
55-
.compile_blob(filters.0, false)
56-
.expect("Successfull compilation");
57-
58-
// serialize the BPF programs & output them to a file
5942
let out_path = format!("{}/{}", out_dir, ADVANCED_BINARY_FILTER_FILE_NAME);
60-
let output_file = File::create(out_path).expect("Create seccompiler output path");
61-
bincode::serialize_into(output_file, &bpf_data).expect("Seccompiler serialization");
43+
seccompiler::compile_bpf(&seccomp_json_path, &target_arch, &out_path, false)
44+
.expect("Cannot compile seccomp filters");
6245
}

src/firecracker/examples/seccomp/jailer.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::fs::File;
55
use std::os::unix::process::CommandExt;
66
use std::process::{Command, Stdio};
77

8-
use seccompiler::{apply_filter, deserialize_binary};
8+
use vmm::seccomp::{apply_filter, deserialize_binary};
99

1010
fn main() {
1111
let args: Vec<String> = args().collect();

src/firecracker/examples/seccomp/panic.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use std::env::args;
44
use std::fs::File;
55

6-
use seccompiler::{apply_filter, deserialize_binary};
6+
use vmm::seccomp::{apply_filter, deserialize_binary};
77

88
fn main() {
99
let args: Vec<String> = args().collect();

src/firecracker/src/api_server/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ use std::sync::mpsc;
1414

1515
pub use micro_http::{Body, HttpServer, Request, Response, ServerError, StatusCode, Version};
1616
use parsed_request::{ParsedRequest, RequestAction};
17-
use seccompiler::BpfProgramRef;
1817
use serde_json::json;
1918
use utils::time::{get_time_us, ClockType};
2019
use vmm::logger::{
2120
debug, error, info, update_metric_with_elapsed_time, warn, ProcessTimeReporter, METRICS,
2221
};
2322
use vmm::rpc_interface::{ApiRequest, ApiResponse, VmmAction};
23+
use vmm::seccomp::BpfProgramRef;
2424
use vmm::vmm_config::snapshot::SnapshotType;
2525
use vmm_sys_util::eventfd::EventFd;
2626

@@ -78,7 +78,7 @@ impl ApiServer {
7878
// Load seccomp filters on the API thread.
7979
// Execution panics if filters cannot be loaded, use --no-seccomp if skipping filters
8080
// altogether is the desired behaviour.
81-
if let Err(err) = seccompiler::apply_filter(seccomp_filter) {
81+
if let Err(err) = vmm::seccomp::apply_filter(seccomp_filter) {
8282
panic!(
8383
"Failed to set the requested seccomp filters on the API thread: {}",
8484
err
@@ -208,7 +208,7 @@ mod tests {
208208
use vmm::builder::StartMicrovmError;
209209
use vmm::logger::StoreMetric;
210210
use vmm::rpc_interface::{VmmActionError, VmmData};
211-
use vmm::seccomp_filters::get_empty_filters;
211+
use vmm::seccomp::get_empty_filters;
212212
use vmm::vmm_config::instance_info::InstanceInfo;
213213
use vmm::vmm_config::snapshot::CreateSnapshotParams;
214214
use vmm_sys_util::tempfile::TempFile;

src/firecracker/src/api_server_adapter.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ use std::sync::{Arc, Mutex};
88
use std::thread;
99

1010
use event_manager::{EventOps, Events, MutEventSubscriber, SubscriberOps};
11-
use seccompiler::BpfThreadMap;
1211
use vmm::logger::{error, warn, ProcessTimeReporter};
1312
use vmm::resources::VmResources;
1413
use vmm::rpc_interface::{
1514
ApiRequest, ApiResponse, BuildMicrovmFromRequestsError, PrebootApiController,
1615
RuntimeApiController, VmmAction,
1716
};
17+
use vmm::seccomp::BpfThreadMap;
1818
use vmm::vmm_config::instance_info::InstanceInfo;
1919
use vmm::{EventManager, FcExitCode, Vmm};
2020
use vmm_sys_util::epoll::EventSet;

src/firecracker/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ use std::{io, panic};
1717
use api_server_adapter::ApiServerError;
1818
use event_manager::SubscriberOps;
1919
use seccomp::FilterError;
20-
use seccompiler::BpfThreadMap;
2120
use utils::arg_parser::{ArgParser, Argument};
2221
use utils::validators::validate_instance_id;
2322
use vmm::arch::host_page_size;
@@ -27,6 +26,7 @@ use vmm::logger::{
2726
};
2827
use vmm::persist::SNAPSHOT_VERSION;
2928
use vmm::resources::VmResources;
29+
use vmm::seccomp::BpfThreadMap;
3030
use vmm::signal_handler::register_signal_handlers;
3131
use vmm::snapshot::{Snapshot, SnapshotError};
3232
use vmm::vmm_config::instance_info::{InstanceInfo, VmState};

src/firecracker/src/seccomp.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ use std::fs::File;
55
use std::io::{BufReader, Read};
66
use std::path::Path;
77

8-
use seccompiler::{deserialize_binary, BpfThreadMap, DeserializationError};
9-
use vmm::seccomp_filters::get_empty_filters;
8+
use vmm::seccomp::{deserialize_binary, get_empty_filters, BpfThreadMap, DeserializationError};
109

1110
const THREAD_CATEGORIES: [&str; 3] = ["vmm", "api", "vcpu"];
1211

@@ -118,7 +117,7 @@ fn filter_thread_categories(map: BpfThreadMap) -> Result<BpfThreadMap, FilterErr
118117
mod tests {
119118
use std::sync::Arc;
120119

121-
use seccompiler::BpfThreadMap;
120+
use vmm::seccomp::BpfThreadMap;
122121
use vmm_sys_util::tempfile::TempFile;
123122

124123
use super::*;

0 commit comments

Comments
 (0)