This adds the fn aa_policy_cache_add_ro_dir() to the library allowing
for readonly layers to be added to the policy cache. It does not
make those additional layers functional. Which requires the ability
to create and search an overlay of directories.
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Christian Boltz <apparmor@cboltz.de>
Make the internal cache dir tracking use a fixed array and update
all references to the internal dirfd to index the array.
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Christian Boltz <apparmor@cboltz.de>
Prepare to refactore init_cache_features() with cache_check_features()
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Christian Boltz <apparmor@cboltz.de>
A policy cache is for a specific set of kernel features so there is no
need to keep these separate.
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Christian Boltz <apparmor@cboltz.de>
Adjust the cache directory name from
<cache_loc>/<feature_id>
to
<cache_loc>/<feature_id>.<n>
where <n> is 0 for the first cache created for a given feature_id.
If there is a feature_id collision then <n> will be incremented to
the next number.
The .features file within each cache directory is used to disambiguate
which feature_id cache dir belongs to which feature set.
Cache collisions and missing caches cause a slow path that searches
existing cache dirs that fit the cache_name pattern, to ensure the
proper dir is chosen.
TODO: add regression tests
create cache dir check it
copy different feature set to it
create cache dir again, check it, check that it incremented...
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Christian Boltz <apparmor@cboltz.de>
It is possible that a given feature set will hash to the same cache
directory as a different feature set. This will be a problem if binary
caches are required, eg. early boot with systemd doing the cache load.
Detect cache collisions and fail. This is a precursor to handling
collision resolution and should not be committed without the follow
up patch to properly handle collisions.
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Christian Boltz <apparmor@cboltz.de>
Murmur3 hash is a better hash that djb2 and has a lower chance of
hash collisions, so switch over to using it.
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Christian Boltz <apparmor@cboltz.de>
Carry the changes made in
libapparmor: Preserve errno across aa_*_unref() functions
into the multicache patcheset
Signed-off-by: John Johansen <john.johansen@canonical.com>
Christian Boltz <apparmor@cboltz.de>
Move the policy cache directory from <cacheloc>/cache/ to
<cacheloc>/cache.d/<features_id>/ where <features_id> is a unique
identifier for a set of aa_features. This allows for multiple AppArmor
policy caches exist on a system. Each policy cache will uniquely
correspond to a specific set of AppArmor kernel features. This means
that a system can reboot into a number of different kernels and the
parser will select the existing policy cache that matches each kernel's
set of AppArmor features.
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: John Johansen <john.johansen@canonical.com>
Add and export aa_features_id() which can be used to get a unique
identifier for an aa_features object. Internally, this is a djb2 hash of
the features string. The hash function used and even the makeup of the
features ID can be easily changed in the future since external consumers
must use this function to fetch the features ID.
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: John Johansen <john.johansen@canonical.com>
Store a hash value that can be used to represent the aa_features
object. This will be useful when storing multiple AppArmor policy cache
directories, each based on a kernel feature set.
The hash algorithm used is currently djb2. It was simple to add for
testing purposes, but may eventually need to be changed to something
that is resilient against collisions since there is no handling of
features file hash collisions.
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: John Johansen <john.johansen@canonical.com>
Add and export aa_policy_cache_dir_path_preview() which allows the
parser to know exactly where the policy cache binaries, for the
specified aa_policy_cache and aa_features objects, would be stored. This
function may be useful to preview the policy cache dir without having
sufficient permissions or desires to create a policy cache dir.
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: John Johansen <john.johansen@canonical.com>
Add and export aa_policy_cache_dir_path() which allows the parser to
know exactly where the policy cache binaries, for the current
aa_policy_cache and aa_features objects, will be stored. The parser
previously assumed that it was <cacheloc>/cache/ but it will soon be
<cacheloc>/cache.d/<features_id>/.
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: John Johansen <john.johansen@canonical.com>
The fix for issue #3/merge !86 in commit f0876ea9 contained a syntax
error that prevented libapparmor from building successfully. This
commit addresses the issue.
Signed-off-by: Steve Beattie <steve.beattie@canonical.com>
Several log examples result in rules where the 'owner' conditional
should be added. With logparser.py fixed to handle owner-only events, we
need to add the owner conditional to several test_multi/*.profile files.
I verified all log files for the changed profiles and made sure that
- the log line contains fsuid= and ouid=
- fsuid == ouid
I also did a quick check on all log events containing ouid= and for
those with fsuid == ouid, I checked that the profile has the owner
conditional.
Acked-by: Seth Arnold <seth.arnold@canonical.com> for trunk and 2.11
(see mail from 2017-07-31)
The RETURN VALUE section contained two typos where "kernel_features" was
used instead of "kernel_interface".
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Callers of aa_features_unref(), aa_kernel_interface_unref(), and
aa_policy_cache_unref() had to store off errno and restore it after
calling those functions in error paths. This patch preserves errno
across those *_unref() functions so that callers don't have to.
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
The added testcase for a ptrace target with an empty string
(ptrace_garbage_lp1689667_1.in) was causing the swig python test script
to fail. The generated python swig record for libapparmor ends up
setting a number of fields to None or other values that indicate the
value is unset, and the test script was checking if the value in the
field didn't evaluate to False in a python 'if' test.
Unfortunately, python evaluates the empty string '' as False in 'if'
tests, resulting in the specific field that contained the empty string
to be dropped from the returned record. This commit fixes that by
special case checking for the empty string.
Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: John Johansen <john.johansen@canonical.com>
The macros __BEGIN_DECLS and __END_DECLS are not conforming to
any standard, but are a custom extension of the glibc library. As
such, it may not be available in other libc implementations, with
one example being musl libc. So compiling libapparmor won't work
with a strictly standards-conforming library.
These macros are typically used for header files which might be
included in a C++ project. Depending on whether the header is
seen by a C or C++ compiler, it will hint that functions have C
linkage. The macros themselves are rather simple:
#ifdef __cplusplus
# define __BEGIN_DECLS extern "C" {
# define __END_DECLS }
#else
# define __BEGIN_DECLS
# define __END_DECLS
#endif
To fix compilation with musl libc, simply expand those macros to
explicitly use `extern "C"`. This is already used in other parts
of apparmor and should thus be safe to use.
Signed-off-by: Patrick Steinhardt <ps@pks.im>
In http://bazaar.launchpad.net/~apparmor-dev/apparmor/master/revision/3659,
a testcase was added that where the expected output file did not match
the input source name, cause libapparmor's regression tests to fail:
Output doesn't match expected data:
--- ./test_multi/ptrace_no_denied_mask.out 2017-08-18 16:35:30.000000000 -0700
+++ ./test_multi/out/ptrace_no_denied_mask.out 2017-08-18 16:35:38.985863094 -0700
@@ -1,5 +1,5 @@
START
-File: ptrace_1.in
+File: ptrace_no_denied_mask.in
Event type: AA_RECORD_DENIED
Audit ID: 1495217772.047:4471
Operation: ptrace
FAIL: ptrace_no_denied_mask
This patch corrects the issue.
Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
(garbage) ptrace events like
... apparmor="DENIED" operation="ptrace" profile="/bin/netstat" pid=1962 comm="netstat" target=""
cause an empty name2 field, which leads to a crash in the tools.
This patch lets logparser.py ignore such garbage log events, which also
avoids the crash.
As usual, add some testcases.
test-libapparmor-test_multi.py needs some special handling to ignore the
empty name2 field in one of the testcases.
References: https://bugs.launchpad.net/apparmor/+bug/1689667
Acked-by: Seth Arnold <seth.arnold@canonical.com> for trunk and 2.11.
Older releases can't handle ptrace log events and therefore can't crash ;-)
Error messages should only show up in build logs when the error has been
encountered. This patch silences these shell commands from being printed
before they're interpreted.
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: John Johansen <john.johansen@canonical.com>
Acked-by: Christian Boltz <apparmor@cboltz.de>
A multi job `make check` command could fail due to check-local running
before the check-DEJAGNU target, which is automatically generated by
automake, would complete. This would result in a build failure due to
libaalogparse.log not yet existing.
Fix the issue by depending on the check-DEJAGNU target.
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: John Johansen <john.johansen@canonical.com>
That's much better than crashing aa-logprof ;-) (use the log line in
the added testcase if you want to see the crash)
Reported by pfak on IRC.
Acked-by: Seth Arnold <seth.arnold@canonical.com> for trunk, 2.10 and 2.9.
Sometimes network events come with an operation keyword looking like
file_perm which makes them look like file events. Instead of ignoring
these events (which was a hotfix to avoid crashes), improve the type
detection.
In detail, this means:
- replace OPERATION_TYPES (which was basically a list of network event
keywords) with OP_TYPE_FILE_OR_NET (which is a list of keywords for
file and network events)
- change op_type() parameters to expect the whole event, not only the
operation keyword, and rebuild the type detection based on the event
details
- as a side effect, this simplifies the detection for file event
operations in parse_event_for_tree()
- remove workaround code from parse_event_for_tree()
Also add 4 new testcases with log messages that were ignored before.
References:
a) various bugreports about crashes caused by unexpected operation keywords:
https://bugs.launchpad.net/apparmor/+bug/1466812https://bugs.launchpad.net/apparmor/+bug/1509030https://bugs.launchpad.net/apparmor/+bug/1540562https://bugs.launchpad.net/apparmor/+bug/1577051https://bugs.launchpad.net/apparmor/+bug/1582374
b) the summary bug for this patch
https://bugs.launchpad.net/apparmor/+bug/1613061
Acked-by: Steve Beattie <steve@nxnw.org> for trunk and 2.10.
Fix import errors with swig > 3.0.8 with the libapparmor python
bindings. Do this by removing the code to rename the generated
LibAppArmor.py, and instead use a stub __init__.py that automatically
imports everything from LibAppArmor.py. Also adjust bzrignore to
compensate for the autogenerated file name changing.
Bug: https://bugzilla.opensuse.org/show_bug.cgi?id=987607
Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: Christian Boltz <apparmor@cboltz.de>
The log line (with a different profile=...) was sitting around on my
disk since a year, so let's do something useful with it ;-)
Acked-by: Seth Arnold <seth.arnold@canonical.com>
This patch adds profiles for all log sniplets that are expected to
result in a profile rule.
This also means some changes in test-libapparmor-test_multi.py are
needed:
- split off log_to_profile_skip from log_to_profile_known_failures to
- only skip tests in log_to_profile_skip (causing a crash or requiring
user interaction)
- run tests in log_to_profile_known_failures, but expect a non-equal
result (caused by not added rules etc.)
- add quite some tests to log_to_profile_known_failures - they were
skipped before because they didn't have a *.profile file.
- add handling for hats to shorten list of known failures
This fixes testcase24 and testcase33 (after adjusting the profiles)
and lots of the new *.profile files.
- since we now have *.profile files for all log events that should result
in a profile rule, no longer ignore FileNotFoundError
Acked-by: Seth Arnold <seth.arnold@canonical.com>
This patch adds TestLogToProfile to test-libapparmor-test_multi.py which
"translates" the test_multi log sniplets to a profile, and checks if it
matches the expected profile.
The expected profile for one log event will obviously contain only one
rule, and gets added as *.profile to the test_multi directory.
This patch includes 33 test_multi profiles - which means 83 more need to
be created. Whenever you have some time, add one or two! (Please write
those test_multi profiles manually, without using the tools.)
I know some parts of the test code looks complicated. Unfortunately this
is how things work - compare it with do_logprof_pass() in aa.py...
While on it, set tests = 'invalid' which ensures a failure in case
parse_test_profiles() doesn't set the tests array, and move printing
the test name out of parse_test_profiles() to avoid printing it twice.
A nice side effect of this patch is increased test coverage:
- 30% -> 40% in aa.py (= 250 more lines)
- 52% -> 78% in aamode.py (= 23 more lines)
- 26% -> 68% in logparser.py (= 120 more lines)
- total coverage increases from 57% to 62%
Acked-by: Seth Arnold <seth.arnold@canonical.com>
The features_struct.size variable is used to hold a buffer size and it
is also passed in as the size parameter to read(). It should be a size_t
instead of an int.
A new helper function, features_buffer_remaining(), is created to handle
the two places where the remaining bytes in the features buffer are
calculated.
This patch also changes the size parameter of load_features_dir() to a
size_t to match the same parameter of load_features_file() as well as
the features_struct.size change described above.
Two casts were needed when comparing signed types to unsigned types.
These casts are safe because the signed value is checked for "< 0"
immediately before the casts.
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
The load_features_file() function returned an int but calculated the
value by subtracting two pointers. On 64 bit systems, that results in a
64 bit value being represented as a 32 bit type.
Coverity CID #55992
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
Fixes build error when attempting to build and test the 2.10.95 release
on Ubuntu 14.04:
$ (cd libraries/libapparmor/ && ./autogen.sh && ./configure && \
make && make check) > /dev/null
...
libtool: Version mismatch error. This is libtool 2.4.6 Debian-2.4.6-0.1, but the
libtool: definition of this LT_INIT comes from libtool 2.4.2.
libtool: You should recreate aclocal.m4 with macros from libtool 2.4.6 Debian-2.4.6-0.1
libtool: and run autoconf again.
make[2]: *** [grammar.lo] Error 63
make[1]: *** [all] Error 2
make: *** [all-recursive] Error 1
The --force option is needed to regenerate the libtool file in
libraries/libapparmor/.
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: Steve Beattie <steve@nxnw.org>
We already ignore network events that look like file events (based on
the operation keyword) if they have a request_mask of 'send' or
'receive' to avoid aa-logprof crashes because of "unknown" permissions.
It turned out that both can happen at once, so we should also ignore
this case.
Also add the now-ignored log event as test_multi testcase.
References: https://bugs.launchpad.net/apparmor/+bug/1577051#13
Acked-by: Tyler Hicks <tyhicks@canonical.com> for trunk, 2.10 and 2.9.
Some people have the full hostname in their syslog messages, so
libapparmor needs to accept hostnames that contain dots.
References: https://bugs.launchpad.net/apparmor/+bug/1453300 comments
#1 and #2 (the log samples reported by scrx in #apparmor)
Acked-by: Seth Arnold <seth.arnold@canonical.com>
Acked-by: John Johansen <john.johansen@canonical.com>
for trunk, 2.10 and 2.9.
It's possible to end up unreferencing a kernel_interface object that
has ->dirfd set to -1. This patch avoids calling close(2) on that fd.
(close(-1) will just return EBADF anyway.)
Coverity CIDs #55996 and #55997
Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: Tyler Hicks <tyhicks@canonical.com>
This makes some of the references to functions in the aa_query_label(2)
manpage more consistent and fixes a couple of grammar issues. It also
tries to make the qualifying statements in apparmor.d(5) more distinct,
and also fixes some typos there as well.
Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: Tyler Hicks <tyhicks@canonical.com>
The aa_stack_profile() and aa_stack_onexec() functions were added to
libapparmor since 2.10.
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: Steve Beattie <steve@nxnw.org>
Based on the existing implementations of aa_change_profile(2) and
aa_change_onexec(2).
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: John Johansen <john.johansen@canonical.com>