Add basic support for policy to specify a feature abi. Under the
current implementation the first feature abi specified will be
used as the policy abi for the entire profile.
If no feature abi is defined before rules are processed then the
default policy abi will be used.
If multiple feature abi rules are encountered and the specified
abi is different then a warning will be issued, and the initial abi
will continue to be used. The ability to support multiple policy
feature abis during a compile will be added in a future patch.
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/491
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Steve Beattie <sbeattie@ubuntu.com>
Define EXTRA_WARNINGS in the common/Make.rules helper so that adding
additional warnings can be done in one(-ish) location, and replace
locally defined C compiler warning flags with EXTRA_WARNINGS in most
locations in the build tree.
v2: issue a warning for any compiler option that the compiler does not
support
Signed-off-by: Steve Beattie <steve.beattie@canonical.com>
asprintf(3) returns a signed int, so storing the result in a size_t is
and then comparing that stored value against -1 is not such a good idea.
Signed-off-by: Steve Beattie <steve.beattie@canonical.com>
Acked-by: John Johansen <john.johansen@canonical.com>
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/549
With LSM stacking apparmor may be available even if it is not
enabled. If apparmor is available but not enabled it does not own
the /proc/<pid>/attr/* interface and should not use it as they
will not provide apparmor context.
Note: this also applies to the SO_PEERSEC interface, currently we
only fail is apparmor does not own the interface. Once the new interface
command is finalized supprt to use that will be added.
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Steve Beattie <steve.beattie@canonical.com>
LSM stacking makes the old /proc/<pid>/attr/* interfaces potentially
be shared such that the values returned might be for a different LSM
than apparmor.
Use the new apparmor dedicated interface at /proc/<pid>/attr/apparmor/*
if it is present.
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Steve Beattie <steve.beattie@canonical.com>
The library version must be consistent across releases. Since 2.13.4
and master use the same library version it needs to be updated.
Signed-off-by: John Johansen <john.johansen@canonical.com>
Improve readability by being explicit about the value to use when the
conditional evaluates to true.
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Suggested-by: John Johansen <john.johansen@canonical.com>
v2:
- parse partial log line broken at \n
- add testcase_dbus_10.* for partial log line
- remove quotes from testcasw_dbus_09.profile
The following log format has been seen in the wild, and currently results
in a RECORD_INVALID
[4835959.046111] audit: type=1107 audit(1561053426.749:186): pid=640 uid=103 auid=4294967295 ses=4294967295 msg='apparmor="ALLOWED" operation="dbus_method_call" bus="system" path="/org/freedesktop/systemd1" interface="org.freedesktop.systemd1.Manager" member="LookupDynamicUserByName" mask="send" name="org.freedesktop.systemd1" pid=20596 label="/usr/sbin/sshd" peer_pid=1 peer_label="unconfined"
exe="/usr/bin/dbus-daemon" sauid=103 hostname=? addr=? terminal=?'
Test parsing the above message with and without the \n embedded between
peer_label= and exec=
Acked-by: Seth Arnold <seth.arnold@canonical.com>
Signed-off-by: John Johansen <john.johansen@canonical.com>
The calling function and the merge() macro both make use of a variable
named "i" but this causes problems when merging. The aa_policy_cache.sh
test script experiences "bad file descriptor" failures due to the merged
list containing invalid fd values (-1).
Fix this by renaming merge()'s index variables from i and j to y and z
to hopefully prevent future overlap. The better fix here would be to
convert merge() to a function but that's a more intrusive change and I
don't have an easy way to test the overlay feature.
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
qsort()'s _size_ parameter is used to indicate the size of the elements
in the _base_ array parameter. Adjust the third argument to qsort() to
indicate that we're dealing with an array of struct dirent pointers
rather than an array of struct dirent.
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
This "will break with non-glibc libcs on Debian and with glibc headers moved to
multiarch locations" (https://bugs.debian.org/798955). Patch based on the one
proposed by Helmut Grohne <helmut@subdivi.de>, amended to replace hard coded
"gcc" with "$(CC)".
Bug-Debian: https://bugs.debian.org/909966
The function was messing up its use of fds, it could get away with
it because the cb_dirfd passed to fdopendir was still valid until
closedir was called but if code was moved around, or fdopendir
code changed behavior it could easily break.
Also the check for dup failing was wrong fix it.
Reference: coverity #187003
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Time-out
The open-coded readdirfd fn used to replace scandirat skipped
checks for memory allocation failures and cleaning on faulures,
fix this.
Acked-by: Tyler Hicks <tyhicks@canonical.com>
Signed-off-by: John Johansen <john.johansen@canonical.com>
The `scandirat` function is a nonstandard GNU extension, which opens a
directory relative to a file descriptor. musl libc does not implement
that function and thus cannot be used to compile libapparmor.
All our uses of `scandirat` directly scan the directory the file
descriptor is referring to, not any directory beneath the FD. Implement
a function `readdirfd()`, which gets as arguments the directory FD, the
location where to put the list of directory entries as well as a
function pointer to a comparing function. `readdirfd` will then scan all
directory entries except "." and ".." and return them via an allocated
array. The array is sorted in case the comparing function is set.
PR: https://gitlab.com/apparmor/apparmor/merge_requests/107
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: John Johansen <john.johansen@canonical.com>
The `secure_getenv` function is a non-POSIX compliant extension of
glibc. In contrast to the POSIX `getenv`, `secure_getenv` will return
`NULL` for all environment variables when the program is run with
escalated privileges due to an SUID or SGID bit. Some strictly
POSIX-compliant libc libraries, most notably musl libc, do not have this
function and do not wish to implement it. Thus, AppArmor cannot be
compiled on such systems.
In libapparmor, `secure_getenv` is only used to determine whether the
environment variable DEBUG_ENV_VAR has been set to enable debugging. In
case an unprivileged user runs a SUID/SGID executable linked against
libapparmor, we do not want that user to be able to get additional
information via debug output.
The fix here is to produce an error only in case where debug output is
enabled by defining ENABLE_DEBUG_OUTPUT. Otherwise, we simply define
`secure_getenv` to `NULL` to completely disable the debug output.
Signed-off-by: Patrick Steinhardt <ps@pks.im>
While the parser makes use of the `aa_policy_cache_add_ro_dir` function,
it is not being declared as a global function in the libapparmor.map
file. Due to this, dynamic linking of apparmor_parser with
libapparmor.so is not possible.
[Fixed up to use 2.13.1 symbol section as when the
`aa_policy_cache_add_ro_dir` was introduced -- @smb]
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Steve Beattie <steve.beattie@canonical.com>
PR: https://gitlab.com/apparmor/apparmor/merge_requests/107
Commit 63b7cb0660 (libapparmor: convert
multicache from using djb2 hashing to murmur3 hash) mistakenly added
PmurHash.h to the list of files generated by the build process and thus
should be removed when the 'maintainerclean' make target is invoked.
This fixes the issue by removing PmurHash.h from the list of generated
files.
Signed-off-by: Steve Beattie <steve.beattie@canonical.com>
Acked-by: Christian Boltz <apparmor@cboltz.de>
PR: https://gitlab.com/apparmor/apparmor/merge_requests/112
The refactor unfortunately changed dirfd to fd on one mkdirat, but
fd is always invalid at this point resulting in the parser reporting
Failed setting up policy cache (../profiles/cache/): Bad file descriptor
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Steve Beattie <steve@nxnw.org>
PR: https://gitlab.com/apparmor/apparmor/merge_requests/103
The code refactoring didn't update some debug messages. Update to
keep the debug messages and add a few extra while we are at it.
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Steve Beattie <steve@nxnw.org>
PR: https://gitlab.com/apparmor/apparmor/merge_requests/103
The recently added overlay cache directory support added to libapparmor
makes use of reallocarray(3) to resize memory allocations; however,
reallocarray() was only included in glibc 2.26. This commit adds a
configure check for reallocarray() and if it's not available, provides
it as a wrapper around realloc(3).
PR: https://gitlab.com/apparmor/apparmor/merge_requests/100
Signed-off-by: Steve Beattie <steve.beattie@canonical.com>
Acked-by: John Johansen <john.johansen@canonical.com>
The versioning previous patches was inconsistent because the multicache
patch have been in development for a while and the target version has
changed.
Cleanup libapparmor .map file to use the 2.13 release version
Signed-off-by: John Johansen <john.johansen@canonical.com>
Christian Boltz <apparmor@cboltz.de>
Allow the parser to use cache overlays by extending the --cache-loc
flag to support multiple locations via a comma separated list.
eg.
--cache-loc=/var/cache/apparmor/,/etc/apparmor.d/cache.d/
The overlayed cache directories are searched in the order
specified. So in the above example /var/cache/apparmor is searched
before /etc/apparmor.d/
Time stamps are ignored in the search, the first match found wins
regardless if there exists a matching cache file with a newer timestamp
in a directory is later in the search.
Cache writes will only occur to the first dir in the list. So
/var/cache/apparmor/ in the above example.
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Christian Boltz <apparmor@cboltz.de>
For some longer pathname fstat is returning a bad size resulting in
the path being truncated. Fix this by detecting a potential truncation
and re-doing the readlink.
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Christian Boltz <apparmor@cboltz.de>
Add the support to have the cache be able to search multiple locations
so that the policy cache can be split into multiple locations and
that there can be a local cache that can override preshipped caches.
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Christian Boltz <apparmor@cboltz.de>
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>