Fix policy generation for small dfas

cherry-pick of r2303 from trunk

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>
This commit is contained in:
John Johansen 2014-01-09 17:43:59 -08:00
parent 5ed40d9399
commit ac7ab1c089
2 changed files with 6 additions and 5 deletions

View file

@ -92,10 +92,10 @@ CHFA::CHFA(DFA &dfa, map<uchar, uchar> &eq, dfaflags_t flags): eq(eq)
default_base.push_back(make_pair(dfa.nonmatching, 0));
num.insert(make_pair(dfa.nonmatching, num.size()));
accept.resize(dfa.states.size());
accept2.resize(dfa.states.size());
next_check.resize(optimal);
free_list.resize(optimal);
accept.resize(max(dfa.states.size(), 2ul));
accept2.resize(max(dfa.states.size(), 2ul));
next_check.resize(max(optimal, 256ul));
free_list.resize(next_check.size());
accept[0] = 0;
accept2[0] = 0;

View file

@ -361,7 +361,7 @@ inline int sd_write_blob(sd_serialize *p, void *b, int buf_size, char *name)
return 1;
}
#define align64(X) (((size_t) (X) + (size_t) 7) & ~((size_t) 7))
#define align64(X) (((X) + (typeof(X)) 7) & ~((typeof(X)) 7))
inline int sd_write_aligned_blob(sd_serialize *p, void *b, int buf_size,
char *name)
{
@ -369,6 +369,7 @@ inline int sd_write_aligned_blob(sd_serialize *p, void *b, int buf_size,
u32 tmp;
if (!sd_write_name(p, name))
return 0;
pad = align64((p->pos + 5) - p->buffer) - ((p->pos + 5) - p->buffer);
if (!sd_prepare_write(p, SD_BLOB, 4 + buf_size + pad))
return 0;