write_prof_data[hat] is correct (it only contains one profile, see bug 1528139),
write_prof_data[profile][hat] is not and returns an empty (sub)hasher.
This affects RE_PROFILE_START and RE_PROFILE_BARE_FILE_ENTRY.
Acked-by: Kshitij Gupta <kgupta8592@gmail.com> for trunk, 2.9 and 2.10
Instead of reusing opt_named_transition and be forced to reconstruct the
target path when is looks like ":odd:target", create simpler grammer
rules that have nothing to do with named transitions and namespaces.
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: John Johansen <john.johansen@canonical.com>
a) change log_dict to profile_storage()
Change collapse_log() to initialize log_dict[aamode][profile][hat]
as profile_storage() instead of a hasher().
This also means path events need to go into
log_dict[aamode][profile][hat]['allow']['path']
instead of
log_dict[aamode][profile][hat]['path']
to match the profile_storage() layout.
b) Simplify log translation
The translation from logparser.py's output to *Rule events was more ugly
than needed. This patch removes one step.
Instead of translating log_dict to log_obj in ask_the_questions(), add
*Rule objects to log_dict and adjust ask_the_questions() to use log_dict
instead of log_obj.
This also means log_obj in ask_the_questions() is now superfluous and
can be removed.
c) Other small changes:
- use is_known_rule() instead of .is_covered() for capability events,
which means included files are also checked now.
- remove the "if rule_obj.log_event != aamode:" check, because
a) it depends on the content of *Rule.log_event (which means it
ignores events with log_event != 'ALLOWING' or 'REJECTING'
b) it's superfluous because the whole code section is wrapped in a
"for aamode in sorted(log.dict.keys())" which means we have
separate loops for enforce and complain mode already
Acked-by: Kshitij Gupta <kgupta8592@gmail.com>
If the program specified as get_output param isn't executable or doesn't
exist at all, get_output() returns with ret = -1.
Raising an exception looks like a better option, especially because
other possible exec failures already raise an exception ("Unable to
fork").
Note: get_output is only used by get_reqs() which also does the
os.access() check for x permissions (and raises an exception), so in
practise raising an exception in get_output() doesn't change anything.
This change also allows to rewrite and simplify get_output() quite a bit.
Another minor change (and fix) is in the removal of the last line. The
old code removed the last line if output contained at least two items.
This had two not-so-nice effects:
- an empty output resulted in [''] instead of []
- if a command didn't add a \n on the last line, this line was deleted
nevertheless
The patch changes that to always remove the last line if it is empty,
which fixes both issues mentioned above.
Also add a test to ensure the exception is really raised, and adjust the
test that expects an empty stdout.
Acked-by: Kshitij Gupta <kgupta8592@gmail.com>
To make these tests independent from the underlaying system, add a
fake_ldd script that provides hardcoded ldd output for the "known"
executables and libraries.
To avoid interferences with the real system (especially symlinks), all
paths in fake_ldd have '/AATest' prepended.
Acked-by: Kshitij Gupta <kgupta8592@gmail.com>
To ensure aa-cleanprof works as expected (and writing the rules works
as expected), add some rules for every rule class to the cleanprof.in
and cleanprof.out test profiles.
Acked-by: Kshitij Gupta <kgupta8592@gmail.com>
According to a discussion with John on IRC, denied_mask="x" can only
happen for 'exec' log events. This patch raises an exception if John
is wrong ;-)
Acked-by: Kshitij Gupta <kgupta8592@gmail.com>
This should happen rarely, but nevertheless it can happen - and since
AppArmor needs the symlink target in the profile, we have to resolve all
symlinks.
Acked-by: Kshitij Gupta <kgupta8592@gmail.com>
If a profile file contains multiple profiles and one of those profiles
contains a rule managed by a *Ruleset class,
serialize_profile_from_old_profile() crashes with an AttributeError.
This happens because profile_data / write_prof_data contain only one
profile with its hats, which explodes if a file contains multiple
profiles, as reported in lp#1528139
Fixing this would need lots of
write_prof_data[hat] -> write_prof_data[profile][hat]
changes (and of course also a change in the calling code) or, better
option, a full rewrite of serialize_profile_from_old_profile().
Unfortunately I don't have the time to do the rewrite at the moment (I
have other things on my TODO list), and changing write_prof_data[hat] ->
write_prof_data[profile][hat] is something that might introduce more
breakage, so I'm not too keen to do that.
Therefore this patch wraps the serialize_profile_from_old_profile() call
in try/except. If it fails, the diff will include an error message and
recommend to use 'View Changes b/w (C)lean profiles' instead, which is
known to work.
Note: I know using an error message as 'newprofile' isn't an usual way
to display an error message, but I found it more intuitive than
displaying it as a warning (without $PAGER).
References: https://bugs.launchpad.net/ubuntu/+source/apparmor/+bug/1528139
Acked-by: Seth Arnold <seth.arnold@canonical.com> for trunk and 2.10
dovecot-lda needs to read and write /tmp/dovecot.lda.*.
It also needs to be able to execute sendmail to send sieve vacation
mails.
For now, I'm using a child profile for sendmail to avoid introducing a
new profile with possible regressions. This child profile is based on
the usr.sbin.sendmail profile in extras and should cover both postfix'
and sendmail's sendmail.
I also mixed in some bits that were needed for (postfix) sendmail on my
servers, and dropped some rules that were obsolete (directory rules not
ending with a /) or covered by an abstraction.
In the future, we might want to provide a stand-alone profile for
sendmail (based on this child profile) and change the rule in the
dovecot-lda profile to Px.
References: https://bugzilla.opensuse.org/show_bug.cgi?id=954959https://bugzilla.opensuse.org/show_bug.cgi?id=954958
Acked-by: Seth Arnold <seth.arnold@canonical.com> for trunk, 2.10 and 2.9.
parser/tst/simple_tests/profile/profile_ns_bad8.sd was added in r3376
(trunk) / r3312 (2.10 branch) and contains the profile name ':ns/t'
which misses the terminating ':' for the namespace.
Unfortunately the tools don't understand namespaces yet and just use the
full profile name. This also means this test doesn't fail as expected
when tested against the utils code.
This patch adds profile_ns_bad8.sd to the exception list of
test-parser-simple-tests.py.
Acked-by: Steve Beattie <steve@nxnw.org> for trunk and 2.10.
https://launchpad.net/bugs/1540666
Reuse the new parse_label() function to initialize named_transition
structs so that transition targets, when used with change_profile, are
properly seperated into a profile namespace and profile name.
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: John Johansen <john.johansen@canonical.com>
Bug: https://launchpad.net/bugs/1379874
https://launchpad.net/bugs/1544387
Don't split namespaces from profile names using YACC grammar. Instead,
treat the entire string as a label in the grammer. The label can then be
split into a namespace and a profile name using the new parse_label()
function.
This fixes a bug that caused the profile keyword to not be used with a
label containing a namespace in the profile declaration.
Fixing this bug uncovered a bad parser test case at
simple_tests/profile/profile_ns_ok1.sd. The test case mistakenly
included two definitions of the :foo:unattached profile despite being
marked as expected to pass. I've adjusted the name of one of the
profiles to :foo:unattached2.
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: John Johansen <john.johansen@canonical.com>
https://launchpad.net/bugs/1546455
Don't filter out AF_UNSPEC from the list of valid protocol families so
that the parser will accept rules such as 'network unspec,'.
There are certain syscalls, such as socket(2), where the LSM hooks are
called before the protocol family is validated. In these cases, AppArmor
was emitting denials even though socket(2) will eventually fail. There
may be cases where AF_UNSPEC sockets are accepted and we need to make
sure that we're mediating those appropriately.
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Suggested-by: Steve Beattie <steve@nxnw.org>
Acked-by: John Johansen <john.johansen@canonical.com>
[cboltz: Add 'unspec' to the network domain keywords of the utils]
If a profile file contains multiple profiles, aa-mergeprof crashes on
saving in write_profile() because the second profile in the file is not
listed in 'changed'. (This happens only if the second profile didn't
change.)
This patch first checks if 'changed' contains the profile before
pop()ing it.
Reproducer: copy utils/test/cleanprof_test.in to your profile directory
and run aa-mergeprof utils/test/cleanprof_test.out. Then just press
's' to save the profile.
Acked-by: Kshitij Gupta <kgupta8592@gmail.com> for trunk, 2.10 and 2.9
If autodep() is called with a pname starting with / (which can happen
for (N)amed exec depending on the user input), this pname is mapped to
bin_name.
This might look like a good idea, however if the given pname doesn't
exist as file on-disk, autodep() returns None instead of a (mostly
empty) profile. (Reproducer: choose (N)amed, enter "/foo/bar")
Further down the road, this results in two things:
a) the None result gets written as empty profile file (with only a "Last
modified" line)
b) a crash if someone chooses to add an abstraction to the None, because
None doesn't support the delete_duplicates() method for obvious
reasons ;-)
Unfortunately this patch also introduces a regression - aa-logprof now
fails to follow the exec and doesn't ask about the log events for the
exec target anymore. However this doesn't really matter because of a) -
asking and saving to /dev/null vs. not asking isn't a real difference ;-)
Actually the patch slightly improves things - it creates a profile for
the exec target, but only with the depmod() defaults (abstractions/base)
and always in complain mode.
I'd prefer a patch that also creates a complete profile for the exec
target, but that isn't as easy as fixing the issues mentioned above and
therefore is something for a future fix. To avoid we forget it, I opened
https://bugs.launchpad.net/apparmor/+bug/1545155
Note: 2.9 "only" writes an empty file and doesn't crash - but writing
an empty profile is still an improvement.
Acked-by: Kshitij Gupta <kgupta8592@gmail.com> for trunk, 2.10 and 2.9
deny rules don't allow ix, Px, Ux etc. - only 'deny /foo x,' is allowed.
Acked-by: Seth Arnold <seth.arnold@canonical.com> for trunk and 2.10
Note: Seth mentioned in the mail that he doesn't like the 'deny x'
section too much, but we didn't find a better solution when discussing
it on IRC. Therefore I keep the patch unchanged, but will happily
review a follow-up patch if someone sends one ;-)
This test causes `make check` to fail but it is known bug so mark it as
a TODO test.
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: Steve Beattie <steve@nxnw.org>
According to the discussion with John on IRC, exec log events for
directories should never happen, therefore let handle_children()
raise an exception.
Acked-by: Kshitij Gupta <kgupta8592@gmail.com>
Most probably-file log events can also be network events. Therefore
check for request_mask in all events, not only file_perm, file_inherit
and (from the latest bugreport) file_receive.
References: https://bugs.launchpad.net/apparmor/+bug/1540562
Acked-by: Kshitij Gupta <kgupta8592@gmail.com> for trunk, 2.10 and 2.9.
support systems that use libnl-3-200 via libnss-gw-name.
Patch initially proposed by Simon McVittie <smcv@debian.org>.
Bug-Debian: #810888
Acked-By: Jamie Strandboge <jamie@canonical.com>
support systems with NetworkManager but no resolvconf where /etc/resolv.conf is
a symlink to /var/run/NetworkManager/resolv.conf
Patch proposed by Simon McVittie <smcv@debian.org>.
Bug-Debian: #813835
Acked-By: Jamie Strandboge <jamie@canonical.com>
If reading /dev/urandom failed, the corresponding file descriptor was
leaked through the error path.
Coverity CID #56012
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: Steve Beattie <steve@nxnw.org>
The variable was only referenced by commented section of code so move
the declaration into the comment.
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: Steve Beattie <steve@nxnw.org>
Add a target that uses cov-build, which must be found in $PATH, to
generate an intermediate Coverity directory called cov-int. The
intermediate Coverity directory will be based on a clean snapshot of the
last commit in the bzr tree. Finally, the intermediate directory is
converted to a compressed tarball, stored in
apparmor-<SNAPSHOT_VERSION>-cov-int.tar.gz, and is suitable for
uploading to scan.coverity.com.
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: Steve Beattie <steve@nxnw.org>
Turn REPO_VERSION and SNAPSHOT_DIR into make variables that may be
reused by future targets that specify the snapshot target as a
prerequisite. This prevents us from having to repeatedly call out to
potentially slow commands on bound bzr branches, such as the bzr
version-info command stored in the REPO_VERSION_CMD make variable.
The new REPO_VERSION make variable is turned into a "simply expanded"
variable as to not require a callout to bzr each time it is expanded.
The SNAPSHOT_DIR shell variable is renamed to SNAPSHOT_NAME as a make
variable. The new name may be slightly more descriptive in the future as
the variable will be reused in other ways besides a simple directory
name.
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: Steve Beattie <steve@nxnw.org>
bzr version-info supports directly printing the bare revno to stdout so
we should use that instead of parsing the default verbose output.
This change simplifies the shell snippet used to assign the
REPO_VERSION_CMD make variable. It was also tested to work with the bzr
present in Ubuntu 12.04.
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: Christian Boltz <apparmor@cboltz.de>
Acked-by: Steve Beattie <steve@nxnw.org>
Order the DIRS variable according to build order. This allows the DIRS
variable to be iterated over to build libapparmor, binutils, parser,
utils, etc., without having to reorder the list.
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: Steve Beattie <steve@nxnw.org>
Acked-by: Christian Boltz <apparmor@cboltz.de>
I suspect that the incorrect description of EPERM was copied from
the aa_change_hat man page, where it is possible to see EPERM if the
application is not confined by AppArmor.
This patch corrects the description by documenting that the only
possible way to see EPERM is if a confined application has the
no_new_privs bit set.
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Reported-by: Seth Arnold <seth.arnold@canonical.com>
Acked-by: John Johansen <john.johansen@canonical.com>
It is possible that file descriptors will be revalidated after an
aa_change_profile() but there is a lot of complexity involved that
doesn't need to be spelled out in the man page. Instead, mention that
revalidation is possible but the only way to ensure that file
descriptors are not passed on is to close them.
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Reported-by: Seth Arnold <seth.arnold@canonical.com>
Acked-by: John Johansen <john.johansen@canonical.com>
The statement was meant to convey the difference between aa_change_hat()
and aa_change_profile(). Unfortunately, it read as if there was
something preventing a program from using aa_change_profile() twice to
move from profile A to profile B and back to profile A, even if profiles
A and B contained the necessary rules.
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Reported-by: Seth Arnold <seth.arnold@canonical.com>
Acked-by: Christian Boltz <apparmor@cboltz.de>
On Debian and Ubuntu it's possible to have multiple ruby interpreters
installed, and the default to use is handled by the ruby-defaults
package, which includes a symlink from /usr/bin/ruby to the versioned
ruby interpreter.
This patch makes aa.py:get_interpreter_and_abstraction() take that into
account by using a regex to match possible versions of ruby. Testcases
are included. (I noticed this lack of support because on Ubuntu the ruby
test was failing because get_interpreter_and_abstraction() would get the
complete path, which on my 16.04 laptop would get /usr/bin/ruby2.2.)
Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
This patch frees some leaked memory that occur when errors are
detected while adding variables to the parser's symbol table. While not
a significant issue currently due to the parser exiting on failures, as
the process of library-ifying the parser continues, these need to be
addressed. It also makes it easier to use tools like Address Sanitizer
on the parser against our test suite.
Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: Tyler Hicks <tyhicks@canonical.com>
The rule classes have lots of
if self.all_foo:
foo_txt = _('ALL')
else:
foo_txt = self.foo
in logprof_header_localvars().
To avoid repeating this over and over, split it off to a
logprof_value_or_all() function.
This function can handle
- str (will be returned unmodified
- AARE (.regex will be used)
- sets/lists/tuples (will be ' '.join()ed and sorted)
Other types are returned unmodified.
Acked-by: Steve Beattie <steve@nxnw.org>
When hitting an unknown line while parsing a profile, it's a good idea
to include that line in the error message ;-)
Note: 2.9 would print a literal \n because it doesn't have apparmor.fail,
so it will get a slightly different patch with spaces instead of \n.
Acked-by: Steve Beattie <steve@nxnw.org> for trunk, 2.10 and 2.9.
Checking if two AARE objects are equal is not hard, but also not a
one-liner.
Since we need to do this more than once (and even more often in other
outstanding rule classes), split that code into an _is_equal_aare()
function and change PtraceRule and SignalRule to use it.
To make things even more easier, the parameters to use match the
_is_covered_aare() syntax.
Acked-by: Steve Beattie <steve@nxnw.org>
If a *Ruleset is empty, let __repr__() print/return
<FooRuleset (empty) />
instead of
<FooRuleset>
</FooRuleset>
Acked-by: Steve Beattie <steve@nxnw.org> for trunk and 2.10.
PtraceRule 'access' and SignalRule 'access' and 'signal' can contain
more than one value. Therefore adjust is_covered_localvars() in both
to use the list (subset) instead of the plain (exactly equal) check.
Also add a testcase for each to ensure the list/subset check works as
expected.
Acked-by: Steve Beattie <steve@nxnw.org>
is_covered_localvars() in the rule classes need the same set of checks
again and again. This patch adds the helper functions _is_covered_list(),
_is_covered_aare() and _is_covered_plain() to check against lists, AARE
and plain variables like str.
The helpers check if the values from the other rule are valid (either
ALL or the value need to be set) and then check if the value is covered
by the other rule's values.
This results in replacing 7 lines with 2 in the rule classes and avoids
repeating code over and over.
Note that the helper functions depend on the *Rule.rule_name variable in
the exception message, therefore rule_name gets added to all rule
classes.
Acked-by: Steve Beattie <steve@nxnw.org>
The first entry in the grouping_count array is never initialized to 0;
subsequent depths are. This patch initializes the whole array.
Issue found with valgrind.
Signed-off-by: Steve Beattie <steve@nxnw.org> (with improvement from Seth)
Acked-by: Seth Arnold <seth.arnold@canonical.com>
This patch fixes the unit test memory leaks found
by intrigeri using AddressSanitizer in the following email thread:
https://lists.ubuntu.com/archives/apparmor/2015-August/008491.html
Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: Seth Arnold <seth.arnold@canonical.com>