Commit graph

3488 commits

Author SHA1 Message Date
John Johansen
832455de2c Change expr tree construction so that rules are grouped by perms
Currently rules are added to the expression tree in order, and then
tree simplification and factoring is done. This forces simplification
to "search" through the tree to find rules with the same permissions
during right factoring, which dependent on ordering of factoring may
not be able to group all rules of the same permissions.

Instead of having tree factoring do the work to regroup rules with the
same permissions, pregroup them as part of the expr tree construction.
And only build the full tree when the dfa is constructed.

Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Steve Beattie <steve@nxnw.org>
2015-06-25 16:38:02 -06:00
John Johansen
5a9300c91c Move the permission map into the rule set
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Steve Beattie <steve@nxnw.org>
2015-06-25 15:54:15 -06:00
John Johansen
292f3be438 switch away from doing an individual accept node for each perm bit
accept nodes per perm bit where done from the very begining in a
false belief that they would help produce minimized dfas because
a nfa states could share partial overlapping permissions.

In reality they make tree factoring harder, reduce in longer nfa
state sets during dfa construction and do not result in a minimized
dfa.

Moving to unique permission sets, allows us to minimize the number
of nodes sets, and helps reduce recreating each set type multiple
times during the dfa construction.

Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Steve Beattie <steve@nxnw.org>
2015-06-25 14:08:55 -06:00
Christian Boltz
f202cc1fd2 profiles: postfix/master also needs lock permissions for master.pid
reported by darix some weeks ago, and also confirmed on my own servers.


Acked-by: Seth Arnold <seth.arnold@canonical.com> for trunk and 2.9
2015-06-25 13:16:49 +02:00
Steve Beattie
2cbd6c9880 parser: fix make parser_regex missing dependency
parser_regex.c includes libapparmor_re/aare_rules.h and thus it should
depend on it in the Makefile.

Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
2015-06-24 16:18:04 -07:00
Tyler Hicks
b786c64b17 utils: Don't use access() to determine readability of profiles file
LSMs, such as AppArmor, aren't consulted when a program calls access(2).
This can result in access(2) returning 0 but a subsequent open(2)
failing.

The aa-status utility was doing the access() -> open() sequence and we
became aware of a large number of tracebacks due to open() failing for
lack of permissions. This patch catches any IOError exceptions thrown by
open(). It continues to print the same error message as before when
access() failed but also prints that error message when AppArmor blocks
the open of the apparmorfs profiles file.

https://launchpad.net/bugs/1466768

Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: Steve Beattie <steve@nxnw.org>
2015-06-22 10:14:14 -05:00
Christian Boltz
140b88b818 Change aa.py delete_duplicates() to loop over rule classes
That's better than doing copy&paste for each added rule class ;-)


Acked-by: Kshitij Gupta <kgupta8592@gmail.com>
2015-06-19 23:27:06 +02:00
Christian Boltz
f9c60c06d7 severity.py: use re_match_include()
load_variables() used a nearly-correct regex. Drop it and use
re_match_include() instead.


Acked-by: Kshitij Gupta <kgupta8592@gmail.com>
2015-06-19 21:43:19 +02:00
Christian Boltz
2754e2964b Move re_match_include() to regex.py and improve it
The function is basically a wrapper around a regex, so regex.py is a
much better home.

While on it, rename the regex to RE_INCLUDE, change it to named matches,
use RE_EOL to handle comments and compile it outside the function, which
should result in a (small) performance improvement.

Also rewrite re_match_include(), let it check for empty include
filenames ("#include <>") and let it raise AppArmorException in that
case.

Finally, adjust code calling it to the new location, and add some tests
for re_match_include()


Acked-by: Kshitij Gupta <kgupta8592@gmail.com>
2015-06-19 21:41:41 +02:00
Christian Boltz
5e5f8f0001 Add profile_storage()
profile_storage() returns an empty, properly initialized profile.
It doesn't explicitly init all keys (yet) and will be extended over
time, with the final goal to get rid of hasher().

Also change various places in aa.py to use it (instead of an empty
hasher or sub-hasher), and remove various "init rule class (if not done
yet)" cases.

This also avoids a crash in aa-cleanprof remove_duplicate_rules().
Hats weren't properly initialized in aa.py parse_profile_data()
(especially rule classes were missing), which caused a crash because
hasher doesn't support the delete_duplicates() method.


Acked-by: Kshitij Gupta <kgupta8592@gmail.com>
2015-06-19 21:39:56 +02:00
Christian Boltz
94a2db187a Remove support for writing change hat declarations ("^hat,")
Change hat declarations ("^hat,") are no longer supported (see previous
patch for details). Therefore remove support for writing them.

This also means to completely remove the 'declared' flag, which was only
needed for hat declarations, and was (after the previous patch) always
set to False.

Also add a hat to the cleanprof_test.{in,out} test profile to make sure
aa-cleanprof doesn't break hats, and a hat declaration with the same
name to make sure it gets removed and doesn't break the "real" hat.


Acked-by: Kshitij Gupta <kgupta8592@gmail.com>
2015-06-19 21:25:39 +02:00
Christian Boltz
d37f777858 Ignore change hat declarations when parsing a profile
Hat declarations ("^hat,") were added in 2.3 for declaring external
hats, but in the meantime aren't supported by the parser anymore (tested
with 2.9.2 parser).

Additionally, if a profile contains both a hat declaration and the hat
("^hat { ...}"), the hat declaration can overwrite the content of the
hat on a "last one wins" base.

This is caused by setting 'declared' to True, which means write_piece()
will only write the "^hat," line, but not the "^hat { ... }" block.

Therefore no longer set 'declared' to True, print a warning that hat
declarations are no longer supported, and ignore the rule. This also
means that running aa-cleanprof can make the profile valid again :-)

Also no longer change 'hat' when hitting a profile declaration, which
also looks wrong.


Note: This change removes the only usage of 'declared'. A follow-up
patch (trunk only) will completely remove the 'declared' handling.


Reproducer profile (run aa-cleanprof on it):
(will crash in remove_duplicate_rules() 80% of the time - if so, try
multiple times. One of the next patches will fix that. Or just try 2.9,
which doesn't have the crash in remove_duplicate_rules().)

/usr/bin/true {

  ^FOO {
    capability setgid,
  }

  # deletes the content of ^FOO when saving the profile! (last one wins)
  # additionally, the parser says this is invalid syntax
  ^FOO,

}


See also the "Hat declarations" thread on the ML,
https://lists.ubuntu.com/archives/apparmor/2015-June/008107.html



Acked-by: Kshitij Gupta <kgupta8592@gmail.com> for both 2.9 and trunk.
2015-06-19 21:17:02 +02:00
Christian Boltz
cdb12a9694 Change aa.py to use RlimitRule and RlimitRuleset
Change aa.py to use RlimitRule and RlimitRuleset instead of a sub-hasher
to store and write rlimit rules. In detail:
- drop all rlimit rule parsing from parse_profile_data() and
  serialize_profile_from_old_profile() - instead, just call
  RlimitRule.parse()
- change write_rlimits() to use RlimitRuleset
- add removal of superfluous/duplicate change_profile rules (the old
  code didn't do this)
- update the comment about aa[profile][hat] usage - rlimit and
  change_profile are no longer dicts.

Also cleanup RE_PROFILE_RLIMIT in regex.py - the parenthesis around
'<=' are no longer needed.


Note: This patch is quite small because aa-logprof doesn't ask for
rlimit rules.

I tested all changes manually with aa-cleanprof and aa-logprof (adding
some file rules, rlimit rules kept unchanged)


Acked-by: Kshitij Gupta <kgupta8592@gmail.com>
2015-06-19 21:12:29 +02:00
Christian Boltz
73dfc75ff4 profiles/Makefile check-parser depends on local/* files
Acked-by: Kshitij Gupta <kgupta8592@gmail.com>
2015-06-19 21:05:49 +02:00
Christian Boltz
7d625e384e check-logprof needs local/* files
check-logprof in profiles/Makefile needs the local/* files.
Add a dependency to make sure they are generated.


Acked-by: Kshitij Gupta <kgupta8592@gmail.com>
2015-06-18 22:58:59 +02:00
Tyler Hicks
fa05c2e2e4 libapparmor: Don't apply special SWIG %exception to some functions
Only use the special %exception directive for functions that return a
negative int and set errno upon error.

This prevents, for example, _aa_is_blacklisted() from raising an
exception when it returns -1. This is important because it doesn't set
errno so an exception based on the value of errno would be
unpredictable.

Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: John Johansen <john.johansen@canonical.com>
2015-06-16 15:51:19 -05:00
Tyler Hicks
d428ef45ea libapparmor: Remove unused path param from _aa_is_blacklisted()
When is_blacklisted() was internal to the parser, it would print an
error message when encountering some file names. If the path parameter
was non-null, the error message would include the file path instead of
the file name.

Now that the function has been moved to libapparmor, callers are
expected to print the appropriate error message if _aa_is_blacklisted()
returns -1. Since the error message printing no longer occurs inside of
_aa_is_blacklisted(), the path parameter can be removed.

Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: John Johansen <john.johansen@canonical.com>
2015-06-16 15:49:51 -05:00
Tyler Hicks
da52144601 libapparmor: Provide privately exported aa_is_blacklisted() through swig
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: Christian Boltz <apparmor@cboltz.de>
Acked-by: John Johansen <john.johansen@canonical.com>
2015-06-16 15:49:24 -05:00
Tyler Hicks
4d60e07a25 libapparmor: Add README files to the file blacklist
Ignore README files when performing an operation on a list of files.

This matches the behavior of the is_skipped_file() function in aa.py.
The hope is that is_skippable_file() can reuse _aa_is_blacklisted().

Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
2015-06-15 23:58:45 -05:00
Tyler Hicks
42a66e64ee libapparmor: Store the string len instead of calling strlen() twice
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
2015-06-15 23:58:40 -05:00
Tyler Hicks
3e80c75f57 libapparmor: Perform strlen() test before indexing into the string
It looks odd to access the first character of a string before checking
to see if the string's length is zero. This is actually fine, in
practice, since strlen() looks at the first character of the string for
the presence of '\0' which means this is entirely a cosmetic change.

Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
2015-06-15 23:58:29 -05:00
Tyler Hicks
994eb7e3b9 libapparmor: Make swig aware of aa_splitcon(3)
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: John Johansen <john.johansen@canonical.com>
2015-06-15 18:16:42 -05:00
Tyler Hicks
cb6b450dbf libapparmor: Use extern specifier for new API functions in apparmor.h
Prepend the function prototypes with extern to match the style of the
existing prototypes.

Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: John Johansen <john.johansen@canonical.com>
2015-06-15 18:16:42 -05:00
Tyler Hicks
233d553c89 libapparmor: Set errno to EEXIST when only invalid caches are available
The errno values libapparmor's aa_policy_cache_new() uses to indicate
when the cache directory does not exist and when an existing, invalid
cache already exists needed to be separated out. They were both ENOENT
but now the latter situation uses EEXIST.

libapparmor also needed to be updated to not print an error message to
the syslog from aa_policy_cache_new() when the max_caches parameter is
0, indicating that a new cache should not be created, and the cache
directory does not exist. This is an error situation but a debug message
is more appropriate.

Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: John Johansen <john.johansen@canonical.com>
2015-06-15 18:16:42 -05:00
Tyler Hicks
2da4200cc0 libapparmor: Create a man page for aa_policy_cache
Create a section 3 man page for the aa_policy_cache family of functions.
Additionally, update the in-code descriptions to match the descriptions
in the man page.

Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: John Johansen <john.johansen@canonical.com>
2015-06-15 15:11:51 -05:00
Tyler Hicks
b7538a6dda libapparmor: Create a man page for aa_kernel_interface
Create a section 3 man page for the aa_kernel_interface family of
functions. Additionally, update the in-code descriptions to match the
descriptions in the man page.

Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: John Johansen <john.johansen@canonical.com>
2015-06-15 15:11:51 -05:00
Tyler Hicks
155a1b0d4a libapparmor: Create a man page for aa_features
Create a section 3 man page for the aa_features family of functions.
Additionally, update the in-code descriptions to match the descriptions
in the man page.

Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: John Johansen <john.johanse@canonical.com>
2015-06-15 15:11:51 -05:00
Tyler Hicks
9231d76c35 libapparmor: Migrate aa_policy_cache API to openat() style
The aa_policy_cache_new() and aa_policy_cache_remove() functions are
changed to accept a dirfd parameter.

The cache dirfd (by default, /etc/apparmor.d/cache) is opened earlier in
aa_policy_cache_new(). Previously, the directory wasn't accessed until
later in the following call chain:

  aa_policy_cache_new() -> init_cache_features() -> create_cache()

Because of this change, the logic to create the cache dir must be moved
from create_cache() to aa_policy_cache_new().

Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: John Johansen <john.johansen@canonical.com>
2015-06-15 15:11:51 -05:00
Tyler Hicks
3d18857dae libapparmor: Migrate aa_kernel_interface API to openat() style
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: John Johansen <john.johansen@canonical.com>
2015-06-15 15:11:51 -05:00
Tyler Hicks
350e964e30 libapparmor: Migrate aa_features API to openat() style
Instead of only accepting a path in the aa_features API, accept a
directory file descriptor and a path like then openat() family of
syscalls. This type of interface is better since it can operate exactly
like a path-only interface, by passing AT_FDCWD or -1 as the dirfd.
However, using the dirfd/path combination, it can eliminate string
allocations needed to open files in subdirectories along with the
even more important benefits mentioned in the open(2) man page.

Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
2015-06-15 15:11:51 -05:00
Tyler Hicks
35f7ab4cdb libapparmor: Clean up function that wraps features dir reading
Make the function prototype for reading a features directory the same
as the function prototype for reading a features file.

Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
2015-06-15 15:11:51 -05:00
Tyler Hicks
c9c3c09106 libapparmor: Introduce a single function for reading features files
Two different implementations were in use for reading features files.
One for reading a single file and another for reading a single file
after walking a directory. This patch creates a single function that is
used in both cases.

Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
2015-06-15 15:11:51 -05:00
Tyler Hicks
86de47d08a libapparmor: Use directory file descriptor in _aa_dirat_for_each()
The _aa_dirat_for_each() function used the DIR * type for its first
parameter. It then switched back and forth between the directory file
descriptors, retrieved with dirfd(), and directory streams, retrieved
with fdopendir(), when making syscalls and calling the call back
function.

This patch greatly simplifies the function by simply using directory
file descriptors. No functionality is lost since callers can still
easily use the function after calling dirfd() to retrieve the underlying
file descriptor.

Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
2015-06-15 15:11:51 -05:00
Tyler Hicks
014e079261 libapparmor: Allow creating a kernel_interface with a NULL kernel_features
The most common case when creating an aa_kernel_interface object will be
to do so while using the current kernel's feature set for the
kernel_features parameter. Rather than have callers instantiate their
own aa_features object in this situation, aa_kernel_interface_new()
should do it for them if they specify NULL for the kernel_features
parameter.

Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: Steve Beattie <steve@nxnw.org>
2015-06-15 15:11:51 -05:00
Tyler Hicks
611e891631 libapparmor: Allow creating a policy_cache with a NULL kernel_features
The most common case when creating an aa_policy_cache object will be to
do so while using the current kernel's feature set for the
kernel_features parameter. Rather than have callers instantiate their
own aa_features object in this situation, aa_policy_cache_new() should
do it for them if they specify NULL for the kernel_features parameter.

Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: Steve Beattie <steve@nxnw.org>
2015-06-15 15:11:51 -05:00
Tyler Hicks
0c19c8d596 libapparmor: Improve documentation of aa_policy_cache_replace_all()
Document that the kernel_interface parameter is optional.

Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: Steve Beattie <steve@nxnw.org>
2015-06-15 15:11:51 -05:00
Tyler Hicks
3c972e27e5 libapparmor: Adjust some aa_policy_cache function comments
The aa_features object that is passed to aa_policy_cache_new() does not
have to represent the currently running kernel. It may represent a
different kernel, such as a kernel that was just installed, that is not
currently running.

This patch adjusts the function comments to remove mentions of
"... the currently running kernel".

Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: Steve Beattie <steve@nxnw.org>
2015-06-15 15:11:51 -05:00
Tyler Hicks
5d6eb1a40f libapparmor: Simplify aa_policy_cache API
This patch changes the aa_policy_cache_new() prototype and gets rid of
aa_policy_cache_is_valid() and aa_policy_cache_create().

The create bool of aa_policy_cache_new() is replaced with a 16 bit
unsigned int used to specify the maximum number of caches that should be
present in the specified cache directory. If the number is exceeded, the
old cache directories are reaped. The definition of "old" is private to
libapparmor and only 1 cache directory is currently supported. However,
that will change in the near future and multiple cache directories will
be supported.

If 0 is specified for the max_caches parameter, no new caches can be
created and only an existing, valid cache can be used. An error is
returned if no valid caches exist in that case.

If UINT16_MAX is specified, an unlimited amount of caches can be created
and reaping is disabled.

This means that 0 to (2^16)-2, or infinite, caches will be supported in
the future.

This change allows for the parser to continue to support the
--skip-bad-cache (by passing 0 for max_caches) and the --write-cache
option (by passing 1 or more for max_caches) without confusing
libapparmor users with the aa_policy_cache_{is_valid,create}()
functions.

Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: John Johansen <john.johansen@canonical.com>
2015-06-15 15:11:50 -05:00
Christian Boltz
5e0d6456e2 Add quotes around '->' at various places in apparmor.d.pod.
Also fix a Cux that should be CUx.


Acked-By: Seth Arnold <seth.arnold@canonical.com> for 2.9 and trunk
2015-06-13 01:01:55 +02:00
John Johansen
7aae13f3df Fix: the default pattern for missing change_onexec id
The default change_onexec id is slightly wrong, it allows matching
'/' as an executable but it really should be anything under /

This results in the equality tests for change_profile failing as it
is different than what specifying /** in a rule does.

We could define rules need to be {/,}** to be equivalent but since
/ can not be an executable change the default value to match what
/** is converted in to.

Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Steve Beattie <steve@nxnw.org>
2015-06-12 15:25:10 -07:00
John Johansen
3fab352dc4 Extend change_profile tests
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Steve Beattie <steve@nxnw.org>
2015-06-12 15:25:10 -07:00
John Johansen
f364cd7f6f Refactor change_profile to bring ns and none ns target into one rule
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Steve Beattie <steve@nxnw.org>
2015-06-12 15:25:10 -07:00
John Johansen
731718971f Refactor to use a common ns_id for namespace identifiers
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Steve Beattie <steve@nxnw.org>
2015-06-12 15:25:10 -07:00
John Johansen
d5c815783b Fix: refactor change_profile to deal with unexpected TOK_ID error
bison isn't properly handling the 3 options of

TOK_CHANGE_PROFILE opt_id TOK_END_OF_RULE
TOK_CHANGE_PROFILE opt_id TOK_ARROW TOK_ID TOK_END_OF_RULE
TOK_CHANGE_PROFILE opt_id TOK_ARROW TOK_COLON TOK_ID TOK_COLON TOK_END_OF_RULE

specifying
  change_profile /exec,

results in an unexpected TOK_ID error

refactor so that they share the 3 options share a common head which fixes
the problem.

Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Steve Beattie <steve@nxnw.org>
2015-06-12 15:25:10 -07:00
John Johansen
899cea3396 Fix screening of change_profile permission from file rule entries
While change_profile rules are always created separately from file
rules. The merge phase can result in change_profile rules merging
with file rules, resulting in the change_profile permission being
set when a file rule is created.

Make sure to screen off the change_profile permission, when creating
a file rule.

Note: the proper long term fix is to split file, link and change_profile
rules into their own classes.

Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Steve Beattie <steve@nxnw.org>
2015-06-12 15:25:10 -07:00
John Johansen
6707489cdc Update change_profile rules to allow specifying the onexec condition
Note: this patch currently overlays onexec with link_name to take
advantage of code already being used on link_name. Ideally what needs
to happen is entry needs to be split into file, link and change_profile
entry classes.

Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Steve Beattie <steve@nxnw.org>
2015-06-12 15:25:10 -07:00
Felix Geyer
95cbbe32e0 Respect $CPPFLAGS
Some parts of the AppArmor build system don't respect $CPPFLAGS.
The attached patch fixes this.

Acked-by: Steve Beattie <steve@nxnw.org>
2015-06-10 12:36:15 -07:00
Christian Boltz
5a0d64a70e Get variable names in aa-mergeprof ask_the_questions() in sync with aa.py
Add two variable references (aa and changed) in aa-mergeprof
ask_the_questions() so that the code can use the short name and be more
in sync with aa.py ask_the_questions().

With this patch applied, the "for ruletype in ['capability', 'network']:"
block is in sync, with the exception of the sections that intentionally
differ:
- the check for the profile mode
- the default button selection based on profile mode
- the seen_events counter

The patch also includes some minor whitespace fixes.


Acked-by: Steve Beattie <steve@nxnw.org>
2015-06-08 22:25:44 +02:00
Christian Boltz
e68d2c70df Add *.orig to .bzrignore
Applying patches often creates *.orig files, and those files are quite
annoying in the "bzr status" output and also in the "unknown" file list
when commiting.

Note: I intentionally don't want to add *.rej files - while those files
should never end up in bzr, they are important enough to be listed in
bzr status output.


Acked-by: Steve Beattie <steve@nxnw.org>
2015-06-08 22:23:51 +02:00
Christian Boltz
033a35b7d7 split flags_bad.sd
flags_bad.sd contains multiple failures. Split the file into multiple
files with one failure in each and, while on it, using more helpful
filenames.


Acked-by: Steve Beattie <steve@nxnw.org>
2015-06-08 22:22:07 +02:00