1
0
mirror of https://github.com/containers/youki synced 2026-05-04 06:00:48 +02:00
Files
sat0ken 11e26109a0 Extend experiment seccomp program (#3464)
* update seccomp program of update method and add function

- add default error return code to InstructionData
- add action to Rule
- add action to fn new of Rule and fix test code
- add seccomp compare op code to const
- ported function from libcontainer of seccomp
- update Cargo.toml and lock
- add const of seccomp flags
- add flags to InstructionData
- add derive
- improve implementation to generate filter from LinuxSeccomp
- update main.rs to use oci_spec
- fix format

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

* implementation From trait

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

* implement seccomp flags if config.json define

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

* add BPF Instruction to validate

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

* add fn to get nr offset from seccomp_data

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

* modify generate BPF program order

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

* implement check args of seccomp program and add test code

- modify systemcall of args check logic
- add for test code and add serde to use json
- update gen_validate
- update seccomp_data_args_offset to get args index
- add file for test
- update check argument code
- update check argument code
- fix test code
- remove unusual args from fn to_instruction_with_args
- add test code
- add test case with args
- add test for arm64

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

* move test json file to tests

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

* change to return Result

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

* change fn seccomp_data_args_offset to return Result

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

* to change return Result, add unwrap

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

* run cargo fmt

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

* fix offset size

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

* add design pattern to rule

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

* change method to return Result

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

* change method name

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

* improve multipul variable set to use is_none method

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

* fix test code

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

* insert BPF_JMP to new to omit code

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

* omit BPM_JMP from code

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

* add check argument count

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

* fix if value is 0, set the value

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

* fix for cargo clippy

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

* change argument string to Path

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

* change to return Result and remove unwrap

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

* change struct name InstructionData to SeccompProgramPlan

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

* implement TryFrom to SeccompProgramPlan

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

* update oci-spec-rs

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

* errno correctly set to the value of action

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

* refactoring testutils.rs to use oci-spec-rs to parse json

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

* refactor fn try_from to separate logic

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

* fix test code and refactor

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

* change type of syscall Vec<String> to Vec<u64> to sort

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

* add const to jump_num

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

* cargo fmt

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

* minor update for test

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

* create example dir and move main.rs

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

* fix typo

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

* update package and toolchain

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

* cargo fmt

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

* remove unused package

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

* organize tests dir

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

* update Cargo.toml

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

* add readjson file by libseccomp

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

* update README

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

* cargo fmt
fix warning

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

* fix typo

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>

---------

Signed-off-by: sat0ken <15720506+sat0ken@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-08 08:52:54 +09:00

104 lines
4.1 KiB
Rust

use std::path::Path;
use std::{fs, io};
use anyhow::Error;
use libseccomp::ScmpAction::{Allow, Errno, KillProcess, KillThread, Log, Notify, Trace, Trap};
use libseccomp::{ScmpAction, ScmpCompareOp};
use oci_spec::runtime::{
Arch as OciSpecArch, LinuxSeccomp, LinuxSeccompAction, LinuxSeccompBuilder,
LinuxSeccompOperator, LinuxSyscall, LinuxSyscallBuilder,
};
use seccomp::seccomp::{Seccomp, SeccompProgramPlan};
#[allow(dead_code)]
pub fn convert_action(
action: LinuxSeccompAction,
option: Option<u32>,
) -> Result<ScmpAction, Error> {
match action {
LinuxSeccompAction::ScmpActKill => Ok(KillProcess),
LinuxSeccompAction::ScmpActKillThread => Ok(KillThread),
LinuxSeccompAction::ScmpActKillProcess => Ok(KillProcess),
LinuxSeccompAction::ScmpActTrap => Ok(Trap),
LinuxSeccompAction::ScmpActErrno => Ok(Errno(option.unwrap() as i32)),
LinuxSeccompAction::ScmpActNotify => Ok(Notify),
LinuxSeccompAction::ScmpActTrace => Ok(Trace(option.unwrap() as u16)),
LinuxSeccompAction::ScmpActLog => Ok(Log),
LinuxSeccompAction::ScmpActAllow => Ok(Allow),
}
}
#[allow(dead_code)]
pub fn convert_operation(
op: LinuxSeccompOperator,
value: Option<u64>,
) -> Result<ScmpCompareOp, Error> {
match op {
LinuxSeccompOperator::ScmpCmpNe => Ok(ScmpCompareOp::NotEqual),
LinuxSeccompOperator::ScmpCmpLt => Ok(ScmpCompareOp::Less),
LinuxSeccompOperator::ScmpCmpLe => Ok(ScmpCompareOp::LessOrEqual),
LinuxSeccompOperator::ScmpCmpEq => Ok(ScmpCompareOp::Equal),
LinuxSeccompOperator::ScmpCmpGe => Ok(ScmpCompareOp::GreaterEqual),
LinuxSeccompOperator::ScmpCmpGt => Ok(ScmpCompareOp::Greater),
LinuxSeccompOperator::ScmpCmpMaskedEq => Ok(ScmpCompareOp::MaskedEqual(value.unwrap())),
}
}
pub fn read_seccomp_testdata(file_path: &Path) -> Result<LinuxSeccomp, io::Error> {
let contents = fs::read_to_string(file_path)?;
let seccomp: LinuxSeccomp = serde_json::from_str(&contents)?;
Ok(seccomp)
}
#[allow(dead_code)]
pub fn generate_seccomp_instruction(file_path: &Path) -> anyhow::Result<()> {
let seccomp = read_seccomp_testdata(file_path)?;
let mut cnt = 0;
if let Some(syscalls) = seccomp.syscalls() {
for syscall in syscalls {
let mut build_syscall: LinuxSyscall = if let Some(args) = syscall.args() {
println!("--- test case {} with args---", cnt);
LinuxSyscallBuilder::default()
.names(syscall.names().to_vec())
.action(syscall.action())
.args(args.to_vec())
.build()?
} else {
println!("--- test case {}---", cnt);
LinuxSyscallBuilder::default()
.names(syscall.names().to_vec())
.action(syscall.action())
.build()?
};
if let Some(errno_ret) = syscall.errno_ret() {
build_syscall.set_errno_ret(Option::from(errno_ret));
}
let spec_seccomp = LinuxSeccompBuilder::default()
.architectures(vec![OciSpecArch::ScmpArchX86_64])
.default_action(seccomp.default_action())
.default_errno_ret(seccomp.default_errno_ret().unwrap())
.syscalls(vec![build_syscall])
.build()?;
let inst_data = SeccompProgramPlan::try_from(spec_seccomp)?;
let mut seccomp = Seccomp::new();
if !inst_data.flags.is_empty() {
seccomp.set_flags(inst_data.flags.clone());
}
seccomp.filters = Vec::try_from(inst_data)?;
// println!("--- test case {}---", cnt);
for filter in &seccomp.filters {
println!(
"code: {:02x}, jt: {:02x}, jf: {:02x}, k: {:08x}",
filter.code,
filter.offset_jump_true,
filter.offset_jump_false,
filter.multiuse_field
)
}
println!("--- test case {} end", cnt);
cnt += 1;
}
}
Ok(())
}