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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
The following patch:
- removes re import
- uses apparmor.re_match_include instead of the regex
which also means to use the correct regex instead of
the slightly wrong one cleanprofile.py had
Acked-by: Christian Boltz <apparmor@cboltz.de>
The cleanprofile.py has an apparmor import, this patch modifies the import to make it consistent with the rest of modules.
Acked-by: Christian Boltz <apparmor@cboltz.de>
The following patch:
- Brings the return to the correct indentation
- Adds a sorted call over the set keys of hat in the profile
Acked-by: Christian Boltz <apparmor@cboltz.de> for trunk and 2.9.
After switching to winbindd as test profile, comments about the ntpd
profile don't make sense anymore ;-)
The patch also includes some whitespace fixes.
Acked-by: Kshitij Gupta <kgupta8592@gmail.com>
Acked-by: Steve Beattie <steve@nxnw.org>
This time we only have 98% coverage (some missing and partial) because
I didn't find corner cases that raise some exceptions ;-)
Acked-by: Steve Beattie <steve@nxnw.org>
The class comes with the usual set of features, so I'll only mention a
special feature: the is_covered() and is_equal() functions can even
compare limits with different units (for example they recognize that
2minutes == 120seconds).
Also change RE_PROFILE_RLIMIT:
- make it a bit more strict (the old one accepted any chars, including
spaces, for rlimit and value)
- convert it to named matches
- '<=' isn't optional - remove the '?' (but keep the parenthesis to
avoid breaking parsing in aa.py)
- allow rules with no spaces around '<='
Acked-by: Steve Beattie <steve@nxnw.org>
aa-cleanprof (actually clean_profile() in tools.py) used reload_base()
from aa.py which sends the parser output to /dev/null. This had two
effects:
- aa-cleanprof ignored the --no-reload parameter
- there was no error message because reload_base() /dev/null's the
parser output
This patch changes clean_profile() to use reload_profile() from tools.py
(which honors the --no-reload option).
Also add a TODO note to aa.py reload_base(), the (AFAIK only) winner of
the 'useless use of cat' award in the AppArmor code.
We should really change it to use reload_profile(), even if that means
moving the function from tools.py to aa.py or common.py. And it should
not /dev/null the apparmor_parser output. ;-)
References: https://bugs.launchpad.net/apparmor/+bug/1443637
Acked-by: Steve Beattie <steve@nxnw.org>
aa-complain is part of the enforce/complain/disable triple. Therefore
I expect it to actually load a profile in complain mode.
To do this, it has to delete the 'disable' symlink, but set_complain()
in aa.py didn't do this (and therefore kept the profile disabled).
Acked-by: Kshitij Gupta <kgupta8592@gmail.com>
Users might expect that setting a profile into audit mode also activates
it (which shouldn't happen IMHO because the audit flag is not part of
the enforce/complain/disable triple), so we should at least tell them.
References: https://bugs.launchpad.net/apparmor/+bug/1429448
Acked-by: Kshitij Gupta <kgupta8592@gmail.com>
aa-complain, aa-enforce, aa-disable and aa-audit refused to change
profiles for non-existing binaries. This patch also allows paths
starting with /. This also makes it possible to use
aa-complain '/{usr/,}bin/ping'
and
aa-complain /etc/apparmor.d/bin.ping
This patch fixes https://bugs.launchpad.net/apparmor/+bug/1416346
Well, mostly - we still need to decide how we handle wildcards in
profile names:
aa-complain ping
aa-complain /usr/bin/ping
will still error out with "Profile not found" because it isn't an exact
match (and matching the wildcard would change more than the user wants).
Oh, and this patch also fixes the last failure in minitools_test.py.
Acked-by: Steve Beattie <steve@nxnw.org> for trunk and 2.9
Change minitools_test.py to use the winbind instead of the ntpd profile
for testing. The tests broke because the ntpd profile has the
attach_disconnected flag set now, and therefore didn't match the
expected flags anymore.
Also replace the usage of filecmp.cmp() in the cleanprof test with
reading the file and using assertEqual - this has the advantage that we
get a full diff instead of just "files differ".
Note: The aa-cleanprof test is still failing because of a bug in
tools.py, but will be fixed by the next patch.
See https://bugs.launchpad.net/apparmor/+bug/1416346 for details.
Acked-by: Kshitij Gupta <kgupta8592@gmail.com>