From a90fc1c7cc88e27463869f405d1197817be6573a Mon Sep 17 00:00:00 2001
From: Wei Gao <gaowei66@huawei.com>
Date: Fri, 19 Feb 2021 14:59:02 +0800
Subject: [PATCH 2/2] seccomp: split normal scene and balloon device scene,
 update comment and doc.

Signed-off-by: Wei Gao <gaowei66@huawei.com>
---
 device_model/src/lib.rs                    |  6 ++++-
 device_model/src/micro_vm/micro_syscall.rs | 29 ++++++++--------------
 device_model/src/virtio/balloon.rs         | 15 +++++++++++
 docs/config_guidebook.md                   |  2 +-
 src/main.rs                                |  8 ++++--
 5 files changed, 38 insertions(+), 22 deletions(-)

diff --git a/device_model/src/lib.rs b/device_model/src/lib.rs
index 4701bdb..e9ba4bf 100644
--- a/device_model/src/lib.rs
+++ b/device_model/src/lib.rs
@@ -46,7 +46,11 @@ mod mmio;
 mod virtio;
 
 pub use error_chain::*;
-pub use micro_vm::{micro_syscall::register_seccomp, LightMachine};
+pub use micro_vm::{
+    micro_syscall::{register_seccomp, syscall_allow_list},
+    LightMachine,
+};
+pub use virtio::balloon::balloon_allow_list;
 
 use address_space::GuestAddress;
 
diff --git a/device_model/src/micro_vm/micro_syscall.rs b/device_model/src/micro_vm/micro_syscall.rs
index e4ce724..b333fb3 100644
--- a/device_model/src/micro_vm/micro_syscall.rs
+++ b/device_model/src/micro_vm/micro_syscall.rs
@@ -51,12 +51,12 @@ const KVM_SET_DEVICE_ATTR: u32 = 0x4018_aee1;
 ///
 /// # Notes
 /// This allowlist limit syscall with:
-/// * x86_64-unknown-gnu: 35 syscalls
-/// * x86_64-unknown-musl: 34 syscalls
-/// * aarch64-unknown-gnu: 34 syscalls
-/// * aarch64-unknown-musl: 33 syscalls
+/// * x86_64-unknown-gnu: 36 syscalls
+/// * x86_64-unknown-musl: 36 syscalls
+/// * aarch64-unknown-gnu: 38 syscalls
+/// * aarch64-unknown-musl: 38 syscalls
 /// To reduce performance losses, the syscall rules is ordered by frequency.
-fn syscall_allow_list() -> Vec<BpfRule> {
+pub fn syscall_allow_list() -> Vec<BpfRule> {
     vec![
         BpfRule::new(libc::SYS_read),
         BpfRule::new(libc::SYS_write),
@@ -85,6 +85,7 @@ fn syscall_allow_list() -> Vec<BpfRule> {
         BpfRule::new(libc::SYS_rt_sigprocmask),
         #[cfg(target_arch = "x86_64")]
         BpfRule::new(libc::SYS_open),
+        #[cfg(target_arch = "aarch64")]
         BpfRule::new(libc::SYS_openat),
         BpfRule::new(libc::SYS_sigaltstack),
         BpfRule::new(libc::SYS_mmap),
@@ -107,22 +108,15 @@ fn syscall_allow_list() -> Vec<BpfRule> {
         BpfRule::new(libc::SYS_gettid),
         BpfRule::new(libc::SYS_getpid),
         BpfRule::new(libc::SYS_fstat),
+        #[cfg(target_arch = "aarch64")]
         BpfRule::new(libc::SYS_pread64),
+        #[cfg(target_arch = "aarch64")]
         BpfRule::new(libc::SYS_pwrite64),
-        BpfRule::new(libc::SYS_mprotect),
-        BpfRule::new(libc::SYS_clone),
-        BpfRule::new(libc::SYS_set_robust_list),
-        BpfRule::new(libc::SYS_sched_getaffinity),
-        BpfRule::new(libc::SYS_nanosleep),
-        BpfRule::new(libc::SYS_timerfd_create),
-        BpfRule::new(libc::SYS_timerfd_settime),
-        BpfRule::new(libc::SYS_timerfd_gettime),
         BpfRule::new(libc::SYS_statx),
         #[cfg(target_arch = "x86_64")]
         BpfRule::new(libc::SYS_unlink),
         #[cfg(target_arch = "aarch64")]
         BpfRule::new(libc::SYS_unlinkat),
-        #[cfg(target_env = "gnu")]
         BpfRule::new(libc::SYS_madvise)
             .add_constraint(SeccompCmpOpt::Eq, 2, libc::MADV_DONTNEED as u32)
             .add_constraint(SeccompCmpOpt::Eq, 2, libc::MADV_WILLNEED as u32),
@@ -157,12 +151,11 @@ fn ioctl_allow_list() -> BpfRule {
 }
 
 /// Register seccomp rules in syscall allowlist to seccomp.
-pub fn register_seccomp() -> Result<()> {
+pub fn register_seccomp(bpf_rules: Vec<BpfRule>) -> Result<()> {
     let mut seccomp_filter = SyscallFilter::new(SeccompOpt::Trap);
 
-    let mut bpf_rules = syscall_allow_list();
-    for bpf_rule in &mut bpf_rules {
-        seccomp_filter.push(bpf_rule);
+    for mut bpf_rule in bpf_rules {
+        seccomp_filter.push(&mut bpf_rule);
     }
 
     seccomp_filter.realize()?;
diff --git a/device_model/src/virtio/balloon.rs b/device_model/src/virtio/balloon.rs
index 50f5eb1..f50fa82 100644
--- a/device_model/src/virtio/balloon.rs
+++ b/device_model/src/virtio/balloon.rs
@@ -36,6 +36,7 @@ use util::{
         read_fd, EventNotifier, EventNotifierHelper, NotifierCallback, NotifierOperation,
     },
     num_ops::{read_u32, round_down, write_u32},
+    seccomp::BpfRule,
 };
 use vmm_sys_util::{epoll::EventSet, eventfd::EventFd, timerfd::TimerFd};
 
@@ -890,6 +891,20 @@ pub fn qmp_query_balloon() -> Option<u64> {
     None
 }
 
+/// Create a syscall bpf rule for device `Balloon`.
+pub fn balloon_allow_list(syscall_allow_list: &mut Vec<BpfRule>) {
+    syscall_allow_list.extend(vec![
+        BpfRule::new(libc::SYS_mprotect),
+        BpfRule::new(libc::SYS_clone),
+        BpfRule::new(libc::SYS_set_robust_list),
+        BpfRule::new(libc::SYS_sched_getaffinity),
+        BpfRule::new(libc::SYS_nanosleep),
+        BpfRule::new(libc::SYS_timerfd_create),
+        BpfRule::new(libc::SYS_timerfd_settime),
+        BpfRule::new(libc::SYS_timerfd_gettime),
+    ])
+}
+
 #[cfg(test)]
 mod tests {
     pub use super::super::*;
diff --git a/docs/config_guidebook.md b/docs/config_guidebook.md
index ec5ac04..a0143fc 100644
--- a/docs/config_guidebook.md
+++ b/docs/config_guidebook.md
@@ -593,7 +593,7 @@ And you can also restore StratoVirt's **pid number** to a file by:
 ### 4.2 Seccomp
 
 StratoVirt use [seccomp(2)](https://man7.org/linux/man-pages/man2/seccomp.2.html) to limit the syscalls
-in StratoVirt process by default. StratoVirt use only 44 syscalls in aarch64 (44 syscalls in x86_64) after running. 
+in StratoVirt process by default. StratoVirt use only 36 syscalls in x86_64 (38 syscalls in aarch64) after running. 
 It will make a slight influence on performance to StratoVirt. If you want to disable seccomp, you can
 run StratoVirt with `-disable-seccomp`.
 
diff --git a/src/main.rs b/src/main.rs
index 9cfecbe..ec955a2 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -22,7 +22,7 @@ use std::sync::{Arc, Mutex};
 
 use vmm_sys_util::terminal::Terminal;
 
-use device_model::{register_seccomp, LightMachine};
+use device_model::{balloon_allow_list, register_seccomp, syscall_allow_list, LightMachine};
 use machine_manager::qmp::QmpChannel;
 use machine_manager::socket::Socket;
 use machine_manager::{
@@ -160,7 +160,11 @@ fn real_main(cmd_args: &arg_parser::ArgMatches, vm_config: VmConfig) -> Result<(
     vm.vm_start(cmd_args.is_present("freeze_cpu"))?;
 
     if !cmd_args.is_present("disable-seccomp") {
-        register_seccomp()?;
+        let mut allow_list = syscall_allow_list();
+        if cmd_args.is_present("balloon") {
+            balloon_allow_list(&mut allow_list);
+        }
+        register_seccomp(allow_list)?;
     }
 
     EventLoop::loop_run().chain_err(|| "MainLoop exits unexpectedly: error occurs")?;
-- 
2.27.0

