Commit graph

1039 commits

Author SHA1 Message Date
Steve Beattie
19cf0fd89d merge from trunk 2014-03-18 10:02:27 -07:00
John Johansen
fa1a5f8a61 Remove the old unused ptrace code that snuck in years ago.
It was never used, never supported, and we are doing it differently now.

Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
2014-03-12 05:02:32 -07:00
John Johansen
6744feeb76 Capability entries in the profile are not being correctly initialized to 0
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Steve Beattie <steve@nxnw.org>
2014-02-27 13:53:28 -08:00
Steve Beattie
e4c534fc99 merge apparmor trunk back into the tree 2014-02-20 17:37:42 -08:00
Steve Beattie
192ca1dc57 parser: exit with error on invalid arguments
The parser currently indicates that it exited successfully if invalid
arguments are passed to it, which makes it difficult to detect when
other tools are calling it incorrectly. This patch causes it to return
'1' indicating a failure.

Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: John Johansen <john.johansen@canonical.com>
2014-02-20 16:53:18 -08:00
Tyler Hicks
4b950117f9 parser: Quiet search dir valgrind warning and remove suppression
When passing an include directory on the command line to
apparmor_parser, valgrind emits a warning:

 Invalid read of size 4
    at 0x404DA6: add_search_dir(char const*) (parser_include.c:152)
    by 0x40BB37: process_arg(int, char*) (parser_main.c:457)
    by 0x403D43: main (parser_main.c:590)
  Address 0x572207c is 28 bytes inside a block of size 29 alloc'd
    at 0x4C2A420: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    by 0x53E31C9: strdup (strdup.c:42)
    by 0x404D94: add_search_dir(char const*) (parser_include.c:145)
    by 0x40BB37: process_arg(int, char*) (parser_main.c:457)
    by 0x403D43: main (parser_main.c:590)

This patch quiets the warning by removing strlen() calls on the t char
array. Instead, it only calls strlen() on the dir char array. t is a
dupe of dir and strlen(dir) does not trigger the valgrind warning.

Additionally, this patch adds a bit of defensive programming to the
while loop to ensure that index into the t array is never negative.

Finally, the valgrind suppression is removed from valgrind_simple.py.

Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: Steve Beattie <steve@nxnw.org>
2014-02-05 15:17:32 -05:00
Steve Beattie
0d613279ba parser: remove one valgrind suppression from test script
With commit 2364 addressing one of valgrind's false positives, we can
remove the related valgrind suppression entry from the test script.

Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
Acked-by: Tyler Hicks <tyhicks@canonical.com>
2014-02-05 10:58:03 -08:00
Tyler Hicks
2001fb6f81 parser: Quiet valgrind false positive
strlen() assumes that it can read an entire word but when a char array
does not end on a word boundary, it reads past the end of the array.
This results in the following valgrind warning:

 Invalid read of size 4
    at 0x40A162: yylex() (parser_lex.l:277)
    by 0x40FA14: yyparse() (parser_yacc.c:1487)
    by 0x40C5B9: process_profile(int, char const*) (parser_main.c:1003)
    by 0x404074: main (parser_main.c:1340)
  Address 0x578d870 is 16 bytes inside a block of size 18 alloc'd
    at 0x4C2A420: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    by 0x53E31C9: strdup (strdup.c:42)
    by 0x40A145: yylex() (parser_lex.l:276)
    by 0x40FA14: yyparse() (parser_yacc.c:1487)
    by 0x40C5B9: process_profile(int, char const*) (parser_main.c:1003)
    by 0x404074: main (parser_main.c:1340)

This patch quiets the warning by not using strlen(). This can be done
because yyleng already contains the length of string.

Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: Steve Beattie <steve@nxnw.org>
2014-02-05 13:39:24 -05:00
John Johansen
5df1ac3610 Move short_options next to long_options to make them easier to keep in sync
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
Acked-by: Steve Beattie <steve@nxnw.org>
2014-02-05 09:10:53 -05:00
Steve Beattie
0a8e97098d parser: fix --cache-loc short arg option (-L)
When the --cache-loc option was added in trunk commit 1916, it was
intended that -L would be the short form of the option (based on
documentation and usage changes). However, the commit mistakenly
did not include the short option in the list include in the call
to getopt_long(3). This patch adds it along with the indicator
that it requires an argument (the different cache location) to the
getopt_long() call.

Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
2014-02-04 14:28:21 -08:00
John Johansen
572fe066da The preprocessing output is broken, in a couple of places
includes come out like

  #include 

  ##included <tunables/home>

which is wrong because #include by itself is broken, and since -p is
supposed to be removing includes, it should not be directly echoed

any keyword in the keyword table is double echoed

  ownerowner /{run,dev}/shm/pulse-shm* rwk


Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Steve Beattie <steve@nxnw.org>
2014-02-02 19:23:10 -10:00
Steve Beattie
cb679f3206 add keyword 'other' vim syntax support, plus language parsing tests
Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: John Johansen <john.johansen@canonical.com>
2014-01-24 11:17:23 -08:00
Steve Beattie
9bb81e1ed3 parser: add rttime rlimit support
This patch adds support for the rttime rlimit (aka RLIMIT_RTTIME),
available since the 2.6.25 kernel, according to the getrlimit(2)
man page; see that man page for more details on this rlimit.
An acceptance test is also added, as well as an update to the
apparmor.vim input template.

While reviewing to see what made sense in apparmor.vim for the rttime
rlimit, I discovered that RLIMIT_RTTIME's units are microseconds, not
seconds like RLIMIT_CPU (according to the setrlimit(2) manpage). This
necessitated not sharing the case switch with RLIMIT_CPU. I didn't add
a keyword for microseconds, but I did for milliseconds. I also don't
accept any unit larger than minutes, as it didn't seem appropriate
(and even minutes felt... gratuitous). I would appreciate feedback
on what keywords would be useful here.

Patch History:
  v1: initial submission
  v2: - add apparmor.vim support for rttime keyword
      - adjust RLIMIT_TIME value assignment due to its units being
	microseconds, not seconds, and add milliseconds keyword.

Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: John Johansen <john.johansen@canonical.com>
2014-01-24 11:06:31 -08:00
Steve Beattie
1fd3b5ed5a parser: close file handle left opened
Close file handle left opened if parser.cfg is found and read from.
Found by cppcheck.

Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: John Johansen <john.johansen@canonical.com>
2014-01-24 10:59:30 -08:00
Steve Beattie
fb3baeaf23 parser: fix memory leak on calloc() failure
Fix leaked memory if calloc() fails. Found by cppcheck.

Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: John Johansen <john.johansen@canonical.com>
2014-01-24 10:58:06 -08:00
Steve Beattie
8237c6fb28 parser: simplify handling of default matching patterns
Seth Arnold noticed an ugly string.clear(); convert_entry(string,
NULL) pattern occurred frequently following the conversion to using
std::string. This patch replaces that by using a static pointer to
a constant string matching pattern, and also converts other uses of
that pattern. It also adds a function wrapper that will clear the
passed buffer before calling convert_entry().

Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: John Johansen <john.johansen@canonical.com>
2014-01-24 10:47:42 -08:00
Steve Beattie
d4c8971b65 parser: pull forward free() calls
As noted by Seth Arnold, in expand_by_alternations() if our set
variable has at least one value, then we're going to rewrite the entry,
so rather than sprinkle the free()s near where the reallocation occurs,
use one free() once we're guaranteed to need to do so.

Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: John Johansen <john.johansen@canonical.com>
2014-01-24 10:45:48 -08:00
Steve Beattie
78fe398a2f parser: replace reverse iterator
As suggested by Seth Arnold, we can use string::find_last_not_of()
instead of using C++'s hideous reverse iterators.

Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: John Johansen <john.johansen@canonical.com>
2014-01-24 10:30:08 -08:00
Steve Beattie
39564bbdf5 parser: remove unneeded e_buffer_overflow
As noted by Seth Arnold, e_buffer_overflow is no longer set in
convert_aaregex_to_pcre(), so remove it and the sole check for it.

Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: John Johansen <john.johansen@canonical.com>
2014-01-24 10:27:58 -08:00
Steve Beattie
6e701f798f parser: remove static sized buffer in process_dbus_entry()
This patch converts a stack allocated buffer into an std::ostringstream
object. The stringstream interface for specifying the equivalent of
a printf %02x conversion is a bit of an awkward construction, however.

Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: John Johansen <john.johansen@canonical.com>
2014-01-24 10:25:47 -08:00
Steve Beattie
5f18a7c237 parser: remove unneeded vars/allocations in regex unit tests
Based on feedback from Seth Arnold, the convert_aaregex_to_pcre()'s
first argument is const char *, and thus the unit test macros don't need
to pass a copy of the input string to it, as it's guaranteed to be
unmodified by the function.

Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: John Johansen <john.johansen@canonical.com>
2014-01-24 10:21:30 -08:00
Steve Beattie
fdd89f1da5 parser: eliminate bison warning
This patch eliminates the bison warning about "%name-prefix =" being
deprecated.

Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: John Johansen <john.johansen@canonical.com>
2014-01-24 10:19:59 -08:00
Launchpad Translations on behalf of apparmor-dev
32eb900317 Launchpad automatic translations update. 2014-01-22 05:15:04 +00:00
Steve Beattie
f6af922088 po files: eliminate msgfmt missing language header warning
Current builds include many warnings when building translations message
files like so:

  msgfmt -c -o ja.mo ja.po
  ja.po:5: warning: header field 'Language' missing in header

According to what I read in the entry for Language in
http://www.gnu.org/software/gettext/manual/gettext.html#Header-Entry
the language entry should be (in our case) the same as the file name
minus the .po suffix. This patch adds the language field for those
po files that were missing it.

Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: Christian Boltz <apparmor@cboltz.de>
2014-01-20 11:45:10 -08:00
Steve Beattie
5bae654061 parser: add additional language tests to get wider test coverage
This patch adds several assorted language tests, to exercise various
parts of the parser that were not being covered by the language tests
previously. Areas lacking were found using the coverage compilation
option; coverage from the language tests is still incomplete.

Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: Christian Boltz <apparmor@cboltz.de>
2014-01-17 23:20:51 -08:00
Steve Beattie
bae37248f5 parser+utils: adjust translation bugs reporting address
This patch updates the Report-Msgid-Bugs-To: to point to the apparmor
list instead of the old Novell forge address. It also makes the
Project-Id-Version: field consistent.

Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: Christian Boltz <apparmor@cboltz.de>
2014-01-17 11:19:33 -08:00
Steve Beattie
62d636f125 parser: add rlimit language acceptance tests
The parser was lacking language tests for rlimits. This test adds
several, one for each rlimit type.

Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: Christian Boltz <apparmor@cboltz.de>
2014-01-16 23:11:07 -08:00
Steve Beattie
49ec571bd0 parser: remove unneeded goto target in build_mnt_opts()
As noted by Seth Arnold, there's now only one failure case in the
function and thus does not warrant a goto target (especially since
there's no cleanup to occur).

Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: Christian Boltz <apparmor@cboltz.de>
2014-01-16 19:09:35 -08:00
Steve Beattie
aae194cc54 Merge the subsequent launchpad translations back into trunk. 2014-01-14 14:28:03 -08:00
Steve Beattie
a5a9e6c7a8 Merge initial launchpad translations import. 2014-01-14 14:23:44 -08:00
Steve Beattie
252829aee0 Merge in collected changes from trunk since branching off the
translations branch.
2014-01-14 10:36:36 -08:00
Tyler Hicks
9c1890fe13 parser: Make equality test output look like minimize test output
Subtle change to remove the "..." between the test description and
result and also to single-space the output. This brings the output in
line with what minimize.sh outputs, which is the test that runs just
before equality.sh.

Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: John Johansen <john.johansen@canonical.com>
2014-01-12 22:38:10 -06:00
Tyler Hicks
f6f8232b6c parser: Add DFA minimization test that mimics D-Bus abstractions
This test ensures that the proper DFA minimization occurs when a
permissive D-Bus abstraction #include's the corresponding strict
abstraction.

Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-By: Christian Boltz <apparmor@cboltz.de>
2014-01-10 15:35:51 -06:00
Steve Beattie
9fcbd8af1c parser: fix compilation failure on 32 bit systems
std::max in C++ requires that both arguments be the same type. The
previous fix added std::max comparisons between unsigned long numeric
constants and size_t, this fix casts the numeric constants to size_t.

Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: John Johansen <john.johansen@canonical.com>
2014-01-10 11:02:59 -08:00
John Johansen
b6cb988ed7 Tests for DFA minimization
Tests should be added for other rule types but this is a good start at
testing DFA minimization.

Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: John Johansen <john.johansen@canonical.com>
Acked-By: Christian Boltz <apparmor@cboltz.de>
2014-01-09 17:34:28 -08:00
John Johansen
92eae9d2d9 Fix dump output of expr tree
Make the accept information dump output be in hexidecimal like the
other dumps so its easier to reference between them.

Signed-off-by: John Johansen <john.johansen@canonical.com>
2014-01-09 17:30:00 -08:00
John Johansen
35f89fc3d6 Fix for the previous minimization patch
This was part of the original minimization patch, but got dropped when
applying to bzr. Again bzr status didn't show any files out of place
nor did the patching fail :(

Signed-off-by: John Johansen <john.johansen@canonical.com>
2014-01-09 17:27:47 -08:00
John Johansen
7ba571395e Fixes to that where dropped from the diff-encode patch
This diff is part of the diffencode patch but was dropped when it was
applied to bzr. I have no idea why and status showed a clean tree.

Signed-off-by: John Johansen <john.johansen@canonical.com>
2014-01-09 17:24:40 -08:00
John Johansen
3fb0689b84 Fix policy generation for small dfas
So there are multiple bugs in policy generation for small dfas.
- A bug where dfas reduced to only have a none accepting state
  drop the start state for accept tables in the chfa encoding

  eg. deny audit dbus,

  the accept and accept2 tables are resized to 1 but the cfha format
  requires at least 2. 1 for the none accepting state and 1 for the
  start state.
  the kernel check that the accept tables == other state table sizes
  caught this and rejected it.

- the next/check table needs to be padded to the largest base position
  used + 256 so no input can ever overflow the next/check table
  (next/check[base+c]).

  This is normally handled by inserting a transition which resizes
  the table. However in this case there where no transitions being
  inserted into the dfa. Resulting in a next/check table size of
  2, with a base pos of 0. Meaning the table needed to be padded
  to 256.

- there is an alignment bug for dfas within the container (see below)
  what follows is a hexdump of the generated policy. With the
  different parts broken out. There are 2 dfas (policy and older file) and
  it is the second dfa that is out of alignment.

  The aadfa blob wrapper should be making sure that the start of the actual
  dfa is in alignment but this is not happening. In this example


00000000  04 08 00 76 65 72 73 69  6f 6e 00 02 05 00 00 00  |...version......|
00000010  04 08 00 70 72 6f 66 69  6c 65 00 07 05 40 00 2f  |...profile...@./|
00000020  68 6f 6d 65 2f 75 62 75  6e 74 75 2f 62 7a 72 2f  |home/ubuntu/bzr/|
00000030  61 70 70 61 72 6d 6f 72  2f 74 65 73 74 73 2f 72  |apparmor/tests/r|
00000040  65 67 72 65 73 73 69 6f  6e 2f 61 70 70 61 72 6d  |egression/apparm|
00000050  6f 72 2f 71 75 65 72 79  5f 6c 61 62 65 6c 00 04  |or/query_label..|
00000060  06 00 66 6c 61 67 73 00  07 02 00 00 00 00 02 00  |..flags.........|
00000070  00 00 00 02 00 00 00 00  08 02 00 00 00 00 02 00  |................|
00000080  00 00 00 02 00 00 00 00  02 00 00 00 00 04 07 00  |................|
00000090  63 61 70 73 36 34 00 07  02 00 00 00 00 02 00 00  |caps64..........|
000000a0  00 00 02 00 00 00 00 02  00 00 00 00 08 04 09 00  |................|
000000b0  70 6f 6c 69 63 79 64 62  00 07

begin of policy dfa blob wrapper
000000b0                                 04 06 00 61 61 64  |policydb.....aad|
000000c0  66 61 00 06

size of the following blob (in little endian) so 0x80
000000c0              80 00 00 00  

begin of actual policy dfa, notice alignment on 8 byte boundry
000000c0                           1b 5e 78 3d 00 00 00 18  |fa.......^x=....|
000000d0  00 00 00 80 00 00 6e 6f  74 66 6c 65 78 00 00 00  |......notflex...|
000000e0  00 01 00 04 00 00 00 00  00 00 00 01 00 00 00 00  |................|
000000f0  00 07 00 04 00 00 00 00  00 00 00 01 00 00 00 00  |................|
00000100  00 02 00 04 00 00 00 00  00 00 00 02 00 00 00 00  |................|
00000110  00 00 00 00 00 00 00 00  00 04 00 02 00 00 00 00  |................|
00000120  00 00 00 02 00 00 00 00  00 08 00 02 00 00 00 00  |................|
00000130  00 00 00 02 00 00 00 00  00 03 00 02 00 00 00 00  |................|
00000140  00 00 00 02 00 00 00 00  08

dfa blob wrapper
00000140                              04 06 00 61 61 64 66  |............aadf|
00000150  61 00 06

size of the following blob (in little endian) so 0x4c8
00000150          c8 04 00 00

begin of file dfa, notice alignment. NOT on 8 byte boundry
                               1b  5e 78 3d 00 00 00 18 00  |a.......^x=.....|
00000160  00 04 c8 00 00 6e 6f 74  66 6c 65 78 00 00 00 00  |.....notflex....|
00000170  01 00 04 00 00 00 00 00  00 00 06 00 00 00 00 00  |................|
00000180  00 00 00 00 9f c2 7f 00  00 00 00 00 00 00 00 00  |................|
00000190  04 00 30 00 00 00 00 00  07 00 04 00 00 00 00 00  |..0.............|
000001a0  00 00 06 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000001b0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000001c0  02 00 04 00 00 00 00 00  00 00 06 00 00 00 00 00  |................|
000001d0  00 00 00 00 00 00 01 00  00 00 01 00 00 00 02 00  |................|
000001e0  00 00 00 00 00 00 00 00  04 00 02 00 00 00 00 00  |................|
000001f0  00 00 06 00 00 00 00 00  02 00 00 00 05 00 05 00  |................|
00000200  08 00 02 00 00 00 00 00  00 01 02 00 00 00 03 00  |................|
00000210  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000260  00 00 00 00 00 00 00 00  00 00 02 00 04 00 00 00  |................|
00000270  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000410  03 00 02 00 00 00 00 00  00 01 02 00 00 00 02 00  |................|
00000420  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000470  00 00 00 00 00 00 00 00  00 00 01 00 03 00 04 00  |................|
00000480  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000610  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00

end of container
00000610                                                08  |................|
00000620

Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Steve Beattie <steve@nxnw.org>
2014-01-09 17:09:54 -08:00
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
John Johansen
22855508e8 Add Differential State Compression to the DFA
Differential state compression encodes a state's transitions as the
difference between the state and its default state (the state it is
relative too).

This reduces the number of transitions that need to be stored in the
transition table, hence reducing the size of the dfa.  There is a
trade off in that a single input character may have to traverse more
than one state.  This is somewhat offset by reduced table sizes providing
better locality and caching properties.

With carefully encoding we can still make constant match time guarentees.
This patch guarentees that a state that is differentially encoded will do at
most 3m state traversal to match an input of length m (as opposed to a
non-differentially compressed dfa doing exactly m state traversals).
In practice the actually number of extra traversals is less than this becaus
we selectively choose which states are differentially encoded.

In addition to reducing the size of the dfa by reducing the number of
transitions that have to be stored.  Differential encoding reduces the
number of transitions that need to be considered by comb compression,
which can result in tighter packing, due to a reduction in sparseness, and
also reduces the time spent in comb compression which currently uses an
O(n^2) algorithm.

Differential encoding will always result in a DFA that is smaller or equal
in size to the encoded DFA, and will usually improve compilation times,
with the performance improvements increasing as the DFA gets larger.

Eg. Given a example DFA that created 8991 states after minimization.
* If only comb compression (current default) is used

 52057 transitions are packed into a table of 69591 entries. Achieving an
 efficiency of about 75% (an average of about 7.74 table entries per state).
 With a resulting compressed dfa16 size of 404238 bytes and a run time for
 the dfa compilation of
   real 0m9.037s
   user 0m8.893s
   sys  0m0.036s

* If differential encoding + comb compression is used, 8292 of the 8991
  states are differentially encoded, with 31557 trans removed.  Resulting in

  20500 transitions are packed into a table of 20675 entries.  Acheiving an
  efficiency of about 99.2% (an average of about 2.3 table entries per state
  With a resulting compressed dfa16 size of 207874 bytes (about 48.6%
  reduction) and a run time for the dfa compilation of
   real 0m5.416s (about 40% faster)
   user 0m5.280s
   sys  0m0.040s

Repeating with a larger DFA that has 17033 states after minimization.
* If only comb compression (current default) is used

 102992 transitions are packed into a table of 137987 entries.  Achieving
 an efficiency of about 75% (an average of about 8.10 entries per state).
 With a resultant compressed dfa16 size of 790410 bytes and a run time for d
 compilation of
  real  0m28.153s
  user  0m27.634s
  sys   0m0.120s

* with differential encoding
 39374 transition are packed into a table of 39594 entries. Achieving an
 efficiency of about 99.4% (an average of about 2.32 entries per state).
 With a resultant compressed dfa16 size of 396838 bytes (about 50% reduction
 and a run time for dfa compilation of
  real  0m11.804s (about 58% faster)
  user  0m11.657s
  sys   0m0.084s

Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
2014-01-09 16:55:55 -08:00
Launchpad Translations on behalf of apparmor-dev
11301681aa Launchpad automatic translations update. 2014-01-08 04:35:03 +00:00
Steve Beattie
260d73f752 parser: Add make variable to build against local or system libapparmor [v3]
By default, statically link against the in-tree libapparmor. If the
in-tree libapparmor is not yet built, print a helpful error message. To
build against the system libapparmor, the USE_SYSTEM make
variable can be set on the command line like so:

  $ make USE_SYSTEM=1

This patch also fixes issues around the inclusion of the apparmor.h
header. Previously, the in-tree apparmor.h was always being included
even if the parser was being linked against the system libapparmor.
It modifies the apparmor.h include path based on the previous patch
separating them out in the libapparmor source. This was needed because
header file name collisions were already occurring.

For source files needing to include apparmor.h, the make targets were
also updated to depend on the local apparmor.h when building against
the in-tree libapparmor.  When building against the system libapparmor,
the variable used in the dependency list is empty. Likewise, a
libapparmor.a dependency is added to the apparmor_parser target when
building against the in-tree apparmor.

Patch history:
  v1: from Tyler Hicks <tyhicks@canonical.com>
      - initial version
  v2: revert to altering the include search path rather than including
      the apparmor.h header directly via cpp arguments, alter the
      include statements to <sys/apparmor.h> which will work against
      either in-tree or (default) system paths.
  v3: convert controlling variable to USE_SYSTEM from SYSTEM_LIBAPPARMOR
      to unify between the parser and the regression tests.

Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Signed-off-by: Steve Beattie <steve@nxnw.org>
2014-01-06 14:46:10 -08:00
Steve Beattie
4146495b05 parser: remove now unused clone_and_chain functions
With the previous patch to switch to using alternations for variable
expansion, the clone_and_chain set of functions are no longer needed
and no longer need to be passed around. This patch removes them.
(I kept this patch separate to keep the previous patch smaller and more
easily reviewed.)

Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
2013-12-16 01:30:13 -08:00
Steve Beattie
68a9f24fb5 parser: convert var expansion to use alternations
This patch converts the parser's variable expansion from adding new
entries for each additional variable value to incorporating an
alternation that includes all the values for the variable; e.g. given:

  @{BINS}=/bin /usr/bin /sbin /usr/sbin
  @{BINS}/binary ix,

rather than expanding to exntries for

  /bin/binary
  /usr/bin/binary
  /sbin/binary
  /usr/sbin/binary

one entry would remain that looks like:

  {/bin,/usr/bin,/sbin,/usr/sbin}/binary

One complication with this patch is that we try to prevent mistakes for
our users with variable expansion around '/'s; it's common for people to
write profiles that contain things like:

 @{BAR}=/bingo/*/ /bango/
 /foo/@{BAR}/baz

We already have a post-processing step that walks entries looking
for multiple sequences of '/'s and filters them into single
'/' which worked when creating new entries for each variable
expansion. Converting to alternation expansion breaks this filtering,
so code is added that removes leading and trailing slashes in variable
values in the expansion if the character immediately preceding or
following the variable is also a slash.

The intent behind this is to reduce the amount of memory allocations
and structure walking that needed to occur in when converting from the
entry strings to the back end nodes. Examples with real world profiles
showed performance improvements ranging from 2.5% to 10%. However,
because the back end operations are sensitive to the front end inputs,
it is possible for worse results to occur; for example, it takes the
simple_tests/vars/vars_stress_0[123].sd tests significantly longer to
complete after this patch is applied (vars_stress_03.sd in particular
takes ~23 times longer). An initial analysis of profiling output in
this negative case looks like it causes the tree simplification in
the back end to do more work for unknown reasons.

On the other hand, the test simple_tests/vars/vars_dbus_9.sd
(introduced in "[patch 09/12] parser: more dbus variable testcases")
takes ~1 sec to complete on my laptop before this patch, and roughly
0.01s with this patch applied.

(One option would be to keep the "expand entries" approach as an
alternative, but I couldn't come up with a good heuristic for when
to use it instead.)

Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
2013-12-16 01:28:38 -08:00
Steve Beattie
513d507423 parser: convert process_mnt_entry's typebuf to std::string
This patch addresses the FIXMEs from the last patch by converting
process_mnt_entry's typebuf from a char[] to std::string. As a side
effect, the code in build_list_val_expr() is greatly simplified.

Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
2013-12-16 01:17:21 -08:00
Steve Beattie
cc1a6f0e55 parser: remove length restriction in convert_aaregex_to_pcre usage
This patch removes the string length limit in convert_aaregex_to_pcre()
usage. One of the benefits to moving to C++ is the ability to use
std::strings, which dynamically resize themselves. While it's a large
patch, a non-trivial amount is due to needing to get a char * string
back out via the c_str() method.

The unit tests are modified to include checks to ensure that
convert_aaregex_to_pcre only appends to the passed pcre string,
it never resets it.

As the test case with overlong alternations added in the previous
patch now passes, the TODO status is removed from it.

(Note: there's a couple of FIXME comments related to converting typebuf
to std::string that are added by this patch that are addressed in the
next patch. I kept that conversion separate to try to reduce the size
of this patch a little.)

Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
2013-12-16 01:15:17 -08:00
Steve Beattie
62c13f66b0 parser: add large number of alternations test case
This patch adds a test case with an extremely large set of alternations.
It is marked TODO, because it fails with the current parser due to
strings used in convert_aaregex_to_pcre() being limited to (roughly)
PATH_MAX.

While contrived, it is possible to have alternations that are longer
than PATH_MAX that always  match paths that are shorter than PATH_MAX.

Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
2013-12-16 00:33:08 -08:00
Christian Boltz
d60f1a19da can ?not fix apparmor.pod
At least that's how this patch started ;-)

The updated (and much bigger) patch
- removes the note about can ?not mknod
- also removes mount and umount from the can ?not list which are covered
  by mount rules now
- updates the example audit.log lines to the current log format
- updates the description of the log format

Acked-By: Seth Arnold <seth.arnold@canonical.com> (on IRC)

Seth also promised a follow-up patch with the remaining changes.
2013-12-12 03:07:37 +01:00
Steve Beattie
f0cfec62cd parser: add some developer documentation
Patch history:
  v1: initial version
  v2: based on feedback from cboltz and sarnold:
      - fix bad grammar when mentioning *.gcno and *.gcda files
      - mention that distros generally don't need other options besides
        verbose builds
      - fix 'the valgrind' grammar messup.

Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
2013-12-10 14:15:02 -08:00