1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
// SPDX-License-Identifier: Apache-2.0 or MIT
//
// Copyright 2021 Sony Group Corporation
//
use crate::error::ErrorKind::*;
use crate::error::{Result, SeccompError};
use libseccomp_sys::*;
use std::str::FromStr;
/// Represents filter attributes.
///
/// You can set/get the attributes of a filter context with
/// [`ScmpFilterContext::set_filter_attr`](crate::ScmpFilterContext::set_filter_attr)
/// and [`ScmpFilterContext::get_filter_attr`](crate::ScmpFilterContext::get_filter_attr)
/// methods.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum ScmpFilterAttr {
/// The default filter action as specified in the call to seccomp reset.
ActDefault,
/// The filter action taken when the loaded filter does not
/// match the architecture of the executing application.
ActBadArch,
/// A flag to specify if the NO_NEW_PRIVS functionality should
/// be enabled before loading the seccomp filter into the kernel.
CtlNnp,
/// A flag to specify if the kernel should attempt to
/// synchronize the filters across all threads on seccomp load.
CtlTsync,
/// A flag to specify if the libseccomp should allow filter rules
/// to be created for the -1 syscall.
ApiTskip,
/// A flag to specify if the kernel should log all filter
/// actions taken except for the [`ScmpAction::Allow`](crate::ScmpAction::Allow) action.
CtlLog,
/// A flag to disable Speculative Store Bypass mitigations for
/// this filter.
CtlSsb,
/// A flag to specify the optimization level of the seccomp
/// filter.
CtlOptimize,
/// A flag to specify if the libseccomp should pass system error
/// codes back to the caller instead of the default -ECANCELED.
ApiSysRawRc,
/// A flag to specify if libseccomp should request wait killable
/// semantics when possible.
CtlWaitkill,
}
impl ScmpFilterAttr {
pub(crate) fn to_sys(self) -> scmp_filter_attr {
match self {
Self::ActDefault => scmp_filter_attr::SCMP_FLTATR_ACT_DEFAULT,
Self::ActBadArch => scmp_filter_attr::SCMP_FLTATR_ACT_BADARCH,
Self::CtlNnp => scmp_filter_attr::SCMP_FLTATR_CTL_NNP,
Self::CtlTsync => scmp_filter_attr::SCMP_FLTATR_CTL_TSYNC,
Self::ApiTskip => scmp_filter_attr::SCMP_FLTATR_API_TSKIP,
Self::CtlLog => scmp_filter_attr::SCMP_FLTATR_CTL_LOG,
Self::CtlSsb => scmp_filter_attr::SCMP_FLTATR_CTL_SSB,
Self::CtlOptimize => scmp_filter_attr::SCMP_FLTATR_CTL_OPTIMIZE,
Self::ApiSysRawRc => scmp_filter_attr::SCMP_FLTATR_API_SYSRAWRC,
Self::CtlWaitkill => scmp_filter_attr::SCMP_FLTATR_CTL_WAITKILL,
}
}
}
impl FromStr for ScmpFilterAttr {
type Err = SeccompError;
/// Converts string seccomp filter attribute to `ScmpFilterAttr`.
///
/// # Arguments
///
/// * `attr` - A string filter attribute, e.g. `SCMP_FLTATR_*`.
///
/// See the [`seccomp_attr_set(3)`] man page for details on valid filter attribute values.
///
/// [`seccomp_attr_set(3)`]: https://www.man7.org/linux/man-pages/man3/seccomp_attr_set.3.html
///
/// # Errors
///
/// If an invalid filter attribute is specified, an error will be returned.
fn from_str(attr: &str) -> Result<Self> {
match attr {
"SCMP_FLTATR_ACT_DEFAULT" => Ok(Self::ActDefault),
"SCMP_FLTATR_ACT_BADARCH" => Ok(Self::ActBadArch),
"SCMP_FLTATR_CTL_NNP" => Ok(Self::CtlNnp),
"SCMP_FLTATR_CTL_TSYNC" => Ok(Self::CtlTsync),
"SCMP_FLTATR_API_TSKIP" => Ok(Self::ApiTskip),
"SCMP_FLTATR_CTL_LOG" => Ok(Self::CtlLog),
"SCMP_FLTATR_CTL_SSB" => Ok(Self::CtlSsb),
"SCMP_FLTATR_CTL_OPTIMIZE" => Ok(Self::CtlOptimize),
"SCMP_FLTATR_API_SYSRAWRC" => Ok(Self::ApiSysRawRc),
"SCMP_FLTATR_CTL_WAITKILL" => Ok(Self::CtlWaitkill),
_ => Err(SeccompError::new(FromStr(attr.to_string()))),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse_filter_attr() {
let test_data = &[
("SCMP_FLTATR_ACT_DEFAULT", ScmpFilterAttr::ActDefault),
("SCMP_FLTATR_ACT_BADARCH", ScmpFilterAttr::ActBadArch),
("SCMP_FLTATR_CTL_NNP", ScmpFilterAttr::CtlNnp),
("SCMP_FLTATR_CTL_TSYNC", ScmpFilterAttr::CtlTsync),
("SCMP_FLTATR_API_TSKIP", ScmpFilterAttr::ApiTskip),
("SCMP_FLTATR_CTL_LOG", ScmpFilterAttr::CtlLog),
("SCMP_FLTATR_CTL_SSB", ScmpFilterAttr::CtlSsb),
("SCMP_FLTATR_CTL_OPTIMIZE", ScmpFilterAttr::CtlOptimize),
("SCMP_FLTATR_API_SYSRAWRC", ScmpFilterAttr::ApiSysRawRc),
("SCMP_FLTATR_CTL_WAITKILL", ScmpFilterAttr::CtlWaitkill),
];
for data in test_data {
assert_eq!(
ScmpFilterAttr::from_str(data.0).unwrap().to_sys(),
data.1.to_sys()
);
}
assert!(ScmpFilterAttr::from_str("SCMP_INVALID_FLAG").is_err());
}
}