1use crate::error::ErrorKind::*;
7use crate::error::{Result, SeccompError};
8use libseccomp_sys::*;
9use std::str::FromStr;
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
14#[non_exhaustive]
15pub enum ScmpArch {
16 Native,
18 X86,
20 X8664,
22 X32,
24 Arm,
26 Aarch64,
28 Loongarch64,
30 M68k,
32 Mips,
34 Mips64,
36 Mips64N32,
38 Mipsel,
40 Mipsel64,
42 Mipsel64N32,
44 Ppc,
46 Ppc64,
48 Ppc64Le,
50 S390,
52 S390X,
54 Parisc,
56 Parisc64,
58 Riscv64,
60 Sheb,
62 Sh,
64}
65
66impl ScmpArch {
67 pub(crate) fn to_sys(self) -> u32 {
68 match self {
69 Self::Native => SCMP_ARCH_NATIVE,
70 Self::X86 => SCMP_ARCH_X86,
71 Self::X8664 => SCMP_ARCH_X86_64,
72 Self::X32 => SCMP_ARCH_X32,
73 Self::Arm => SCMP_ARCH_ARM,
74 Self::Aarch64 => SCMP_ARCH_AARCH64,
75 Self::Loongarch64 => SCMP_ARCH_LOONGARCH64,
76 Self::M68k => SCMP_ARCH_M68K,
77 Self::Mips => SCMP_ARCH_MIPS,
78 Self::Mips64 => SCMP_ARCH_MIPS64,
79 Self::Mips64N32 => SCMP_ARCH_MIPS64N32,
80 Self::Mipsel => SCMP_ARCH_MIPSEL,
81 Self::Mipsel64 => SCMP_ARCH_MIPSEL64,
82 Self::Mipsel64N32 => SCMP_ARCH_MIPSEL64N32,
83 Self::Ppc => SCMP_ARCH_PPC,
84 Self::Ppc64 => SCMP_ARCH_PPC64,
85 Self::Ppc64Le => SCMP_ARCH_PPC64LE,
86 Self::S390 => SCMP_ARCH_S390,
87 Self::S390X => SCMP_ARCH_S390X,
88 Self::Parisc => SCMP_ARCH_PARISC,
89 Self::Parisc64 => SCMP_ARCH_PARISC64,
90 Self::Riscv64 => SCMP_ARCH_RISCV64,
91 Self::Sheb => SCMP_ARCH_SHEB,
92 Self::Sh => SCMP_ARCH_SH,
93 }
94 }
95
96 pub(crate) fn from_sys(arch: u32) -> Result<Self> {
97 match arch {
98 SCMP_ARCH_NATIVE => Ok(Self::Native),
99 SCMP_ARCH_X86 => Ok(Self::X86),
100 SCMP_ARCH_X86_64 => Ok(Self::X8664),
101 SCMP_ARCH_X32 => Ok(Self::X32),
102 SCMP_ARCH_ARM => Ok(Self::Arm),
103 SCMP_ARCH_AARCH64 => Ok(Self::Aarch64),
104 SCMP_ARCH_LOONGARCH64 => Ok(Self::Loongarch64),
105 SCMP_ARCH_M68K => Ok(Self::M68k),
106 SCMP_ARCH_MIPS => Ok(Self::Mips),
107 SCMP_ARCH_MIPS64 => Ok(Self::Mips64),
108 SCMP_ARCH_MIPS64N32 => Ok(Self::Mips64N32),
109 SCMP_ARCH_MIPSEL => Ok(Self::Mipsel),
110 SCMP_ARCH_MIPSEL64 => Ok(Self::Mipsel64),
111 SCMP_ARCH_MIPSEL64N32 => Ok(Self::Mipsel64N32),
112 SCMP_ARCH_PPC => Ok(Self::Ppc),
113 SCMP_ARCH_PPC64 => Ok(Self::Ppc64),
114 SCMP_ARCH_PPC64LE => Ok(Self::Ppc64Le),
115 SCMP_ARCH_S390 => Ok(Self::S390),
116 SCMP_ARCH_S390X => Ok(Self::S390X),
117 SCMP_ARCH_PARISC => Ok(Self::Parisc),
118 SCMP_ARCH_PARISC64 => Ok(Self::Parisc64),
119 SCMP_ARCH_RISCV64 => Ok(Self::Riscv64),
120 SCMP_ARCH_SHEB => Ok(Self::Sheb),
121 SCMP_ARCH_SH => Ok(Self::Sh),
122 _ => Err(SeccompError::new(InvalidArch(arch))),
123 }
124 }
125
126 pub fn native() -> Self {
135 Self::from_sys(unsafe { seccomp_arch_native() }).expect("Could not get native architecture")
136 }
137}
138
139impl FromStr for ScmpArch {
140 type Err = SeccompError;
141
142 fn from_str(arch: &str) -> Result<Self> {
156 match arch {
157 "SCMP_ARCH_NATIVE" => Ok(Self::Native),
158 "SCMP_ARCH_X86" => Ok(Self::X86),
159 "SCMP_ARCH_X86_64" => Ok(Self::X8664),
160 "SCMP_ARCH_X32" => Ok(Self::X32),
161 "SCMP_ARCH_ARM" => Ok(Self::Arm),
162 "SCMP_ARCH_AARCH64" => Ok(Self::Aarch64),
163 "SCMP_ARCH_LOONGARCH64" => Ok(Self::Loongarch64),
164 "SCMP_ARCH_M68K" => Ok(Self::M68k),
165 "SCMP_ARCH_MIPS" => Ok(Self::Mips),
166 "SCMP_ARCH_MIPS64" => Ok(Self::Mips64),
167 "SCMP_ARCH_MIPS64N32" => Ok(Self::Mips64N32),
168 "SCMP_ARCH_MIPSEL" => Ok(Self::Mipsel),
169 "SCMP_ARCH_MIPSEL64" => Ok(Self::Mipsel64),
170 "SCMP_ARCH_MIPSEL64N32" => Ok(Self::Mipsel64N32),
171 "SCMP_ARCH_PPC" => Ok(Self::Ppc),
172 "SCMP_ARCH_PPC64" => Ok(Self::Ppc64),
173 "SCMP_ARCH_PPC64LE" => Ok(Self::Ppc64Le),
174 "SCMP_ARCH_S390" => Ok(Self::S390),
175 "SCMP_ARCH_S390X" => Ok(Self::S390X),
176 "SCMP_ARCH_PARISC" => Ok(Self::Parisc),
177 "SCMP_ARCH_PARISC64" => Ok(Self::Parisc64),
178 "SCMP_ARCH_RISCV64" => Ok(Self::Riscv64),
179 "SCMP_ARCH_SHEB" => Ok(Self::Sheb),
180 "SCMP_ARCH_SH" => Ok(Self::Sh),
181 _ => Err(SeccompError::new(FromStr(arch.to_string()))),
182 }
183 }
184}
185
186#[cfg(test)]
187mod tests {
188 use super::*;
189
190 #[test]
191 fn test_parse_arch() {
192 let test_data = &[
193 ("SCMP_ARCH_NATIVE", ScmpArch::Native),
194 ("SCMP_ARCH_X86", ScmpArch::X86),
195 ("SCMP_ARCH_X86_64", ScmpArch::X8664),
196 ("SCMP_ARCH_X32", ScmpArch::X32),
197 ("SCMP_ARCH_ARM", ScmpArch::Arm),
198 ("SCMP_ARCH_AARCH64", ScmpArch::Aarch64),
199 ("SCMP_ARCH_LOONGARCH64", ScmpArch::Loongarch64),
200 ("SCMP_ARCH_M68K", ScmpArch::M68k),
201 ("SCMP_ARCH_MIPS", ScmpArch::Mips),
202 ("SCMP_ARCH_MIPS64", ScmpArch::Mips64),
203 ("SCMP_ARCH_MIPS64N32", ScmpArch::Mips64N32),
204 ("SCMP_ARCH_MIPSEL", ScmpArch::Mipsel),
205 ("SCMP_ARCH_MIPSEL64", ScmpArch::Mipsel64),
206 ("SCMP_ARCH_MIPSEL64N32", ScmpArch::Mipsel64N32),
207 ("SCMP_ARCH_PPC", ScmpArch::Ppc),
208 ("SCMP_ARCH_PPC64", ScmpArch::Ppc64),
209 ("SCMP_ARCH_PPC64LE", ScmpArch::Ppc64Le),
210 ("SCMP_ARCH_S390", ScmpArch::S390),
211 ("SCMP_ARCH_S390X", ScmpArch::S390X),
212 ("SCMP_ARCH_PARISC", ScmpArch::Parisc),
213 ("SCMP_ARCH_PARISC64", ScmpArch::Parisc64),
214 ("SCMP_ARCH_RISCV64", ScmpArch::Riscv64),
215 ("SCMP_ARCH_SHEB", ScmpArch::Sheb),
216 ("SCMP_ARCH_SH", ScmpArch::Sh),
217 ];
218
219 for data in test_data {
220 assert_eq!(
221 ScmpArch::from_sys(ScmpArch::from_str(data.0).unwrap().to_sys()).unwrap(),
222 data.1
223 );
224 }
225 assert!(ScmpArch::from_str("SCMP_INVALID_FLAG").is_err());
226 assert!(ScmpArch::from_sys(1).is_err());
227 }
228}