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
10 changes: 3 additions & 7 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
---
name: Bug report
about: Create a report to help us improve
title: '[Bug] Title'
labels: 'Quality: Bug'
assignees: ''
---
______________________________________________________________________

## name: Bug report about: Create a report to help us improve title: '[Bug] Title' labels: 'Quality: Bug' assignees: ''

# Describe the bug

Expand Down
10 changes: 3 additions & 7 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
---
name: Feature request
about: Suggest an idea for this project
title: '[Feature Request] Title'
labels: ''
assignees: ''
---
______________________________________________________________________

## name: Feature request about: Suggest an idea for this project title: '[Feature Request] Title' labels: '' assignees: ''

# Feature Request

Expand Down
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,34 +37,49 @@ and this project adheres to
rescan the PCI bus after hotplug and remove the device before unplug since no
automatic notification mechanism is implemented yet. More information can be
found in the [Device Hotplugging](docs/device-hotplug.md) documentation page.

- [#5771](https://github.com/firecracker-microvm/firecracker/pull/5771): Add
opt-in `--landlock-restrict-fs` flag to the jailer that uses the Linux
Landlock LSM as a defense-in-depth mechanism. When enabled, the jailed
Firecracker process is restricted to only accessing files within the jail
directory, even if it escapes the `pivot_root` chroot via a kernel exploit.
Best-effort: silently ignored on kernels without Landlock support (< 5.13).

- [#5323](https://github.com/firecracker-microvm/firecracker/pull/5323): Add
support for Vsock Unix domain socket path overriding on snapshot restore. More
information can be found in the
[docs](docs/vsock.md/#unix-domain-socket-renaming).

- [#5824](https://github.com/firecracker-microvm/firecracker/pull/5824): Add
optional rate limiting to serial console output, configurable via the
`rate_limiter` field on `PUT /serial`. A new metric is exposed under `uart`:
`rate_limiter_dropped_bytes`.

- [#5799](https://github.com/firecracker-microvm/firecracker/pull/5799): Add
per-callsite rate limiting for error, warn, and info level log messages. Each
callsite independently allows up to 10 messages per 5-second window. When
logging resumes after suppression, a warn-level summary reports the count of
suppressed messages. A new `rate_limited_log_count` metric tracks the total
number of suppressed messages.

- [#5789](https://github.com/firecracker-microvm/firecracker/pull/5789): Add
rate-limiter support to virtio-pmem device to allow control over I/O bandwidth
generated by the FLUSH requests from the guest.

- [#5872](https://github.com/firecracker-microvm/firecracker/pull/5872): Add
notification suppression support in the virtio-vsock device via the EVENT_IDX
virtio feature to reduce device overhead.

- [#5828](https://github.com/firecracker-microvm/firecracker/pull/5828):
Advertise MTU to the guest via `VIRTIO_NET_F_MTU` using a new optional `mtu`
field in the `network-interfaces` API. When set, a compatible guest driver
will configure the interface with the specified MTU.

- [#5906](https://github.com/firecracker-microvm/firecracker/pull/5906): Add
`rng-seed` FDT node for aarch64 guests which provides an initial random seed
for the guest to use. This helps older aarch64 machines which do not have
hardware random generators.

- Added support for Linux 6.18 host kernels alongside the existing 5.10 and 6.1
host kernels. See the [kernel support policy](docs/kernel-policy.md) for
details.
Expand Down
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -225,5 +225,5 @@ message automatically.

Forgot to add DCO to a commit? Amend it with `git commit --amend -s`.

[^1]: Performance improvements in non-hot paths are unlikely to be considered
valuable.
\[^1\]: Performance improvements in non-hot paths are unlikely to be considered
valuable.
32 changes: 32 additions & 0 deletions Cargo.lock

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

10 changes: 5 additions & 5 deletions SPECIFICATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,12 @@ on the following:
are full will be lost. Any such events will be signaled through the
`lost-logs` and `lost-metrics` counters.

[^1]: CPU ms are actual ms of a user space thread's on-CPU runtime; useful for
getting consistent measurements for some performance metrics.
\[^1\]: CPU ms are actual ms of a user space thread's on-CPU runtime; useful for
getting consistent measurements for some performance metrics.

[^2]: No logs are currently produced in the span of time between the `jailer`
process start-up and the logging system initialization in the
`firecracker` process.
\[^2\]: No logs are currently produced in the span of time between the `jailer`
process start-up and the logging system initialization in the `firecracker`
process.

[1]: https://aws.amazon.com/ec2/instance-types/m5/
[2]: https://aws.amazon.com/ec2/instance-types/m6/
9 changes: 9 additions & 0 deletions docs/jailer.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ jailer --id <id> \
[--resource-limit <resource=value>] \
[--daemonize] \
[--new-pid-ns] \
[--landlock-restrict-fs] \
[--...extra arguments for Firecracker]
```

Expand Down Expand Up @@ -98,6 +99,14 @@ Here is an example on how to set multiple resource limits using this argument:
`CLONE_NEWPID` flag. As a result, the jailer and the process running the exec
file have different PIDs. The PID of the child process is stored in the jail
root directory inside `<exec_file_name>.pid`.
- When present, `--landlock-restrict-fs` uses the Linux
[Landlock LSM](https://docs.kernel.org/userspace-api/landlock.html) to
restrict the jailed Firecracker process to only accessing files within the
jail directory. This is a defense-in-depth measure: even if the process
escapes the `pivot_root` chroot via a kernel exploit, Landlock (enforced by a
separate LSM path) independently prevents access to files outside the jail.
The flag operates in best-effort mode — on kernels without Landlock support
(\< 5.13) it has no effect.
- The jailer adheres to the "end of command options" convention, meaning all
parameters specified after `--` are forwarded to Firecracker. For example,
this can be paired with the `--config-file` Firecracker argument to specify a
Expand Down
1 change: 0 additions & 1 deletion docs/memory-hotplug.md
Original file line number Diff line number Diff line change
Expand Up @@ -333,5 +333,4 @@ driver may be able to trick the backend to access unplugged memory. This is not
possible in Firecracker itself as unplugged memory slots are `mprotect`-ed.

[^uffd]: snapshotting/handling-page-faults-on-snapshot-resume.md#userfaultfd

[^vhost-user]: api_requests/block-vhost-user.md
6 changes: 3 additions & 3 deletions docs/prod-host-setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,6 @@ sudo modprobe $KVM_VENDOR_MOD
To validate that the change took effect, the file
`/sys/module/kvm/parameters/nx_huge_pages` should say `never`.

[^1]: Look for `GRUB_CMDLINE_LINUX` in file `/etc/default/grub` in RPM-based
systems, and
[this doc for Ubuntu](https://wiki.ubuntu.com/Kernel/KernelBootParameters).
\[^1\]: Look for `GRUB_CMDLINE_LINUX` in file `/etc/default/grub` in RPM-based
systems, and
[this doc for Ubuntu](https://wiki.ubuntu.com/Kernel/KernelBootParameters).
1 change: 1 addition & 0 deletions src/jailer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ bench = false
tracing = ["log-instrument", "utils/tracing"]

[dependencies]
landlock = "0.4.5"
libc = "0.2.186"
log-instrument = { path = "../log-instrument", optional = true }
regex = { version = "1.12.3", default-features = false, features = ["std"] }
Expand Down
48 changes: 48 additions & 0 deletions src/jailer/src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use vmm_sys_util::syscall::SyscallReturnCode;
use crate::JailerError;
use crate::cgroup::{CgroupConfiguration, CgroupConfigurationBuilder};
use crate::chroot::chroot;
use crate::landlock;
use crate::resource_limits::{FSIZE_ARG, NO_FILE_ARG, ResourceLimits};

pub const PROC_MOUNTS: &str = "/proc/mounts";
Expand Down Expand Up @@ -124,6 +125,7 @@ pub struct Env {
netns: Option<String>,
daemonize: bool,
new_pid_ns: bool,
landlock: bool,
start_time_us: u64,
start_time_cpu_us: u64,
jailer_cpu_time_us: u64,
Expand Down Expand Up @@ -187,6 +189,8 @@ impl Env {

let new_pid_ns = arguments.flag_present("new-pid-ns");

let landlock = arguments.flag_present("landlock-restrict-fs");

// Optional arguments.
let mut cgroup_conf = None;
let parent_cgroup = match arguments.single_value("parent-cgroup") {
Expand Down Expand Up @@ -263,6 +267,7 @@ impl Env {
netns,
daemonize,
new_pid_ns,
landlock,
start_time_us,
start_time_cpu_us,
jailer_cpu_time_us: 0,
Expand Down Expand Up @@ -669,6 +674,14 @@ impl Env {
#[cfg(target_arch = "aarch64")]
self.copy_midr_el1_info()?;

// Prepare the Landlock ruleset before chrooting, while the jail directory is still
// reachable by its host path. The PathFd captures the inode and survives pivot_root.
let landlock_ruleset = if self.landlock {
Some(landlock::prepare_ruleset(self.chroot_dir())?)
} else {
None
};

// Jail self.
chroot(self.chroot_dir())?;

Expand Down Expand Up @@ -762,6 +775,12 @@ impl Env {
self.jailer_cpu_time_us += get_time_us(ClockType::ProcessCpu);
}

// Enforce the Landlock ruleset right before exec so that the restrictions are inherited
// by the jailed Firecracker process.
if let Some(ruleset) = landlock_ruleset {
landlock::enforce(ruleset)?;
}

// If specified, exec the provided binary into a new PID namespace.
if self.new_pid_ns {
self.exec_into_new_pid_ns(chroot_exec_file)
Expand Down Expand Up @@ -804,6 +823,7 @@ mod tests {
pub netns: Option<&'a str>,
pub daemonize: bool,
pub new_pid_ns: bool,
pub landlock: bool,
pub cgroups: Vec<&'a str>,
pub resource_limits: Vec<&'a str>,
pub parent_cgroup: Option<&'a str>,
Expand All @@ -823,6 +843,7 @@ mod tests {
netns: Some("zzzns"),
daemonize: true,
new_pid_ns: true,
landlock: false,
cgroups: vec!["cpu.shares=2", "cpuset.mems=0"],
resource_limits: vec!["no-file=1024", "fsize=1048575"],
parent_cgroup: None,
Expand Down Expand Up @@ -873,6 +894,10 @@ mod tests {
arg_vec.push("--new-pid-ns".to_string());
}

if arg_vals.landlock {
arg_vec.push("--landlock-restrict-fs".to_string());
}

if let Some(parent_cg) = arg_vals.parent_cgroup {
arg_vec.push("--parent-cgroup".to_string());
arg_vec.push(parent_cg.to_string());
Expand Down Expand Up @@ -1226,6 +1251,7 @@ mod tests {
netns: Some("zzzns"),
daemonize: false,
new_pid_ns: false,
landlock: false,
cgroups: Vec::new(),
resource_limits: Vec::new(),
parent_cgroup: None,
Expand Down Expand Up @@ -1444,6 +1470,28 @@ mod tests {
assert_eq!(entries.enumerate().count(), 6);
}

#[test]
fn test_new_env_with_landlock() {
let mut mock_cgroups = MockCgroupFs::new().unwrap();
mock_cgroups.add_v1_mounts().unwrap();

let pseudo_exec_file_path = get_pseudo_exec_file_path();
let arg_vals = ArgVals {
landlock: true,
..ArgVals::new(pseudo_exec_file_path.as_str())
};

let args_vec = make_args(&arg_vals);
assert!(args_vec.contains(&"--landlock-restrict-fs".to_string()));

let arg_parser = build_arg_parser();
let mut args = arg_parser.arguments().clone();
args.parse(&args_vec).unwrap();
let env =
Env::new(&args, 0, 0, mock_cgroups.proc_mounts_path.to_str().unwrap()).unwrap();
assert!(env.landlock);
}

#[test]
fn test_save_exec_file_pid() {
let exec_file_name = "file";
Expand Down
Loading