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 128 129 130 131 132 133 134 135 136
// SPDX-License-Identifier: Apache-2.0 or MIT
//
// Copyright 2021 Sony Group Corporation
//
use super::cvt;
use crate::error::{Result, SeccompError};
use crate::version::ensure_supported_version;
use crate::{check_version, ScmpVersion};
use libseccomp_sys::*;
/// Sets the API level forcibly.
///
/// General use of this function is strongly discouraged.
/// See the [`seccomp_api_get(3)`] man page for details on available API levels.
///
/// [`seccomp_api_get(3)`]: https://www.man7.org/linux/man-pages/man3/seccomp_api_get.3.html
///
/// This function corresponds to
/// [`seccomp_api_set`](https://www.man7.org/linux/man-pages/man3/seccomp_api_set.3.html).
///
/// # Arguments
///
/// * `level` - The API level
///
/// # Errors
///
/// If the API level can not be detected due to the library being older than v2.4.0,
/// an error will be returned.
///
/// # Examples
///
/// ```
/// # use libseccomp::*;
/// set_api(1)?;
/// # Ok::<(), Box<dyn std::error::Error>>(())
/// ```
pub fn set_api(level: u32) -> Result<()> {
cvt(unsafe { seccomp_api_set(level) })?;
Ok(())
}
/// Gets the API level supported by the system.
///
/// See the [`seccomp_api_get(3)`] man page for details on available API levels.
///
/// [`seccomp_api_get(3)`]: https://www.man7.org/linux/man-pages/man3/seccomp_api_get.3.html
///
/// This function corresponds to
/// [`seccomp_api_get`](https://www.man7.org/linux/man-pages/man3/seccomp_api_get.3.html).
///
/// # Examples
///
/// ```
/// # use libseccomp::*;
/// set_api(1)?;
/// assert_eq!(get_api(), 1);
/// # Ok::<(), Box<dyn std::error::Error>>(())
/// ```
pub fn get_api() -> u32 {
unsafe { seccomp_api_get() }
}
/// Checks that both the libseccomp API level and the libseccomp version being
/// used are equal to or greater than the specified API level and version.
///
/// This function returns `Ok(true)` if both the libseccomp API level and the
/// libseccomp version are equal to or greater than the specified API level and
/// version, `Ok(false)` otherwise.
///
/// # Arguments
///
/// * `min_level` - The libseccomp API level you want to check
/// * `expected` - The libseccomp version you want to check
///
/// # Errors
///
/// If an issue is encountered getting the current API level or version,
/// an error will be returned.
///
/// # Examples
///
/// ```
/// # use libseccomp::*;
/// assert!(check_api(3, ScmpVersion::from((2, 4, 0)))?);
/// # Ok::<(), Box<dyn std::error::Error>>(())
/// ```
pub fn check_api(min_level: u32, expected: ScmpVersion) -> Result<bool> {
let level = get_api();
if level >= min_level && check_version(expected)? {
Ok(true)
} else {
Ok(false)
}
}
/// Ensures that both the libseccomp API level and the libseccomp version are
/// equal to or greater than the specified API level and version.
///
/// # Arguments
///
/// * `msg` - An arbitrary non-empty operation description, used as a part
/// of the error message returned.
/// * `min_level` - The libseccomp API level you want to check
/// * `expected` - The libseccomp version you want to check
///
/// # Errors
///
/// If the libseccomp API level and the libseccomp version being used are less than
/// the specified version, an error will be returned.
pub(crate) fn ensure_supported_api(msg: &str, min_level: u32, expected: ScmpVersion) -> Result<()> {
let level = get_api();
if level >= min_level {
ensure_supported_version(msg, expected)
} else {
let current = ScmpVersion::current()?;
Err(SeccompError::with_msg(format!(
"{} requires libseccomp >= {} and API level >= {} (current version: {}, API level: {})",
msg, expected, min_level, current, level
)))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_ensure_supported_api() {
assert!(ensure_supported_api("test", 3, ScmpVersion::from((2, 4, 0))).is_ok());
assert!(ensure_supported_api("test", 100, ScmpVersion::from((2, 4, 0))).is_err());
}
}