On Tue, 10 Dec 2024 at 08:57, Takaya Saeki <takayas@xxxxxxxxxxxx> wrote: > > Hello Christian and SELinux developers, > > I observed 3.8-rc1 introduced an incompatible change that appears to be a > regression regarding how file_contexts matching rules are applied when multiple > rules match the same path. Thanks for testing and reporting. > Before 3.8-rc1, when multiple rules matched a path, the last matching rule in > the file_contexts file was applied. However, in 3.8-rc1, the rule precedence > has changed, and the chosen rule is no longer easily predictable. I think we > should keep the older version's precedence rule to avoid breaking existing > rules. > > This is a real-world example from Android: > > > /system(/.*)? u:object_r:system_file:s0 > > /(vendor|system/vendor)(/.*)? u:object_r:vendor_file:s0 > > Before 3.8-rc1, the second rule was applied to /system/vendor because it was > the last matching rule. However, with 3.8-rc1, the first rule is applied > instead. In 3.8-rc1, the rules appear to be sorted by decreasing regex string > length, leading to this incompatible behavior. I can reproduce the behavior. The precedence logic was based on the common and (in my point of view) standard SELinux file context order: Order regular expressions based on the length of their prefix stem (non-regex characters). See support/fc_sort.py in the Reference and Fedora Policy, semanage_fc_compare() in libsemanage/semanage_store.c and cil_post_filecon_compare() in libsepol/cil/src/cil_post.c. > Furthermore, the new behavior, where the longest rule is supposedly > prioritized, isn't consistently applied either. Consider these rules below. > Even though the second rule is longer, the first rule is applied to /foo/bar. > This is because now the node for `foo` is processed first. > > > /foo/b.* u:object_r:b_something_file:s0 > > /(foo|baz)/bar u:object_r:bar_file:s0 This behavior is intended since the length of the prefix stem of the first entry is 6 ("/foo/b") and the second one has s prefix stem length of 1 ("/"). > I think we would want to preserve the original line numbers of rules and pick > the largest one in each prefix node. After that, maybe we should match > remaining rules of the root node to check if there are matching rules of even > larger line numbers. > > This is the regression I mentioned in > https://lore.kernel.org/selinux/CAH9xa6ct0Zf+vg6H6aN9aYzsAPjq8dYM7aF5Sw2eD31cFQ9BZA@xxxxxxxxxxxxxx/ > > Thanks, > Takaya