Add an option to allow setting/pinning the feature ABI and overriding
of ABI rules if they exist.
--override-policy-abi
This option is primarily for profile development and testing without
allowing adjusting feature abis temporarily without modifying the
profile.
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/579
Signed-off-by: John Johansen <john.johansen@canonical.com>
In AppArmor 2 distros could pin the feature file being used by setting
the feature-file option in the config file.
With AppArmor 3 policy is now explicitly tagged with an abi rule.
The problem is the interaction on systems that have a mixture of
AppArmor 2 and AppArmor 3 policy and use feature pinning.
The feature pinning is required to make the apparmor 2 policy behave
as expected but it also overrides the abi rules that are explicitly
set as part of the policy. This means we either have the apparmor 2
pinned policy working as desired or the apparmor 3 policy, but not
both.
To fix this make setting the flag on command line or in config file
lower priority than an abi rule specified in policy. The ability
to override abi rules will be added in a separate patch.
The Priority ordering to determine the policy abi to use is
1. Use abi rules if present
2. if no abi rule use command line option
3. if no abi rule or command line option use config setting
4. if none of the above use the default abi
PR: https://gitlab.com/apparmor/apparmor/-/merge_requests/579
Signed-off-by: John Johansen <john.johansen@canonical.com>
The kernel and policy abis can be used to detect and support new
capabilities without having to update base_cap_names.h and and
rebuilding the compiler.
This is not perfect however in that the does not provide any backwards
compatibility mappings, so we still need to keep the internal
capability table.
Signed-off-by: John Johansen <john.johansen@canonical.com>
We need to be able to dynamically add capabilities to the capability
list so switch to using a dynamically allocated table that we can
extend.
Signed-off-by: John Johansen <john.johansen@canonical.com>
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>
The features abi adds the ability to track the policy abi separate
from the kernel. This allow the compiler to determine whether policy
was developed with a certain feature in mind, eg. unix rules.
This allows the compiler to know whether it should tell the kernel to
enforce the feature if the kernel supports the rule but the policy
doesn't use it.
To find if a feature is supported we take the intersection of what is
supported by the policy and what is supported by the kernel.
Policy encoding features like whether to diff_encode policy are not
influenced by policy so these remain kernel only features.
In addition to adding the above intersection of policy rename
--compile-features to --policy-features as better represents what it
represents. --compile-features is left as a hidden item for backwards
compatibility.
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>
Correct the long option used to print the cache directory.
Fixes: e9d9395f91 ("parser: Add option to print the cache directory")
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
The parser currently skips the cache if optimizations are specified
because it can not determine if the cached policy was compiled
with the specified optimization. However this causes cache misses
even if policy is cached with those options, and distros are setting
some optimizations by default.
Instead of skipping reading the cache if optimizations are set, users
can force overwriting the cache if needed, until the parser can
store aditional meta info in the cache.
BugLink: http://bugs.launchpad.net/bugs/1820068
Signed-off-by: John Johansen <john.johansen@canonical.com>
Update the indetation of work_spawn to correct for the changes made in
cb43e57d27 ("parser: Fix parser failing to handle errors when setting up work")
the indetation was not updated in that patch to make the changes made
easier to review and see in diffs.
Signed-off-by: John Johansen <john.johansen@canonical.com>
The parser is not correctly handling some error conditions when
dealing with work units. Failure to spawn work, access files, etc
should be returned where appropriate, and be able to abort processing
if abort_on_error is set.
In addition some errors are leading to a direct exit without checking
for abort_on_error.
BugLink: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=921866
BugLink: http://bugs.launchpad.net/bugs/1815294
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Eric Chiang <ericchiang@google.com>
Currently if stdin is used the warning
apparmor_parser: cannot use or update cache, disable, or force-complain via stdin
is always displayed but if caching has been disabled there is no need for
this message.
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Christian Boltz <apparmor@cboltz.de>
Using stdin with --write-cache set results in
# apparmor_parser --show-cache --write-cache
Cache: added primary location '/var/cache/apparmor'
Warnung aus stdin (Zeile 1): Cache: added readonly location '/usr/share/apparmor/cache'
Warnung aus stdin (Zeile 1): apparmor_parser: cannot use or update cache, disable, or force-complain via stdin
Cache miss: stdin
Wrote cache: /var/cache/apparmor/9b2cd0d0.0/(null)
The "Wrote cache:" message is referencing a null value and should not
be displayed.
BugLink: http://bugs.launchpad.net/bugs/1787717
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Timeout
Requiring --config-file to be first in the option list is not user
friendly fix the option parsing so that --config-file can be specified
anywhere in the option list.
This also fixes a bug where even when the --config-file option is
first the option parsing fails because the detection logic is broken
for some option cases.
PR: https://gitlab.com/apparmor/apparmor/merge_requests/175
Acked-by: Seth Arnold <seth.arnold@canonical.com>
Signed-off-by: John Johansen <john.johansen@canonical.com>
To help avoid the duplicate option problem in the future sort and group
the config options using numbers at the end of the option table.
PR: https://gitlab.com/apparmor/apparmor/merge_requests/173
Acked-by: Seth Arnold <seth.arnold@canonical.com>
Signed-off-by: John Johansen <john.johansen@canonical.com>
Unfortunately both --config-file and --compile-features are using
139 to indicate the feature which breaks one or the other depending
on how the switch state that processes the options is compiled.
PR: https://gitlab.com/apparmor/apparmor/merge_requests/173
Acked-by: Seth Arnold <seth.arnold@canonical.com>
Signed-off-by: John Johansen <john.johansen@canonical.com>
After the config file patch was committed to 2.13 a couple of
improvements were suggested by intrigeri and cboltz. These have
been done as a separate patch so they can be applied to both
dev and 2.13.
PR: https://gitlab.com/apparmor/apparmor/merge_requests/170
Acked-by: Christian Boltz <apparmor@cboltz.de>
Signed-off-by: John Johansen <john.johansen@canonical.com>
The compiler is spitting out the warning
parser_main.c:1291:16: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
char *tmp = "/var/cache/apparmor";
fix this by constifying the cacheloc array.
Signed-off-by: John Johansen <john.johansen@canonical.com>
The parser config file can affect the parsers behavior during tests.
Allow overriding the default location with the option
--config-file=
the option must be the first option in the commands argument list.
Also provile a
--print-config-file
option to display what the parser is using for a config file.
BugLink: http://bugs.launchpad.net/bugs/1277711
Acked-by: Christian Boltz <apparmor@cboltz.de>
Signed-off-by: John Johansen <john.johansen@canonical.com>
Let's not store a bunch of automatically generated binary files in /etc.
AppArmor 3.0 will store the cache in /var/cache and most distros
(openSUSE, Debian, and soon Ubuntu) moved it there already.
Bug-Debian: https://bugs.debian.org/904637
Split the features file into compile features and kernel features
which is needed for policy versioning and the new caching scheme.
A new flag --kernel-features was added to set the kernel features but
unfortunately -M, --features-file was setup to only specify the
compile features, when it used to effectively specify both the
compile and kernel features.
This broke existing uses of -M.
Fix this by having -M specify both the compile and kernel features,
and a new flag --compile-features that can be used to specify the
compile fature set separate from the kernel feature set.
sbeattie> fixed up error message to refer to compile features when
--compile-features argument fails.
Fixes: 9e48a5da5e ("parser: split kernel features from compile features.")
Signed-off-by: John Johansen <john.johansen@canonical.com>
Signed-off-by: Steve Beattie <steve.beattie@canonical.com>
PR: https://gitlab.com/apparmor/apparmor/merge_requests/104
The parser currently uses a fork model to do job processing. For
consistency even when the number of jobs is set to 1 a single
work process is forked. However this makes using gdb more difficult
and can be even worse for other debugging tools.
Make -j 0 disable all job spawning so all processing happens in the
main process.
PR: https://gitlab.com/apparmor/apparmor/merge_requests/105
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Steve Beattie <steve@nxnw.org>
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>
The feature set needs to be split, the kernel features set determines
the cache location and controls features down grades to ensure
policy generates a policy that is usable on a given kernel.
The compile featurs set governs the feature set supported by policy
and primarily determines how policy is parsed and compiled.
Taking the intersection of the two feature sets to determine rule
downgrades for a specific kernel is left to a separate patch.
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>
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>
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>
The --print-cache-dir option can be used to have the parser print the
value of the cache directory that is specific to the features used (from
the current kernel, the --match-string option, or the --features-file
option). After printing the path, apparmor_parser will exit. This is
helpful because the final component in the path will become
unpredictable because it will be based on arbitrary hash function
output.
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: John Johansen <john.johansen@canonical.com>
BugLink: http://bugs.launchpad.net/bugs/1566490
This patch enables to parser to scale the max jobs if new resources are
being brought online by the scheduler.
It only enables the scaling check if there is a difference between the
maximum number of cpus (CONF) and the number of online (ONLN) cpus.
Instead of checking for more resources regardless, of whether the online
cpu count is increasing it limits its checking to a maximum of
MAX CPUS + 1 - ONLN cpus times. With each check coming after fork spawns a
new work unit, giving the scheduler a chance to bring new cpus online
before the next check. The +1 ensures the checks will be done at least
once after the scheduling task sleeps waiting for its children giving
the scheduler an extra chance to bring cpus online.
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
Check if the current kernel supports stacking. If not, ensure that named
transitions (exec, change_profile, etc.) do not attempt to stack their
targets.
Also, set up the change_profile vector according to whether or not the
kernel supports stacking. Earlier kernels expect the policy namespace to
be in its own NUL-terminated vector element rather than passing the
entire label (namespace and profile name) as a single string to the
kernel.
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
BugLink: http://bugs.launchpad.net/bugs/1534405
Patch -r 2952 switched over to using the library kernel interface, and
added a kernel_interface parameter to the dir_cb struct, that is
used to process directories.
Unfortunately kernel_interface parameter of the dir_cb struct is not being
properly initialized resulting in odd failures and sefaults when the parser
is processing directories.
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
Acked-by: Steve Beattie <steve@nxnw.org>
This adds a basic support for parallel compiles. It uses a fork()/wait
model due to the parsers current dependence on global variables and
structures. It has been setup in a similar manner to how cilk handles
multithreading to make it easy to port to a managed thread model once
the parser removes the dependence on global compute structures in the
backend.
This patch adds two new command line flags
-j <n> or --jobs <n>
which follows the make syntax of specifying parallel jobs currently
defaults to -jauto
-j8 or --jobs=8 allows for 8 parallel jobs
-jauto or --jobs=auto sets the jobs to the # of cpus
-jx4 or --jobs=x4 sets the jobs to # of cpus * 4
-jx1 is equivalent to -jauto
Note: unlike make -j must be accompanied by an option
--max-jobs=<n>
allows setting hard cap on the number of jobs that can be specified
by --jobs. It defaults to the number of processors in the system * 8.
It supports the "auto" and "max" keywords, and using x<n> for a
multiple of the available cpus.
additionally the -d flag has been modified to take an optional parameter
and
--debug=jobs
will output debug information for the job control logic.
In light testing on one machine the job control logic provides a nice
performance boost. On an x86 test machine with 60 profiles in the
/etc/apparmor.d/ directory, for the command
time apparmor_parser -QT /etc/apparmor.d/
old (equiv of -j1):
real 0m10.968s
user 0m10.888s
sys 0m0.088s
ubuntu parallel load using xargs:
real 0m8.003s
user 0m21.680s
sys 0m0.216s
-j:
real 0m6.547s
user 0m17.900s
sys 0m0.132s
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
Drop the reference to the libapparmor policy_cache pseudo object when
the parser is done.
Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
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>
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>
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>
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>
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>
Currently the cache file has its mtime set at creation time, but this
can lead to cache issues when a policy file is updated separately from
the cache. This makes it possible for an update to ship a policy file
that is newer than the what the cache file was generated from, but
result in a cache hit because the cache file was local compiled after
the policy file was package into an update (this requires the update
to set the mtime of the file when locally installed to the mtime of
the file in its update archive but this is commonly done, especially
in image based updates).
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
With create_cache() headed for libapparmor, we can't use the show_cache
or write_cache globals.
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: John Johansen <john.johansen@canonical.com>
Create new, ref, and unref functions for aa_kernel_interface. The "new"
function allows for the caller to pass in an aa_features object that is
then used to check if the kernel supports set load operations.
Additionally, the "new" function allows for the apparmorfs path to be
discovered once instead of during every policy load.
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: John Johansen <john.johansen@canonical.com>
This is the start of the kernel_interface API that allows callers to
specify a buffer, a file path, or a file descriptor that should be
copied to the proper kernel interface for loading, replacing, or
removing in-kernel policies.
Support exists for reading from a file path or file descriptor into a
buffer and then writing that buffer to the appropriate apparmorfs
interface file.
An aa_kernel_interface_write_policy() function is also provided for
callers that want to route a buffer to an arbitrary file descriptor
instead of to an apparmorfs file. This is useful when an admin instructs
apparmor_parser to write to stdout or a file.
Additionally, it removes some parser-specific globals from the
kernel_interface.c file, such as OPTION_{ADD,REPLACE,REMOVE}, in
preparation for moving the code into a library.
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: John Johansen <john.johansen@canonical.com>