11use std:: fs;
2- use libseccomp:: { ScmpAction , ScmpFilter } ;
2+ use libseccomp:: { ScmpAction , ScmpArch , ScmpFilterContext , ScmpSyscall } ;
33use miette:: { miette, Result } ;
44
55pub fn apply_seccomp ( profile_path : & str ) -> Result < ( ) > {
66 let content = fs:: read_to_string ( profile_path)
77 . map_err ( |e| miette ! ( "Failed to read seccomp profile: {}" , e) ) ?;
8+
89 let profile: SeccompProfile = serde_json:: from_str ( & content)
910 . map_err ( |e| miette ! ( "Invalid seccomp profile: {}" , e) ) ?;
10- let mut filter = ScmpFilter :: new ( str_to_scmp_action ( & profile. default_action ) ) ?;
11- for arch in profile. architectures {
12- filter. add_arch ( str_to_scmp_arch ( & arch) ) ?;
11+
12+ let default_action = str_to_scmp_action ( & profile. default_action ) ;
13+
14+ let mut filter = ScmpFilterContext :: new_filter ( default_action)
15+ . map_err ( |e| miette ! ( "Failed to create seccomp filter: {}" , e) ) ?;
16+
17+ for arch in & profile. architectures {
18+ filter
19+ . add_arch ( str_to_scmp_arch ( arch) )
20+ . map_err ( |e| miette ! ( "Failed to add arch {}: {}" , arch, e) ) ?;
1321 }
14- for syscall in profile. syscalls {
15- let action = str_to_scmp_action ( & syscall. action ) ;
16- for name in syscall. names {
17- filter. add_rule ( action, name) ?;
22+
23+ for syscall_rule in & profile. syscalls {
24+ let action = str_to_scmp_action ( & syscall_rule. action ) ;
25+ for name in & syscall_rule. names {
26+ let syscall = ScmpSyscall :: from_name ( name)
27+ . map_err ( |e| miette ! ( "Unknown syscall '{}': {}" , name, e) ) ?;
28+ filter
29+ . add_rule ( action, syscall)
30+ . map_err ( |e| miette ! ( "Failed to add rule for '{}': {}" , name, e) ) ?;
1831 }
1932 }
20- filter. load ( ) ?;
33+
34+ filter
35+ . load ( )
36+ . map_err ( |e| miette ! ( "Failed to load seccomp filter: {}" , e) ) ?;
37+
2138 Ok ( ( ) )
2239}
2340
@@ -37,15 +54,34 @@ struct SyscallRule {
3754fn str_to_scmp_action ( s : & str ) -> ScmpAction {
3855 match s {
3956 "SCMP_ACT_ALLOW" => ScmpAction :: Allow ,
40- "SCMP_ACT_ERRNO" => ScmpAction :: Errno ( 1 ) ,
57+ "SCMP_ACT_KILL" => ScmpAction :: KillThread ,
58+ "SCMP_ACT_KILL_PROCESS" => ScmpAction :: KillProcess ,
59+ "SCMP_ACT_TRAP" => ScmpAction :: Trap ,
60+ "SCMP_ACT_LOG" => ScmpAction :: Log ,
61+ "SCMP_ACT_ERRNO" => ScmpAction :: Errno ( libc:: EPERM as u32 ) ,
62+ s if s. starts_with ( "SCMP_ACT_ERRNO(" ) => {
63+ let n: u32 = s
64+ . trim_start_matches ( "SCMP_ACT_ERRNO(" )
65+ . trim_end_matches ( ')' )
66+ . parse ( )
67+ . unwrap_or ( libc:: EPERM as u32 ) ;
68+ ScmpAction :: Errno ( n)
69+ }
4170 _ => ScmpAction :: Allow ,
4271 }
4372}
4473
45- fn str_to_scmp_arch ( s : & str ) -> libseccomp :: ScmpArch {
74+ fn str_to_scmp_arch ( s : & str ) -> ScmpArch {
4675 match s {
47- "x86_64" => libseccomp:: ScmpArch :: X86_64 ,
48- "aarch64" => libseccomp:: ScmpArch :: AARCH64 ,
49- _ => libseccomp:: ScmpArch :: Native ,
76+ "SCMP_ARCH_X86" => ScmpArch :: X86 ,
77+ "SCMP_ARCH_X86_64" | "x86_64" => ScmpArch :: X8664 ,
78+ "SCMP_ARCH_X32" => ScmpArch :: X32 ,
79+ "SCMP_ARCH_ARM" => ScmpArch :: Arm ,
80+ "SCMP_ARCH_AARCH64" | "aarch64" => ScmpArch :: Aarch64 ,
81+ "SCMP_ARCH_MIPS" => ScmpArch :: Mips ,
82+ "SCMP_ARCH_MIPS64" => ScmpArch :: Mips64 ,
83+ "SCMP_ARCH_PPC64LE" => ScmpArch :: Ppc64Le ,
84+ "SCMP_ARCH_S390X" => ScmpArch :: S390X ,
85+ _ => ScmpArch :: Native ,
5086 }
5187}
0 commit comments