File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 1+ //! AppArmor profile transition for the workload process.
2+
3+ use std:: io:: Write ;
4+
5+ /// Stage an AppArmor profile transition that takes effect on the next `execve`
6+ /// (the kernel's `aa_change_onexec` interface).
7+ ///
8+ /// The named profile must already be loaded in the kernel. Writing an un-loaded/unknown
9+ /// profile name here will cause the next `execve` to fail with `-ENOENT`.
10+ /// Must be called after `PR_SET_NO_NEW_PRIVS` and before `execvpe()`.
11+ ///
12+ /// The command must reach the kernel in a single `write(2)`, so it is formatted
13+ /// into one buffer. Writes to the per-LSM attr node `/proc/self/attr/apparmor/exec`
14+ /// (present on Linux 5.1+), and falls back to the pre-5.1 global node `/proc/self/attr/exec`.
15+ pub fn change_onexec ( profile : & str ) -> std:: io:: Result < ( ) > {
16+ let cmd = format ! ( "exec {profile}" ) ;
17+ let mut file = match std:: fs:: OpenOptions :: new ( )
18+ . write ( true )
19+ . open ( "/proc/self/attr/apparmor/exec" )
20+ {
21+ Ok ( file) => file,
22+ Err ( e) if e. kind ( ) == std:: io:: ErrorKind :: NotFound => std:: fs:: OpenOptions :: new ( )
23+ . write ( true )
24+ . open ( "/proc/self/attr/exec" ) ?,
25+ Err ( e) => return Err ( e) ,
26+ } ;
27+ file. write_all ( cmd. as_bytes ( ) )
28+ }
Original file line number Diff line number Diff line change @@ -86,6 +86,12 @@ pub struct ExecutableSpec {
8686 #[ serde( default ) ]
8787 pub seccomp : Option < SeccompFilter > ,
8888
89+ /// An optional AppArmor profile name to transition to on `execve`. The named
90+ /// profile must already be loaded in the kernel. Staged after
91+ /// `PR_SET_NO_NEW_PRIVS`, before `execvpe()`.
92+ #[ serde( default ) ]
93+ pub apparmor : Option < String > ,
94+
8995 /// An optional out-of-memory score adjustment value.
9096 pub oom_score_adj : Option < i32 > ,
9197}
Original file line number Diff line number Diff line change 1+ pub mod apparmor;
12pub mod caps;
23pub mod cgroup;
34pub mod config;
Original file line number Diff line number Diff line change @@ -725,6 +725,11 @@ impl ExecutableSpec {
725725 unsafe { filter. install ( ) ? } ;
726726 }
727727
728+ if let Some ( profile) = & self . apparmor {
729+ crate :: apparmor:: change_onexec ( profile)
730+ . map_err ( |e| anyhow ! ( "failed to set AppArmor profile {profile:?}: {e}" ) ) ?;
731+ }
732+
728733 // The Rust runtime ignores SIGPIPE (SIG_IGN) process-wide, and that
729734 // disposition is inherited across execve. Restore SIG_DFL so the
730735 // workload sees the standard broken-pipe behaviour, matching runc/crun.
You can’t perform that action at this time.
0 commit comments