apparmor/parser/libapparmor_re/apparmor_re.h
John Johansen f0b154528d Fix dfa minimization
So DFA minimization has a bug and feature that keeps it from  minimizing
some dfas completely. This feature/bug did not result in incorrect dfas,
it just fails to result in full minimization.

The same mappings comparison is wrong. Or more correctly it is right when
transitions are not remapped to minimization partitions, but it may be
wrong when states are remapped. This means it will cause excess
partitioning (not removing all the states it should).

The trans hashing does a "guess" at partition splitting as a performance
enhancement. Basically it leverages the information that states that have
different transitions or transitions on different characters are not the
same. However this isn't always the case, because minimization can cause
some of those transitions to be altered. In previous testing this was
always a win, with only a few extra states being added some times. However
this changes with when the same mappings are fixed, as the hashing that was
done was based on the same flawed mapping as the broken same mappings.

If the same mappings are fixed and the hashing is not removed then there
is little to no change. However with both changes applied some dfas see
significant improvements. These improvements often result in performance
improvements despite minimization doing more work, because it means less
work to be done in the chfa comb compression

eg. test case that raised the issue (thanks tyler)
  /t { mount fstype=ext2, mount, }

  used to be minimized to
   {1} <== (allow/deny/audit/quiet)
   {6} (0x 2/0/0/0)

   {1} -> {2}: 0x7
   {2} -> {3}: 0x0
   {2} -> {2}: []
   {3} -> {4}: 0x0
   {3} -> {3}: []
   {4} -> {6}: 0x0
   {4} -> {7}: 0x65 e
   {4} -> {5}: []
   {5} -> {6}: 0x0
   {5} -> {5}: []
   {6}  (0x 2/0/0/0) -> {6}: [^\0x0]
   {7} -> {6}: 0x0
   {7} -> {8}: 0x78 x
   {7} -> {5}: []
   {8} -> {6}: 0x0
   {8} -> {5}: 0x74 t
   {8} -> {5}: []

  with the patch it is now properly minimized to
    {1} <== (allow/deny/audit/quiet)
    {6} (0x 2/0/0/0)

    {1} -> {2}: 0x7
    {2} -> {3}: 0x0
    {2} -> {2}: []
    {3} -> {4}: 0x0
    {3} -> {3}: []
    {4} -> {6}: 0x0
    {4} -> {4}: []
    {6}  (0x 2/0/0/0) -> {6}: [^\0x0]


The evince profile set sees some significant improvements picking a couple
example from its "minimized" dfas (it has 12) we see a reduction from 9720
states to 6232 states, and 6537 states to 3653 states. All told seeing the
performance/profile size going from
  2.8 parser: 4.607s 1007267 bytes
  dev head:   3.48s  1007267 bytes
  min fix:    2.68s  549603 bytes

of course evince is an extreme example so a few more

firefox
   2.066s   404549 bytes
 to
   1.336s   250585 bytes


cupsd
   0.365s   90834 bytes
 to
   0.293s   58855 bytes

dnsmasq
   0.118s   35689 bytes
 to
   0.112s   27992 bytes


smbd
   0.187s   40897 bytes
 to
   0.162s   33665 bytes


weather applet profile from ubuntu touch
   0.618s   105673 bytes
 to
   0.432s   89300 bytes


I have not seen a case where the parser regresses on performance but it is
possible. This patch will not cause a regression on generated policy size,
at worst it will result in policy that is the same size

Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: Steve Beattie <steve@nxnw.org>
2014-01-09 17:06:48 -08:00

58 lines
2 KiB
C

/*
* (C) 2006, 2007 Andreas Gruenbacher <agruen@suse.de>
* Copyright (c) 2003-2008 Novell, Inc. (All rights reserved)
* Copyright 2009-2012 Canonical Ltd.
*
* The libapparmor library is licensed under the terms of the GNU
* Lesser General Public License, version 2.1. Please see the file
* COPYING.LGPL.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef APPARMOR_RE_H
#define APPARMOR_RE_H
typedef int dfaflags_t;
#define DFA_CONTROL_EQUIV (1 << 0)
#define DFA_CONTROL_TREE_NORMAL (1 << 1)
#define DFA_CONTROL_TREE_SIMPLE (1 << 2)
#define DFA_CONTROL_TREE_LEFT (1 << 3)
#define DFA_CONTROL_MINIMIZE (1 << 4)
#define DFA_CONTROL_FILTER_DENY (1 << 6)
#define DFA_CONTROL_REMOVE_UNREACHABLE (1 << 7)
#define DFA_CONTROL_TRANS_HIGH (1 << 8)
#define DFA_CONTROL_DIFF_ENCODE (1 << 9)
#define DFA_DUMP_DIFF_PROGRESS (1 << 10)
#define DFA_DUMP_DIFF_ENCODE (1 << 11)
#define DFA_DUMP_DIFF_STATS (1 << 12)
#define DFA_DUMP_MIN_PARTS (1 << 13)
#define DFA_DUMP_UNIQ_PERMS (1 << 14)
#define DFA_DUMP_MIN_UNIQ_PERMS (1 << 15)
#define DFA_DUMP_TREE_STATS (1 << 16)
#define DFA_DUMP_TREE (1 << 17)
#define DFA_DUMP_SIMPLE_TREE (1 << 18)
#define DFA_DUMP_PROGRESS (1 << 19)
#define DFA_DUMP_STATS (1 << 20)
#define DFA_DUMP_STATES (1 << 21)
#define DFA_DUMP_GRAPH (1 << 22)
#define DFA_DUMP_TRANS_PROGRESS (1 << 23)
#define DFA_DUMP_TRANS_STATS (1 << 24)
#define DFA_DUMP_TRANS_TABLE (1 << 25)
#define DFA_DUMP_EQUIV (1 << 26)
#define DFA_DUMP_EQUIV_STATS (1 << 27)
#define DFA_DUMP_MINIMIZE (1 << 28)
#define DFA_DUMP_UNREACHABLE (1 << 29)
#define DFA_DUMP_RULE_EXPR (1 << 30)
#define DFA_DUMP_NODE_TO_DFA (1 << 31)
#endif /* APPARMOR_RE_H */