Move large test modules into separate files
This complies better with the Android Rust style guide, and makes it
easier to navigate the code.
Test: keystore2_test libwatchdog_rs.test librkpd_client.test
Change-Id: Iceb49e309af66ec16d31da66b328936b0312061a
diff --git a/keystore2/src/permission.rs b/keystore2/src/permission.rs
index 982bc82..d79445b 100644
--- a/keystore2/src/permission.rs
+++ b/keystore2/src/permission.rs
@@ -38,6 +38,9 @@
#[cfg(test)]
use tests::test_getcon as getcon;
+#[cfg(test)]
+mod tests;
+
lazy_static! {
// Panicking here is allowed because keystore cannot function without this backend
// and it would happen early and indicate a gross misconfiguration of the device.
@@ -397,433 +400,3 @@
selinux::check_permission(caller_ctx, &target_context, perm)
}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use anyhow::anyhow;
- use anyhow::Result;
- use keystore2_selinux::*;
-
- const ALL_PERMS: KeyPermSet = key_perm_set![
- KeyPerm::ManageBlob,
- KeyPerm::Delete,
- KeyPerm::UseDevId,
- KeyPerm::ReqForcedOp,
- KeyPerm::GenUniqueId,
- KeyPerm::Grant,
- KeyPerm::GetInfo,
- KeyPerm::Rebind,
- KeyPerm::Update,
- KeyPerm::Use,
- KeyPerm::ConvertStorageKeyToEphemeral,
- ];
-
- const SYSTEM_SERVER_PERMISSIONS_NO_GRANT: KeyPermSet = key_perm_set![
- KeyPerm::Delete,
- KeyPerm::UseDevId,
- // No KeyPerm::Grant
- KeyPerm::GetInfo,
- KeyPerm::Rebind,
- KeyPerm::Update,
- KeyPerm::Use,
- ];
-
- const NOT_GRANT_PERMS: KeyPermSet = key_perm_set![
- KeyPerm::ManageBlob,
- KeyPerm::Delete,
- KeyPerm::UseDevId,
- KeyPerm::ReqForcedOp,
- KeyPerm::GenUniqueId,
- // No KeyPerm::Grant
- KeyPerm::GetInfo,
- KeyPerm::Rebind,
- KeyPerm::Update,
- KeyPerm::Use,
- KeyPerm::ConvertStorageKeyToEphemeral,
- ];
-
- const UNPRIV_PERMS: KeyPermSet = key_perm_set![
- KeyPerm::Delete,
- KeyPerm::GetInfo,
- KeyPerm::Rebind,
- KeyPerm::Update,
- KeyPerm::Use,
- ];
-
- /// The su_key namespace as defined in su.te and keystore_key_contexts of the
- /// SePolicy (system/sepolicy).
- const SU_KEY_NAMESPACE: i32 = 0;
- /// The shell_key namespace as defined in shell.te and keystore_key_contexts of the
- /// SePolicy (system/sepolicy).
- const SHELL_KEY_NAMESPACE: i32 = 1;
-
- pub fn test_getcon() -> Result<Context> {
- Context::new("u:object_r:keystore:s0")
- }
-
- // This macro evaluates the given expression and checks that
- // a) evaluated to Result::Err() and that
- // b) the wrapped error is selinux::Error::perm() (permission denied).
- // We use a macro here because a function would mask which invocation caused the failure.
- //
- // TODO b/164121720 Replace this macro with a function when `track_caller` is available.
- macro_rules! assert_perm_failed {
- ($test_function:expr) => {
- let result = $test_function;
- assert!(result.is_err(), "Permission check should have failed.");
- assert_eq!(
- Some(&selinux::Error::perm()),
- result.err().unwrap().root_cause().downcast_ref::<selinux::Error>()
- );
- };
- }
-
- fn check_context() -> Result<(selinux::Context, i32, bool)> {
- // Calling the non mocked selinux::getcon here intended.
- let context = selinux::getcon()?;
- match context.to_str().unwrap() {
- "u:r:su:s0" => Ok((context, SU_KEY_NAMESPACE, true)),
- "u:r:shell:s0" => Ok((context, SHELL_KEY_NAMESPACE, false)),
- c => Err(anyhow!(format!(
- "This test must be run as \"su\" or \"shell\". Current context: \"{}\"",
- c
- ))),
- }
- }
-
- #[test]
- fn check_keystore_permission_test() -> Result<()> {
- let system_server_ctx = Context::new("u:r:system_server:s0")?;
- assert!(check_keystore_permission(&system_server_ctx, KeystorePerm::AddAuth).is_ok());
- assert!(check_keystore_permission(&system_server_ctx, KeystorePerm::ClearNs).is_ok());
- assert!(check_keystore_permission(&system_server_ctx, KeystorePerm::Lock).is_ok());
- assert!(check_keystore_permission(&system_server_ctx, KeystorePerm::Reset).is_ok());
- assert!(check_keystore_permission(&system_server_ctx, KeystorePerm::Unlock).is_ok());
- assert!(check_keystore_permission(&system_server_ctx, KeystorePerm::ChangeUser).is_ok());
- assert!(check_keystore_permission(&system_server_ctx, KeystorePerm::ChangePassword).is_ok());
- assert!(check_keystore_permission(&system_server_ctx, KeystorePerm::ClearUID).is_ok());
- let shell_ctx = Context::new("u:r:shell:s0")?;
- assert_perm_failed!(check_keystore_permission(&shell_ctx, KeystorePerm::AddAuth));
- assert_perm_failed!(check_keystore_permission(&shell_ctx, KeystorePerm::ClearNs));
- assert_perm_failed!(check_keystore_permission(&shell_ctx, KeystorePerm::List));
- assert_perm_failed!(check_keystore_permission(&shell_ctx, KeystorePerm::Lock));
- assert_perm_failed!(check_keystore_permission(&shell_ctx, KeystorePerm::Reset));
- assert_perm_failed!(check_keystore_permission(&shell_ctx, KeystorePerm::Unlock));
- assert_perm_failed!(check_keystore_permission(&shell_ctx, KeystorePerm::ChangeUser));
- assert_perm_failed!(check_keystore_permission(&shell_ctx, KeystorePerm::ChangePassword));
- assert_perm_failed!(check_keystore_permission(&shell_ctx, KeystorePerm::ClearUID));
- Ok(())
- }
-
- #[test]
- fn check_grant_permission_app() -> Result<()> {
- let system_server_ctx = Context::new("u:r:system_server:s0")?;
- let shell_ctx = Context::new("u:r:shell:s0")?;
- let key = KeyDescriptor { domain: Domain::APP, nspace: 0, alias: None, blob: None };
- check_grant_permission(&system_server_ctx, SYSTEM_SERVER_PERMISSIONS_NO_GRANT, &key)
- .expect("Grant permission check failed.");
-
- // attempts to grant the grant permission must always fail even when privileged.
- assert_perm_failed!(check_grant_permission(
- &system_server_ctx,
- KeyPerm::Grant.into(),
- &key
- ));
- // unprivileged grant attempts always fail. shell does not have the grant permission.
- assert_perm_failed!(check_grant_permission(&shell_ctx, UNPRIV_PERMS, &key));
- Ok(())
- }
-
- #[test]
- fn check_grant_permission_selinux() -> Result<()> {
- let (sctx, namespace, is_su) = check_context()?;
- let key = KeyDescriptor {
- domain: Domain::SELINUX,
- nspace: namespace as i64,
- alias: None,
- blob: None,
- };
- if is_su {
- assert!(check_grant_permission(&sctx, NOT_GRANT_PERMS, &key).is_ok());
- // attempts to grant the grant permission must always fail even when privileged.
- assert_perm_failed!(check_grant_permission(&sctx, KeyPerm::Grant.into(), &key));
- } else {
- // unprivileged grant attempts always fail. shell does not have the grant permission.
- assert_perm_failed!(check_grant_permission(&sctx, UNPRIV_PERMS, &key));
- }
- Ok(())
- }
-
- #[test]
- fn check_key_permission_domain_grant() -> Result<()> {
- let key = KeyDescriptor { domain: Domain::GRANT, nspace: 0, alias: None, blob: None };
-
- assert_perm_failed!(check_key_permission(
- 0,
- &selinux::Context::new("ignored").unwrap(),
- KeyPerm::Grant,
- &key,
- &Some(UNPRIV_PERMS)
- ));
-
- check_key_permission(
- 0,
- &selinux::Context::new("ignored").unwrap(),
- KeyPerm::Use,
- &key,
- &Some(ALL_PERMS),
- )
- }
-
- #[test]
- fn check_key_permission_domain_app() -> Result<()> {
- let system_server_ctx = Context::new("u:r:system_server:s0")?;
- let shell_ctx = Context::new("u:r:shell:s0")?;
- let gmscore_app = Context::new("u:r:gmscore_app:s0")?;
-
- let key = KeyDescriptor { domain: Domain::APP, nspace: 0, alias: None, blob: None };
-
- assert!(check_key_permission(0, &system_server_ctx, KeyPerm::Use, &key, &None).is_ok());
- assert!(check_key_permission(0, &system_server_ctx, KeyPerm::Delete, &key, &None).is_ok());
- assert!(check_key_permission(0, &system_server_ctx, KeyPerm::GetInfo, &key, &None).is_ok());
- assert!(check_key_permission(0, &system_server_ctx, KeyPerm::Rebind, &key, &None).is_ok());
- assert!(check_key_permission(0, &system_server_ctx, KeyPerm::Update, &key, &None).is_ok());
- assert!(check_key_permission(0, &system_server_ctx, KeyPerm::Grant, &key, &None).is_ok());
- assert!(check_key_permission(0, &system_server_ctx, KeyPerm::UseDevId, &key, &None).is_ok());
- assert!(check_key_permission(0, &gmscore_app, KeyPerm::GenUniqueId, &key, &None).is_ok());
-
- assert!(check_key_permission(0, &shell_ctx, KeyPerm::Use, &key, &None).is_ok());
- assert!(check_key_permission(0, &shell_ctx, KeyPerm::Delete, &key, &None).is_ok());
- assert!(check_key_permission(0, &shell_ctx, KeyPerm::GetInfo, &key, &None).is_ok());
- assert!(check_key_permission(0, &shell_ctx, KeyPerm::Rebind, &key, &None).is_ok());
- assert!(check_key_permission(0, &shell_ctx, KeyPerm::Update, &key, &None).is_ok());
- assert_perm_failed!(check_key_permission(0, &shell_ctx, KeyPerm::Grant, &key, &None));
- assert_perm_failed!(check_key_permission(0, &shell_ctx, KeyPerm::ReqForcedOp, &key, &None));
- assert_perm_failed!(check_key_permission(0, &shell_ctx, KeyPerm::ManageBlob, &key, &None));
- assert_perm_failed!(check_key_permission(0, &shell_ctx, KeyPerm::UseDevId, &key, &None));
- assert_perm_failed!(check_key_permission(0, &shell_ctx, KeyPerm::GenUniqueId, &key, &None));
-
- // Also make sure that the permission fails if the caller is not the owner.
- assert_perm_failed!(check_key_permission(
- 1, // the owner is 0
- &system_server_ctx,
- KeyPerm::Use,
- &key,
- &None
- ));
- // Unless there was a grant.
- assert!(check_key_permission(
- 1,
- &system_server_ctx,
- KeyPerm::Use,
- &key,
- &Some(key_perm_set![KeyPerm::Use])
- )
- .is_ok());
- // But fail if the grant did not cover the requested permission.
- assert_perm_failed!(check_key_permission(
- 1,
- &system_server_ctx,
- KeyPerm::Use,
- &key,
- &Some(key_perm_set![KeyPerm::GetInfo])
- ));
-
- Ok(())
- }
-
- #[test]
- fn check_key_permission_domain_selinux() -> Result<()> {
- let (sctx, namespace, is_su) = check_context()?;
- let key = KeyDescriptor {
- domain: Domain::SELINUX,
- nspace: namespace as i64,
- alias: None,
- blob: None,
- };
-
- assert!(check_key_permission(0, &sctx, KeyPerm::Use, &key, &None).is_ok());
- assert!(check_key_permission(0, &sctx, KeyPerm::Delete, &key, &None).is_ok());
- assert!(check_key_permission(0, &sctx, KeyPerm::GetInfo, &key, &None).is_ok());
- assert!(check_key_permission(0, &sctx, KeyPerm::Rebind, &key, &None).is_ok());
- assert!(check_key_permission(0, &sctx, KeyPerm::Update, &key, &None).is_ok());
-
- if is_su {
- assert!(check_key_permission(0, &sctx, KeyPerm::Grant, &key, &None).is_ok());
- assert!(check_key_permission(0, &sctx, KeyPerm::ManageBlob, &key, &None).is_ok());
- assert!(check_key_permission(0, &sctx, KeyPerm::UseDevId, &key, &None).is_ok());
- assert!(check_key_permission(0, &sctx, KeyPerm::GenUniqueId, &key, &None).is_ok());
- assert!(check_key_permission(0, &sctx, KeyPerm::ReqForcedOp, &key, &None).is_ok());
- } else {
- assert_perm_failed!(check_key_permission(0, &sctx, KeyPerm::Grant, &key, &None));
- assert_perm_failed!(check_key_permission(0, &sctx, KeyPerm::ReqForcedOp, &key, &None));
- assert_perm_failed!(check_key_permission(0, &sctx, KeyPerm::ManageBlob, &key, &None));
- assert_perm_failed!(check_key_permission(0, &sctx, KeyPerm::UseDevId, &key, &None));
- assert_perm_failed!(check_key_permission(0, &sctx, KeyPerm::GenUniqueId, &key, &None));
- }
- Ok(())
- }
-
- #[test]
- fn check_key_permission_domain_blob() -> Result<()> {
- let (sctx, namespace, is_su) = check_context()?;
- let key = KeyDescriptor {
- domain: Domain::BLOB,
- nspace: namespace as i64,
- alias: None,
- blob: None,
- };
-
- if is_su {
- check_key_permission(0, &sctx, KeyPerm::Use, &key, &None)
- } else {
- assert_perm_failed!(check_key_permission(0, &sctx, KeyPerm::Use, &key, &None));
- Ok(())
- }
- }
-
- #[test]
- fn check_key_permission_domain_key_id() -> Result<()> {
- let key = KeyDescriptor { domain: Domain::KEY_ID, nspace: 0, alias: None, blob: None };
-
- assert_eq!(
- Some(&KsError::sys()),
- check_key_permission(
- 0,
- &selinux::Context::new("ignored").unwrap(),
- KeyPerm::Use,
- &key,
- &None
- )
- .err()
- .unwrap()
- .root_cause()
- .downcast_ref::<KsError>()
- );
- Ok(())
- }
-
- #[test]
- fn key_perm_set_all_test() {
- let v = key_perm_set![
- KeyPerm::ManageBlob,
- KeyPerm::Delete,
- KeyPerm::UseDevId,
- KeyPerm::ReqForcedOp,
- KeyPerm::GenUniqueId,
- KeyPerm::Grant,
- KeyPerm::GetInfo,
- KeyPerm::Rebind,
- KeyPerm::Update,
- KeyPerm::Use // Test if the macro accepts missing comma at the end of the list.
- ];
- let mut i = v.into_iter();
- assert_eq!(i.next().unwrap().name(), "delete");
- assert_eq!(i.next().unwrap().name(), "gen_unique_id");
- assert_eq!(i.next().unwrap().name(), "get_info");
- assert_eq!(i.next().unwrap().name(), "grant");
- assert_eq!(i.next().unwrap().name(), "manage_blob");
- assert_eq!(i.next().unwrap().name(), "rebind");
- assert_eq!(i.next().unwrap().name(), "req_forced_op");
- assert_eq!(i.next().unwrap().name(), "update");
- assert_eq!(i.next().unwrap().name(), "use");
- assert_eq!(i.next().unwrap().name(), "use_dev_id");
- assert_eq!(None, i.next());
- }
- #[test]
- fn key_perm_set_sparse_test() {
- let v = key_perm_set![
- KeyPerm::ManageBlob,
- KeyPerm::ReqForcedOp,
- KeyPerm::GenUniqueId,
- KeyPerm::Update,
- KeyPerm::Use, // Test if macro accepts the comma at the end of the list.
- ];
- let mut i = v.into_iter();
- assert_eq!(i.next().unwrap().name(), "gen_unique_id");
- assert_eq!(i.next().unwrap().name(), "manage_blob");
- assert_eq!(i.next().unwrap().name(), "req_forced_op");
- assert_eq!(i.next().unwrap().name(), "update");
- assert_eq!(i.next().unwrap().name(), "use");
- assert_eq!(None, i.next());
- }
- #[test]
- fn key_perm_set_empty_test() {
- let v = key_perm_set![];
- let mut i = v.into_iter();
- assert_eq!(None, i.next());
- }
- #[test]
- fn key_perm_set_include_subset_test() {
- let v1 = key_perm_set![
- KeyPerm::ManageBlob,
- KeyPerm::Delete,
- KeyPerm::UseDevId,
- KeyPerm::ReqForcedOp,
- KeyPerm::GenUniqueId,
- KeyPerm::Grant,
- KeyPerm::GetInfo,
- KeyPerm::Rebind,
- KeyPerm::Update,
- KeyPerm::Use,
- ];
- let v2 = key_perm_set![
- KeyPerm::ManageBlob,
- KeyPerm::Delete,
- KeyPerm::Rebind,
- KeyPerm::Update,
- KeyPerm::Use,
- ];
- assert!(v1.includes(v2));
- assert!(!v2.includes(v1));
- }
- #[test]
- fn key_perm_set_include_equal_test() {
- let v1 = key_perm_set![
- KeyPerm::ManageBlob,
- KeyPerm::Delete,
- KeyPerm::Rebind,
- KeyPerm::Update,
- KeyPerm::Use,
- ];
- let v2 = key_perm_set![
- KeyPerm::ManageBlob,
- KeyPerm::Delete,
- KeyPerm::Rebind,
- KeyPerm::Update,
- KeyPerm::Use,
- ];
- assert!(v1.includes(v2));
- assert!(v2.includes(v1));
- }
- #[test]
- fn key_perm_set_include_overlap_test() {
- let v1 = key_perm_set![
- KeyPerm::ManageBlob,
- KeyPerm::Delete,
- KeyPerm::Grant, // only in v1
- KeyPerm::Rebind,
- KeyPerm::Update,
- KeyPerm::Use,
- ];
- let v2 = key_perm_set![
- KeyPerm::ManageBlob,
- KeyPerm::Delete,
- KeyPerm::ReqForcedOp, // only in v2
- KeyPerm::Rebind,
- KeyPerm::Update,
- KeyPerm::Use,
- ];
- assert!(!v1.includes(v2));
- assert!(!v2.includes(v1));
- }
- #[test]
- fn key_perm_set_include_no_overlap_test() {
- let v1 = key_perm_set![KeyPerm::ManageBlob, KeyPerm::Delete, KeyPerm::Grant,];
- let v2 =
- key_perm_set![KeyPerm::ReqForcedOp, KeyPerm::Rebind, KeyPerm::Update, KeyPerm::Use,];
- assert!(!v1.includes(v2));
- assert!(!v2.includes(v1));
- }
-}