[sestarnix][policy] Normalize constraint terms for testing
The order of operands seems to depend on the policy
compiler version, at least for context expressions
with commutative operators.
Bug: 372400976
Change-Id: Ib7724cfd546ad6513da798b95b4b56473a21aaf1
Reviewed-on: https://fuchsia-review.googlesource.com/c/fuchsia/+/1221053
Commit-Queue: Laura Peskin <pesk@google.com>
Fuchsia-Auto-Submit: Laura Peskin <pesk@google.com>
Reviewed-by: Wez <wez@google.com>
diff --git a/src/starnix/lib/selinux/src/policy/constraints.rs b/src/starnix/lib/selinux/src/policy/constraints.rs
index d070b13..059c8ec 100644
--- a/src/starnix/lib/selinux/src/policy/constraints.rs
+++ b/src/starnix/lib/selinux/src/policy/constraints.rs
@@ -369,8 +369,42 @@
use super::*;
use crate::policy::{find_class_by_name, parse_policy_by_reference};
+ fn normalize_context_expr(expr: ContextExpression) -> ContextExpression {
+ let (left, right) = match expr.operator {
+ ContextOperator::Dominates | ContextOperator::DominatedBy => (expr.left, expr.right),
+ ContextOperator::Equal | ContextOperator::NotEqual | ContextOperator::Incomparable => {
+ match (&expr.left, &expr.right) {
+ (ContextOperand::UserId(left), ContextOperand::UserId(right)) => (
+ ContextOperand::UserId(std::cmp::min(*left, *right)),
+ ContextOperand::UserId(std::cmp::max(*left, *right)),
+ ),
+ (ContextOperand::TypeId(left), ContextOperand::TypeId(right)) => (
+ ContextOperand::TypeId(std::cmp::min(*left, *right)),
+ ContextOperand::TypeId(std::cmp::max(*left, *right)),
+ ),
+ (ContextOperand::RoleId(left), ContextOperand::RoleId(right)) => (
+ ContextOperand::RoleId(std::cmp::min(*left, *right)),
+ ContextOperand::RoleId(std::cmp::max(*left, *right)),
+ ),
+ _ => (expr.left, expr.right),
+ }
+ }
+ };
+ ContextExpression { operator: expr.operator, left, right }
+ }
+
+ fn normalize(expr: Vec<ConstraintNode>) -> Vec<ConstraintNode> {
+ expr.into_iter()
+ .map(|node| match node {
+ ConstraintNode::Leaf(context_expr) => {
+ ConstraintNode::Leaf(normalize_context_expr(context_expr))
+ }
+ ConstraintNode::Branch(_) => node,
+ })
+ .collect()
+ }
+
#[test]
- #[ignore = "TODO: Fix test to accommodate apparent non-determinism in commutative operator arguments"]
fn decode_constraint_expr() {
let policy_bytes = include_bytes!("../../testdata/micro_policies/constraints_policy.pp");
let policy = parse_policy_by_reference(policy_bytes.as_slice())
@@ -396,7 +430,7 @@
.iter()
.map(|x| ConstraintNode::try_from_constraint_term(x, &source, &target))
.collect();
- assert!(result.is_ok());
+ let constraint_nodes = normalize(result.expect("decode constraint terms"));
let expected = vec![
// ( u2 == { user0 user1 } )
ConstraintNode::Leaf(ContextExpression {
@@ -435,7 +469,7 @@
ConstraintNode::Branch(BooleanOperator::Or),
];
- assert_eq!(result.unwrap(), expected)
+ assert_eq!(constraint_nodes, expected)
}
#[test]
diff --git a/src/starnix/lib/selinux/src/policy/mod.rs b/src/starnix/lib/selinux/src/policy/mod.rs
index 0417c1f59..8df7ed3 100644
--- a/src/starnix/lib/selinux/src/policy/mod.rs
+++ b/src/starnix/lib/selinux/src/policy/mod.rs
@@ -38,15 +38,15 @@
pub const SUPPORTED_POLICY_VERSION: u32 = 33;
/// Identifies a user within a policy.
-#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
+#[derive(Copy, Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
pub struct UserId(NonZeroU32);
/// Identifies a role within a policy.
-#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
+#[derive(Copy, Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
pub struct RoleId(NonZeroU32);
/// Identifies a type within a policy.
-#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
+#[derive(Copy, Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
pub struct TypeId(NonZeroU32);
/// Identifies a sensitivity level within a policy.