1 // Copyright (c) 2024 Huawei Technologies Co.,Ltd. All rights reserved.
2 //
3 // StratoVirt is licensed under Mulan PSL v2.
4 // You can use this software according to the terms and conditions of the Mulan
5 // PSL v2.
6 // You may obtain a copy of Mulan PSL v2 at:
7 // http://license.coscl.org.cn/MulanPSL2
8 // THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY
9 // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
10 // NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
11 // See the Mulan PSL v2 for more details.
12
13 use std::{fs, path::Path};
14
15 use anyhow::{Context, Result};
16
17 const APPARMOR_ENABLED_PATH: &str = "/sys/module/apparmor/parameters/enabled";
18 const APPARMOR_INTERFACE: &str = "/proc/self/attr/apparmor/exec";
19 const APPARMOR_LEGACY_INTERFACE: &str = "/proc/self/attr/exec";
20
is_enabled() -> Result<bool>21 pub fn is_enabled() -> Result<bool> {
22 let enabled = fs::read_to_string(APPARMOR_ENABLED_PATH)
23 .with_context(|| format!("Failed to read {}", APPARMOR_ENABLED_PATH))?;
24 Ok(enabled.starts_with('Y'))
25 }
26
apply_profile(profile: &str) -> Result<()>27 pub fn apply_profile(profile: &str) -> Result<()> {
28 if profile.is_empty() {
29 return Ok(());
30 }
31
32 // Try the module specific subdirectory. This is recommended to configure LSMs
33 // since Linux kernel 5.1. AppArmor has such a directory since Linux kernel 5.8.
34 match activate_profile(Path::new(APPARMOR_INTERFACE), profile) {
35 Ok(_) => Ok(()),
36 Err(_) => activate_profile(Path::new(APPARMOR_LEGACY_INTERFACE), profile)
37 .with_context(|| "Failed to apply apparmor profile"),
38 }
39 }
40
activate_profile(path: &Path, profile: &str) -> Result<()>41 fn activate_profile(path: &Path, profile: &str) -> Result<()> {
42 fs::write(path, format!("exec {}", profile))?;
43 Ok(())
44 }
45