smack-team/smack — pull request #39 by rafal-krypa (2014-01-27 18:14:48+00:00)
Title: Handling of multiple rules with the same subject and object

Rules having the same subject and object (and different permissions) can appear in several places. The issue causes superfluous data and file size, possibly undefined policy for some rules and performance degradation.

1. Repeated rules in smack_accesses
When smack_accesses_add() or smack_accesses_add_modify() is called multiple times with the same (subject, object) pair, each call just adds new list entry at the end. This is fast and simple, but causes the list to grow unnecessarily. Only one rule for each (subject, object) pair is really needed.
Pull request https://github.com/smack-team/smack/pull/14 attempts to fix that.

2. Repeated rules in a policy config file
When rule set as described above is saved to a file, it will contain all of the repeated rules. This causes need to parse them and write to kernel. It could be replaced with a shorter rule list with the same effect.
This would be fixed by https://github.com/smack-team/smack/pull/14 or a separate patch optimizing the rule set just for the file write.

3. Repeated rules in several policy config files
If there are multiple files containing rules for the same (subject, object) pair, the whole policy is actually undefined. The final rule for that subject and object will depend on the order in which files are loaded. Smackload program uses nftw() to traverse directory, which in turn uses readdir(). This doesn't guarantee the order of files, leaving it up to the file system implementation. The order can also change when new policy files are created.
This should be fixed by using different directory traversal mechanisms or at least detecting the problem and reporting it.

4. Repeated rules in write to kernel
This is a consequence of the previous points. Kernel does the actual rule replacement when it encounters the same subject and object as before. But it causes more data to be written to kernel than needed. Smack_accesses_apply() takes longer and the system boots up slower.