2
0
mirror of https://gitlab.com/apparmor/apparmor synced 2025-09-01 06:45:38 +00:00

Compare commits

..

84 Commits

Author SHA1 Message Date
Steve Beattie
b37bd8a1aa Point makefile at correct launchpad branch to generate tarball from. 2015-04-23 12:46:45 -07:00
Christian Boltz
ead71a306a Enable testloops for nosetests
Ensure nosetests sees all tests in the tests[] tuples. This requires
some name changes because nosetests thinks all function names containing
"test" are tests. (A "not a test" docorator would be an alternative, but
that would require some try/except magic to avoid a dependency on nose.)

To avoid nosetests thinks the functions are a test,
- rename setup_all_tests() to setup_all_loops()
- rename regex_test() to _regex_test() (in test-regex_matches.py)

Also add the module_name as parameter to setup_all_loops and always run
it (not only if __name__ == '__main__').

Known issue: nosetests errors out with
    ValueError: no such test method in <class ...>: stub_test
when trying to run a single test generated out of tests[].
(debugging hint: stub_test is the name used in setup_test_loop().)
But that's still an improvement over not seeing those tests at all ;-)


Acked-by: Steve Beattie <steve@nxnw.org> for trunk and 2.9.
2015-04-22 22:03:36 +02:00
Christian Boltz
aa45be1c10 Fix crash in serialize_profile_from_old_profiles()
Assume you have a profile like

    /bin/foo {
      /etc/ r,
      network,
      /usr/ r,
    }

(important: there must be be a non-path rule between the two path blocks)

Then run aa-logprof and add another path event. When choosing (V)iew changes,
it will crash with a misleading

  File ".../utils/apparmor/aamode.py", line 205, in split_mode
      other = mode - user
      TypeError: unsupported operand type(s) for -: 'collections.defaultdict' and 'set'

The reason for this is our beloved hasher, which is playing funny games
another time.

The patch wraps the hasher usage with a check for the parent element to
avoid auto-creation of empty childs, which then lead to the above crash.


BTW: This is another issue uncovered by the LibreOffice profile ;-)


Acked-by: Steve Beattie <steve@nxnw.org> for trunk and 2.9.
2015-04-16 13:11:39 +02:00
Steve Beattie
c1c5192532 profiles: update postfix-common abstraction
Merge from trunk revision 3012

Update the postfix-common abstraction to cope with signal and unix
socket mediation, update the access to the sasl library locations
in a multiarch compliant way, and allow access to limited bits
of the filesystem paths under which postfix chroots itself to
(/var/spool/postfix/ on Ubuntu).

Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: Tyler Hicks <tyhicks@canonical.com>
2015-04-15 23:35:52 -07:00
Christian Boltz
2b9260f27a Fix serialize_profile_from_old_profiles() to not crash on "@{var} +="
serialize_profile_from_old_profiles() calls store_list_var() with an
empty hasher. This fails for "+=" because in this case store_list_var()
expects a non-empty hasher with the variable already defined, and raises
an exception because of the empty hasher.

This patch sets "correct = False" if a "+=" operation appears, which
means the variable will be written in "clean" mode instead.

Adding proper support for "add to variable" needs big changes (like
storing a variable's "history" - where it was initially defined and what
got added where).



Acked-by: Steve Beattie <steve@nxnw.org> for trunk and 2.9.
2015-04-16 02:02:02 +02:00
Christian Boltz
4063647a5f fix handling of adding to variables
the LibreOffice profile uncovered that handling of @{var} += is broken:

  File ".../utils/apparmor/aa.py", line 3272, in store_list_var
    var[list_var] = set(var[list_var] + vlist)
TypeError: unsupported operand type(s) for +: 'set' and 'list'

This patch fixes it:
- change separate_vars() to use and return a set instead of a list
  (FYI: separate_vars() is only called by store_list_var())
- adoptstore_list_var() to expect a set
- remove some old comments in these functions
- explain the less-intuitive parameters of store_list_var()

Also add some tests for separate_vars() and store_list_var().
The tests were developed based on the old code, but not all of them
succeed with the old code.

As usual, the tests uncovered some interesting[tm] behaviour in
separate_vars() (see the XXX comments and tell me what the really
expected behaviour is ;-)


Acked-by: Steve Beattie <steve@nxnw.org> for trunk and 2.9
2015-04-16 01:59:10 +02:00
Christian Boltz
b4048cf3de logparser.py: change mask only for path events
Move the code that does the c -> a and d -> w replacement in denied_mask
and requested_mask so that it only runs for path and exec events, but not
for other events (like dbus and ptrace). The validate_log_mode() and
log_str_to_mode() calls are also moved.

Technically, this means moving code from parse_event() to the path
and exec sections in add_event_to_tree().

This also means aa-logprof no longer crashes if it hits a ptrace or
dbus event in the log.

The "if dmask:" and "if rmask:" checks are removed - if a path event
doesn't have these two, it is totally broken and worth a aa-logprof
crash ;-)

Also adjust the parse_event() tests to expect the "raw" mask instead of
a set.

Note: the 2.9 branch doesn't contain test-capability.py, therefore I
skipped this part of the patch for obvious reasons ;-)

This patch fixes
https://bugs.launchpad.net/apparmor/+bug/1426651 and
https://bugs.launchpad.net/apparmor/+bug/1243932


I manually tested that
- c and d log events are still converted to a and w
- aa-logprof handles exec events correctly
- ptrace events no longer crash aa-logprof

Note: add_event_to_tree() is not covered by tests.


Acked-by: Steve Beattie <steve@nxnw.org> for trunk and 2.9
2015-04-16 01:53:39 +02:00
Christian Boltz
8a475341e8 utils: simplify serialize_parse_profile_start()
Merge from trunk revision 3001

Change serialize_parse_profile_start() to use parse_profile_start()
instead of using duplicated code.

The behaviour is mostly kept, with the exception that the function is
more strict now and raises exceptions instead of ignoring errors.

In practise, this won't change anything because the profiles are parsed
with parse_profile() (which calls parse_profile_start()) - and that
already errors out.

The tests are updated to match the more strict behaviour.

The next step would be to drop serialize_parse_profile_start()
completely, but this isn't urgent and can/should be done when we have
test coverage for serialize_profile_from_old_profile() one day ;-)

Acked-by: Steve Beattie <steve@nxnw.org>
2015-04-13 19:07:47 -07:00
Christian Boltz
5ca6986b43 utils: fix is_skippable_dir() and add tests
Merge from trunk revision 3000

Fix is_skippable_dir() - the regex also matched things like
/etc/apparmor.d/dont_disable, while it should match on the full
directory name.

Also add some tests based on a real-world aa-logprof run (with "print (path)"
in is_skippable_dir()) and some additional "funny"[tm] dirs.

Needless to say that the tests
        ('dont_disable',                False),
        ('/etc/apparmor.d/cache_foo',   False),
will fail with the old is_skippable_dir().

Acked-by: Steve Beattie <steve@nxnw.org>
2015-04-13 19:00:47 -07:00
Christian Boltz
4b58cf3bc4 utils: replace RE_PROFILE_START
Merge from trunk revision 2999

Replace RE_PROFILE_START with RE_PROFILE_START_2 and adjust all
code sections that used RE_PROFILE_START_2.

The only real change is that test_get_flags_invalid_01 and
test_get_flags_invalid_02 now expect AppArmorException instead of
AppArmorBug.

Acked-by: Steve Beattie <steve@nxnw.org> for trunk
2015-04-13 18:58:25 -07:00
Christian Boltz
a373b4ee93 utils: implement attachment handling after rewriting set_profile_flags()
to use write_header(), and making set_profile_flags
more strict.

Merge from trunk revisions 2996, 2997, and 2998.

Changes in set_profile_flags():
- rewrite set_profile_flags to use parse_profile_start_line() and
  write_header().
- replace the silent failure for non-existing files with a proper
  exception (using lazy programming - the check is done by removing the
  "if os.path.isfile()" check, open_file_read then raises the
  exception ;-)
- comment out regex_hat_flag and the code that was supposed to handle
  hat flags, which were totally broken. We'll need another patch to fix
  it, and we also need to decide if we want to do that because it
  introduces a behaviour change (currently, aa-complain etc. don't
  change hat flags).

The tests for set_profile_flags() are also updated:
- prepend a space to comments because write_header always adds a space
  between '{' and the comment
- remove a test with superfluous quotes that are no longer kept
  (that's
  just a profile cleanup, so dropping that test is the easiest way)
- update test_set_flags_10 and test_set_flags_12 to use the correct
  profile name
- enable the tests for invalid (empty) flags
- update the test for a non-existing file

this patch makes set_profile_flags more strict:
- raise AppArmorBug if newflags contains only whitespace
- raise AppArmorBug if the file doesn't contain the specified profile or
  no profile at all

The tests are adjusted to expect AppArmorBug instead of a silent
failure. Also, some tests are added for profile=None, which means to
change the flags for all profiles in a file.
- test_set_flags_08 is now test_set_flags_invalid_04
- test_set_flags_invalid_03 is changed to only contain one reason for
  a failure, not two ;-)

Finally implement attachment handling

This patch implements attachment handling - aa-logprof now works with
profiles that have an attachment defined, instead of ignoring audit.log
entries for those profiles.

Changes:
- parse_profile_start_line(): remove workaround that merged the
  attachment into the profile name
- parse_profile_data(): store attachment when parsing a profile
- update test_parse_profile_start_03,
  test_serialize_parse_profile_start_03,
  test_set_flags_nochange_09 and some parse_profile_start_line() tests -
  they now expect correct attachment handling

Acked-by: Steve Beattie <steve@nxnw.org>
2015-04-13 18:53:59 -07:00
Christian Boltz
8d5569f20b utils: rewrite parse_profile_start()
Merge from trunk revision 2990

Rewrite parse_profile_start() in aa.py to a more readable version.
The behaviour remains unchanged (and is covered by tests).

Acked-by: Kshitij Gupta <kgupta8592@gmail.com>
2015-04-13 18:49:37 -07:00
Christian Boltz
5390777e45 utils: add tests for RE_PROFILE_START_2 and parse_profile_start_line()
Merge from trunk revision 2989

Also add AANamedRegexTest class that can be used to test a regex with
named match groups.

Acked-by: Steve Beattie <steve@nxnw.org>
2015-04-13 18:47:12 -07:00
Christian Boltz
79240e7ddd utils: test new parameters of write_header()
Merge from trunk revision 2988

Change the write_header tests so that the 'profile_keyword' and
'header_comment' parameters can be (and are) tested:
- add a None for both to the existing tests
- add some tests that come with the profile keyword and/or a comment

Acked-by: Steve Beattie <steve@nxnw.org>
2015-04-13 18:45:05 -07:00
Christian Boltz
494daee246 utils: extend and partially rewrite write_header()
Merge from trunk revision 2987

- add support for prof_data['header_comment'] (comment after '{')
  and prof_data['profile_keyword'] (to force the 'profile' keyword, even
  if it isn't needed) to write_header().
  (set_profile_flags() will be the only user of these two for now)

- fix a crash if depth is not an integer - for example,
      len('   ')/2   # 3 spaces = 1.5
  would cause a crash.
  Also add a test for 1.5 and 1.3 spaces.

- rewrite the handling of flags to avoid we have to maintain two
  different template lines.

- update the tests to set 'profile_keyword' and 'header_comment' to None.
  This avoids big changes in the test code. I'll send another patch that
  makes sure profile_keyword and header_comment are tested ;-)

Acked-by: Steve Beattie <steve@nxnw.org>
2015-04-13 18:41:59 -07:00
Christian Boltz
194cbfa94c utils: add attachment to parse_profile_start() return values
Merge from trunk revision 2986

Add the attachment to the parse_profile_start() and
serialize_parse_profile_start() return values, and adjust the functions
calling the *parse_profile_start() functions to save the attachment in
the "attachment" variable (which isn't used yet).

Also adjust the tests for the added return value.

(Sorry for not getting the resultset right from the beginning!)

Acked-by: Steve Beattie <steve@nxnw.org>
2015-04-13 18:36:42 -07:00
Christian Boltz
9452e1e2af utils: Add support for attachments to write_header()
Merge from trunk revision 2985

Also fix a little bug that added the profile keyword if the path needed
quotes (profile "/foo bar" - but "/foo bar" is enough). This was caused
by a regex that always matched on quoted paths (hint: "/ matches
^[^/] ;-)

Also add some tests with attachments and update the test for the bugfix
mentioned above.

Now the remaining part is to make sure that prof_data['attachment'] gets
set when parsing the profiles :-)

Acked-by: Steve Beattie <steve@nxnw.org>
2015-04-13 18:34:33 -07:00
Christian Boltz
1556f782e3 utils: add tests for set_profile_flags() (and some fun)
Merge from trunk commit 2983

Add various tests for set_profile_flags, and document various
interesting[tm] things I discovered while writing the tests (see
the inline comments for details).

Also adds a read_file() function to common_test.py.

The most interesting[tm] thing I found is:
    regex_hat_flag = re.compile('^([a-z]*)\s+([A-Z]*)\s*(#.*)?$')
which matches various unexpected things - but not a hat :-/
(see mailinglist for all funny details)

Acked-by: Steve Beattie <steve@nxnw.org>
2015-04-13 18:31:53 -07:00
Christian Boltz
7d1ff607fe utils: add and use parse_profile_start_line(); convert
serialize_parse_profile_start() to use parse_profile_start_line();
update test-aa.py to match parse_profile_start() and
get_profile_flags() changes

Merge from trunk commits 2978, 2979, and 2982

Add the parse_profile_start_line() function to regex.py, which is
a wrapper for RE_PROFILE_START_2 and returns an array with named matches.

Also change some places in aa.py from using RE_PROFILE_START to
the parse_profile_start_line() function.

Notes: - until everything is migrated to the new function, I'll
keep the old
  RE_PROFILE_START unchanged - that's the reason to add the new
  regex as RE_PROFILE_START_2
- the patch changes only aa.py sections that are covered by tests
  already (which means some users of RE_PROFILE_START are remaining)
- parse_profile_start_line() merges 'profile' and 'attachment' into
  'profile' (aka the old, broken behaviour) until aa.py can handle
  the attachment properly. The alternative would be to ignore
'attachment', which would be worse.

Convert serialize_parse_profile_start() to use
parse_profile_start_line(), and adjust a test to expect an AppArmorBug
instead of an AttributeError exception.

Also add two tests (they succeed with the old and the new code).
Note that these tests document interesting[tm] behaviour - I tend to
think that those cases should raise an exception, but I'm not sure about
this because serialize_profile_from_old_profile() is a good example for
interesting[tm] code :-/

I couldn't come up with a real-world test profile that would hit those
cases without erroring out aa-logprof earlier - maybe the (more
sane-looking) parse_profiles() / serialize_parse_profile_start()
protects us from hitting this interesting[tm] behaviour.

The previous patch slightly changed the behaviour of parse_profile_start()
and get_profile_flags() - they raise AppArmorBug instead of
AppArmorException when specifying a line that is not the start of a
profile and therefore doesn't match RE_PROFILE_START_2.

This patch updates test-aa.py to expect the correct exceptions, and adds
another test with quoted profile name to ensure that stripping the
quotes works as expected.

Acked-by: Steve Beattie <steve@nxnw.org>
2015-04-13 18:24:20 -07:00
Steve Beattie
242ece320a utils: merge test-only changes from trunk
Merge from trunk revisions 2976+2980, 2977, 2981, and 2984.
2015-04-13 18:03:55 -07:00
Christian Boltz
dc1d8e5253 add tests for write_header()
Merge from trunk revision 2984

Also add loop support to test-aa.py.

BTW: In case you wonder - the need to replace unittest.TestCase with
AATest is intentional. It might look annoying, but it makes sure that
a test-*.py file doesn't contain a test class where tests = [...] is
ignored because it's still unittest.TestCase.
(Technically, setup_all_tests() will error out if a test class doesn't
contain tests = [...] - either explicit or via its parent AATest.)

Acked-by: Steve Beattie <steve@nxnw.org>
2015-04-13 14:42:40 -07:00
Christian Boltz
0ac23ee34a add tests for serialize_parse_profile_start() to test-aa.py
to document the function's behaviour.
Merge from trunk revision 2981.

Acked-by: Steve Beattie <steve@nxnw.org>
2015-04-13 14:38:08 -07:00
Christian Boltz
5bc15cda41 Convert test-regex_matches.py to the new tests[] loop.
Merge from trunk revision 2977

The test behaviour is the same with and without this patch - 166 tests
run, all successful.

Acked-by: Steve Beattie <steve@nxnw.org>
2015-04-13 14:32:15 -07:00
Christian Boltz
9ebb1913bd add better loop support to common_test.py
Merge from trunk revisions 2976 and 2980

Add better support for looping over a tests[] array to common_test.py:
- class AATest - a base class we can use for all tests, and that will
  probably get more features in the future (for example tempdir
  handling)
- setup_all_tests() - a function that iterates over all classes in the
  given file and calls setup_test_loops() for each of them
- setup_tests_loop() - a function that creates tests based on tests[]
  in the given class. Those tests call the class' _run_test() method for
  each test specified in tests[]  (inspired by setup_regex_tests() ;-)

This means we can get rid of the manually maintained tests list in
test-regex_matches.py and just need to call setup_all_tests() once in
each file.

The patch also adds test-example.py, which is
- a demo of the code added to common_test.py
- a template file that we can copy for future test-*.py

Acked-by: Steve Beattie <steve@nxnw.org>
2015-04-13 14:28:48 -07:00
Christian Boltz
720f6624e6 write_net_rules() fixes, part 3
Thanks to the used data structure, write_net_rules() replaces bare
'network,' rules with the invalid 'network all,' when saving a profile.
This patch makes sure a correct 'network,' rule is written.

Also reset 'audit' to avoid all (remaining) rules get the audit flag
after writing an audit network rule.

Note: The first section of the function (that claims to be responsible
for bare 'network,' rules) is probably never hit - but I'm not too keen
to remove it and try it out ;-)


Acked-by: Steve Beattie <steve@nxnw.org> for trunk and 2.9.
2015-04-11 02:21:05 +02:00
Christian Boltz
387de4458f Fix doubled arrow in exec rules
When parsing a profile with named exec rules, the exec target included
the arrow. This resulted in two arrows when writing the profile (and one
more each time the profile was updated).

Fix this by using the match group that only contains the exec target
without the arrow in parse_profile_data() and
serialize_profile_from_old_profile().

References: https://bugs.launchpad.net/apparmor/+bug/1437901


Acked-by: Steve Beattie <steve@nxnw.org> for trunk and 2.9.
2015-04-11 02:16:08 +02:00
Steve Beattie
38a69f5ebc profiles: allow ubuntu-helpers to generate texlive fonts
Merge from trunk revision 3004

When evince opens a dvi file, it updates the user fonts using
texlive commands in /usr/share/texlive/texmf-dist/web2c/ (or possibly
/usr/share/texlive/texmf/web2c/ in older releases). This patch adjusts
the sanitized_helper profile to allow these tools to run.

Bug: https://bugs.launchpad.net/ubuntu/+source/apparmor/+bug/1010909

Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-By: Jamie Strandboge <jamie@canonical.com>
2015-04-10 09:52:36 -07:00
Christian Boltz
7d84c61b6c Fix writing network rules, part 2
write_net_rules() doesn't add a space after 'audit' in two of three
cases, leading to invalid network rules.
This patch adds the missing spaces.


Acked-by: Seth Arnold <seth.arnold@canonical.com>
for both trunk and 2.9
2015-04-10 01:53:42 +02:00
Christian Boltz
f836ebd42b Fix writing network rules
write_net_rules() creates invalid rules for network rules with one
parameter (for example "network bluetooth").
Add a trailing comma to create valid rules.


Acked-by: Seth Arnold <seth.arnold@canonical.com>
for both trunk and 2.9.
2015-04-09 13:29:09 +02:00
Christian Boltz
52b6aeb04c logparser.py: merge path handling in add_event_to_tree()
Merge path handling for 'inode_*' in add_event_to_tree() with the
handling for other path events.

The code is slightly more strict now - 'inode_' in e['operation'] is
replaced with e['operation'].startswith('inode_').

This patch is a cleanup and also a preparation to fix
https://bugs.launchpad.net/apparmor/+bug/1426651 and
https://bugs.launchpad.net/apparmor/+bug/1243932


Acked-by: Seth Arnold <seth.arnold@canonical.com>
Acked for both 2.9 and trunk.
2015-04-03 17:45:48 +02:00
Christian Boltz
475a9bc691 honor 'chmod' events in logparser.py / aa-logprof
aa-logprof doesn't ask anything for

type=AVC msg=audit(1427633461.202:281): apparmor="DENIED" operation="chmod" profile="/usr/lib64/firefox/plugin-container" name="/home/cb/.config/ibus/bus/" pid=7779 comm="plugin-containe" requested_mask="w" denied_mask="w" fsuid=1000 ouid=1000

This patch fixes this by adding 'chmod' to the list of file operation
types in logparser.py.


Acked-by: Seth Arnold <seth.arnold@canonical.com>
for both trunk and 2.9.
2015-04-03 17:44:38 +02:00
Christian Boltz
0f7bf53afb Tell python2 about math
if 3/2 == 1:
    print("python2 inside")

Add "from __future__ import division" so that python2 returns the
correct result (if needed, as float)

On related news: At least python3 knows how to calculate correctly.


Acked-by: Steve Beattie <steve@nxnw.org> for trunk and 2.9
2015-04-02 23:40:15 +02:00
Jamie Strandboge
8dcd54e365 cherrypick from trunk:
add --include-templates-dir and --include-policy-groups-dir options to easyprof
  to support framework policy on Snappy for Ubuntu Core

  Signed-off-by: Jamie Strandboge <jamie@canonical.com>
  Acked-by: Seth Arnold <seth.arnold@canonical.com>
2015-03-31 16:24:31 -05:00
Steve Beattie
097eb4258f fix two issues for older linux releases
Merge from trunk revision 2975

The following patch addresses two issues on older releases:

1) In trunk commit 2911, the line 'undefine VERBOSE' was added to
   parser/tst/Makefile so that the equality tests would not generate
   verbose output when $VERBOSE != 1. Unfortunately, the 'undefine'
   keyword was not introduced in GNU Make until version 3.82. On
   distro releases like Ubuntu 12.04 LTS that include versions of Make
   older than that, make check and make clean abort when VERBOSE is
   not set to 1. The patch fixes that by setting VERBOSE to a zero
   length string if does not already equal 1.

2) In trunk commit 2923, a workaround for systemd as init was added
   to the pivot_root regression test. The workaround included a
   call to ps(1) to determine if systemd is pid 1. Unfortunately,
   in older versions of the procps package (such as the version in
   Ubuntu 12.04 LTS), 'ps -hp1' emits the warning

     Warning: bad ps syntax, perhaps a bogus '-'? See http://procps.sf.net/faq.html

   The patch below converts the ps call to 'ps hp1' which does not
   generate the warning.

Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: John Johansen <john.johansen@canonical.com>
2015-03-31 02:50:40 -07:00
Cameron Norman
9bc15eb6b8 profiles: update dnsmasq profile for lxc support
Merge from trunk revision 2974

Patch from Cameron Norman <camerontnorman@gmail.com> based on a patch
from Christian Boltz <apparmor@cboltz.de>.

This patch allows /var/lib/misc/dnsmasq.*.leases rw and
/{,var/}run/lxc/dnsmasq.pid rw for LXC networking setup.

Acked-by: Steve Beattie <steve@nxnw.org>
2015-03-30 22:26:32 -07:00
Seth Arnold
9d6f7f53cb Add new gdm path for Xauthority file
Bruce Pieterse reports that AppArmor denied evince, among other
applications, from starting properly:
https://bugs.launchpad.net/ubuntu/+source/apparmor/+bug/1432126

He tested a slight variant of the attached patch and reported success. I
propose this patch for both trunk and 2.9.

Signed-off-by: Seth Arnold <seth.arnold@canonical.com>
Acked-by: Tyler Hicks <tyhicks@canonical.com>
2015-03-25 15:32:29 -07:00
Steve Beattie
c1ae887576 tests: work around systemd mounting / shared in pivot_root tests
Merge from trunk revision 2923


The systemd init daemon mounts the / filesystem as shared [1], which
breaks pivot_root(2). The following patch adjusts the pivot_root
test script to remount / as private if it detects that its shared,
allowing the tests to run successfully, and then undoes it once the
tests are complete.

[1] http://cgit.freedesktop.org/systemd/systemd/commit/?id=b3ac5f8cb98757416d8660023d6564a7c411f0a0

Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
2015-03-24 17:12:18 -07:00
Steve Beattie
0ec6ce96d2 parser: fix compilation failure of deny link rules, expand equality tests
Merge from trunk commits 2909, 2910, 2911, and 2912

BugLink: http://bugs.launchpad.net/bugs/1433829

The apparmor_parser fails to compile deny rules with only link
permissions.

  Eg.
       deny /f l,
       deny l /f,
       deny link /f -> /d,

Will all fail to compile with the following assert

  apparmor_parser: aare_rules.cc:99: Node* convert_file_perms(int, uint32_t, uint32_t, bool): Assertion `perms != 0' failed.

NOTE: this is a minimal patch a bigger patch that cleans-up and separates
      and reorganizes file, link, exec, and change_profile rules is needed

parser: Expand Equality tests

This adds several new equality tests and turned up a couple of more
bugs
https://launchpad.net/bugs/1433829
https://launchpad.net/bugs/1434018

- add link/link subset tests
- add pix, Pix, cix, Cix, pux, Pux, cux, Cux and specified profile
  transitions (/f px -> b ...)
- test equality of leading and trailing permission file rules
  ie.   /foo rw, == rw /foo,
- test that specific x match overrides generic x rule. ie.
  /** ix, /foo px, is different than /** ix, /foo ix,
- test that deny removes permission
  /f[abc] r, deny /fb r,  is differnt than /f[abc] r,

In addition to adding the new tests, it changes the output of the
equality tests, so that if the $verbose variable is not set successful
tests only output a period, with failed tests outputing the full
info.  If verbose is set the full test info is output as before.

It also does:

- make the verbose output of equality.sh honor whether or not
  the environment variable VERBOSE is set
- thereby making the output verbose when 'make check V=1' or 'make
  check VERBOSE=1' is given from within the parser/ directory. This
  will make distribution packagers happy when diagnosing build
  failures caused by test failures.
- if verbose output is not emitted and the tests were successful, emit
  a newline before printing PASS.
- verify audit and audit allow is equal
- verify audit differs from deny and audit deny
- verify deny differs from audit deny
- make the verbose text a little more useful for some cases
- correct overlap exec tests to substitute in looped perms

Signed-off-by: John Johansen <john.johansen@canonical.com>
Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
2015-03-23 12:43:57 -07:00
Christian Boltz
8c19eb5521 dovecot auth needs to read openssl.cnf
Darix' guess is that this is needed by libpq because he uses a postgresql
database with dovecot and has ssl enabled in postgresql.

Acked-by: Seth Arnold <seth.arnold@canonical.com> for trunk and 2.9
2015-03-19 13:58:11 +01:00
Steve Beattie
21a41deabe parser: fix equality and valgrind test scripts to use features file
Merge from trunk commit revision 2907

This patch fixes the equality test script and the valgrind wrapper
script to make the parser under test use the features.all features file
from the features_files/ subdirectory. Otherwise, the equality tests
will fail on systems where the not all of the current language features
are supported. The equality fix does so in a way to make the script work
correctly regardless of the directory it is run from.

Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: John Johansen <john.johansen@canonical.com>
2015-03-19 04:37:25 -07:00
Steve Beattie
576e8fe33b parser: fix warning in net_find_af_name
Merge from trunk commit 2906

The fix to prevent the compiler from SEGV'ing when dumping network
rules in commit 2888 introduced the following compiler warning:

  network.c: In function ‘const char* net_find_af_name(unsigned int)’:
  network.c:331:16: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
    for (i = 0; i < sizeof(network_mappings) / sizeof(*network_mappings); i++) {

The problem is that the counter i is an int, but sizeof returns size_t
which is unsigned. The following patch fixes the issue by converting the
type of i to size_t.

Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: John Johansen <john.johansen@canonical.com>
2015-03-19 00:14:12 -07:00
Tyler Hicks
3c928c04e1 parser: Test the 'allow' modifier
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: John Johansen <john.johansen@canonical.com>
Acked-by: Steve Beattie <steve@nxnw.org>
2015-03-18 12:34:49 -05:00
Tyler Hicks
37b872b155 parser: Test the 'audit allow' modifier
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: John Johansen <john.johansen@canonical.com>
2015-03-18 12:34:44 -05:00
Tyler Hicks
5ab8b7a483 parser: Verify policies change with the audit and deny modifiers
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: John Johansen <john.johansen@canonical.com>
2015-03-18 12:34:41 -05:00
Tyler Hicks
b813f4ba53 parser: Add ability to test the inequality of binary policies
Previously, we only had the ability to test that binary policy files
were equal. This patch allows for the testing of binary policy files
that are not equal.

Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: John Johansen <john.johansen@canonical.com>
2015-03-18 12:34:38 -05:00
John Johansen
05ab11fec4 Fix compilation of audit modifiers
cherry-pick: -r2901

This fixes the incorrect compilation of audit modifiers for exec and
pivot_root as detailed in

https://launchpad.net/bugs/1431717
https://launchpad.net/bugs/1432045

The permission accumulation routine on the backend was incorrectly setting
the audit mask based off of the exec type bits (info about the exec) and
not the actual exec permission.

This bug could have also caused permissions issues around overlapping exec
generic and exact match exec rules, except the encoding of EXEC_MODIFIERS
ensured that the
  exact_match_allow & AA_USER/OTHER_EXEC_TYPE
  test would never fail for a permission accumulation with the exec permission
  set.

Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Steve Beattie <steve@nxnw.org>
2015-03-18 10:22:31 -07:00
Christian Boltz
2d7ba0871f Split off serialize_parse_profile_start_line() from
serialize_profile_from_old_profile() in aa.py, as a preparation to add
tests and then switch to the upcoming RE_PROFILE_START wrapper function.

Besides moving the code, I replaced write_prof_data[profile][hat]['profile']
and write_prof_data[profile][hat]['external'] with function parameters
to avoid that I have to pass around the full write_prof_data.

Note: The "lineno" parameter is technically superfluous - I kept it to
have the parameters as close to parse_profile_start() as possible and
hope that I can merge those functions later (when we have test coverage).


Acked-by: Steve Beattie <steve@nxnw.org> for trunk and 2.9.
2015-03-10 19:09:16 +01:00
Christian Boltz
c98b26069a tools.py: add functions to unload and reload profiles
and change the code to use them

Also add a comment to act() that it's only used by aa-cleanprof.

Note: The new functions add the --base parameter to the apparmor_parser
calls, which also means the disable directory inside the given profile
dir (and not always /etc/apparmor.d/disable) is now honored.


Acked-by: Steve Beattie <steve@nxnw.org> for trunk and 2.9.
2015-03-07 20:32:11 +01:00
Christian Boltz
70dc81c4fd merge 'path' if conditions in logparser.py / add_event_to_tree()
logparser.py / add_event_to_tree() has 5 places to handle 'path' events.
This patch merges most if conditions to reduce that to 2 places.

It also makes the matching a bit more strict - instead of using 'in',
'xattr' has to be an exact match and 'file_' is matched with startswith().

Also, 'getattr' is added to the list of file events.


Acked-by: Steve Beattie <steve@nxnw.org> (also for 2.9)



---------- trunk only, unclear for 2.9 --------------
2015-03-07 20:26:32 +01:00
Christian Boltz
1b68baf7a3 let load_include raise an exception if an include file can't be found
instead of ignoring the error silently

Acked-by: Steve Beattie <steve@nxnw.org> for both trunk and 2.9.
2015-03-07 13:28:41 +01:00
Christian Boltz
6af7faa2b7 add read_profiles() call to cmd_disable()
Without it, aa-disable
- didn't error out when hitting a broken profile directory
- didn't find a profile if it doesn't use the default naming scheme
  (for example /bin/true profile hiding in bin.false)


Acked-by: Steve Beattie <steve@nxnw.org> for trunk and 2.9
2015-03-07 13:27:57 +01:00
Steve Beattie
a1529a16bd profiles: add mir abstraction
Merge from trunk revision 2893

As mir has come into use in Ubuntu touch and is available for testing on
Ubuntu desktop, confined apps need access to a few mir specific things.
This patch adds a mir abstraction.

Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: Tyler Hicks <tyhicks@canonical.com>
2015-03-05 11:51:16 -08:00
Steve Beattie
321a2c1dcb regression tests: fix gcc-5 inline confusion
Merge from trunk revision 2889

Parts of the regression tests that use the do_open() inline function
from changehat.h fail to build under gcc-5 like so:

  cc -g -O0 -Wall -Wstrict-prototypes    changeprofile.c  -lapparmor -o changeprofile /tmp/ccT6GE6k.o: In function `main':
    /home/ubuntu/bzr/apparmor/tests/regression/apparmor/changeprofile.c:43: undefined reference to `do_open'
    collect2: error: ld returned 1 exit status
    <builtin>: recipe for target 'changeprofile' failed

This patch converts the do_open function declaration to be static
inline, which apparently keeps gcc-5 from getting confused.

Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: John Johansen <john.johansen@canonical.com>
2015-03-03 23:32:26 -08:00
Alain BENEDETTI
735ef5d32b utils/aa-status: don't crash when non-ASCII mountpoints are in use
Merge from trunk revision 2892

aa-status was crashing when parsing through /proc/mounts looking
to see if and where the securityfs synthetic file system is mounted
if there was a mount point that contained characters outside of the
charset in use in the environment of aa-status. This patch fixes the
issue by converting the read of /proc/mounts into a binary read and
then uses decode on the elements.

Patch by Alain BENEDETTI.
Acked-by: Steve Beattie <steve@nxnw.org>
2015-03-03 22:25:32 -08:00
Tyler Hicks
9428498d90 parser: Fix error checking of file opening in features_dir_cb()
The error path was being taken when openat() return 0 but openat()
returns -1 on error.

Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
2015-03-03 20:28:22 -06:00
Christian Boltz
3ea1e541c7 Add test for disconnected path
As a follow-up to the logparser.py change that converts disconnected
path events to an error, add a testcase to test-logparser.py.


Acked-by: Steve Beattie <steve@nxnw.org> for both trunk and 2.9.
2015-03-03 22:18:24 +01:00
Philip Withnall
29b0634f34 parser: net_find_af_name: do not assume that address families are consecutive,
remove unused net_find_af_val function, and network_families array
Merge from trunk commit 2888.

net_find_af_name: do not assume that address families are consecutive

The network_families array is automatically built from AF_NAMES, which is
extracted from the defines in <bits/socket.h>. The code assumes that
network_families is indexed by the AF defines. However, since the
defines are sparse, and the gaps in the array are not packed with
zeroes, the array is shorter than expected, and the indexing is wrong.

When this function was written, the network families that were
covered might well have been consecutive, but this is no longer true:
there's a gap between AF_LLC (26) and AF_CAN (29).

This assumption caused a crash in our testing while parsing the rule
"network raw".

Remove unused net_find_af_val function, and network_families array

Like net_find_af_name, this assumed that AF_* values were consecutive.

Patches from Philip Withnall and Simon McVittie.
2015-03-03 12:04:13 -08:00
Christian Boltz
586222c94e move strip_quotes() from aa.py to regex.py
The upcoming function parse_profile_start() (which is a wrapper around
the updated RE_PROFILE_START, and will live in regex.py) needs
strip_profile(), but importing it from aa.py fails with an import loop.
Therefore this patch moves strip_quotes() from aa.py to regex.py and
re-imports it into aa.py.

As a bonus, the patch also adds some tests for strip_quotes() ;-)


Also add TestStripQuotes to the test_suite list because it won't run
otherwise.

Acked-by: Steve Beattie <steve@nxnw.org> for both trunk and 2.9
2015-03-03 20:18:30 +01:00
Christian Boltz
232b51504c let logparser.py parse_event() change disconnected path events to 'ERROR'
This means that aa-logprof will ignore the event instead of crashing with
    AppArmorException: 'Unexpected rank input: var/run/nscd/passwd'

Note that I made the check as specific as possible to be sure it doesn't
hide other events.

References: https://bugzilla.opensuse.org/show_bug.cgi?id=918787



Acked-by: Steve Beattie <steve@nxnw.org> for 2.9



(This is a backport of trunk r2877, but without the test-capability.py
adjustment because that file doesn't exist in 2.9)
2015-03-03 12:34:47 +01:00
Christian Boltz
df099620dd aa.py: split off parse_profile_start() from parse_profile_data() and add tests
Move the code for parsing the profile start ("/foo {") from aa.py
parse_profile_data() to a separate function parse_profile_start().

Most of the changes are just moving around code, with some small
exceptions:
- instead of handing over profile_data to parse_profile_start() to
  modify it, it sets two variables (pps_set_profile and
  pps_set_hat_external) as part of its return value, which are then
  used in parse_profile_data() to set the flags in profile_data.
- existing_profiles[profile] = file   is executed later, which means
  it used the strip_quotes() version of profile now
- whitespace / tab level changes

The patch also adds some tests for the parse_profile_start() function.



Acked-by: Steve Beattie <steve@nxnw.org> for 2.9 as well.
2015-03-02 21:46:45 +01:00
Christian Boltz
22d647ecb1 Add some tests for aa.py get_profile_flags().
Also adds a check to get_profile_flags() to catch an invalid syntax:
    /foo (  ) {
was accepted by get_profile_flags, while
    /foo () {
failed.

When testing with the parser, both result in a syntax error, therefore
the patch makes sure it also fails in get_profile_flags().


Acked-by: Steve Beattie <steve@nxnw.org> for trunk and 2.9
2015-03-02 19:38:34 +01:00
Tyler Hicks
07b0886796 parser: Fix "PDEBUG" redefined warning
Only present when building with DEBUG=1.

Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
2015-03-02 09:59:17 -06:00
Tyler Hicks
9da31bf281 parser: Fix -Wformat-extra-args warning
Only present when building with DEBUG=1.

Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
Acked-by: Steve Beattie <steve@nxnw.org>
2015-03-02 09:59:14 -06:00
Tyler Hicks
c5ff27a91b parser: Send PDEBUG() to stderr
PDEBUG() and PERROR() should both go to stderr.

Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
2015-03-02 09:59:11 -06:00
Tyler Hicks
cf4afcb860 parser: Fix return value of dirat_for_each()
Seth pointed out that dirat_for_each() didn't correctly handle the
return value from readdir_r(). On error, it directly returns a positive
errno value. This would have resulted in that positive errno value being
returned, with an undefined errno value set, from dirat_for_each().
However, the dirat_for_each() documentation states that -1 is returned,
with errno set, on error.

This patch results in readdir_r()'s return value being handled
appropriately. In addition, it ensures that 0 is always returned on
success.

Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Reported-by: Seth Arnold <seth.arnold@canonical.com>
Acked-by: Steve Beattie <steve@nxnw.org>
2015-03-02 09:54:57 -06:00
Cameron Norman
75a186fa9f profiles: add geary email client to ubuntu-email abstraction
Merge from trunk revision 2876

Merge from Cameron Norman <camerontnorman@gmail.com>
Acked-by: Steve Beattie <steve@nxnw.org>
2015-02-27 23:28:05 -08:00
Felix Geyer
05bef291d7 profiles: allow aspell access to /usr/share/aspell/
Merge from trunk revision 2875

From: Felix Geyer <debfx@ubuntu.com>

At least Debian/Ubuntu started shipping some aspell files in
/usr/share/aspell/.
For example:
/usr/share/aspell/iso-8859-1.cmap
/usr/share/aspell/iso-8859-1.cset

The abstraction should allow read access to these files.

Acked-by: Steve Beattie <steve@nxnw.org>
2015-02-27 23:16:32 -08:00
Steve Beattie
76f71f7d84 profiles: add support for /etc/pki/ in ssl certs abstraction
Merge from trunk revision 2874.

These appear to be related to the update-ca-trust tool.

Thanks to Gregor Dschung <dschung@cs.uni-kl.de>
2015-02-27 22:57:41 -08:00
Christian Boltz
34f2c1c6ea cleanup aa-disable handling in tools.py
Remove the check if the disable directory exists. If it's really
missing, it will be auto-created by create_symlink(), so we
automagically fix things instead of annoying the user with an
error message ;-)

Acked-by: Steve Beattie <steve@nxnw.org> for both trunk and 2.9.
2015-02-28 00:25:45 +01:00
Christian Boltz
67dae2f1cf Fix the minitools (aa-audit, aa-complain, aa-enforce, aa-autodep)
to work with multiple profiles at once.

References: https://bugs.launchpad.net/apparmor/+bug/1378095

Acked-by: Steve Beattie <steve@nxnw.org> for trunk and 2.9.
2015-02-27 14:21:05 +01:00
Seth Arnold
bbaaa00249 parser: fix dbus.cc issue when building with gcc 5
Merge from trunk revision 2868.

This should fix a gcc 5 build failure (untested) with os << .. << os

This build failure was discovered by doko's archive rebuild:
http://people.ubuntuwire.org/~wgrant/rebuild-ftbfs-test/test-rebuild-20150202-gcc5-vivid.html

Acked-by: Steve Beattie <steve@nxnw.org>
2015-02-26 16:18:15 -08:00
Steve Beattie
9ed8789918 parser: fix more gcc 5 compilation problems
Merge from trunk revision 2871

Don't pass an ostream reference into another ostream via <<.

Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
2015-02-26 15:20:19 -08:00
Christian Boltz
f45628d749 delete traces of program-chunks directory from apparmor.d(5)
Acked-by: Tyler Hicks <tyhicks@canonical.com>
2015-02-26 18:45:41 +01:00
Christian Boltz
602decfbfc Update is_skippable_file() to match all extensions that are listed in
libapparmor _aa_is_blacklisted() - some extensions were missing in the
python code.

Also make the code more readable and add some testcases.

Notes:
- the original code additionally ignored *.swp. I didn't include that -
  *.swp looks like vim swap files which are also dot files
- the python code ignores README files, but the C code doesn't
  (do we need to add README in the C code?)


Acked-by: Kshitij Gupta <kgupta8592@gmail.com> for 2.9 and trunk
Acked-by: Steve Beattie <steve@nxnw.org>
2015-02-04 13:18:47 +01:00
Christian Boltz
9aa1efd744 Fix aa-unconfined to work with profile names that don't start with / or null
Reported by u on the debian pkg-apparmor-team ML.


Acked-by: John Johansen <john.johansen@canonical.com>
2015-02-02 20:53:29 +01:00
Jamie Strandboge
c51a68eaaf Description: Allow writes to /{,var}/run/systemd/journal/dev-log, the systemd
journal socket. On Debian and Ubuntu systems, /dev/log is a symlink to
 /run/systemd/journal/dev-log, so this access is now required in the base
 abstraction to maintain current behavior.
Bug: https://bugs.launchpad.net/apparmor/+bug/1413232

Acked-By: Jamie Strandboge <jamie@canonical.com>
Acked-by: Steve Beattie <steve@nxnw.org>
2015-01-21 13:37:49 -06:00
Christian Boltz
49b739b184 Add some tests for logparser.py based on the log lines from
https://bugs.launchpad.net/apparmor/+bug/1399027

Also move some existing tests from aa_test.py to test-logparser.py and
adds checks for RE_LOG_v2_6_audit and RE_LOG_v2_6_syslog to them.


Acked-by: Steve Beattie <steve@nxnw.org> for trunk and 2.9
2015-01-18 14:57:10 +01:00
Christian Boltz
53d071adf5 update logparser.py to support the changed syslog format by adding
(audit:\s+)?   to RE_LOG_v2_6_syslog

References: https://bugs.launchpad.net/apparmor/+bug/1399027


Acked-by: Seth Arnold <seth.arnold@canonical.com> (for trunk)

Acked-by: Steve Beattie <steve@nxnw.org> for 2.9 as well
2015-01-17 14:35:38 +01:00
Christian Boltz
70cda06789 Fix the dnsmasq profile to allow executing bash to run the --dhcp-script
argument. Also fixed /usr/lib -> /usr/{lib,lib64} to get libvirt
leasehelper script to run even on x86_64.

References: https://bugzilla.opensuse.org/show_bug.cgi?id=911001

Patch by "Cédric Bosdonnat" <cbosdonnat@suse.com>

Note: the original patch used {lib,lib64} - I changed it to lib{,64} to
match the style we typically use.

Acked-by: John Johansen <john.johansen@canonical.com>

(backport of trunk r2841)
2014-12-22 17:57:40 +01:00
Christian Boltz
e8ffc1c4e8 update and cleanup usr.sbin.dovecot profile
Add #include <abstractions/dovecot-common> to the usr.sbin.dovecot
profile. Effectively this adds "deny capability block_suspend," which
is the only missing part from
https://bugs.launchpad.net/apparmor/+bug/1296667/

Also remove "capability setgid," (covered by
abstractions/dovecot-common) and "@{PROC}/filesystems r," (part of
abstractions/base).

Acked-by: John Johansen <john.johansen@canonical.com>

(backport of trunk r2840)
2014-12-22 17:51:02 +01:00
Christian Boltz
09c93be47c Add some missing /run/dovecot/* to usr.lib.dovecot.imap{, -login}
Add the needed permissions as reported in
https://bugs.launchpad.net/apparmor/+bug/1296667/ comment #1
to the usr.lib.dovecot.imap and imap-login profiles.

Acked-by: John Johansen <john.johansen@canonical.com>

(backport of trunk r2839)
2014-12-22 17:43:54 +01:00
Christian Boltz
ac8d886645 update the mysqld profile in the extras directory to
something that works on my servers ;-)

Acked-by: John Johansen <john.johansen@canonical.com>

(backport of trunk r2838)
2014-12-22 17:39:29 +01:00
Christian Boltz
ec1dda24d0 fix network rule description in apparmor.d.pod
(backport from trunk r2837)

Acked-by: John Johansen <john.johansen@canonical.com> (for trunk)

Acked-by: Steve Beattie <steve@nxnw.org> (for 2.9)
2014-12-19 13:57:12 +01:00
Steve Beattie
e7e9053598 Update version in preparation for 2.9.2 development. 2014-12-16 13:37:58 -08:00
1386 changed files with 15683 additions and 70336 deletions

View File

@@ -2,7 +2,6 @@ apparmor-*
parser/po/*.mo
parser/af_names.h
parser/cap_names.h
parser/tst_lib
parser/tst_misc
parser/tst_regex
parser/tst_symtab
@@ -19,14 +18,13 @@ parser/*.8
parser/*.7.html
parser/*.5.html
parser/*.8.html
parser/common
parser/apparmor_parser
parser/libapparmor_re/parse.cc
parser/libapparmor_re/regexp.cc
parser/techdoc.aux
parser/techdoc.log
parser/techdoc.pdf
parser/techdoc.toc
profiles/apparmor.d/local/*.*
libraries/libapparmor/Makefile
libraries/libapparmor/Makefile.in
libraries/libapparmor/aclocal.m4
@@ -43,32 +41,20 @@ libraries/libapparmor/install-sh
libraries/libapparmor/libtool
libraries/libapparmor/ltmain.sh
libraries/libapparmor/missing
libraries/libapparmor/test-driver
libraries/libapparmor/ylwrap
libraries/libapparmor/doc/Makefile
libraries/libapparmor/doc/Makefile.in
libraries/libapparmor/doc/*.2
libraries/libapparmor/doc/aa_*.3
libraries/libapparmor/include/Makefile
libraries/libapparmor/include/Makefile.in
libraries/libapparmor/include/sys/Makefile
libraries/libapparmor/include/sys/Makefile.in
libraries/libapparmor/src/.deps
libraries/libapparmor/src/.libs
libraries/libapparmor/src/Makefile
libraries/libapparmor/src/Makefile.in
libraries/libapparmor/src/af_protos.h
libraries/libapparmor/src/change_hat.lo
libraries/libapparmor/src/features.lo
libraries/libapparmor/src/grammar.lo
libraries/libapparmor/src/kernel.lo
libraries/libapparmor/src/kernel_interface.lo
libraries/libapparmor/src/libaalogparse.lo
libraries/libapparmor/src/libimmunix_warning.lo
libraries/libapparmor/src/policy_cache.lo
libraries/libapparmor/src/private.lo
libraries/libapparmor/src/scanner.lo
libraries/libapparmor/src/libapparmor.pc
libraries/libapparmor/src/libapparmor.la
libraries/libapparmor/src/libimmunix.la
libraries/libapparmor/src/grammar.c
@@ -84,20 +70,12 @@ libraries/libapparmor/swig/perl/Makefile
libraries/libapparmor/swig/perl/Makefile.PL
libraries/libapparmor/swig/perl/Makefile.in
libraries/libapparmor/swig/perl/Makefile.perl
libraries/libapparmor/swig/perl/Makefile.perle
libraries/libapparmor/swig/perl/MYMETA.json
libraries/libapparmor/swig/perl/MYMETA.yml
libraries/libapparmor/swig/perl/blib
libraries/libapparmor/swig/perl/libapparmor_wrap.c
libraries/libapparmor/swig/perl/pm_to_blib
libraries/libapparmor/swig/python/LibAppArmor.py
libraries/libapparmor/swig/python/build/
libraries/libapparmor/swig/python/libapparmor_wrap.c
libraries/libapparmor/swig/python/Makefile
libraries/libapparmor/swig/python/Makefile.in
libraries/libapparmor/swig/python/setup.py
libraries/libapparmor/swig/python/test/Makefile
libraries/libapparmor/swig/python/test/Makefile.in
libraries/libapparmor/swig/ruby/Makefile
libraries/libapparmor/swig/ruby/Makefile.in
libraries/libapparmor/testsuite/.deps
@@ -116,6 +94,10 @@ libraries/libapparmor/testsuite/libaalogparse.test/Makefile
libraries/libapparmor/testsuite/libaalogparse.test/Makefile.in
libraries/libapparmor/testsuite/test_multi/out
changehat/mod_apparmor/.libs
changehat/mod_apparmor/common
changehat/pam_apparmor/common
changehat/tomcat_apparmor/common
utils/common
utils/*.8
utils/*.8.html
utils/*.5
@@ -183,5 +165,4 @@ tests/regression/apparmor/unix_fd_server
tests/regression/apparmor/unlink
tests/regression/apparmor/xattrs
tests/regression/apparmor/coredump
**/__pycache__/
*.orig
./utils/apparmor/__pycache__

View File

@@ -1,30 +1,24 @@
#
#
.PHONY: all
all:
@echo "*** See README for information how to build AppArmor ***"
exit 1
OVERRIDE_TARBALL=yes
COMMONDIR=common
include ${COMMONDIR}/Make.rules
include common/Make.rules
DIRS=libraries/libapparmor \
binutils \
parser \
DIRS=parser \
profiles \
utils \
libraries/libapparmor \
changehat/mod_apparmor \
changehat/pam_apparmor \
profiles \
tests
#REPO_URL?=lp:apparmor
# --per-file-timestamps is failing over SSH, https://bugs.launchpad.net/bzr/+bug/1257078
REPO_URL?=https://code.launchpad.net/~apparmor-dev/apparmor/master
REPO_URL?=https://code.launchpad.net/~apparmor-dev/apparmor/2.9
# alternate possibilities to export from
#REPO_URL=.
#REPO_URL="bzr+ssh://bazaar.launchpad.net/~sbeattie/+junk/apparmor-dev/"
COVERITY_DIR=cov-int
RELEASE_DIR=apparmor-${VERSION}
__SETUP_DIR?=.
@@ -39,25 +33,19 @@ TAR_EXCLUSIONS=
.PHONY: tarball
tarball: clean
REPO_VERSION=`$(value REPO_VERSION_CMD)` && \
make export_dir __EXPORT_DIR=${RELEASE_DIR} __REPO_VERSION=$${REPO_VERSION} && \
make setup __SETUP_DIR=${RELEASE_DIR} && \
REPO_VERSION=`$(value REPO_VERSION_CMD)` ; \
make export_dir __EXPORT_DIR=${RELEASE_DIR} __REPO_VERSION=$${REPO_VERSION} ; \
make setup __SETUP_DIR=${RELEASE_DIR} ; \
tar ${TAR_EXCLUSIONS} -cvzf ${RELEASE_DIR}.tar.gz ${RELEASE_DIR}
.PHONY: snapshot
snapshot: clean
$(eval REPO_VERSION:=$(shell $(value REPO_VERSION_CMD)))
$(eval SNAPSHOT_NAME=apparmor-$(VERSION)~$(REPO_VERSION))
make export_dir __EXPORT_DIR=${SNAPSHOT_NAME} __REPO_VERSION=${REPO_VERSION} && \
make setup __SETUP_DIR=${SNAPSHOT_NAME} && \
tar ${TAR_EXCLUSIONS} -cvzf ${SNAPSHOT_NAME}.tar.gz ${SNAPSHOT_NAME}
REPO_VERSION=`$(value REPO_VERSION_CMD)` ; \
SNAPSHOT_DIR=apparmor-${VERSION}~$${REPO_VERSION} ;\
make export_dir __EXPORT_DIR=$${SNAPSHOT_DIR} __REPO_VERSION=$${REPO_VERSION} ; \
make setup __SETUP_DIR=$${SNAPSHOT_DIR} ; \
tar ${TAR_EXCLUSIONS} -cvzf $${SNAPSHOT_DIR}.tar.gz $${SNAPSHOT_DIR} ;
.PHONY: coverity
coverity: snapshot
cd $(SNAPSHOT_NAME)/libraries/libapparmor && ./configure --with-python
$(foreach dir, $(filter-out utils profiles tests, $(DIRS)), \
cov-build --dir $(COVERITY_DIR) -- make -C $(SNAPSHOT_NAME)/$(dir);)
tar -cvzf $(SNAPSHOT_NAME)-$(COVERITY_DIR).tar.gz $(COVERITY_DIR)
.PHONY: export_dir
export_dir:
@@ -67,7 +55,7 @@ export_dir:
.PHONY: clean
clean:
-rm -rf ${RELEASE_DIR} ./apparmor-${VERSION}~* ${COVERITY_DIR}
-rm -rf ${RELEASE_DIR} ./apparmor-${VERSION}~*
for dir in $(DIRS); do \
make -C $$dir clean; \
done
@@ -75,12 +63,6 @@ clean:
.PHONY: setup
setup:
cd $(__SETUP_DIR)/libraries/libapparmor && ./autogen.sh
# parser has an extra doc to build
make -C $(__SETUP_DIR)/parser extra_docs
# libraries/libapparmor needs configure to have run before
# building docs
$(foreach dir, $(filter-out libraries/libapparmor tests, $(DIRS)), \
make -C $(__SETUP_DIR)/$(dir) docs;)
.PHONY: tag
tag:

34
README
View File

@@ -27,7 +27,6 @@ Source Layout
AppArmor consists of several different parts:
binutils/ source for basic utilities written in compiled languages
changehat/ source for using changehat with Apache, PAM and Tomcat
common/ common makefile rules
desktop/ empty
@@ -72,13 +71,6 @@ $ make install
generate Ruby bindings to libapparmor.]
Binary Utilities:
$ cd binutils
$ make
$ make check
$ make install
Utilities:
$ cd utils
$ make
@@ -112,7 +104,7 @@ $ make check # depends on the parser having been built first
$ make install
[Note that for the parser, binutils, and utils, if you only wish to build/use
[Note that for the parser and the utils, if you only with to build/use
some of the locale languages, you can override the default by passing
the LANGS arguments to make; e.g. make all install "LANGS=en_US fr".]
@@ -196,27 +188,6 @@ $ ./stress.sh
(see stress.sh -h for options)
Coverity Support
----------------
Coverity scans are available to AppArmor developers at
https://scan.coverity.com/projects/apparmor.
In order to submit a Coverity build for analysis, the cov-build binary
must be discoverable from your PATH. See the "To Setup" section of
https://scan.coverity.com/download?tab=cxx to obtain a pre-built copy of
cov-build.
To generate a compressed tarball of an intermediate Coverity directory:
$ make coverity
The compressed tarball is written to
apparmor-<SNAPSHOT_VERSION>-cov-int.tar.gz, where <SNAPSHOT_VERSION>
is something like 2.10.90~3328, and must be uploaded to
https://scan.coverity.com/projects/apparmor/builds/new for analysis. You must
include the snapshot version in Coverity's project build submission form, in
the "Project Version" field, so that it is quickly obvious to all AppArmor
developers what snapshot of the AppArmor repository was used for the analysis.
-----------------------------------------------
Building and Installing AppArmor Kernel Patches
-----------------------------------------------
@@ -232,8 +203,7 @@ The AppArmor userspace utilities are written with some assumptions about
installed and available versions of other tools. This is a (possibly
incomplete) list of known version dependencies:
The Python utilities require a minimum of Python 2.7 (deprecated) or Python 3.3.
Python 3.x is recommended. Python 2.x support is deprecated since AppArmor 2.11.
The Python utilities require a minimum of Python 2.7 or Python 3.3.
Some utilities (aa-exec, aa-notify and aa-decode) require Perl 5.10.1 or newer.

View File

@@ -1,157 +0,0 @@
# ----------------------------------------------------------------------
# Copyright (c) 2015
# Canonical Ltd. (All rights reserved)
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of version 2 of the GNU General Public
# License published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# ----------------------------------------------------------------------
NAME=aa-binutils
all:
COMMONDIR=../common/
include $(COMMONDIR)/Make.rules
DESTDIR=/
BINDIR=${DESTDIR}/usr/bin
LOCALEDIR=/usr/share/locale
MANPAGES=aa-enabled.1 aa-exec.1
WARNINGS = -Wall
EXTRA_WARNINGS = -Wsign-compare -Wmissing-field-initializers -Wformat-security -Wunused-parameter
CPP_WARNINGS =
ifndef CFLAGS
CFLAGS = -g -O2 -pipe
ifdef DEBUG
CFLAGS += -pg -D DEBUG
endif
ifdef COVERAGE
CFLAGS = -g -pg -fprofile-arcs -ftest-coverage
endif
endif #CFLAGS
EXTRA_CFLAGS = ${CFLAGS} ${CPPFLAGS} ${EXTRA_CXXFLAGS} ${CPP_WARNINGS}
#INCLUDEDIR = /usr/src/linux/include
INCLUDEDIR =
ifdef INCLUDEDIR
CFLAGS += -I$(INCLUDEDIR)
endif
# Internationalization support. Define a package and a LOCALEDIR
EXTRA_CFLAGS+=-DPACKAGE=\"${NAME}\" -DLOCALEDIR=\"${LOCALEDIR}\"
SRCS = aa_enabled.c
HDRS =
TOOLS = aa-enabled aa-exec
AALIB = -Wl,-Bstatic -lapparmor -Wl,-Bdynamic -lpthread
ifdef USE_SYSTEM
# Using the system libapparmor so Makefile dependencies can't be used
LIBAPPARMOR_A =
INCLUDE_APPARMOR =
APPARMOR_H =
LIBAPPARMOR_LDFLAGS =
else
LIBAPPARMOR_SRC = ../libraries/libapparmor/
LOCAL_LIBAPPARMOR_INCLUDE = $(LIBAPPARMOR_SRC)/include
LOCAL_LIBAPPARMOR_LDPATH = $(LIBAPPARMOR_SRC)/src/.libs
LIBAPPARMOR_A = $(LOCAL_LIBAPPARMOR_LDPATH)/libapparmor.a
INCLUDE_APPARMOR = -I$(LOCAL_LIBAPPARMOR_INCLUDE)
APPARMOR_H = $(LOCAL_LIBAPPARMOR_INCLUDE)/sys/apparmor.h
LIBAPPARMOR_LDFLAGS = -L$(LOCAL_LIBAPPARMOR_LDPATH)
endif
EXTRA_CFLAGS += $(INCLUDE_APPARMOR)
LDFLAGS += $(LIBAPPARMOR_LDFLAGS)
ifdef V
VERBOSE = 1
endif
ifndef VERBOSE
VERBOSE = 0
endif
ifeq ($(VERBOSE),1)
BUILD_OUTPUT =
Q =
else
BUILD_OUTPUT = > /dev/null 2>&1
Q = @
endif
export Q VERBOSE BUILD_OUTPUT
po/%.pot: %.c
$(MAKE) -C po $(@F) NAME=$* SOURCES=$*.c
# targets arranged this way so that people who don't want full docs can
# pick specific targets they want.
arch: $(TOOLS)
manpages: $(MANPAGES)
docs: manpages
indep: docs
$(Q)$(MAKE) -C po all
all: arch indep
.PHONY: coverage
coverage:
$(MAKE) clean $(TOOLS) COVERAGE=1
ifndef USE_SYSTEM
$(LIBAPPARMOR_A):
@if [ ! -f $@ ]; then \
echo "error: $@ is missing. Pick one of these possible solutions:" 1>&2; \
echo " 1) Build against the in-tree libapparmor by building it first and then trying again. See the top-level README for help." 1>&2; \
echo " 2) Build against the system libapparmor by adding USE_SYSTEM=1 to your make command." 1>&2;\
return 1; \
fi
endif
aa-enabled: aa_enabled.c $(LIBAPPARMOR_A)
$(CC) $(LDFLAGS) $(EXTRA_CFLAGS) -o $@ $< $(LIBS) $(AALIB)
aa-exec: aa_exec.c $(LIBAPPARMOR_A)
$(CC) $(LDFLAGS) $(EXTRA_CFLAGS) -o $@ $< $(LIBS) $(AALIB)
.SILENT: check
.PHONY: check
check: check_pod_files tests
.SILENT: tests
tests: $(TOOLS) $(TESTS)
echo "no tests atm"
.PHONY: install
install: install-indep install-arch
.PHONY: install-arch
install-arch: arch
install -m 755 -d ${BINDIR}
install -m 755 ${TOOLS} ${BINDIR}
.PHONY: install-indep
install-indep: indep
$(MAKE) -C po install NAME=${NAME} DESTDIR=${DESTDIR}
$(MAKE) install_manpages DESTDIR=${DESTDIR}
ifndef VERBOSE
.SILENT: clean
endif
.PHONY: clean
clean: pod_clean
rm -f core core.* *.o *.s *.a *~ *.gcda *.gcno
rm -f gmon.out
rm -f $(TOOLS) $(TESTS)
$(MAKE) -s -C po clean

View File

@@ -1,94 +0,0 @@
# This publication is intellectual property of Canonical Ltd. Its contents
# can be duplicated, either in part or in whole, provided that a copyright
# label is visibly located on each copy.
#
# All information found in this book has been compiled with utmost
# attention to detail. However, this does not guarantee complete accuracy.
# Neither Canonical Ltd, the authors, nor the translators shall be held
# liable for possible errors or the consequences thereof.
#
# Many of the software and hardware descriptions cited in this book
# are registered trademarks. All trade names are subject to copyright
# restrictions and may be registered trade marks. Canonical Ltd
# essentially adheres to the manufacturer's spelling.
#
# Names of products and trademarks appearing in this book (with or without
# specific notation) are likewise subject to trademark and trade protection
# laws and may thus fall under copyright restrictions.
#
=pod
=head1 NAME
aa-enabled - test whether AppArmor is enabled
=head1 SYNOPSIS
B<aa-enabled> [options]
=head1 DESCRIPTION
B<aa-enabled> is used to determine if AppArmor is enabled.
=head1 OPTIONS
B<aa-enabled> accepts the following arguments:
=over 4
=item -h, --help
Display a brief usage guide.
=item -q, --quiet
Do not output anything to stdout. This option is intended to be used by
scripts that simply want to use the exit code to determine if AppArmor is
enabled.
=back
=head1 EXIT STATUS
Upon exiting, B<aa-enabled> will set its exit status to the following values:
=over 4
=item B<0>
if AppArmor is enabled.
=item B<1>
if AppArmor is not enabled/loaded.
=item B<2>
intentionally not used as an B<aa-enabled> exit status.
=item B<3>
if the AppArmor control files aren't available under /sys/kernel/security/.
=item B<4>
if B<aa-enabled> doesn't have enough privileges to read the apparmor control files.
=item B<64>
if any unexpected error or condition is encountered.
=back
=head1 BUGS
If you find any bugs, please report them at
L<https://bugs.launchpad.net/apparmor/+filebug>.
=head1 SEE ALSO
apparmor(7), apparmor.d(5), aa_is_enabled(2), and L<http://wiki.apparmor.net>.
=cut

View File

@@ -1,92 +0,0 @@
/*
* Copyright (C) 2015 Canonical Ltd.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
* License published by the Free Software Foundation.
*/
#include <errno.h>
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libintl.h>
#define _(s) gettext(s)
#include <sys/apparmor.h>
void print_help(const char *command)
{
printf(_("%s: [options]\n"
" options:\n"
" -q | --quiet Don't print out any messages\n"
" -h | --help Print help\n"),
command);
exit(1);
}
/* Exit statuses and meanings are documented in the aa-enabled.pod file */
static void exit_with_error(int saved_errno, int quiet)
{
int err;
switch(saved_errno) {
case ENOSYS:
if (!quiet)
printf(_("No - not available on this system.\n"));
exit(1);
case ECANCELED:
if (!quiet)
printf(_("No - disabled at boot.\n"));
exit(1);
case ENOENT:
if (!quiet)
printf(_("Maybe - policy interface not available.\n"));
exit(3);
case EPERM:
case EACCES:
if (!quiet)
printf(_("Maybe - insufficient permissions to determine availability.\n"));
exit(4);
}
if (!quiet)
printf(_("Error - %s\n"), strerror(saved_errno));
exit(64);
}
int main(int argc, char **argv)
{
int enabled;
int quiet = 0;
setlocale(LC_MESSAGES, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
if (argc > 2) {
printf(_("unknown or incompatible options\n"));
print_help(argv[0]);
} else if (argc == 2) {
if (strcmp(argv[1], "--quiet") == 0 ||
strcmp(argv[1], "-q") == 0) {
quiet = 1;
} else if (strcmp(argv[1], "--help") == 0 ||
strcmp(argv[1], "-h") == 0) {
print_help(argv[0]);
} else {
printf(_("unknown option '%s'\n"), argv[1]);
print_help(argv[0]);
}
}
enabled = aa_is_enabled();
if (!enabled)
exit_with_error(errno, quiet);
if (!quiet)
printf(_("Yes\n"));
exit(0);
}

View File

@@ -1,218 +0,0 @@
/*
* Copyright (c) 2015
* Canonical, Ltd. (All rights reserved)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
* License published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact Novell, Inc. or Canonical
* Ltd.
*/
#include <errno.h>
#include <getopt.h>
#include <libintl.h>
#include <limits.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <sys/apparmor.h>
#include <unistd.h>
#define _(s) gettext(s)
static const char *opt_profile = NULL;
static const char *opt_namespace = NULL;
static bool opt_debug = false;
static bool opt_immediate = false;
static bool opt_verbose = false;
static void usage(const char *name, bool error)
{
FILE *stream = stdout;
int status = EXIT_SUCCESS;
if (error) {
stream = stderr;
status = EXIT_FAILURE;
}
fprintf(stream,
_("USAGE: %s [OPTIONS] <prog> <args>\n"
"\n"
"Confine <prog> with the specified PROFILE.\n"
"\n"
"OPTIONS:\n"
" -p PROFILE, --profile=PROFILE PROFILE to confine <prog> with\n"
" -n NAMESPACE, --namespace=NAMESPACE NAMESPACE to confine <prog> in\n"
" -d, --debug show messages with debugging information\n"
" -i, --immediate change profile immediately instead of at exec\n"
" -v, --verbose show messages with stats\n"
" -h, --help display this help\n"
"\n"), name);
exit(status);
}
#define error(fmt, args...) _error(_("aa-exec: ERROR: " fmt "\n"), ## args)
static void _error(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
exit(EXIT_FAILURE);
}
#define debug(fmt, args...) _debug(_("aa-exec: DEBUG: " fmt "\n"), ## args)
static void _debug(const char *fmt, ...)
{
va_list args;
if (!opt_debug)
return;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
}
#define verbose(fmt, args...) _verbose(_(fmt "\n"), ## args)
static void _verbose(const char *fmt, ...)
{
va_list args;
if (!opt_verbose)
return;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
}
static void verbose_print_argv(char **argv)
{
if (!opt_verbose)
return;
fprintf(stderr, _("exec"));
for (; *argv; argv++)
fprintf(stderr, " %s", *argv);
fprintf(stderr, "\n");
}
static char **parse_args(int argc, char **argv)
{
int opt;
struct option long_opts[] = {
{"debug", no_argument, 0, 'd'},
{"help", no_argument, 0, 'h'},
{"profile", required_argument, 0, 'p'},
{"namespace", required_argument, 0, 'n'},
{"immediate", no_argument, 0, 'i'},
{"verbose", no_argument, 0, 'v'},
};
while ((opt = getopt_long(argc, argv, "+dhp:n:iv", long_opts, NULL)) != -1) {
switch (opt) {
case 'd':
opt_debug = true;
break;
case 'h':
usage(argv[0], false);
break;
case 'p':
opt_profile = optarg;
break;
case 'n':
opt_namespace = optarg;
break;
case 'i':
opt_immediate = true;
break;
case 'v':
opt_verbose = true;
break;
default:
usage(argv[0], true);
break;
}
}
if (optind >= argc)
usage(argv[0], true);
return argv + optind;
}
static void build_name(char *name, size_t name_len,
const char *namespace, const char *profile)
{
size_t required_len = 1; /* reserve 1 byte for NUL-terminator */
if (namespace)
required_len += 1 + strlen(namespace) + 3; /* :<NAMESPACE>:// */
if (profile)
required_len += strlen(profile);
if (required_len > name_len)
error("name too long (%zu > %zu)", required_len, name_len);
name[0] = '\0';
if (namespace) {
strcat(name, ":");
strcat(name, namespace);
strcat(name, "://");
}
if (profile)
strcat(name, profile);
}
int main(int argc, char **argv)
{
char name[PATH_MAX];
int rc = 0;
argv = parse_args(argc, argv);
if (opt_namespace || opt_profile)
build_name(name, sizeof(name), opt_namespace, opt_profile);
else
goto exec;
if (opt_immediate) {
verbose("aa_change_profile(\"%s\")", name);
rc = aa_change_profile(name);
debug("%d = aa_change_profile(\"%s\")", rc, name);
} else {
verbose("aa_change_onexec(\"%s\")", name);
rc = aa_change_onexec(name);
debug("%d = aa_change_onexec(\"%s\")", rc, name);
}
if (rc) {
if (errno == ENOENT || errno == EACCES) {
error("%s '%s' does not exist\n",
opt_profile ? "profile" : "namespace", name);
} else if (errno == EINVAL) {
error("AppArmor interface not available");
} else {
error("%m");
}
}
exec:
verbose_print_argv(argv);
execvp(argv[0], argv);
error("Failed to execute \"%s\": %m", argv[0]);
}

View File

@@ -1,19 +0,0 @@
# ----------------------------------------------------------------------
# Copyright (C) 2015 Canonical Ltd.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of version 2 of the GNU General Public
# License published by the Free Software Foundation.
# ----------------------------------------------------------------------
all:
# As translations get added, they will automatically be included, unless
# the lang is explicitly added to DISABLED_LANGS; e.g. DISABLED_LANGS=en es
DISABLED_LANGS=
COMMONDIR=../../common
include $(COMMONDIR)/Make-po.rules
XGETTEXT_ARGS+=--language=C --keyword=_ $(shell if [ -f ${NAME}.pot ] ; then echo -n -j ; fi)

View File

@@ -1,66 +0,0 @@
# Copyright (C) 2015 Canonical Ltd
# This file is distributed under the same license as the AppArmor package.
# John Johansen <john.johansen@canonical.com>, 2015.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: apparmor@lists.ubuntu.com\n"
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
#: ../aa_enabled.c:26
#, c-format
msgid ""
"%s: [options]\n"
" options:\n"
" -q | --quiet Don't print out any messages\n"
" -h | --help Print help\n"
msgstr ""
#: ../aa_enabled.c:45
#, c-format
msgid "unknown or incompatible options\n"
msgstr ""
#: ../aa_enabled.c:55
#, c-format
msgid "unknown option '%s'\n"
msgstr ""
#: ../aa_enabled.c:64
#, c-format
msgid "Yes\n"
msgstr ""
#: ../aa_enabled.c:71
#, c-format
msgid "No - not available on this system.\n"
msgstr ""
#: ../aa_enabled.c:74
#, c-format
msgid "No - disabled at boot.\n"
msgstr ""
#: ../aa_enabled.c:77
#, c-format
msgid "Maybe - policy interface not available.\n"
msgstr ""
#: ../aa_enabled.c:81
#, c-format
msgid "Maybe - insufficient permissions to determine availability.\n"
msgstr ""
#: ../aa_enabled.c:84
#, c-format
msgid "Error - '%s'\n"
msgstr ""

View File

@@ -1,68 +0,0 @@
# German translation for apparmor
# Copyright (c) 2016 Rosetta Contributors and Canonical Ltd 2016
# This file is distributed under the same license as the apparmor package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2016.
#
msgid ""
msgstr ""
"Project-Id-Version: apparmor\n"
"Report-Msgid-Bugs-To: AppArmor list <apparmor@lists.ubuntu.com>\n"
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
"PO-Revision-Date: 2017-03-31 10:44+0000\n"
"Last-Translator: Tobias Bannert <tobannert@gmail.com>\n"
"Language-Team: German <de@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2017-04-05 05:23+0000\n"
"X-Generator: Launchpad (build 18335)\n"
"Language: de\n"
#: ../aa_enabled.c:26
#, c-format
msgid ""
"%s: [options]\n"
" options:\n"
" -q | --quiet Don't print out any messages\n"
" -h | --help Print help\n"
msgstr ""
#: ../aa_enabled.c:45
#, c-format
msgid "unknown or incompatible options\n"
msgstr "unbekannte oder nicht kompatible Optionen\n"
#: ../aa_enabled.c:55
#, c-format
msgid "unknown option '%s'\n"
msgstr "unbekannte Option »%s«\n"
#: ../aa_enabled.c:64
#, c-format
msgid "Yes\n"
msgstr "Ja\n"
#: ../aa_enabled.c:71
#, c-format
msgid "No - not available on this system.\n"
msgstr "Nein auf diesem System nicht verfügbar.\n"
#: ../aa_enabled.c:74
#, c-format
msgid "No - disabled at boot.\n"
msgstr "Nein beim Start deaktiviert.\n"
#: ../aa_enabled.c:77
#, c-format
msgid "Maybe - policy interface not available.\n"
msgstr ""
#: ../aa_enabled.c:81
#, c-format
msgid "Maybe - insufficient permissions to determine availability.\n"
msgstr ""
#: ../aa_enabled.c:84
#, c-format
msgid "Error - '%s'\n"
msgstr "Fehler - »%s«\n"

View File

@@ -1,72 +0,0 @@
# English (United Kingdom) translation for apparmor
# Copyright (c) 2016 Rosetta Contributors and Canonical Ltd 2016
# This file is distributed under the same license as the apparmor package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2016.
#
msgid ""
msgstr ""
"Project-Id-Version: apparmor\n"
"Report-Msgid-Bugs-To: AppArmor list <apparmor@lists.ubuntu.com>\n"
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
"PO-Revision-Date: 2016-02-18 06:22+0000\n"
"Last-Translator: Andi Chandler <Unknown>\n"
"Language-Team: English (United Kingdom) <en_GB@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2016-06-01 05:15+0000\n"
"X-Generator: Launchpad (build 18053)\n"
"Language: en_GB\n"
#: ../aa_enabled.c:26
#, c-format
msgid ""
"%s: [options]\n"
" options:\n"
" -q | --quiet Don't print out any messages\n"
" -h | --help Print help\n"
msgstr ""
"%s: [options]\n"
" options:\n"
" -q | --quiet Don't print out any messages\n"
" -h | --help Print help\n"
#: ../aa_enabled.c:45
#, c-format
msgid "unknown or incompatible options\n"
msgstr "unknown or incompatible options\n"
#: ../aa_enabled.c:55
#, c-format
msgid "unknown option '%s'\n"
msgstr "unknown option '%s'\n"
#: ../aa_enabled.c:64
#, c-format
msgid "Yes\n"
msgstr "Yes\n"
#: ../aa_enabled.c:71
#, c-format
msgid "No - not available on this system.\n"
msgstr "No - not available on this system.\n"
#: ../aa_enabled.c:74
#, c-format
msgid "No - disabled at boot.\n"
msgstr "No - disabled at boot.\n"
#: ../aa_enabled.c:77
#, c-format
msgid "Maybe - policy interface not available.\n"
msgstr "Maybe - policy interface not available.\n"
#: ../aa_enabled.c:81
#, c-format
msgid "Maybe - insufficient permissions to determine availability.\n"
msgstr "Maybe - insufficient permissions to determine availability.\n"
#: ../aa_enabled.c:84
#, c-format
msgid "Error - '%s'\n"
msgstr "Error - '%s'\n"

View File

@@ -1,72 +0,0 @@
# Indonesian translation for apparmor
# Copyright (c) 2016 Rosetta Contributors and Canonical Ltd 2016
# This file is distributed under the same license as the apparmor package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2016.
#
msgid ""
msgstr ""
"Project-Id-Version: apparmor\n"
"Report-Msgid-Bugs-To: AppArmor list <apparmor@lists.ubuntu.com>\n"
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
"PO-Revision-Date: 2016-01-20 08:59+0000\n"
"Last-Translator: Ari Setyo Wibowo <mr.a.contact@gmail.com>\n"
"Language-Team: Indonesian <id@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2016-06-01 05:15+0000\n"
"X-Generator: Launchpad (build 18053)\n"
"Language: id\n"
#: ../aa_enabled.c:26
#, c-format
msgid ""
"%s: [options]\n"
" options:\n"
" -q | --quiet Don't print out any messages\n"
" -h | --help Print help\n"
msgstr ""
"%s: [options]\n"
" pilihan:\n"
" -q | --quiet Jangan tampilkan pesan apapun\n"
" -h | --help Tampilkan bantuan\n"
#: ../aa_enabled.c:45
#, c-format
msgid "unknown or incompatible options\n"
msgstr "pilihan yang tidak dikenali atau tidak kompatibel\n"
#: ../aa_enabled.c:55
#, c-format
msgid "unknown option '%s'\n"
msgstr "pilihan tidak dikenali '%s'\n"
#: ../aa_enabled.c:64
#, c-format
msgid "Yes\n"
msgstr "Ya\n"
#: ../aa_enabled.c:71
#, c-format
msgid "No - not available on this system.\n"
msgstr "Tidak - tidak tersedia di sistem ini.\n"
#: ../aa_enabled.c:74
#, c-format
msgid "No - disabled at boot.\n"
msgstr "Tidak - nonaktifkan saat boot.\n"
#: ../aa_enabled.c:77
#, c-format
msgid "Maybe - policy interface not available.\n"
msgstr "Mungkin - kebijakan antarmuka tidak tersedia.\n"
#: ../aa_enabled.c:81
#, c-format
msgid "Maybe - insufficient permissions to determine availability.\n"
msgstr "Mungkin - izin tidak memadai untuk menentukan ketersediaan.\n"
#: ../aa_enabled.c:84
#, c-format
msgid "Error - '%s'\n"
msgstr "Kesalahan - '%s'\n"

View File

@@ -1,72 +0,0 @@
# Portuguese translation for apparmor
# Copyright (c) 2016 Rosetta Contributors and Canonical Ltd 2016
# This file is distributed under the same license as the apparmor package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2016.
#
msgid ""
msgstr ""
"Project-Id-Version: apparmor\n"
"Report-Msgid-Bugs-To: AppArmor list <apparmor@lists.ubuntu.com>\n"
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
"PO-Revision-Date: 2016-03-03 08:34+0000\n"
"Last-Translator: Ivo Xavier <ivoxavier.8@gmail.com>\n"
"Language-Team: Portuguese <pt@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2016-06-01 05:15+0000\n"
"X-Generator: Launchpad (build 18053)\n"
"Language: pt\n"
#: ../aa_enabled.c:26
#, c-format
msgid ""
"%s: [options]\n"
" options:\n"
" -q | --quiet Don't print out any messages\n"
" -h | --help Print help\n"
msgstr ""
"%s: [opções]\n"
" opções:\n"
" -q | --silencioso Não mostrar mensagens\n"
" -h | --ajuda Mostar ajuda\n"
#: ../aa_enabled.c:45
#, c-format
msgid "unknown or incompatible options\n"
msgstr "opções desconhecidas ou incompatíveis\n"
#: ../aa_enabled.c:55
#, c-format
msgid "unknown option '%s'\n"
msgstr "opção desconhecida '%s'\n"
#: ../aa_enabled.c:64
#, c-format
msgid "Yes\n"
msgstr "Sim\n"
#: ../aa_enabled.c:71
#, c-format
msgid "No - not available on this system.\n"
msgstr "Não - não disponível neste sistema.\n"
#: ../aa_enabled.c:74
#, c-format
msgid "No - disabled at boot.\n"
msgstr "Não - desligado ao iniciar.\n"
#: ../aa_enabled.c:77
#, c-format
msgid "Maybe - policy interface not available.\n"
msgstr "Talvez - política de interface não disponível.\n"
#: ../aa_enabled.c:81
#, c-format
msgid "Maybe - insufficient permissions to determine availability.\n"
msgstr "Talvez - permissões insuficientes para determinar disponibilidade.\n"
#: ../aa_enabled.c:84
#, c-format
msgid "Error - '%s'\n"
msgstr "Erro - '%s'\n"

View File

@@ -1,72 +0,0 @@
# Russian translation for apparmor
# Copyright (c) 2016 Rosetta Contributors and Canonical Ltd 2016
# This file is distributed under the same license as the apparmor package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2016.
#
msgid ""
msgstr ""
"Project-Id-Version: apparmor\n"
"Report-Msgid-Bugs-To: AppArmor list <apparmor@lists.ubuntu.com>\n"
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
"PO-Revision-Date: 2016-03-29 14:46+0000\n"
"Last-Translator: Eugene Marshal <Unknown>\n"
"Language-Team: Russian <ru@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2016-06-01 05:15+0000\n"
"X-Generator: Launchpad (build 18053)\n"
"Language: ru\n"
#: ../aa_enabled.c:26
#, c-format
msgid ""
"%s: [options]\n"
" options:\n"
" -q | --quiet Don't print out any messages\n"
" -h | --help Print help\n"
msgstr ""
"%s: [параметры]\n"
" параметры:\n"
" -q | --quiet не выводить никакие сообщения\n"
" -h | --help вывести справку\n"
#: ../aa_enabled.c:45
#, c-format
msgid "unknown or incompatible options\n"
msgstr "неизвестные или несовместимые параметры\n"
#: ../aa_enabled.c:55
#, c-format
msgid "unknown option '%s'\n"
msgstr "неизвестный параметр '%s'\n"
#: ../aa_enabled.c:64
#, c-format
msgid "Yes\n"
msgstr "Да\n"
#: ../aa_enabled.c:71
#, c-format
msgid "No - not available on this system.\n"
msgstr "Нет - недоступно на этой системе.\n"
#: ../aa_enabled.c:74
#, c-format
msgid "No - disabled at boot.\n"
msgstr "Нет - выключено при загрузке.\n"
#: ../aa_enabled.c:77
#, c-format
msgid "Maybe - policy interface not available.\n"
msgstr "Возможно - интерфейс политики недоступен.\n"
#: ../aa_enabled.c:81
#, c-format
msgid "Maybe - insufficient permissions to determine availability.\n"
msgstr "Возможно - недостаточно разрешений для определения доступности.\n"
#: ../aa_enabled.c:84
#, c-format
msgid "Error - '%s'\n"
msgstr "Ошибка - '%s'\n"

View File

@@ -1,6 +1,5 @@
# ----------------------------------------------------------------------
# Copyright (c) 2004, 2005 NOVELL (All rights reserved)
# Copyright (c) 2016 Canonical, Ltd.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of version 2 of the GNU General Public
@@ -18,7 +17,13 @@ NAME:=apache2-mod_apparmor
all:
COMMONDIR=../../common/
include $(COMMONDIR)/Make.rules
include common/Make.rules
COMMONDIR_EXISTS=$(strip $(shell [ -d ${COMMONDIR} ] && echo true))
ifeq ($(COMMONDIR_EXISTS), true)
common/Make.rules: $(COMMONDIR)/Make.rules
ln -sf $(COMMONDIR) .
endif
TARGET:=mod_apparmor.so
MANPAGES=mod_apparmor.8
@@ -74,10 +79,7 @@ endif
.SILENT: libapparmor_check
libapparmor_check: ; $(ERROR_MESSAGE)
all: libapparmor_check $(TARGET) docs
.PHONY: docs
docs: ${MANPAGES} ${HTMLMANPAGES}
all: libapparmor_check $(TARGET) ${MANPAGES} ${HTMLMANPAGES}
%.so: %.c
${APXS} ${LIBAPPARMOR_FLAGS} -c $< ${LDLIBS}
@@ -90,9 +92,9 @@ install: ${TARGET} ${MANPAGES}
make install_manpages DESTDIR=${DESTDIR}
.PHONY: clean
clean: pod_clean
clean: _clean
rm -rf .libs
rm -f *.la *.lo *.so *.o *.slo
rm -f *.la *.lo *.so *.o *.slo Make.rules
.PHONY: check
check: check_pod_files

View File

@@ -137,7 +137,7 @@ aa_enter_hat(request_rec *r)
ap_get_module_config(r->server->module_config, &apparmor_module);
const char *aa_hat_array[6] = { NULL, NULL, NULL, NULL, NULL, NULL };
int i = 0;
char *aa_label, *aa_mode, *aa_hat;
char *aa_con, *aa_mode, *aa_hat;
const char *vhost_uri;
debug_dump_uri(r);
@@ -201,14 +201,14 @@ aa_enter_hat(request_rec *r)
/* Check to see if a defined AAHatName or AADefaultHatName would
* apply, but wasn't the hat we landed up in; report a warning if
* that's the case. */
aa_ret = aa_getcon(&aa_label, &aa_mode);
aa_ret = aa_getcon(&aa_con, &aa_mode);
if (aa_ret < 0) {
ap_log_rerror(APLOG_MARK, APLOG_WARNING, errno, r, "aa_getcon call failed");
} else {
ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
"AA checks: aa_getcon result is '%s', mode '%s'", aa_label, aa_mode);
"AA checks: aa_getcon result is '%s', mode '%s'", aa_con, aa_mode);
/* TODO: use libapparmor get hat_name fn here once it is implemented */
aa_hat = strstr(aa_label, "//");
aa_hat = strstr(aa_con, "//");
if (aa_hat != NULL && strcmp(aa_mode, "enforce") == 0) {
aa_hat += 2; /* skip "//" */
ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
@@ -226,7 +226,7 @@ aa_enter_hat(request_rec *r)
scfg->hat_name);
}
}
free(aa_label);
free(aa_con);
}
return OK;

View File

@@ -65,7 +65,7 @@ provides the AAHatName and AADefaultHatName Apache configuration options.
AAHatName allows you to specify a hat to be used for a given Apache
E<lt>DirectoryE<gt>, E<lt>DirectoryMatchE<gt>, E<lt>LocationE<gt> or
E<lt>LocationMatchE<gt> directive (see the Apache documentation for more
E<lt>LocationMatchE<gt> directive (see the Apache documenation for more
details). Note that mod_apparmor behavior can become confused if
E<lt>Directory*E<gt> and E<lt>Location*E<gt> directives are intermingled
and it is recommended to use one type of directive. If the hat specified by

View File

@@ -1,6 +1,5 @@
# ----------------------------------------------------------------------
# Copyright (c) 1999, 2004, 2005 NOVELL (All rights reserved)
# Copyright (c) 2016 Canonical, Ltd.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of version 2 of the GNU General Public
@@ -17,8 +16,15 @@
NAME=pam_apparmor
all:
COMMONDIR=../../common/
MAKE_RULES=common/Make.rules
include $(COMMONDIR)/Make.rules
include ${MAKE_RULES}
COMMONDIR_EXISTS=$(strip $(shell [ -d ${COMMONDIR} ] && echo true))
ifeq ($(COMMONDIR_EXISTS), true)
common/Make.rules: $(COMMONDIR)/Make.rules
ln -sf $(COMMONDIR) .
endif
ifdef USE_SYSTEM
LIBAPPARMOR = $(shell if pkg-config --exists libapparmor ; then \
@@ -54,8 +60,8 @@ libapparmor by adding USE_SYSTEM=1 to your make command.${nl}\
AA_LINK_FLAGS = -L$(LIBAPPARMOR_PATH)
AA_LDLIBS = -lapparmor
endif
EXTRA_CFLAGS=$(CFLAGS) $(CPPFLAGS) -fPIC -shared -Wall $(LIBAPPARMOR_INCLUDE)
LINK_FLAGS=-Xlinker -x $(AA_LINK_FLAGS) $(LDFLAGS)
EXTRA_CFLAGS=$(CFLAGS) -fPIC -shared -Wall $(LIBAPPARMOR_INCLUDE)
LINK_FLAGS=-Xlinker -x $(AA_LINK_FLAGS)
LIBS=-lpam $(AA_LDLIBS)
OBJECTS=${NAME}.o get_options.o
@@ -63,11 +69,7 @@ OBJECTS=${NAME}.o get_options.o
.SILENT: libapparmor_check
libapparmor_check: ; $(ERROR_MESSAGE)
all: libapparmor_check $(NAME).so docs
.PHONY: docs
# docs: we should have some
docs:
all: libapparmor_check $(NAME).so
$(NAME).so: ${OBJECTS}
$(CC) $(EXTRA_CFLAGS) $(LINK_FLAGS) -o $@ ${OBJECTS} $(LIBS)
@@ -85,5 +87,7 @@ install: $(NAME).so
install -m 555 $(NAME).so $(SECDIR)/
.PHONY: clean
clean:
clean: ${MAKE_RULES}
rm -f core core.* *.so *.o *.s *.a *~
rm -f ${NAME}-*.tar.gz Make.rules

View File

@@ -111,7 +111,6 @@ int pam_sm_open_session(pam_handle_t *pamh, int flags,
sizeof(magic_token));
if (retval < 0) {
pam_syslog(pamh, LOG_ERR, "Can't read from /dev/urandom\n");
close(fd);
return PAM_PERM_DENIED;
}
} while ((magic_token == 0) || (retval != sizeof(magic_token)));

View File

@@ -17,7 +17,13 @@ NAME = tomcat_apparmor
all:
COMMONDIR=../../../common/
include $(COMMONDIR)/Make.rules
include common/Make.rules
COMMONDIR_EXISTS=$(strip $(shell [ -d ${COMMONDIR} ] && echo true))
ifeq ($(COMMONDIR_EXISTS), true)
common/Make.rules: $(COMMONDIR)/Make.rules
ln -sf $(COMMONDIR) .
endif
LIB = lib
CATALINA_HOME = /usr/share/tomcat5
@@ -28,6 +34,7 @@ all:
clean:
ant clean
rm -f tomcat_apparmor.spec ${NAME}-*.tar.gz Make.rules
install:
install: $(SPECFILE)
ant -Dversion=$(VERSION) -Drelease=$(MAN_RELEASE) -Dcatalina_home=${CATALINA_HOME} -Dinstall_lib=${LIB} install_jar install_jni

View File

@@ -17,7 +17,13 @@ NAME = tomcat_apparmor
all:
COMMONDIR=../../../common/
include $(COMMONDIR)/Make.rules
include common/Make.rules
COMMONDIR_EXISTS=$(strip $(shell [ -d ${COMMONDIR} ] && echo true))
ifeq ($(COMMONDIR_EXISTS), true)
common/Make.rules: $(COMMONDIR)/Make.rules
ln -sf $(COMMONDIR) .
endif
LIB = lib
CATALINA_HOME = /usr/share/tomcat55
@@ -28,6 +34,7 @@ all:
clean:
ant clean
rm -f tomcat_apparmor.spec ${NAME}-*.tar.gz Make.rules
install:
install: $(SPECFILE)
ant -Dversion=$(VERSION) -Drelease=$(MAN_RELEASE) -Dcatalina_home=${CATALINA_HOME} -Dinstall_lib=${LIB} install_jar install_jni

View File

@@ -1,7 +1,7 @@
# ------------------------------------------------------------------
#
# Copyright (c) 1999-2008 NOVELL (All rights reserved)
# Copyright 2009-2015 Canonical Ltd.
# Copyright 2009-2010 Canonical Ltd.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of version 2 of the GNU General Public
@@ -21,7 +21,7 @@
# exist
LOCALEDIR=/usr/share/locale
XGETTEXT_ARGS=--copyright-holder="Canonical Ltd" --msgid-bugs-address=apparmor@lists.ubuntu.com -d ${NAME}
XGETTEXT_ARGS=--copyright-holder="NOVELL, Inc." --msgid-bugs-address=apparmor@lists.ubuntu.com -d ${NAME}
# When making the .pot file, it's expected that the parent Makefile will
# pass in the list of sources in the SOURCES variable

View File

@@ -1,7 +1,7 @@
# ------------------------------------------------------------------
#
# Copyright (C) 2002-2005 Novell/SUSE
# Copyright (C) 2010-2015 Canonical, Ltd.
# Copyright (C) 2010 Canonical, Ltd.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of version 2 of the GNU General Public
@@ -15,21 +15,17 @@
# You should have received a copy of the GNU General Public License
# along with this program; if not, contact Novell, Inc.
# ------------------------------------------------------------------
# Make.rules - common make targets and variables for building AppArmor
# Make.rules - common make targets and variables for building the SHASS
# product.
#
# NOTES:
# Before including this file in your Makefile, you should
# - define COMMONDIR (the location of the common/ directory)
# - define the default rule (usually 'all:'). (Note: you can redefine
# it later in your Makefile)
.PHONY: common_Make.rules_is_a_bad_target
common_Make.rules_is_a_bad_target:
@echo "*** default target in common/Make.rules hit - either you did something strange, or something is broken... ***"
exit 1
# - must define the package NAME before including this file.
# - After checking in to cvs, you'll need to delele the hardlinked
# Make.rules files that already exist in the individual application
# directories
DISTRIBUTION=AppArmor
VERSION=$(shell cat $(COMMONDIR)/Version)
VERSION=$(shell cat common/Version)
# Convenience functions
pathsearch = $(firstword $(wildcard $(addsuffix /$(1),$(subst :, ,$(PATH)))))
@@ -45,7 +41,105 @@ define nl
endef
REPO_VERSION_CMD=[ -x /usr/bin/bzr ] && /usr/bin/bzr version-info --custom --template="{revno}" . 2> /dev/null || awk '{ print $2 }' common/.stamp_rev
# OVERRIDABLE variables
# Set these variables before including Make.rules to change its behavior
# SPECFILE - for packages that have a non-standard specfile name
# EXTERNAL_PACKAGE - for packages that have upstream versions that
# we're locally modifying (e.g. imnxcerttool/gnutls).
#
# use 'make BUILDIR=/some/where/else/' to override the /usr/src/redhat
# location -- it *should* pick out the right thing to do based on the
# .rpmmacros file, but you can still use BUILDDIR to override that.
TESTBUILDDIR=$(shell [ -f ${HOME}/.rpmmacros ] && awk '/^%_topdir/ {print $$2}' ${HOME}/.rpmmacros)
ifndef BUILDDIR
BUILDDIR=$(shell if [ -d "${TESTBUILDDIR}" ] ; then \
echo ${TESTBUILDDIR} | sed "s^/$$^^" ; \
elif [ -d "/usr/src/redhat" ] ; then \
echo "/usr/src/redhat" ; \
elif [ -d "/usr/src/packages" ] ; then \
echo "/usr/src/packages" ; \
else \
echo "/tmp/${NAME}" ; \
fi ;)
endif
ifndef DISTRO
DISTRO=$(shell if [ -f /etc/slackware-version ] ; then \
echo slackware ; \
elif [ -f /etc/debian_version ] ; then \
echo debian ;\
elif which rpm > /dev/null ; then \
if [ "$(rpm --eval '0%{?suse_version}')" != "0" ] ; then \
echo suse ;\
elif [ "$(rpm --eval '%{_host_vendor}')" = redhat ] ; then \
echo rhel4 ;\
elif [ "$(rpm --eval '0%{?fedora}')" != "0" ] ; then \
echo rhel4 ;\
else \
echo unknown ;\
fi ;\
else \
echo unknown ;\
fi)
endif
RPMARG=--define "_topdir $(BUILDDIR:/=)" \
--define "vendor NOVELL, Inc." \
--define "distribution ${DISTRIBUTION}" \
--define "debug_package %{nil}" \
--define "immunix_version ${VERSION}" \
$(shell [ -d ${BUILDDIR}/BUILDROOT ] && echo --define \"buildroot $(BUILDDIR:/=)/BUILDROOT\") \
$(shell [ -n "${DISTRO}" ] && echo --define \"distro ${DISTRO}\")
REPO_VERSION_CMD=([ -x /usr/bin/bzr ] && /usr/bin/bzr version-info . 2> /dev/null || awk '{ print "revno: "$2 }' common/.stamp_rev) | awk '/^revno:/ { print $2 }'
ifdef EXTERNAL_PACKAGE
RPMARG+=--define "_sourcedir $(shell pwd)"
endif
ifndef SPECFILE
SPECFILE = $(NAME).spec
endif
RELEASE_DIR = $(NAME)-$(VERSION)
TAR = /bin/tar czvp -h --exclude .svn --exclude .bzr --exclude .bzrignore --exclude ${RELEASE_DIR}/${RELEASE_DIR} $(shell test -f ${NAME}.exclude && echo "-X ${NAME}.exclude")
LDCONFIG = /sbin/ldconfig
RPMSUBDIRS=SOURCES SPECS BUILD BUILDROOT SRPMS RPMS/i386 RPMS/i586 \
RPMS/i686 RPMS/athlon RPMS/noarch RPMS/x86_64
BUILDRPMSUBDIRS=$(foreach subdir, $(RPMSUBDIRS), $(BUILDDIR:/=)/$(subdir))
ifdef EXTERNAL_PACKAGE
.PHONY: rpm
rpm: clean $(BUILDRPMSUBDIRS)
rpmbuild -ba ${RPMARG} ${SPECFILE}
else
.PHONY: rpm
rpm: clean $(BUILDRPMSUBDIRS)
__REPO_VERSION=`$(value REPO_VERSION_CMD)` ; \
__TARBALL=$(NAME)-$(VERSION)-$${__REPO_VERSION}.tar.gz ; \
make $${__TARBALL} ; \
cp $${__TARBALL} $(BUILDDIR)/SOURCES/
cp ${SPECFILE} $(BUILDDIR)/SPECS/
rpmbuild -ba ${RPMARG} ${SPECFILE}
.PHONY: ${SPECFILE}
${SPECFILE}: ${SPECFILE}.in
__REPO_VERSION=`$(value REPO_VERSION_CMD)` ; \
sed -e "s/@@immunix_version@@/${VERSION}/g" \
-e "s/@@repo_version@@/$${__REPO_VERSION}/g" $< > $@
%.tar.gz: clean ${SPECFILE}
-rm -rf $(RELEASE_DIR)
mkdir $(RELEASE_DIR)
$(TAR) --exclude $@ . | tar xz -C $(RELEASE_DIR)
$(TAR) --exclude $@ -f $@ $(RELEASE_DIR)
rm -rf $(RELEASE_DIR)
ifndef OVERRIDE_TARBALL
.PHONY: tarball
tarball: clean $(TARBALL)
endif
endif
ifndef PYTHON_VERSIONS
PYTHON_VERSIONS = $(call map, pathsearch, python2 python3)
@@ -61,18 +155,24 @@ pyalldo=set -e; $(foreach py, $(PYTHON_VERSIONS), $(py) $(1);)
.PHONY: version
.SILENT: version
version:
echo $(VERSION)
rpm -q --define "_sourcedir ." ${RPMARG} --specfile ${SPECFILE}
.PHONY: repo_version
.SILENT: repo_version
repo_version:
echo $(shell $(value REPO_VERSION_CMD))
$(value REPO_VERSION_CMD)
.PHONY: pod_clean
ifndef VERBOSE
.SILENT: pod_clean
endif
pod_clean:
.PHONY: build_dir
build_dir: $(BUILDRPMSUBDIRS)
$(BUILDRPMSUBDIRS):
mkdir -p $(BUILDRPMSUBDIRS)
.PHONY: _clean
.SILENT: _clean
_clean:
-[ -z "${NAME}" ] || rm -f ${NAME}-${VERSION}-*.tar.gz
-rm -f ${MANPAGES} *.[0-9].gz ${HTMLMANPAGES} pod2htm*.tmp
# =====================
@@ -82,7 +182,7 @@ pod_clean:
# =====================
# emits defined capabilities in a simple list, e.g. "CAP_NAME CAP_NAME2"
CAPABILITIES=$(shell echo "\#include <linux/capability.h>" | cpp -dM | LC_ALL=C sed -n -e '/CAP_EMPTY_SET/d' -e 's/^\#define[ \t]\+CAP_\([A-Z0-9_]\+\)[ \t]\+\([0-9xa-f]\+\)\(.*\)$$/CAP_\1/p' | LC_ALL=C sort)
CAPABILITIES=$(shell echo "\#include <linux/capability.h>" | cpp -dM | LC_ALL=C sed -n -e '/CAP_EMPTY_SET/d' -e 's/^\#define[ \t]\+CAP_\([A-Z0-9_]\+\)[ \t]\+\([0-9xa-f]\+\)\(.*\)$$/CAP_\1/p' | sort)
.PHONY: list_capabilities
list_capabilities: /usr/include/linux/capability.h
@@ -98,7 +198,7 @@ list_capabilities: /usr/include/linux/capability.h
# to mediate. We use PF_ here since that is what is required in
# bits/socket.h, but we will rewrite these as AF_.
FILTER_FAMILIES=PF_UNIX
FILTER_FAMILIES=PF_UNSPEC PF_UNIX
__FILTER=$(shell echo $(strip $(FILTER_FAMILIES)) | sed -e 's/ /\\\|/g')

View File

@@ -1 +1 @@
2.11.95
2.9.2

View File

@@ -24,7 +24,13 @@ NAME = apparmor-utils
all:
COMMONDIR=../../common/
include $(COMMONDIR)/Make.rules
include common/Make.rules
COMMONDIR_EXISTS=$(strip $(shell [ -d ${COMMONDIR} ] && echo true))
ifeq ($(COMMONDIR_EXISTS), true)
common/Make.rules: $(COMMONDIR)/Make.rules
ln -sf $(COMMONDIR) .
endif
MODDIR = Immunix
PERLTOOLS = aa-genprof aa-logprof aa-autodep aa-audit aa-complain aa-enforce \
@@ -50,8 +56,9 @@ install:
ifndef VERBOSE
.SILENT: clean
endif
clean: pod_clean
clean: _clean
rm -f core core.* *.o *.s *.a *~
rm -f Make.rules
rm -rf staging/ build/
.PHONY: check

View File

@@ -1,36 +0,0 @@
# ----------------------------------------------------------------------
# Copyright (c) 2016 Canonical Ltd.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of version 2 of the GNU General Public
# License published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# ----------------------------------------------------------------------
NAME = documentation
all:
COMMONDIR=../common/
include $(COMMONDIR)/Make.rules
all: docs
SOURCES:= $(wildcard *.odt)
DOCS:=$(SOURCES:.odt=.pdf)
.PHONY: docs
docs: $(DOCS)
%.pdf: %.odt
unoconv -v -f pdf --output "$@" "$<"
.PHONY: clean
ifndef VERBOSE
.SILENT: clean
endif
clean:
rm -f *.pdf

Binary file not shown.

Binary file not shown.

View File

@@ -1,118 +0,0 @@
From 24b6ac149a57c2d3d5a9920e64d914e8ff00d346 Mon Sep 17 00:00:00 2001
From: Vegard Nossum <vegard.nossum@oracle.com>
Date: Thu, 7 Jul 2016 13:41:11 -0700
Subject: [PATCH 01/27] apparmor: fix oops, validate buffer size in
apparmor_setprocattr()
When proc_pid_attr_write() was changed to use memdup_user apparmor's
(interface violating) assumption that the setprocattr buffer was always
a single page was violated.
The size test is not strictly speaking needed as proc_pid_attr_write()
will reject anything larger, but for the sake of robustness we can keep
it in.
SMACK and SELinux look safe to me, but somebody else should probably
have a look just in case.
Based on original patch from Vegard Nossum <vegard.nossum@oracle.com>
modified for the case that apparmor provides null termination.
Fixes: bb646cdb12e75d82258c2f2e7746d5952d3e321a
Reported-by: Vegard Nossum <vegard.nossum@oracle.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: John Johansen <john.johansen@canonical.com>
Cc: Paul Moore <paul@paul-moore.com>
Cc: Stephen Smalley <sds@tycho.nsa.gov>
Cc: Eric Paris <eparis@parisplace.org>
Cc: Casey Schaufler <casey@schaufler-ca.com>
Cc: stable@kernel.org
Signed-off-by: John Johansen <john.johansen@canonical.com>
Reviewed-by: Tyler Hicks <tyhicks@canonical.com>
Signed-off-by: James Morris <james.l.morris@oracle.com>
---
security/apparmor/lsm.c | 36 +++++++++++++++++++-----------------
1 file changed, 19 insertions(+), 17 deletions(-)
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index dec607c..5ee8201 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -523,34 +523,34 @@ static int apparmor_setprocattr(struct task_struct *task, char *name,
{
struct common_audit_data sa;
struct apparmor_audit_data aad = {0,};
- char *command, *args = value;
+ char *command, *largs = NULL, *args = value;
size_t arg_size;
int error;
if (size == 0)
return -EINVAL;
- /* args points to a PAGE_SIZE buffer, AppArmor requires that
- * the buffer must be null terminated or have size <= PAGE_SIZE -1
- * so that AppArmor can null terminate them
- */
- if (args[size - 1] != '\0') {
- if (size == PAGE_SIZE)
- return -EINVAL;
- args[size] = '\0';
- }
-
/* task can only write its own attributes */
if (current != task)
return -EACCES;
- args = value;
+ /* AppArmor requires that the buffer must be null terminated atm */
+ if (args[size - 1] != '\0') {
+ /* null terminate */
+ largs = args = kmalloc(size + 1, GFP_KERNEL);
+ if (!args)
+ return -ENOMEM;
+ memcpy(args, value, size);
+ args[size] = '\0';
+ }
+
+ error = -EINVAL;
args = strim(args);
command = strsep(&args, " ");
if (!args)
- return -EINVAL;
+ goto out;
args = skip_spaces(args);
if (!*args)
- return -EINVAL;
+ goto out;
arg_size = size - (args - (char *) value);
if (strcmp(name, "current") == 0) {
@@ -576,10 +576,12 @@ static int apparmor_setprocattr(struct task_struct *task, char *name,
goto fail;
} else
/* only support the "current" and "exec" process attributes */
- return -EINVAL;
+ goto fail;
if (!error)
error = size;
+out:
+ kfree(largs);
return error;
fail:
@@ -588,9 +590,9 @@ fail:
aad.profile = aa_current_profile();
aad.op = OP_SETPROCATTR;
aad.info = name;
- aad.error = -EINVAL;
+ aad.error = error = -EINVAL;
aa_audit_msg(AUDIT_APPARMOR_DENIED, &sa, NULL);
- return -EINVAL;
+ goto out;
}
static int apparmor_task_setrlimit(struct task_struct *task,
--
2.7.4

View File

@@ -1,33 +0,0 @@
From 444bc4f95ec283cd0fb9777f4890bd9bc307809d Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Mon, 11 Apr 2016 16:55:10 -0700
Subject: [PATCH 02/27] apparmor: fix refcount bug in profile replacement
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
---
security/apparmor/policy.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
index 705c287..222052f 100644
--- a/security/apparmor/policy.c
+++ b/security/apparmor/policy.c
@@ -1189,12 +1189,12 @@ ssize_t aa_replace_profiles(void *udata, size_t size, bool noreplace)
aa_get_profile(newest);
aa_put_profile(parent);
rcu_assign_pointer(ent->new->parent, newest);
- } else
- aa_put_profile(newest);
+ }
/* aafs interface uses replacedby */
rcu_assign_pointer(ent->new->replacedby->profile,
aa_get_profile(ent->new));
__list_add_profile(&parent->base.profiles, ent->new);
+ aa_put_profile(newest);
} else {
/* aafs interface uses replacedby */
rcu_assign_pointer(ent->new->replacedby->profile,
--
2.7.4

View File

@@ -1,38 +0,0 @@
From 1224a06778b89dcbf0ca85bd961c2fcdd8765a69 Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Mon, 11 Apr 2016 16:57:19 -0700
Subject: [PATCH 03/27] apparmor: fix replacement bug that adds new child to
old parent
When set atomic replacement is used and the parent is updated before the
child, and the child did not exist in the old parent so there is no
direct replacement then the new child is incorrectly added to the old
parent. This results in the new parent not having the child(ren) that
it should and the old parent when being destroyed asserting the
following error.
AppArmor: policy_destroy: internal error, policy '<profile/name>' still
contains profiles
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
---
security/apparmor/policy.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
index 222052f..c92a9f6 100644
--- a/security/apparmor/policy.c
+++ b/security/apparmor/policy.c
@@ -1193,7 +1193,7 @@ ssize_t aa_replace_profiles(void *udata, size_t size, bool noreplace)
/* aafs interface uses replacedby */
rcu_assign_pointer(ent->new->replacedby->profile,
aa_get_profile(ent->new));
- __list_add_profile(&parent->base.profiles, ent->new);
+ __list_add_profile(&newest->base.profiles, ent->new);
aa_put_profile(newest);
} else {
/* aafs interface uses replacedby */
--
2.7.4

View File

@@ -1,87 +0,0 @@
From 15d921647676fdc2c3ee1cf9aa8f578b1012ecff Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Sun, 8 Jun 2014 11:20:54 -0700
Subject: [PATCH 04/27] apparmor: fix uninitialized lsm_audit member
BugLink: http://bugs.launchpad.net/bugs/1268727
The task field in the lsm_audit struct needs to be initialized if
a change_hat fails, otherwise the following oops will occur
BUG: unable to handle kernel paging request at 0000002fbead7d08
IP: [<ffffffff8171153e>] _raw_spin_lock+0xe/0x50
PGD 1e3f35067 PUD 0
Oops: 0002 [#1] SMP
Modules linked in: pppox crc_ccitt p8023 p8022 psnap llc ax25 btrfs raid6_pq xor xfs libcrc32c dm_multipath scsi_dh kvm_amd dcdbas kvm microcode amd64_edac_mod joydev edac_core psmouse edac_mce_amd serio_raw k10temp sp5100_tco i2c_piix4 ipmi_si ipmi_msghandler acpi_power_meter mac_hid lp parport hid_generic usbhid hid pata_acpi mpt2sas ahci raid_class pata_atiixp bnx2 libahci scsi_transport_sas [last unloaded: tipc]
CPU: 2 PID: 699 Comm: changehat_twice Tainted: GF O 3.13.0-7-generic #25-Ubuntu
Hardware name: Dell Inc. PowerEdge R415/08WNM9, BIOS 1.8.6 12/06/2011
task: ffff8802135c6000 ti: ffff880212986000 task.ti: ffff880212986000
RIP: 0010:[<ffffffff8171153e>] [<ffffffff8171153e>] _raw_spin_lock+0xe/0x50
RSP: 0018:ffff880212987b68 EFLAGS: 00010006
RAX: 0000000000020000 RBX: 0000002fbead7500 RCX: 0000000000000000
RDX: 0000000000000292 RSI: ffff880212987ba8 RDI: 0000002fbead7d08
RBP: ffff880212987b68 R08: 0000000000000246 R09: ffff880216e572a0
R10: ffffffff815fd677 R11: ffffea0008469580 R12: ffffffff8130966f
R13: ffff880212987ba8 R14: 0000002fbead7d08 R15: ffff8800d8c6b830
FS: 00002b5e6c84e7c0(0000) GS:ffff880216e40000(0000) knlGS:0000000055731700
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000002fbead7d08 CR3: 000000021270f000 CR4: 00000000000006e0
Stack:
ffff880212987b98 ffffffff81075f17 ffffffff8130966f 0000000000000009
0000000000000000 0000000000000000 ffff880212987bd0 ffffffff81075f7c
0000000000000292 ffff880212987c08 ffff8800d8c6b800 0000000000000026
Call Trace:
[<ffffffff81075f17>] __lock_task_sighand+0x47/0x80
[<ffffffff8130966f>] ? apparmor_cred_prepare+0x2f/0x50
[<ffffffff81075f7c>] do_send_sig_info+0x2c/0x80
[<ffffffff81075fee>] send_sig_info+0x1e/0x30
[<ffffffff8130242d>] aa_audit+0x13d/0x190
[<ffffffff8130c1dc>] aa_audit_file+0xbc/0x130
[<ffffffff8130966f>] ? apparmor_cred_prepare+0x2f/0x50
[<ffffffff81304cc2>] aa_change_hat+0x202/0x530
[<ffffffff81308fc6>] aa_setprocattr_changehat+0x116/0x1d0
[<ffffffff8130a11d>] apparmor_setprocattr+0x25d/0x300
[<ffffffff812cee56>] security_setprocattr+0x16/0x20
[<ffffffff8121fc87>] proc_pid_attr_write+0x107/0x130
[<ffffffff811b7604>] vfs_write+0xb4/0x1f0
[<ffffffff811b8039>] SyS_write+0x49/0xa0
[<ffffffff8171a1bf>] tracesys+0xe1/0xe6
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
---
security/apparmor/audit.c | 3 ++-
security/apparmor/file.c | 3 ++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/security/apparmor/audit.c b/security/apparmor/audit.c
index 89c7865..3a7f1da 100644
--- a/security/apparmor/audit.c
+++ b/security/apparmor/audit.c
@@ -200,7 +200,8 @@ int aa_audit(int type, struct aa_profile *profile, gfp_t gfp,
if (sa->aad->type == AUDIT_APPARMOR_KILL)
(void)send_sig_info(SIGKILL, NULL,
- sa->u.tsk ? sa->u.tsk : current);
+ sa->type == LSM_AUDIT_DATA_TASK && sa->u.tsk ?
+ sa->u.tsk : current);
if (sa->aad->type == AUDIT_APPARMOR_ALLOWED)
return complain_error(sa->aad->error);
diff --git a/security/apparmor/file.c b/security/apparmor/file.c
index 913f377..43d6ae7 100644
--- a/security/apparmor/file.c
+++ b/security/apparmor/file.c
@@ -110,7 +110,8 @@ int aa_audit_file(struct aa_profile *profile, struct file_perms *perms,
int type = AUDIT_APPARMOR_AUTO;
struct common_audit_data sa;
struct apparmor_audit_data aad = {0,};
- sa.type = LSM_AUDIT_DATA_NONE;
+ sa.type = LSM_AUDIT_DATA_TASK;
+ sa.u.tsk = NULL;
sa.aad = &aad;
aad.op = op,
aad.fs.request = request;
--
2.7.4

View File

@@ -1,32 +0,0 @@
From c1216728b7d644443eef31e4bd9d01b4a0a51d61 Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Fri, 25 Jul 2014 04:02:03 -0700
Subject: [PATCH 05/27] apparmor: exec should not be returning ENOENT when it
denies
The current behavior is confusing as it causes exec failures to report
the executable is missing instead of identifying that apparmor
caused the failure.
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
---
security/apparmor/domain.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
index dc0027b..67a7418 100644
--- a/security/apparmor/domain.c
+++ b/security/apparmor/domain.c
@@ -433,7 +433,7 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
new_profile = aa_get_newest_profile(ns->unconfined);
info = "ux fallback";
} else {
- error = -ENOENT;
+ error = -EACCES;
info = "profile not found";
/* remove MAY_EXEC to audit as failure */
perms.allow &= ~MAY_EXEC;
--
2.7.4

View File

@@ -1,28 +0,0 @@
From 2d3389de6c8ab6b3ad2cef4ea460c8fce2a226b9 Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Fri, 25 Jul 2014 04:01:56 -0700
Subject: [PATCH 06/27] apparmor: fix update the mtime of the profile file on
replacement
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
---
security/apparmor/apparmorfs.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
index ad4fa49..45a6199 100644
--- a/security/apparmor/apparmorfs.c
+++ b/security/apparmor/apparmorfs.c
@@ -379,6 +379,8 @@ void __aa_fs_profile_migrate_dents(struct aa_profile *old,
for (i = 0; i < AAFS_PROF_SIZEOF; i++) {
new->dents[i] = old->dents[i];
+ if (new->dents[i])
+ new->dents[i]->d_inode->i_mtime = CURRENT_TIME;
old->dents[i] = NULL;
}
}
--
2.7.4

View File

@@ -1,36 +0,0 @@
From 9caa96e30a1b2bb191a29af872285c8d0b078c10 Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Fri, 25 Jul 2014 04:02:08 -0700
Subject: [PATCH 07/27] apparmor: fix disconnected bind mnts reconnection
Bind mounts can fail to be properly reconnected when PATH_CONNECT is
specified. Ensure that when PATH_CONNECT is specified the path has
a root.
BugLink: http://bugs.launchpad.net/bugs/1319984
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
---
security/apparmor/path.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/security/apparmor/path.c b/security/apparmor/path.c
index 71e0e3a..bb2f2c6 100644
--- a/security/apparmor/path.c
+++ b/security/apparmor/path.c
@@ -141,7 +141,10 @@ static int d_namespace_path(struct path *path, char *buf, int buflen,
error = -EACCES;
if (*res == '/')
*name = res + 1;
- }
+ } else if (*res != '/')
+ /* CONNECT_PATH with missing root */
+ error = prepend(name, *name - buf, "/", 1);
+
}
out:
--
2.7.4

View File

@@ -1,114 +0,0 @@
From 11702a732e149380e05e2ab8ae1b743ac89f892f Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Fri, 25 Jul 2014 04:02:10 -0700
Subject: [PATCH 08/27] apparmor: internal paths should be treated as
disconnected
Internal mounts are not mounted anywhere and as such should be treated
as disconnected paths.
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
---
security/apparmor/path.c | 64 +++++++++++++++++++++++++++---------------------
1 file changed, 36 insertions(+), 28 deletions(-)
diff --git a/security/apparmor/path.c b/security/apparmor/path.c
index bb2f2c6..596f799 100644
--- a/security/apparmor/path.c
+++ b/security/apparmor/path.c
@@ -25,7 +25,6 @@
#include "include/path.h"
#include "include/policy.h"
-
/* modified from dcache.c */
static int prepend(char **buffer, int buflen, const char *str, int namelen)
{
@@ -39,6 +38,38 @@ static int prepend(char **buffer, int buflen, const char *str, int namelen)
#define CHROOT_NSCONNECT (PATH_CHROOT_REL | PATH_CHROOT_NSCONNECT)
+/* If the path is not connected to the expected root,
+ * check if it is a sysctl and handle specially else remove any
+ * leading / that __d_path may have returned.
+ * Unless
+ * specifically directed to connect the path,
+ * OR
+ * if in a chroot and doing chroot relative paths and the path
+ * resolves to the namespace root (would be connected outside
+ * of chroot) and specifically directed to connect paths to
+ * namespace root.
+ */
+static int disconnect(const struct path *path, char *buf, char **name,
+ int flags)
+{
+ int error = 0;
+
+ if (!(flags & PATH_CONNECT_PATH) &&
+ !(((flags & CHROOT_NSCONNECT) == CHROOT_NSCONNECT) &&
+ our_mnt(path->mnt))) {
+ /* disconnected path, don't return pathname starting
+ * with '/'
+ */
+ error = -EACCES;
+ if (**name == '/')
+ *name = *name + 1;
+ } else if (**name != '/')
+ /* CONNECT_PATH with missing root */
+ error = prepend(name, *name - buf, "/", 1);
+
+ return error;
+}
+
/**
* d_namespace_path - lookup a name associated with a given path
* @path: path to lookup (NOT NULL)
@@ -74,7 +105,8 @@ static int d_namespace_path(struct path *path, char *buf, int buflen,
* control instead of hard coded /proc
*/
return prepend(name, *name - buf, "/proc", 5);
- }
+ } else
+ return disconnect(path, buf, name, flags);
return 0;
}
@@ -120,32 +152,8 @@ static int d_namespace_path(struct path *path, char *buf, int buflen,
goto out;
}
- /* If the path is not connected to the expected root,
- * check if it is a sysctl and handle specially else remove any
- * leading / that __d_path may have returned.
- * Unless
- * specifically directed to connect the path,
- * OR
- * if in a chroot and doing chroot relative paths and the path
- * resolves to the namespace root (would be connected outside
- * of chroot) and specifically directed to connect paths to
- * namespace root.
- */
- if (!connected) {
- if (!(flags & PATH_CONNECT_PATH) &&
- !(((flags & CHROOT_NSCONNECT) == CHROOT_NSCONNECT) &&
- our_mnt(path->mnt))) {
- /* disconnected path, don't return pathname starting
- * with '/'
- */
- error = -EACCES;
- if (*res == '/')
- *name = res + 1;
- } else if (*res != '/')
- /* CONNECT_PATH with missing root */
- error = prepend(name, *name - buf, "/", 1);
-
- }
+ if (!connected)
+ error = disconnect(path, buf, name, flags);
out:
return error;
--
2.7.4

View File

@@ -1,29 +0,0 @@
From c70811d9e6234c96d0ef405cd8ad78b70efb8637 Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Sat, 16 Apr 2016 13:59:02 -0700
Subject: [PATCH 09/27] apparmor: fix put() parent ref after updating the
active ref
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
---
security/apparmor/policy.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
index c92a9f6..455c9f8 100644
--- a/security/apparmor/policy.c
+++ b/security/apparmor/policy.c
@@ -1187,8 +1187,8 @@ ssize_t aa_replace_profiles(void *udata, size_t size, bool noreplace)
/* parent replaced in this atomic set? */
if (newest != parent) {
aa_get_profile(newest);
- aa_put_profile(parent);
rcu_assign_pointer(ent->new->parent, newest);
+ aa_put_profile(parent);
}
/* aafs interface uses replacedby */
rcu_assign_pointer(ent->new->replacedby->profile,
--
2.7.4

View File

@@ -1,87 +0,0 @@
From f671b902943f83f0fbc8c8b7bf8bbfb817d124f1 Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Sat, 16 Apr 2016 14:16:50 -0700
Subject: [PATCH 10/27] apparmor: fix log failures for all profiles in a set
currently only the profile that is causing the failure is logged. This
makes it more confusing than necessary about which profiles loaded
and which didn't. So make sure to log success and failure messages for
all profiles in the set being loaded.
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
---
security/apparmor/policy.c | 29 +++++++++++++++++++----------
1 file changed, 19 insertions(+), 10 deletions(-)
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
index 455c9f8..db31bc5 100644
--- a/security/apparmor/policy.c
+++ b/security/apparmor/policy.c
@@ -1067,7 +1067,7 @@ static int __lookup_replace(struct aa_namespace *ns, const char *hname,
*/
ssize_t aa_replace_profiles(void *udata, size_t size, bool noreplace)
{
- const char *ns_name, *name = NULL, *info = NULL;
+ const char *ns_name, *info = NULL;
struct aa_namespace *ns = NULL;
struct aa_load_ent *ent, *tmp;
int op = OP_PROF_REPL;
@@ -1082,18 +1082,15 @@ ssize_t aa_replace_profiles(void *udata, size_t size, bool noreplace)
/* released below */
ns = aa_prepare_namespace(ns_name);
if (!ns) {
- info = "failed to prepare namespace";
- error = -ENOMEM;
- name = ns_name;
- goto fail;
+ error = audit_policy(op, GFP_KERNEL, ns_name,
+ "failed to prepare namespace", -ENOMEM);
+ goto free;
}
mutex_lock(&ns->lock);
/* setup parent and ns info */
list_for_each_entry(ent, &lh, list) {
struct aa_policy *policy;
-
- name = ent->new->base.hname;
error = __lookup_replace(ns, ent->new->base.hname, noreplace,
&ent->old, &info);
if (error)
@@ -1121,7 +1118,6 @@ ssize_t aa_replace_profiles(void *udata, size_t size, bool noreplace)
if (!p) {
error = -ENOENT;
info = "parent does not exist";
- name = ent->new->base.hname;
goto fail_lock;
}
rcu_assign_pointer(ent->new->parent, aa_get_profile(p));
@@ -1214,9 +1210,22 @@ out:
fail_lock:
mutex_unlock(&ns->lock);
-fail:
- error = audit_policy(op, GFP_KERNEL, name, info, error);
+ /* audit cause of failure */
+ op = (!ent->old) ? OP_PROF_LOAD : OP_PROF_REPL;
+ audit_policy(op, GFP_KERNEL, ent->new->base.hname, info, error);
+ /* audit status that rest of profiles in the atomic set failed too */
+ info = "valid profile in failed atomic policy load";
+ list_for_each_entry(tmp, &lh, list) {
+ if (tmp == ent) {
+ info = "unchecked profile in failed atomic policy load";
+ /* skip entry that caused failure */
+ continue;
+ }
+ op = (!ent->old) ? OP_PROF_LOAD : OP_PROF_REPL;
+ audit_policy(op, GFP_KERNEL, tmp->new->base.hname, info, error);
+ }
+free:
list_for_each_entry_safe(ent, tmp, &lh, list) {
list_del_init(&ent->list);
aa_load_ent_free(ent);
--
2.7.4

View File

@@ -1,33 +0,0 @@
From bc3c7d342bf53afdfdf46bc92dac5c624c89fb91 Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Sat, 16 Apr 2016 14:19:38 -0700
Subject: [PATCH 11/27] apparmor: fix audit full profile hname on successful
load
Currently logging of a successful profile load only logs the basename
of the profile. This can result in confusion when a child profile has
the same name as the another profile in the set. Logging the hname
will ensure there is no confusion.
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
---
security/apparmor/policy.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
index db31bc5..ca402d0 100644
--- a/security/apparmor/policy.c
+++ b/security/apparmor/policy.c
@@ -1159,7 +1159,7 @@ ssize_t aa_replace_profiles(void *udata, size_t size, bool noreplace)
list_del_init(&ent->list);
op = (!ent->old && !ent->rename) ? OP_PROF_LOAD : OP_PROF_REPL;
- audit_policy(op, GFP_ATOMIC, ent->new->base.name, NULL, error);
+ audit_policy(op, GFP_ATOMIC, ent->new->base.hname, NULL, error);
if (ent->old) {
__replace_profile(ent->old, ent->new, 1);
--
2.7.4

View File

@@ -1,112 +0,0 @@
From 848da0479e5b9da3dc2ae4c64e0cca77a0abf02a Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Wed, 20 Apr 2016 14:18:18 -0700
Subject: [PATCH 12/27] apparmor: ensure the target profile name is always
audited
The target profile name was not being correctly audited in a few
cases because the target variable was not being set and gotos
passed the code to set it at apply:
Since it is always based on new_profile just drop the target var
and conditionally report based on new_profile.
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
---
security/apparmor/domain.c | 20 +++++++++-----------
1 file changed, 9 insertions(+), 11 deletions(-)
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
index 67a7418..fc3036b 100644
--- a/security/apparmor/domain.c
+++ b/security/apparmor/domain.c
@@ -346,7 +346,7 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
file_inode(bprm->file)->i_uid,
file_inode(bprm->file)->i_mode
};
- const char *name = NULL, *target = NULL, *info = NULL;
+ const char *name = NULL, *info = NULL;
int error = 0;
if (bprm->cred_prepared)
@@ -399,6 +399,7 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
if (cxt->onexec) {
struct file_perms cp;
info = "change_profile onexec";
+ new_profile = aa_get_newest_profile(cxt->onexec);
if (!(perms.allow & AA_MAY_ONEXEC))
goto audit;
@@ -413,7 +414,6 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
if (!(cp.allow & AA_MAY_ONEXEC))
goto audit;
- new_profile = aa_get_newest_profile(cxt->onexec);
goto apply;
}
@@ -445,10 +445,8 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
if (!new_profile) {
error = -ENOMEM;
info = "could not create null profile";
- } else {
+ } else
error = -EACCES;
- target = new_profile->base.hname;
- }
perms.xindex |= AA_X_UNSAFE;
} else
/* fail exec */
@@ -459,7 +457,6 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
* fail the exec.
*/
if (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS) {
- aa_put_profile(new_profile);
error = -EPERM;
goto cleanup;
}
@@ -474,10 +471,8 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
if (bprm->unsafe & (LSM_UNSAFE_PTRACE | LSM_UNSAFE_PTRACE_CAP)) {
error = may_change_ptraced_domain(new_profile);
- if (error) {
- aa_put_profile(new_profile);
+ if (error)
goto audit;
- }
}
/* Determine if secure exec is needed.
@@ -498,7 +493,6 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
bprm->unsafe |= AA_SECURE_X_NEEDED;
}
apply:
- target = new_profile->base.hname;
/* when transitioning profiles clear unsafe personality bits */
bprm->per_clear |= PER_CLEAR_ON_SETID;
@@ -506,15 +500,19 @@ x_clear:
aa_put_profile(cxt->profile);
/* transfer new profile reference will be released when cxt is freed */
cxt->profile = new_profile;
+ new_profile = NULL;
/* clear out all temporary/transitional state from the context */
aa_clear_task_cxt_trans(cxt);
audit:
error = aa_audit_file(profile, &perms, GFP_KERNEL, OP_EXEC, MAY_EXEC,
- name, target, cond.uid, info, error);
+ name,
+ new_profile ? new_profile->base.hname : NULL,
+ cond.uid, info, error);
cleanup:
+ aa_put_profile(new_profile);
aa_put_profile(profile);
kfree(buffer);
--
2.7.4

View File

@@ -1,27 +0,0 @@
From 706473f3ead5cdffe5ad159adfbc090e0fda81d6 Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Thu, 17 Mar 2016 12:02:54 -0700
Subject: [PATCH 13/27] apparmor: check that xindex is in trans_table bounds
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
---
security/apparmor/policy_unpack.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
index a689f10..c841b12 100644
--- a/security/apparmor/policy_unpack.c
+++ b/security/apparmor/policy_unpack.c
@@ -676,7 +676,7 @@ static bool verify_xindex(int xindex, int table_size)
int index, xtype;
xtype = xindex & AA_X_TYPE_MASK;
index = xindex & AA_X_INDEX_MASK;
- if (xtype == AA_X_TABLE && index > table_size)
+ if (xtype == AA_X_TABLE && index >= table_size)
return 0;
return 1;
}
--
2.7.4

View File

@@ -1,27 +0,0 @@
From 05a64c434466029b298ee1e78a988cd6a7f80c0e Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Wed, 18 Nov 2015 11:41:05 -0800
Subject: [PATCH 14/27] apparmor: fix ref count leak when profile sha1 hash is
read
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
---
security/apparmor/apparmorfs.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
index 45a6199..0d8dd71 100644
--- a/security/apparmor/apparmorfs.c
+++ b/security/apparmor/apparmorfs.c
@@ -331,6 +331,7 @@ static int aa_fs_seq_hash_show(struct seq_file *seq, void *v)
seq_printf(seq, "%.2x", profile->hash[i]);
seq_puts(seq, "\n");
}
+ aa_put_profile(profile);
return 0;
}
--
2.7.4

View File

@@ -1,37 +0,0 @@
From 6b0b8b91f454bd021e27abe0e611a6764e4806c1 Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Wed, 16 Dec 2015 18:09:10 -0800
Subject: [PATCH 15/27] apparmor: fix refcount race when finding a child
profile
When finding a child profile via an rcu critical section, the profile
may be put and scheduled for deletion after the child is found but
before its refcount is incremented.
Protect against this by repeating the lookup if the profiles refcount
is 0 and is one its way to deletion.
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
---
security/apparmor/policy.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
index ca402d0..7807125 100644
--- a/security/apparmor/policy.c
+++ b/security/apparmor/policy.c
@@ -766,7 +766,9 @@ struct aa_profile *aa_find_child(struct aa_profile *parent, const char *name)
struct aa_profile *profile;
rcu_read_lock();
- profile = aa_get_profile(__find_child(&parent->base.profiles, name));
+ do {
+ profile = __find_child(&parent->base.profiles, name);
+ } while (profile && !aa_get_profile_not0(profile));
rcu_read_unlock();
/* refcount released by caller */
--
2.7.4

View File

@@ -1,59 +0,0 @@
From 84acc6aa6976e62756e14d3a00c5634724cbaa59 Mon Sep 17 00:00:00 2001
From: Geliang Tang <geliangtang@163.com>
Date: Mon, 16 Nov 2015 21:46:33 +0800
Subject: [PATCH 16/27] apparmor: use list_next_entry instead of
list_entry_next
list_next_entry has been defined in list.h, so I replace list_entry_next
with it.
Signed-off-by: Geliang Tang <geliangtang@163.com>
Acked-by: Serge Hallyn <serge.hallyn@canonical.com>
Signed-off-by: John Johansen <john.johansen@canonical.com>
---
security/apparmor/apparmorfs.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
index 0d8dd71..729e595 100644
--- a/security/apparmor/apparmorfs.c
+++ b/security/apparmor/apparmorfs.c
@@ -553,8 +553,6 @@ fail2:
}
-#define list_entry_next(pos, member) \
- list_entry(pos->member.next, typeof(*pos), member)
#define list_entry_is_head(pos, head, member) (&pos->member == (head))
/**
@@ -585,7 +583,7 @@ static struct aa_namespace *__next_namespace(struct aa_namespace *root,
parent = ns->parent;
while (ns != root) {
mutex_unlock(&ns->lock);
- next = list_entry_next(ns, base.list);
+ next = list_next_entry(ns, base.list);
if (!list_entry_is_head(next, &parent->sub_ns, base.list)) {
mutex_lock(&next->lock);
return next;
@@ -639,7 +637,7 @@ static struct aa_profile *__next_profile(struct aa_profile *p)
parent = rcu_dereference_protected(p->parent,
mutex_is_locked(&p->ns->lock));
while (parent) {
- p = list_entry_next(p, base.list);
+ p = list_next_entry(p, base.list);
if (!list_entry_is_head(p, &parent->base.profiles, base.list))
return p;
p = parent;
@@ -648,7 +646,7 @@ static struct aa_profile *__next_profile(struct aa_profile *p)
}
/* is next another profile in the namespace */
- p = list_entry_next(p, base.list);
+ p = list_next_entry(p, base.list);
if (!list_entry_is_head(p, &ns->base.profiles, base.list))
return p;
--
2.7.4

View File

@@ -1,50 +0,0 @@
From a3896605318b86d8cf288c122e03604e349d5dd7 Mon Sep 17 00:00:00 2001
From: Jeff Mahoney <jeffm@suse.com>
Date: Fri, 6 Nov 2015 15:17:30 -0500
Subject: [PATCH 17/27] apparmor: allow SYS_CAP_RESOURCE to be sufficient to
prlimit another task
While using AppArmor, SYS_CAP_RESOURCE is insufficient to call prlimit
on another task. The only other example of a AppArmor mediating access to
another, already running, task (ignoring fork+exec) is ptrace.
The AppArmor model for ptrace is that one of the following must be true:
1) The tracer is unconfined
2) The tracer is in complain mode
3) The tracer and tracee are confined by the same profile
4) The tracer is confined but has SYS_CAP_PTRACE
1), 2, and 3) are already true for setrlimit.
We can match the ptrace model just by allowing CAP_SYS_RESOURCE.
We still test the values of the rlimit since it can always be overridden
using a value that means unlimited for a particular resource.
Signed-off-by: Jeff Mahoney <jeffm@suse.com>
Signed-off-by: John Johansen <john.johansen@canonical.com>
---
security/apparmor/resource.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/security/apparmor/resource.c b/security/apparmor/resource.c
index 748bf0c..67a6072 100644
--- a/security/apparmor/resource.c
+++ b/security/apparmor/resource.c
@@ -101,9 +101,11 @@ int aa_task_setrlimit(struct aa_profile *profile, struct task_struct *task,
/* TODO: extend resource control to handle other (non current)
* profiles. AppArmor rules currently have the implicit assumption
* that the task is setting the resource of a task confined with
- * the same profile.
+ * the same profile or that the task setting the resource of another
+ * task has CAP_SYS_RESOURCE.
*/
- if (profile != task_profile ||
+ if ((profile != task_profile &&
+ aa_capable(profile, CAP_SYS_RESOURCE, 1)) ||
(profile->rlimits.mask & (1 << resource) &&
new_rlim->rlim_max > profile->rlimits.limits[resource].rlim_max))
error = -EACCES;
--
2.7.4

View File

@@ -1,40 +0,0 @@
From 6fdcc3cfecd4d89457036627d59ebe5154d094c5 Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Thu, 2 Jun 2016 02:37:02 -0700
Subject: [PATCH 18/27] apparmor: add missing id bounds check on dfa
verification
Signed-off-by: John Johansen <john.johansen@canonical.com>
---
security/apparmor/include/match.h | 1 +
security/apparmor/match.c | 2 ++
2 files changed, 3 insertions(+)
diff --git a/security/apparmor/include/match.h b/security/apparmor/include/match.h
index 001c43a..a1c04fe 100644
--- a/security/apparmor/include/match.h
+++ b/security/apparmor/include/match.h
@@ -62,6 +62,7 @@ struct table_set_header {
#define YYTD_ID_ACCEPT2 6
#define YYTD_ID_NXT 7
#define YYTD_ID_TSIZE 8
+#define YYTD_ID_MAX 8
#define YYTD_DATA8 1
#define YYTD_DATA16 2
diff --git a/security/apparmor/match.c b/security/apparmor/match.c
index 727eb42..f9f57c6 100644
--- a/security/apparmor/match.c
+++ b/security/apparmor/match.c
@@ -47,6 +47,8 @@ static struct table_header *unpack_table(char *blob, size_t bsize)
* it every time we use td_id as an index
*/
th.td_id = be16_to_cpu(*(u16 *) (blob)) - 1;
+ if (th.td_id > YYTD_ID_MAX)
+ goto out;
th.td_flags = be16_to_cpu(*(u16 *) (blob + 2));
th.td_lolen = be32_to_cpu(*(u32 *) (blob + 8));
blob += sizeof(struct table_header);
--
2.7.4

View File

@@ -1,38 +0,0 @@
From 95d203cfb59627a86483a279ba82f1aa75297e07 Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Wed, 15 Jun 2016 09:57:55 +0300
Subject: [PATCH 19/27] apparmor: don't check for vmalloc_addr if kvzalloc()
failed
Signed-off-by: John Johansen <john.johansen@canonical.com>
---
security/apparmor/match.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/security/apparmor/match.c b/security/apparmor/match.c
index f9f57c6..32b72eb 100644
--- a/security/apparmor/match.c
+++ b/security/apparmor/match.c
@@ -75,14 +75,14 @@ static struct table_header *unpack_table(char *blob, size_t bsize)
u32, be32_to_cpu);
else
goto fail;
+ /* if table was vmalloced make sure the page tables are synced
+ * before it is used, as it goes live to all cpus.
+ */
+ if (is_vmalloc_addr(table))
+ vm_unmap_aliases();
}
out:
- /* if table was vmalloced make sure the page tables are synced
- * before it is used, as it goes live to all cpus.
- */
- if (is_vmalloc_addr(table))
- vm_unmap_aliases();
return table;
fail:
kvfree(table);
--
2.7.4

View File

@@ -1,33 +0,0 @@
From e925f976c7a9c85455f67c360671254bac2d9a91 Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Wed, 15 Jun 2016 10:00:55 +0300
Subject: [PATCH 20/27] apparmor: fix oops in profile_unpack() when policy_db
is not present
BugLink: http://bugs.launchpad.net/bugs/1592547
If unpack_dfa() returns NULL due to the dfa not being present,
profile_unpack() is not checking if the dfa is not present (NULL).
Signed-off-by: John Johansen <john.johansen@canonical.com>
---
security/apparmor/policy_unpack.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
index c841b12..dac2121 100644
--- a/security/apparmor/policy_unpack.c
+++ b/security/apparmor/policy_unpack.c
@@ -583,6 +583,9 @@ static struct aa_profile *unpack_profile(struct aa_ext *e)
error = PTR_ERR(profile->policy.dfa);
profile->policy.dfa = NULL;
goto fail;
+ } else if (!profile->policy.dfa) {
+ error = -EPROTO;
+ goto fail;
}
if (!unpack_u32(e, &profile->policy.start[0], "start"))
/* default start state */
--
2.7.4

View File

@@ -1,162 +0,0 @@
From 45774028820fe2ffbbc94667165f04749821d529 Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Wed, 22 Jun 2016 18:01:08 -0700
Subject: [PATCH 21/27] apparmor: fix module parameters can be changed after
policy is locked
the policy_lock parameter is a one way switch that prevents policy
from being further modified. Unfortunately some of the module parameters
can effectively modify policy by turning off enforcement.
split policy_admin_capable into a view check and a full admin check,
and update the admin check to test the policy_lock parameter.
Signed-off-by: John Johansen <john.johansen@canonical.com>
---
security/apparmor/include/policy.h | 2 ++
security/apparmor/lsm.c | 22 ++++++++++------------
security/apparmor/policy.c | 18 +++++++++++++++++-
3 files changed, 29 insertions(+), 13 deletions(-)
diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h
index c28b0f2..52275f0 100644
--- a/security/apparmor/include/policy.h
+++ b/security/apparmor/include/policy.h
@@ -403,6 +403,8 @@ static inline int AUDIT_MODE(struct aa_profile *profile)
return profile->audit;
}
+bool policy_view_capable(void);
+bool policy_admin_capable(void);
bool aa_may_manage_policy(int op);
#endif /* __AA_POLICY_H */
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index 5ee8201..bd40b12 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -751,51 +751,49 @@ __setup("apparmor=", apparmor_enabled_setup);
/* set global flag turning off the ability to load policy */
static int param_set_aalockpolicy(const char *val, const struct kernel_param *kp)
{
- if (!capable(CAP_MAC_ADMIN))
+ if (!policy_admin_capable())
return -EPERM;
- if (aa_g_lock_policy)
- return -EACCES;
return param_set_bool(val, kp);
}
static int param_get_aalockpolicy(char *buffer, const struct kernel_param *kp)
{
- if (!capable(CAP_MAC_ADMIN))
+ if (!policy_view_capable())
return -EPERM;
return param_get_bool(buffer, kp);
}
static int param_set_aabool(const char *val, const struct kernel_param *kp)
{
- if (!capable(CAP_MAC_ADMIN))
+ if (!policy_admin_capable())
return -EPERM;
return param_set_bool(val, kp);
}
static int param_get_aabool(char *buffer, const struct kernel_param *kp)
{
- if (!capable(CAP_MAC_ADMIN))
+ if (!policy_view_capable())
return -EPERM;
return param_get_bool(buffer, kp);
}
static int param_set_aauint(const char *val, const struct kernel_param *kp)
{
- if (!capable(CAP_MAC_ADMIN))
+ if (!policy_admin_capable())
return -EPERM;
return param_set_uint(val, kp);
}
static int param_get_aauint(char *buffer, const struct kernel_param *kp)
{
- if (!capable(CAP_MAC_ADMIN))
+ if (!policy_view_capable())
return -EPERM;
return param_get_uint(buffer, kp);
}
static int param_get_audit(char *buffer, struct kernel_param *kp)
{
- if (!capable(CAP_MAC_ADMIN))
+ if (!policy_view_capable())
return -EPERM;
if (!apparmor_enabled)
@@ -807,7 +805,7 @@ static int param_get_audit(char *buffer, struct kernel_param *kp)
static int param_set_audit(const char *val, struct kernel_param *kp)
{
int i;
- if (!capable(CAP_MAC_ADMIN))
+ if (!policy_admin_capable())
return -EPERM;
if (!apparmor_enabled)
@@ -828,7 +826,7 @@ static int param_set_audit(const char *val, struct kernel_param *kp)
static int param_get_mode(char *buffer, struct kernel_param *kp)
{
- if (!capable(CAP_MAC_ADMIN))
+ if (!policy_admin_capable())
return -EPERM;
if (!apparmor_enabled)
@@ -840,7 +838,7 @@ static int param_get_mode(char *buffer, struct kernel_param *kp)
static int param_set_mode(const char *val, struct kernel_param *kp)
{
int i;
- if (!capable(CAP_MAC_ADMIN))
+ if (!policy_admin_capable())
return -EPERM;
if (!apparmor_enabled)
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
index 7807125..179e68d 100644
--- a/security/apparmor/policy.c
+++ b/security/apparmor/policy.c
@@ -918,6 +918,22 @@ static int audit_policy(int op, gfp_t gfp, const char *name, const char *info,
&sa, NULL);
}
+bool policy_view_capable(void)
+{
+ struct user_namespace *user_ns = current_user_ns();
+ bool response = false;
+
+ if (ns_capable(user_ns, CAP_MAC_ADMIN))
+ response = true;
+
+ return response;
+}
+
+bool policy_admin_capable(void)
+{
+ return policy_view_capable() && !aa_g_lock_policy;
+}
+
/**
* aa_may_manage_policy - can the current task manage policy
* @op: the policy manipulation operation being done
@@ -932,7 +948,7 @@ bool aa_may_manage_policy(int op)
return 0;
}
- if (!capable(CAP_MAC_ADMIN)) {
+ if (!policy_admin_capable()) {
audit_policy(op, GFP_KERNEL, NULL, "not policy admin", -EACCES);
return 0;
}
--
2.7.4

View File

@@ -1,31 +0,0 @@
From 7fcfc22cd04261ac35a579c99bcc804db7eb3e83 Mon Sep 17 00:00:00 2001
From: Heinrich Schuchardt <xypron.glpk@gmx.de>
Date: Fri, 10 Jun 2016 23:34:26 +0200
Subject: [PATCH 22/27] apparmor: do not expose kernel stack
Do not copy uninitalized fields th.td_hilen, th.td_data.
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: John Johansen <john.johansen@canonical.com>
---
security/apparmor/match.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/security/apparmor/match.c b/security/apparmor/match.c
index 32b72eb..3f900fc 100644
--- a/security/apparmor/match.c
+++ b/security/apparmor/match.c
@@ -63,7 +63,9 @@ static struct table_header *unpack_table(char *blob, size_t bsize)
table = kvzalloc(tsize);
if (table) {
- *table = th;
+ table->td_id = th.td_id;
+ table->td_flags = th.td_flags;
+ table->td_lolen = th.td_lolen;
if (th.td_flags == YYTD_DATA8)
UNPACK_ARRAY(table->td_data, blob, th.td_lolen,
u8, byte_to_byte);
--
2.7.4

View File

@@ -1,27 +0,0 @@
From 1b98560066c26fecb0a61aeb9249e141af2e63f9 Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Sat, 9 Jul 2016 23:46:33 -0700
Subject: [PATCH 23/27] apparmor: fix arg_size computation for when setprocattr
is null terminated
Signed-off-by: John Johansen <john.johansen@canonical.com>
---
security/apparmor/lsm.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index bd40b12..1bf6c53 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -552,7 +552,7 @@ static int apparmor_setprocattr(struct task_struct *task, char *name,
if (!*args)
goto out;
- arg_size = size - (args - (char *) value);
+ arg_size = size - (args - (largs ? largs : (char *) value));
if (strcmp(name, "current") == 0) {
if (strcmp(command, "changehat") == 0) {
error = aa_setprocattr_changehat(args, arg_size,
--
2.7.4

View File

@@ -1,603 +0,0 @@
From 8d7c032e7798fa1c46449728874b64fff882368b Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Mon, 4 Oct 2010 15:03:36 -0700
Subject: [PATCH 24/27] UBUNTU: SAUCE: AppArmor: basic networking rules
Base support for network mediation.
Signed-off-by: John Johansen <john.johansen@canonical.com>
---
security/apparmor/.gitignore | 1 +
security/apparmor/Makefile | 42 +++++++++-
security/apparmor/apparmorfs.c | 1 +
security/apparmor/include/audit.h | 4 +
security/apparmor/include/net.h | 44 ++++++++++
security/apparmor/include/policy.h | 3 +
security/apparmor/lsm.c | 112 +++++++++++++++++++++++++
security/apparmor/net.c | 162 +++++++++++++++++++++++++++++++++++++
security/apparmor/policy.c | 1 +
security/apparmor/policy_unpack.c | 46 +++++++++++
10 files changed, 414 insertions(+), 2 deletions(-)
create mode 100644 security/apparmor/include/net.h
create mode 100644 security/apparmor/net.c
diff --git a/security/apparmor/.gitignore b/security/apparmor/.gitignore
index 9cdec70..d5b291e 100644
--- a/security/apparmor/.gitignore
+++ b/security/apparmor/.gitignore
@@ -1,5 +1,6 @@
#
# Generated include files
#
+net_names.h
capability_names.h
rlim_names.h
diff --git a/security/apparmor/Makefile b/security/apparmor/Makefile
index d693df8..5dbb72f 100644
--- a/security/apparmor/Makefile
+++ b/security/apparmor/Makefile
@@ -4,10 +4,10 @@ obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o
apparmor-y := apparmorfs.o audit.o capability.o context.o ipc.o lib.o match.o \
path.o domain.o policy.o policy_unpack.o procattr.o lsm.o \
- resource.o sid.o file.o
+ resource.o sid.o file.o net.o
apparmor-$(CONFIG_SECURITY_APPARMOR_HASH) += crypto.o
-clean-files := capability_names.h rlim_names.h
+clean-files := capability_names.h rlim_names.h net_names.h
# Build a lower case string table of capability names
@@ -25,6 +25,38 @@ cmd_make-caps = echo "static const char *const capability_names[] = {" > $@ ;\
-e 's/^\#define[ \t]+CAP_([A-Z0-9_]+)[ \t]+([0-9]+)/\L\1/p' | \
tr '\n' ' ' | sed -e 's/ $$/"\n/' >> $@
+# Build a lower case string table of address family names
+# Transform lines from
+# define AF_LOCAL 1 /* POSIX name for AF_UNIX */
+# #define AF_INET 2 /* Internet IP Protocol */
+# to
+# [1] = "local",
+# [2] = "inet",
+#
+# and build the securityfs entries for the mapping.
+# Transforms lines from
+# #define AF_INET 2 /* Internet IP Protocol */
+# to
+# #define AA_FS_AF_MASK "local inet"
+quiet_cmd_make-af = GEN $@
+cmd_make-af = echo "static const char *address_family_names[] = {" > $@ ;\
+ sed $< >>$@ -r -n -e "/AF_MAX/d" -e "/AF_LOCAL/d" -e \
+ 's/^\#define[ \t]+AF_([A-Z0-9_]+)[ \t]+([0-9]+)(.*)/[\2] = "\L\1",/p';\
+ echo "};" >> $@ ;\
+ echo -n '\#define AA_FS_AF_MASK "' >> $@ ;\
+ sed -r -n 's/^\#define[ \t]+AF_([A-Z0-9_]+)[ \t]+([0-9]+)(.*)/\L\1/p'\
+ $< | tr '\n' ' ' | sed -e 's/ $$/"\n/' >> $@
+
+# Build a lower case string table of sock type names
+# Transform lines from
+# SOCK_STREAM = 1,
+# to
+# [1] = "stream",
+quiet_cmd_make-sock = GEN $@
+cmd_make-sock = echo "static const char *sock_type_names[] = {" >> $@ ;\
+ sed $^ >>$@ -r -n \
+ -e 's/^\tSOCK_([A-Z0-9_]+)[\t]+=[ \t]+([0-9]+)(.*)/[\2] = "\L\1",/p';\
+ echo "};" >> $@
# Build a lower case string table of rlimit names.
# Transforms lines from
@@ -61,6 +93,7 @@ cmd_make-rlim = echo "static const char *const rlim_names[RLIM_NLIMITS] = {" \
tr '\n' ' ' | sed -e 's/ $$/"\n/' >> $@
$(obj)/capability.o : $(obj)/capability_names.h
+$(obj)/net.o : $(obj)/net_names.h
$(obj)/resource.o : $(obj)/rlim_names.h
$(obj)/capability_names.h : $(srctree)/include/uapi/linux/capability.h \
$(src)/Makefile
@@ -68,3 +101,8 @@ $(obj)/capability_names.h : $(srctree)/include/uapi/linux/capability.h \
$(obj)/rlim_names.h : $(srctree)/include/uapi/asm-generic/resource.h \
$(src)/Makefile
$(call cmd,make-rlim)
+$(obj)/net_names.h : $(srctree)/include/linux/socket.h \
+ $(srctree)/include/linux/net.h \
+ $(src)/Makefile
+ $(call cmd,make-af)
+ $(call cmd,make-sock)
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
index 729e595..181d961 100644
--- a/security/apparmor/apparmorfs.c
+++ b/security/apparmor/apparmorfs.c
@@ -807,6 +807,7 @@ static struct aa_fs_entry aa_fs_entry_features[] = {
AA_FS_DIR("policy", aa_fs_entry_policy),
AA_FS_DIR("domain", aa_fs_entry_domain),
AA_FS_DIR("file", aa_fs_entry_file),
+ AA_FS_DIR("network", aa_fs_entry_network),
AA_FS_FILE_U64("capability", VFS_CAP_FLAGS_MASK),
AA_FS_DIR("rlimit", aa_fs_entry_rlimit),
AA_FS_DIR("caps", aa_fs_entry_caps),
diff --git a/security/apparmor/include/audit.h b/security/apparmor/include/audit.h
index ba3dfd1..5d3c419 100644
--- a/security/apparmor/include/audit.h
+++ b/security/apparmor/include/audit.h
@@ -125,6 +125,10 @@ struct apparmor_audit_data {
u32 denied;
kuid_t ouid;
} fs;
+ struct {
+ int type, protocol;
+ struct sock *sk;
+ } net;
};
};
diff --git a/security/apparmor/include/net.h b/security/apparmor/include/net.h
new file mode 100644
index 0000000..cb8a121
--- /dev/null
+++ b/security/apparmor/include/net.h
@@ -0,0 +1,44 @@
+/*
+ * AppArmor security module
+ *
+ * This file contains AppArmor network mediation definitions.
+ *
+ * Copyright (C) 1998-2008 Novell/SUSE
+ * Copyright 2009-2012 Canonical Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ */
+
+#ifndef __AA_NET_H
+#define __AA_NET_H
+
+#include <net/sock.h>
+
+#include "apparmorfs.h"
+
+/* struct aa_net - network confinement data
+ * @allowed: basic network families permissions
+ * @audit_network: which network permissions to force audit
+ * @quiet_network: which network permissions to quiet rejects
+ */
+struct aa_net {
+ u16 allow[AF_MAX];
+ u16 audit[AF_MAX];
+ u16 quiet[AF_MAX];
+};
+
+extern struct aa_fs_entry aa_fs_entry_network[];
+
+extern int aa_net_perm(int op, struct aa_profile *profile, u16 family,
+ int type, int protocol, struct sock *sk);
+extern int aa_revalidate_sk(int op, struct sock *sk);
+
+static inline void aa_free_net_rules(struct aa_net *new)
+{
+ /* NOP */
+}
+
+#endif /* __AA_NET_H */
diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h
index 52275f0..4fc4dac 100644
--- a/security/apparmor/include/policy.h
+++ b/security/apparmor/include/policy.h
@@ -27,6 +27,7 @@
#include "capability.h"
#include "domain.h"
#include "file.h"
+#include "net.h"
#include "resource.h"
extern const char *const aa_profile_mode_names[];
@@ -176,6 +177,7 @@ struct aa_replacedby {
* @policy: general match rules governing policy
* @file: The set of rules governing basic file access and domain transitions
* @caps: capabilities for the profile
+ * @net: network controls for the profile
* @rlimits: rlimits for the profile
*
* @dents: dentries for the profiles file entries in apparmorfs
@@ -217,6 +219,7 @@ struct aa_profile {
struct aa_policydb policy;
struct aa_file_rules file;
struct aa_caps caps;
+ struct aa_net net;
struct aa_rlimit rlimits;
unsigned char *hash;
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index 1bf6c53..284ddda 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -32,6 +32,7 @@
#include "include/context.h"
#include "include/file.h"
#include "include/ipc.h"
+#include "include/net.h"
#include "include/path.h"
#include "include/policy.h"
#include "include/procattr.h"
@@ -607,6 +608,104 @@ static int apparmor_task_setrlimit(struct task_struct *task,
return error;
}
+static int apparmor_socket_create(int family, int type, int protocol, int kern)
+{
+ struct aa_profile *profile;
+ int error = 0;
+
+ if (kern)
+ return 0;
+
+ profile = __aa_current_profile();
+ if (!unconfined(profile))
+ error = aa_net_perm(OP_CREATE, profile, family, type, protocol,
+ NULL);
+ return error;
+}
+
+static int apparmor_socket_bind(struct socket *sock,
+ struct sockaddr *address, int addrlen)
+{
+ struct sock *sk = sock->sk;
+
+ return aa_revalidate_sk(OP_BIND, sk);
+}
+
+static int apparmor_socket_connect(struct socket *sock,
+ struct sockaddr *address, int addrlen)
+{
+ struct sock *sk = sock->sk;
+
+ return aa_revalidate_sk(OP_CONNECT, sk);
+}
+
+static int apparmor_socket_listen(struct socket *sock, int backlog)
+{
+ struct sock *sk = sock->sk;
+
+ return aa_revalidate_sk(OP_LISTEN, sk);
+}
+
+static int apparmor_socket_accept(struct socket *sock, struct socket *newsock)
+{
+ struct sock *sk = sock->sk;
+
+ return aa_revalidate_sk(OP_ACCEPT, sk);
+}
+
+static int apparmor_socket_sendmsg(struct socket *sock,
+ struct msghdr *msg, int size)
+{
+ struct sock *sk = sock->sk;
+
+ return aa_revalidate_sk(OP_SENDMSG, sk);
+}
+
+static int apparmor_socket_recvmsg(struct socket *sock,
+ struct msghdr *msg, int size, int flags)
+{
+ struct sock *sk = sock->sk;
+
+ return aa_revalidate_sk(OP_RECVMSG, sk);
+}
+
+static int apparmor_socket_getsockname(struct socket *sock)
+{
+ struct sock *sk = sock->sk;
+
+ return aa_revalidate_sk(OP_GETSOCKNAME, sk);
+}
+
+static int apparmor_socket_getpeername(struct socket *sock)
+{
+ struct sock *sk = sock->sk;
+
+ return aa_revalidate_sk(OP_GETPEERNAME, sk);
+}
+
+static int apparmor_socket_getsockopt(struct socket *sock, int level,
+ int optname)
+{
+ struct sock *sk = sock->sk;
+
+ return aa_revalidate_sk(OP_GETSOCKOPT, sk);
+}
+
+static int apparmor_socket_setsockopt(struct socket *sock, int level,
+ int optname)
+{
+ struct sock *sk = sock->sk;
+
+ return aa_revalidate_sk(OP_SETSOCKOPT, sk);
+}
+
+static int apparmor_socket_shutdown(struct socket *sock, int how)
+{
+ struct sock *sk = sock->sk;
+
+ return aa_revalidate_sk(OP_SOCK_SHUTDOWN, sk);
+}
+
static struct security_hook_list apparmor_hooks[] = {
LSM_HOOK_INIT(ptrace_access_check, apparmor_ptrace_access_check),
LSM_HOOK_INIT(ptrace_traceme, apparmor_ptrace_traceme),
@@ -636,6 +735,19 @@ static struct security_hook_list apparmor_hooks[] = {
LSM_HOOK_INIT(getprocattr, apparmor_getprocattr),
LSM_HOOK_INIT(setprocattr, apparmor_setprocattr),
+ LSM_HOOK_INIT(socket_create, apparmor_socket_create),
+ LSM_HOOK_INIT(socket_bind, apparmor_socket_bind),
+ LSM_HOOK_INIT(socket_connect, apparmor_socket_connect),
+ LSM_HOOK_INIT(socket_listen, apparmor_socket_listen),
+ LSM_HOOK_INIT(socket_accept, apparmor_socket_accept),
+ LSM_HOOK_INIT(socket_sendmsg, apparmor_socket_sendmsg),
+ LSM_HOOK_INIT(socket_recvmsg, apparmor_socket_recvmsg),
+ LSM_HOOK_INIT(socket_getsockname, apparmor_socket_getsockname),
+ LSM_HOOK_INIT(socket_getpeername, apparmor_socket_getpeername),
+ LSM_HOOK_INIT(socket_getsockopt, apparmor_socket_getsockopt),
+ LSM_HOOK_INIT(socket_setsockopt, apparmor_socket_setsockopt),
+ LSM_HOOK_INIT(socket_shutdown, apparmor_socket_shutdown),
+
LSM_HOOK_INIT(cred_alloc_blank, apparmor_cred_alloc_blank),
LSM_HOOK_INIT(cred_free, apparmor_cred_free),
LSM_HOOK_INIT(cred_prepare, apparmor_cred_prepare),
diff --git a/security/apparmor/net.c b/security/apparmor/net.c
new file mode 100644
index 0000000..003dd18
--- /dev/null
+++ b/security/apparmor/net.c
@@ -0,0 +1,162 @@
+/*
+ * AppArmor security module
+ *
+ * This file contains AppArmor network mediation
+ *
+ * Copyright (C) 1998-2008 Novell/SUSE
+ * Copyright 2009-2012 Canonical Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ */
+
+#include "include/apparmor.h"
+#include "include/audit.h"
+#include "include/context.h"
+#include "include/net.h"
+#include "include/policy.h"
+
+#include "net_names.h"
+
+struct aa_fs_entry aa_fs_entry_network[] = {
+ AA_FS_FILE_STRING("af_mask", AA_FS_AF_MASK),
+ { }
+};
+
+/* audit callback for net specific fields */
+static void audit_cb(struct audit_buffer *ab, void *va)
+{
+ struct common_audit_data *sa = va;
+
+ audit_log_format(ab, " family=");
+ if (address_family_names[sa->u.net->family]) {
+ audit_log_string(ab, address_family_names[sa->u.net->family]);
+ } else {
+ audit_log_format(ab, "\"unknown(%d)\"", sa->u.net->family);
+ }
+ audit_log_format(ab, " sock_type=");
+ if (sock_type_names[sa->aad->net.type]) {
+ audit_log_string(ab, sock_type_names[sa->aad->net.type]);
+ } else {
+ audit_log_format(ab, "\"unknown(%d)\"", sa->aad->net.type);
+ }
+ audit_log_format(ab, " protocol=%d", sa->aad->net.protocol);
+}
+
+/**
+ * audit_net - audit network access
+ * @profile: profile being enforced (NOT NULL)
+ * @op: operation being checked
+ * @family: network family
+ * @type: network type
+ * @protocol: network protocol
+ * @sk: socket auditing is being applied to
+ * @error: error code for failure else 0
+ *
+ * Returns: %0 or sa->error else other errorcode on failure
+ */
+static int audit_net(struct aa_profile *profile, int op, u16 family, int type,
+ int protocol, struct sock *sk, int error)
+{
+ int audit_type = AUDIT_APPARMOR_AUTO;
+ struct common_audit_data sa;
+ struct apparmor_audit_data aad = { };
+ struct lsm_network_audit net = { };
+ if (sk) {
+ sa.type = LSM_AUDIT_DATA_NET;
+ } else {
+ sa.type = LSM_AUDIT_DATA_NONE;
+ }
+ /* todo fill in socket addr info */
+ sa.aad = &aad;
+ sa.u.net = &net;
+ sa.aad->op = op,
+ sa.u.net->family = family;
+ sa.u.net->sk = sk;
+ sa.aad->net.type = type;
+ sa.aad->net.protocol = protocol;
+ sa.aad->error = error;
+
+ if (likely(!sa.aad->error)) {
+ u16 audit_mask = profile->net.audit[sa.u.net->family];
+ if (likely((AUDIT_MODE(profile) != AUDIT_ALL) &&
+ !(1 << sa.aad->net.type & audit_mask)))
+ return 0;
+ audit_type = AUDIT_APPARMOR_AUDIT;
+ } else {
+ u16 quiet_mask = profile->net.quiet[sa.u.net->family];
+ u16 kill_mask = 0;
+ u16 denied = (1 << sa.aad->net.type) & ~quiet_mask;
+
+ if (denied & kill_mask)
+ audit_type = AUDIT_APPARMOR_KILL;
+
+ if ((denied & quiet_mask) &&
+ AUDIT_MODE(profile) != AUDIT_NOQUIET &&
+ AUDIT_MODE(profile) != AUDIT_ALL)
+ return COMPLAIN_MODE(profile) ? 0 : sa.aad->error;
+ }
+
+ return aa_audit(audit_type, profile, GFP_KERNEL, &sa, audit_cb);
+}
+
+/**
+ * aa_net_perm - very course network access check
+ * @op: operation being checked
+ * @profile: profile being enforced (NOT NULL)
+ * @family: network family
+ * @type: network type
+ * @protocol: network protocol
+ *
+ * Returns: %0 else error if permission denied
+ */
+int aa_net_perm(int op, struct aa_profile *profile, u16 family, int type,
+ int protocol, struct sock *sk)
+{
+ u16 family_mask;
+ int error;
+
+ if ((family < 0) || (family >= AF_MAX))
+ return -EINVAL;
+
+ if ((type < 0) || (type >= SOCK_MAX))
+ return -EINVAL;
+
+ /* unix domain and netlink sockets are handled by ipc */
+ if (family == AF_UNIX || family == AF_NETLINK)
+ return 0;
+
+ family_mask = profile->net.allow[family];
+
+ error = (family_mask & (1 << type)) ? 0 : -EACCES;
+
+ return audit_net(profile, op, family, type, protocol, sk, error);
+}
+
+/**
+ * aa_revalidate_sk - Revalidate access to a sock
+ * @op: operation being checked
+ * @sk: sock being revalidated (NOT NULL)
+ *
+ * Returns: %0 else error if permission denied
+ */
+int aa_revalidate_sk(int op, struct sock *sk)
+{
+ struct aa_profile *profile;
+ int error = 0;
+
+ /* aa_revalidate_sk should not be called from interrupt context
+ * don't mediate these calls as they are not task related
+ */
+ if (in_interrupt())
+ return 0;
+
+ profile = __aa_current_profile();
+ if (!unconfined(profile))
+ error = aa_net_perm(op, profile, sk->sk_family, sk->sk_type,
+ sk->sk_protocol, sk);
+
+ return error;
+}
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
index 179e68d..f1a8541 100644
--- a/security/apparmor/policy.c
+++ b/security/apparmor/policy.c
@@ -603,6 +603,7 @@ void aa_free_profile(struct aa_profile *profile)
aa_free_file_rules(&profile->file);
aa_free_cap_rules(&profile->caps);
+ aa_free_net_rules(&profile->net);
aa_free_rlimit_rules(&profile->rlimits);
kzfree(profile->dirname);
diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
index dac2121..0107bc4 100644
--- a/security/apparmor/policy_unpack.c
+++ b/security/apparmor/policy_unpack.c
@@ -193,6 +193,19 @@ fail:
return 0;
}
+static bool unpack_u16(struct aa_ext *e, u16 *data, const char *name)
+{
+ if (unpack_nameX(e, AA_U16, name)) {
+ if (!inbounds(e, sizeof(u16)))
+ return 0;
+ if (data)
+ *data = le16_to_cpu(get_unaligned((u16 *) e->pos));
+ e->pos += sizeof(u16);
+ return 1;
+ }
+ return 0;
+}
+
static bool unpack_u32(struct aa_ext *e, u32 *data, const char *name)
{
if (unpack_nameX(e, AA_U32, name)) {
@@ -476,6 +489,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e)
{
struct aa_profile *profile = NULL;
const char *name = NULL;
+ size_t size = 0;
int i, error = -EPROTO;
kernel_cap_t tmpcap;
u32 tmp;
@@ -576,6 +590,38 @@ static struct aa_profile *unpack_profile(struct aa_ext *e)
if (!unpack_rlimits(e, profile))
goto fail;
+ size = unpack_array(e, "net_allowed_af");
+ if (size) {
+
+ for (i = 0; i < size; i++) {
+ /* discard extraneous rules that this kernel will
+ * never request
+ */
+ if (i >= AF_MAX) {
+ u16 tmp;
+ if (!unpack_u16(e, &tmp, NULL) ||
+ !unpack_u16(e, &tmp, NULL) ||
+ !unpack_u16(e, &tmp, NULL))
+ goto fail;
+ continue;
+ }
+ if (!unpack_u16(e, &profile->net.allow[i], NULL))
+ goto fail;
+ if (!unpack_u16(e, &profile->net.audit[i], NULL))
+ goto fail;
+ if (!unpack_u16(e, &profile->net.quiet[i], NULL))
+ goto fail;
+ }
+ if (!unpack_nameX(e, AA_ARRAYEND, NULL))
+ goto fail;
+ }
+ /*
+ * allow unix domain and netlink sockets they are handled
+ * by IPC
+ */
+ profile->net.allow[AF_UNIX] = 0xffff;
+ profile->net.allow[AF_NETLINK] = 0xffff;
+
if (unpack_nameX(e, AA_STRUCT, "policydb")) {
/* generic policy dfa - optional and may be NULL */
profile->policy.dfa = unpack_dfa(e);
--
2.7.4

View File

@@ -1,38 +0,0 @@
From aa45ba104003404efb59e6f7178045ade756035d Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Fri, 29 Jun 2012 17:34:00 -0700
Subject: [PATCH 25/27] apparmor: Fix quieting of audit messages for network
mediation
If a profile specified a quieting of network denials for a given rule by
either the quiet or deny rule qualifiers, the resultant quiet mask for
denied requests was applied incorrectly, resulting in two potential bugs.
1. The misapplied quiet mask would prevent denials from being correctly
tested against the kill mask/mode. Thus network access requests that
should have resulted in the application being killed did not.
2. The actual quieting of the denied network request was not being applied.
This would result in network rejections always being logged even when
they had been specifically marked as quieted.
Signed-off-by: John Johansen <john.johansen@canonical.com>
---
security/apparmor/net.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/security/apparmor/net.c b/security/apparmor/net.c
index 003dd18..6e6e5c9 100644
--- a/security/apparmor/net.c
+++ b/security/apparmor/net.c
@@ -88,7 +88,7 @@ static int audit_net(struct aa_profile *profile, int op, u16 family, int type,
} else {
u16 quiet_mask = profile->net.quiet[sa.u.net->family];
u16 kill_mask = 0;
- u16 denied = (1 << sa.aad->net.type) & ~quiet_mask;
+ u16 denied = (1 << sa.aad->net.type);
if (denied & kill_mask)
audit_type = AUDIT_APPARMOR_KILL;
--
2.7.4

View File

@@ -1,180 +0,0 @@
From 1eff686074a6af0cf47fc24c45ebb001c570a98b Mon Sep 17 00:00:00 2001
From: kbuild test robot <fengguang.wu@intel.com>
Date: Fri, 29 Jul 2016 12:44:43 +0800
Subject: [PATCH 27/27] UBUNTU: SAUCE: AppArmor: fix boolreturn.cocci warnings
security/apparmor/policy_unpack.c:143:9-10: WARNING: return of 0/1 in function 'unpack_X' with return type bool
security/apparmor/policy_unpack.c:189:9-10: WARNING: return of 0/1 in function 'unpack_nameX' with return type bool
security/apparmor/policy_unpack.c:475:8-9: WARNING: return of 0/1 in function 'unpack_rlimits' with return type bool
security/apparmor/policy_unpack.c:440:8-9: WARNING: return of 0/1 in function 'unpack_trans_table' with return type bool
security/apparmor/policy_unpack.c:200:10-11: WARNING: return of 0/1 in function 'unpack_u16' with return type bool
security/apparmor/policy_unpack.c:213:10-11: WARNING: return of 0/1 in function 'unpack_u32' with return type bool
security/apparmor/policy_unpack.c:226:10-11: WARNING: return of 0/1 in function 'unpack_u64' with return type bool
security/apparmor/policy_unpack.c:325:10-11: WARNING: return of 0/1 in function 'verify_accept' with return type bool
security/apparmor/policy_unpack.c:739:10-11: WARNING: return of 0/1 in function 'verify_dfa_xindex' with return type bool
security/apparmor/policy_unpack.c:729:9-10: WARNING: return of 0/1 in function 'verify_xindex' with return type bool
Return statements in functions returning bool should use
true/false instead of 1/0.
Generated by: scripts/coccinelle/misc/boolreturn.cocci
Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
Signed-off-by: John Johansen <john.johansen@canonical.com>
---
security/apparmor/policy_unpack.c | 52 +++++++++++++++++++--------------------
1 file changed, 26 insertions(+), 26 deletions(-)
diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
index 0107bc4..af14626 100644
--- a/security/apparmor/policy_unpack.c
+++ b/security/apparmor/policy_unpack.c
@@ -140,11 +140,11 @@ static size_t unpack_u16_chunk(struct aa_ext *e, char **chunk)
static bool unpack_X(struct aa_ext *e, enum aa_code code)
{
if (!inbounds(e, 1))
- return 0;
+ return false;
if (*(u8 *) e->pos != code)
- return 0;
+ return false;
e->pos++;
- return 1;
+ return true;
}
/**
@@ -186,50 +186,50 @@ static bool unpack_nameX(struct aa_ext *e, enum aa_code code, const char *name)
/* now check if type code matches */
if (unpack_X(e, code))
- return 1;
+ return true;
fail:
e->pos = pos;
- return 0;
+ return false;
}
static bool unpack_u16(struct aa_ext *e, u16 *data, const char *name)
{
if (unpack_nameX(e, AA_U16, name)) {
if (!inbounds(e, sizeof(u16)))
- return 0;
+ return false;
if (data)
*data = le16_to_cpu(get_unaligned((u16 *) e->pos));
e->pos += sizeof(u16);
- return 1;
+ return true;
}
- return 0;
+ return false;
}
static bool unpack_u32(struct aa_ext *e, u32 *data, const char *name)
{
if (unpack_nameX(e, AA_U32, name)) {
if (!inbounds(e, sizeof(u32)))
- return 0;
+ return false;
if (data)
*data = le32_to_cpu(get_unaligned((u32 *) e->pos));
e->pos += sizeof(u32);
- return 1;
+ return true;
}
- return 0;
+ return false;
}
static bool unpack_u64(struct aa_ext *e, u64 *data, const char *name)
{
if (unpack_nameX(e, AA_U64, name)) {
if (!inbounds(e, sizeof(u64)))
- return 0;
+ return false;
if (data)
*data = le64_to_cpu(get_unaligned((u64 *) e->pos));
e->pos += sizeof(u64);
- return 1;
+ return true;
}
- return 0;
+ return false;
}
static size_t unpack_array(struct aa_ext *e, const char *name)
@@ -322,12 +322,12 @@ static bool verify_accept(struct aa_dfa *dfa, int flags)
int mode = ACCEPT_TABLE(dfa)[i];
if (mode & ~DFA_VALID_PERM_MASK)
- return 0;
+ return false;
if (ACCEPT_TABLE2(dfa)[i] & ~DFA_VALID_PERM2_MASK)
- return 0;
+ return false;
}
- return 1;
+ return true;
}
/**
@@ -437,12 +437,12 @@ static bool unpack_trans_table(struct aa_ext *e, struct aa_profile *profile)
if (!unpack_nameX(e, AA_STRUCTEND, NULL))
goto fail;
}
- return 1;
+ return true;
fail:
aa_free_domain_entries(&profile->file.trans);
e->pos = pos;
- return 0;
+ return false;
}
static bool unpack_rlimits(struct aa_ext *e, struct aa_profile *profile)
@@ -472,11 +472,11 @@ static bool unpack_rlimits(struct aa_ext *e, struct aa_profile *profile)
if (!unpack_nameX(e, AA_STRUCTEND, NULL))
goto fail;
}
- return 1;
+ return true;
fail:
e->pos = pos;
- return 0;
+ return false;
}
/**
@@ -726,8 +726,8 @@ static bool verify_xindex(int xindex, int table_size)
xtype = xindex & AA_X_TYPE_MASK;
index = xindex & AA_X_INDEX_MASK;
if (xtype == AA_X_TABLE && index >= table_size)
- return 0;
- return 1;
+ return false;
+ return true;
}
/* verify dfa xindexes are in range of transition tables */
@@ -736,11 +736,11 @@ static bool verify_dfa_xindex(struct aa_dfa *dfa, int table_size)
int i;
for (i = 0; i < dfa->tables[YYTD_ID_ACCEPT]->td_lolen; i++) {
if (!verify_xindex(dfa_user_xindex(dfa, i), table_size))
- return 0;
+ return false;
if (!verify_xindex(dfa_other_xindex(dfa, i), table_size))
- return 0;
+ return false;
}
- return 1;
+ return true;
}
/**
--
2.7.4

View File

@@ -1,118 +0,0 @@
From 24b6ac149a57c2d3d5a9920e64d914e8ff00d346 Mon Sep 17 00:00:00 2001
From: Vegard Nossum <vegard.nossum@oracle.com>
Date: Thu, 7 Jul 2016 13:41:11 -0700
Subject: [PATCH 01/27] apparmor: fix oops, validate buffer size in
apparmor_setprocattr()
When proc_pid_attr_write() was changed to use memdup_user apparmor's
(interface violating) assumption that the setprocattr buffer was always
a single page was violated.
The size test is not strictly speaking needed as proc_pid_attr_write()
will reject anything larger, but for the sake of robustness we can keep
it in.
SMACK and SELinux look safe to me, but somebody else should probably
have a look just in case.
Based on original patch from Vegard Nossum <vegard.nossum@oracle.com>
modified for the case that apparmor provides null termination.
Fixes: bb646cdb12e75d82258c2f2e7746d5952d3e321a
Reported-by: Vegard Nossum <vegard.nossum@oracle.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: John Johansen <john.johansen@canonical.com>
Cc: Paul Moore <paul@paul-moore.com>
Cc: Stephen Smalley <sds@tycho.nsa.gov>
Cc: Eric Paris <eparis@parisplace.org>
Cc: Casey Schaufler <casey@schaufler-ca.com>
Cc: stable@kernel.org
Signed-off-by: John Johansen <john.johansen@canonical.com>
Reviewed-by: Tyler Hicks <tyhicks@canonical.com>
Signed-off-by: James Morris <james.l.morris@oracle.com>
---
security/apparmor/lsm.c | 36 +++++++++++++++++++-----------------
1 file changed, 19 insertions(+), 17 deletions(-)
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index dec607c..5ee8201 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -523,34 +523,34 @@ static int apparmor_setprocattr(struct task_struct *task, char *name,
{
struct common_audit_data sa;
struct apparmor_audit_data aad = {0,};
- char *command, *args = value;
+ char *command, *largs = NULL, *args = value;
size_t arg_size;
int error;
if (size == 0)
return -EINVAL;
- /* args points to a PAGE_SIZE buffer, AppArmor requires that
- * the buffer must be null terminated or have size <= PAGE_SIZE -1
- * so that AppArmor can null terminate them
- */
- if (args[size - 1] != '\0') {
- if (size == PAGE_SIZE)
- return -EINVAL;
- args[size] = '\0';
- }
-
/* task can only write its own attributes */
if (current != task)
return -EACCES;
- args = value;
+ /* AppArmor requires that the buffer must be null terminated atm */
+ if (args[size - 1] != '\0') {
+ /* null terminate */
+ largs = args = kmalloc(size + 1, GFP_KERNEL);
+ if (!args)
+ return -ENOMEM;
+ memcpy(args, value, size);
+ args[size] = '\0';
+ }
+
+ error = -EINVAL;
args = strim(args);
command = strsep(&args, " ");
if (!args)
- return -EINVAL;
+ goto out;
args = skip_spaces(args);
if (!*args)
- return -EINVAL;
+ goto out;
arg_size = size - (args - (char *) value);
if (strcmp(name, "current") == 0) {
@@ -576,10 +576,12 @@ static int apparmor_setprocattr(struct task_struct *task, char *name,
goto fail;
} else
/* only support the "current" and "exec" process attributes */
- return -EINVAL;
+ goto fail;
if (!error)
error = size;
+out:
+ kfree(largs);
return error;
fail:
@@ -588,9 +590,9 @@ fail:
aad.profile = aa_current_profile();
aad.op = OP_SETPROCATTR;
aad.info = name;
- aad.error = -EINVAL;
+ aad.error = error = -EINVAL;
aa_audit_msg(AUDIT_APPARMOR_DENIED, &sa, NULL);
- return -EINVAL;
+ goto out;
}
static int apparmor_task_setrlimit(struct task_struct *task,
--
2.7.4

View File

@@ -1,33 +0,0 @@
From 444bc4f95ec283cd0fb9777f4890bd9bc307809d Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Mon, 11 Apr 2016 16:55:10 -0700
Subject: [PATCH 02/27] apparmor: fix refcount bug in profile replacement
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
---
security/apparmor/policy.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
index 705c287..222052f 100644
--- a/security/apparmor/policy.c
+++ b/security/apparmor/policy.c
@@ -1189,12 +1189,12 @@ ssize_t aa_replace_profiles(void *udata, size_t size, bool noreplace)
aa_get_profile(newest);
aa_put_profile(parent);
rcu_assign_pointer(ent->new->parent, newest);
- } else
- aa_put_profile(newest);
+ }
/* aafs interface uses replacedby */
rcu_assign_pointer(ent->new->replacedby->profile,
aa_get_profile(ent->new));
__list_add_profile(&parent->base.profiles, ent->new);
+ aa_put_profile(newest);
} else {
/* aafs interface uses replacedby */
rcu_assign_pointer(ent->new->replacedby->profile,
--
2.7.4

View File

@@ -1,38 +0,0 @@
From 1224a06778b89dcbf0ca85bd961c2fcdd8765a69 Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Mon, 11 Apr 2016 16:57:19 -0700
Subject: [PATCH 03/27] apparmor: fix replacement bug that adds new child to
old parent
When set atomic replacement is used and the parent is updated before the
child, and the child did not exist in the old parent so there is no
direct replacement then the new child is incorrectly added to the old
parent. This results in the new parent not having the child(ren) that
it should and the old parent when being destroyed asserting the
following error.
AppArmor: policy_destroy: internal error, policy '<profile/name>' still
contains profiles
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
---
security/apparmor/policy.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
index 222052f..c92a9f6 100644
--- a/security/apparmor/policy.c
+++ b/security/apparmor/policy.c
@@ -1193,7 +1193,7 @@ ssize_t aa_replace_profiles(void *udata, size_t size, bool noreplace)
/* aafs interface uses replacedby */
rcu_assign_pointer(ent->new->replacedby->profile,
aa_get_profile(ent->new));
- __list_add_profile(&parent->base.profiles, ent->new);
+ __list_add_profile(&newest->base.profiles, ent->new);
aa_put_profile(newest);
} else {
/* aafs interface uses replacedby */
--
2.7.4

View File

@@ -1,87 +0,0 @@
From 15d921647676fdc2c3ee1cf9aa8f578b1012ecff Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Sun, 8 Jun 2014 11:20:54 -0700
Subject: [PATCH 04/27] apparmor: fix uninitialized lsm_audit member
BugLink: http://bugs.launchpad.net/bugs/1268727
The task field in the lsm_audit struct needs to be initialized if
a change_hat fails, otherwise the following oops will occur
BUG: unable to handle kernel paging request at 0000002fbead7d08
IP: [<ffffffff8171153e>] _raw_spin_lock+0xe/0x50
PGD 1e3f35067 PUD 0
Oops: 0002 [#1] SMP
Modules linked in: pppox crc_ccitt p8023 p8022 psnap llc ax25 btrfs raid6_pq xor xfs libcrc32c dm_multipath scsi_dh kvm_amd dcdbas kvm microcode amd64_edac_mod joydev edac_core psmouse edac_mce_amd serio_raw k10temp sp5100_tco i2c_piix4 ipmi_si ipmi_msghandler acpi_power_meter mac_hid lp parport hid_generic usbhid hid pata_acpi mpt2sas ahci raid_class pata_atiixp bnx2 libahci scsi_transport_sas [last unloaded: tipc]
CPU: 2 PID: 699 Comm: changehat_twice Tainted: GF O 3.13.0-7-generic #25-Ubuntu
Hardware name: Dell Inc. PowerEdge R415/08WNM9, BIOS 1.8.6 12/06/2011
task: ffff8802135c6000 ti: ffff880212986000 task.ti: ffff880212986000
RIP: 0010:[<ffffffff8171153e>] [<ffffffff8171153e>] _raw_spin_lock+0xe/0x50
RSP: 0018:ffff880212987b68 EFLAGS: 00010006
RAX: 0000000000020000 RBX: 0000002fbead7500 RCX: 0000000000000000
RDX: 0000000000000292 RSI: ffff880212987ba8 RDI: 0000002fbead7d08
RBP: ffff880212987b68 R08: 0000000000000246 R09: ffff880216e572a0
R10: ffffffff815fd677 R11: ffffea0008469580 R12: ffffffff8130966f
R13: ffff880212987ba8 R14: 0000002fbead7d08 R15: ffff8800d8c6b830
FS: 00002b5e6c84e7c0(0000) GS:ffff880216e40000(0000) knlGS:0000000055731700
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000002fbead7d08 CR3: 000000021270f000 CR4: 00000000000006e0
Stack:
ffff880212987b98 ffffffff81075f17 ffffffff8130966f 0000000000000009
0000000000000000 0000000000000000 ffff880212987bd0 ffffffff81075f7c
0000000000000292 ffff880212987c08 ffff8800d8c6b800 0000000000000026
Call Trace:
[<ffffffff81075f17>] __lock_task_sighand+0x47/0x80
[<ffffffff8130966f>] ? apparmor_cred_prepare+0x2f/0x50
[<ffffffff81075f7c>] do_send_sig_info+0x2c/0x80
[<ffffffff81075fee>] send_sig_info+0x1e/0x30
[<ffffffff8130242d>] aa_audit+0x13d/0x190
[<ffffffff8130c1dc>] aa_audit_file+0xbc/0x130
[<ffffffff8130966f>] ? apparmor_cred_prepare+0x2f/0x50
[<ffffffff81304cc2>] aa_change_hat+0x202/0x530
[<ffffffff81308fc6>] aa_setprocattr_changehat+0x116/0x1d0
[<ffffffff8130a11d>] apparmor_setprocattr+0x25d/0x300
[<ffffffff812cee56>] security_setprocattr+0x16/0x20
[<ffffffff8121fc87>] proc_pid_attr_write+0x107/0x130
[<ffffffff811b7604>] vfs_write+0xb4/0x1f0
[<ffffffff811b8039>] SyS_write+0x49/0xa0
[<ffffffff8171a1bf>] tracesys+0xe1/0xe6
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
---
security/apparmor/audit.c | 3 ++-
security/apparmor/file.c | 3 ++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/security/apparmor/audit.c b/security/apparmor/audit.c
index 89c7865..3a7f1da 100644
--- a/security/apparmor/audit.c
+++ b/security/apparmor/audit.c
@@ -200,7 +200,8 @@ int aa_audit(int type, struct aa_profile *profile, gfp_t gfp,
if (sa->aad->type == AUDIT_APPARMOR_KILL)
(void)send_sig_info(SIGKILL, NULL,
- sa->u.tsk ? sa->u.tsk : current);
+ sa->type == LSM_AUDIT_DATA_TASK && sa->u.tsk ?
+ sa->u.tsk : current);
if (sa->aad->type == AUDIT_APPARMOR_ALLOWED)
return complain_error(sa->aad->error);
diff --git a/security/apparmor/file.c b/security/apparmor/file.c
index 913f377..43d6ae7 100644
--- a/security/apparmor/file.c
+++ b/security/apparmor/file.c
@@ -110,7 +110,8 @@ int aa_audit_file(struct aa_profile *profile, struct file_perms *perms,
int type = AUDIT_APPARMOR_AUTO;
struct common_audit_data sa;
struct apparmor_audit_data aad = {0,};
- sa.type = LSM_AUDIT_DATA_NONE;
+ sa.type = LSM_AUDIT_DATA_TASK;
+ sa.u.tsk = NULL;
sa.aad = &aad;
aad.op = op,
aad.fs.request = request;
--
2.7.4

View File

@@ -1,32 +0,0 @@
From c1216728b7d644443eef31e4bd9d01b4a0a51d61 Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Fri, 25 Jul 2014 04:02:03 -0700
Subject: [PATCH 05/27] apparmor: exec should not be returning ENOENT when it
denies
The current behavior is confusing as it causes exec failures to report
the executable is missing instead of identifying that apparmor
caused the failure.
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
---
security/apparmor/domain.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
index dc0027b..67a7418 100644
--- a/security/apparmor/domain.c
+++ b/security/apparmor/domain.c
@@ -433,7 +433,7 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
new_profile = aa_get_newest_profile(ns->unconfined);
info = "ux fallback";
} else {
- error = -ENOENT;
+ error = -EACCES;
info = "profile not found";
/* remove MAY_EXEC to audit as failure */
perms.allow &= ~MAY_EXEC;
--
2.7.4

View File

@@ -1,28 +0,0 @@
From 2d3389de6c8ab6b3ad2cef4ea460c8fce2a226b9 Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Fri, 25 Jul 2014 04:01:56 -0700
Subject: [PATCH 06/27] apparmor: fix update the mtime of the profile file on
replacement
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
---
security/apparmor/apparmorfs.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
index ad4fa49..45a6199 100644
--- a/security/apparmor/apparmorfs.c
+++ b/security/apparmor/apparmorfs.c
@@ -379,6 +379,8 @@ void __aa_fs_profile_migrate_dents(struct aa_profile *old,
for (i = 0; i < AAFS_PROF_SIZEOF; i++) {
new->dents[i] = old->dents[i];
+ if (new->dents[i])
+ new->dents[i]->d_inode->i_mtime = CURRENT_TIME;
old->dents[i] = NULL;
}
}
--
2.7.4

View File

@@ -1,36 +0,0 @@
From 9caa96e30a1b2bb191a29af872285c8d0b078c10 Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Fri, 25 Jul 2014 04:02:08 -0700
Subject: [PATCH 07/27] apparmor: fix disconnected bind mnts reconnection
Bind mounts can fail to be properly reconnected when PATH_CONNECT is
specified. Ensure that when PATH_CONNECT is specified the path has
a root.
BugLink: http://bugs.launchpad.net/bugs/1319984
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
---
security/apparmor/path.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/security/apparmor/path.c b/security/apparmor/path.c
index 71e0e3a..bb2f2c6 100644
--- a/security/apparmor/path.c
+++ b/security/apparmor/path.c
@@ -141,7 +141,10 @@ static int d_namespace_path(struct path *path, char *buf, int buflen,
error = -EACCES;
if (*res == '/')
*name = res + 1;
- }
+ } else if (*res != '/')
+ /* CONNECT_PATH with missing root */
+ error = prepend(name, *name - buf, "/", 1);
+
}
out:
--
2.7.4

View File

@@ -1,114 +0,0 @@
From 11702a732e149380e05e2ab8ae1b743ac89f892f Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Fri, 25 Jul 2014 04:02:10 -0700
Subject: [PATCH 08/27] apparmor: internal paths should be treated as
disconnected
Internal mounts are not mounted anywhere and as such should be treated
as disconnected paths.
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
---
security/apparmor/path.c | 64 +++++++++++++++++++++++++++---------------------
1 file changed, 36 insertions(+), 28 deletions(-)
diff --git a/security/apparmor/path.c b/security/apparmor/path.c
index bb2f2c6..596f799 100644
--- a/security/apparmor/path.c
+++ b/security/apparmor/path.c
@@ -25,7 +25,6 @@
#include "include/path.h"
#include "include/policy.h"
-
/* modified from dcache.c */
static int prepend(char **buffer, int buflen, const char *str, int namelen)
{
@@ -39,6 +38,38 @@ static int prepend(char **buffer, int buflen, const char *str, int namelen)
#define CHROOT_NSCONNECT (PATH_CHROOT_REL | PATH_CHROOT_NSCONNECT)
+/* If the path is not connected to the expected root,
+ * check if it is a sysctl and handle specially else remove any
+ * leading / that __d_path may have returned.
+ * Unless
+ * specifically directed to connect the path,
+ * OR
+ * if in a chroot and doing chroot relative paths and the path
+ * resolves to the namespace root (would be connected outside
+ * of chroot) and specifically directed to connect paths to
+ * namespace root.
+ */
+static int disconnect(const struct path *path, char *buf, char **name,
+ int flags)
+{
+ int error = 0;
+
+ if (!(flags & PATH_CONNECT_PATH) &&
+ !(((flags & CHROOT_NSCONNECT) == CHROOT_NSCONNECT) &&
+ our_mnt(path->mnt))) {
+ /* disconnected path, don't return pathname starting
+ * with '/'
+ */
+ error = -EACCES;
+ if (**name == '/')
+ *name = *name + 1;
+ } else if (**name != '/')
+ /* CONNECT_PATH with missing root */
+ error = prepend(name, *name - buf, "/", 1);
+
+ return error;
+}
+
/**
* d_namespace_path - lookup a name associated with a given path
* @path: path to lookup (NOT NULL)
@@ -74,7 +105,8 @@ static int d_namespace_path(struct path *path, char *buf, int buflen,
* control instead of hard coded /proc
*/
return prepend(name, *name - buf, "/proc", 5);
- }
+ } else
+ return disconnect(path, buf, name, flags);
return 0;
}
@@ -120,32 +152,8 @@ static int d_namespace_path(struct path *path, char *buf, int buflen,
goto out;
}
- /* If the path is not connected to the expected root,
- * check if it is a sysctl and handle specially else remove any
- * leading / that __d_path may have returned.
- * Unless
- * specifically directed to connect the path,
- * OR
- * if in a chroot and doing chroot relative paths and the path
- * resolves to the namespace root (would be connected outside
- * of chroot) and specifically directed to connect paths to
- * namespace root.
- */
- if (!connected) {
- if (!(flags & PATH_CONNECT_PATH) &&
- !(((flags & CHROOT_NSCONNECT) == CHROOT_NSCONNECT) &&
- our_mnt(path->mnt))) {
- /* disconnected path, don't return pathname starting
- * with '/'
- */
- error = -EACCES;
- if (*res == '/')
- *name = res + 1;
- } else if (*res != '/')
- /* CONNECT_PATH with missing root */
- error = prepend(name, *name - buf, "/", 1);
-
- }
+ if (!connected)
+ error = disconnect(path, buf, name, flags);
out:
return error;
--
2.7.4

View File

@@ -1,29 +0,0 @@
From c70811d9e6234c96d0ef405cd8ad78b70efb8637 Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Sat, 16 Apr 2016 13:59:02 -0700
Subject: [PATCH 09/27] apparmor: fix put() parent ref after updating the
active ref
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
---
security/apparmor/policy.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
index c92a9f6..455c9f8 100644
--- a/security/apparmor/policy.c
+++ b/security/apparmor/policy.c
@@ -1187,8 +1187,8 @@ ssize_t aa_replace_profiles(void *udata, size_t size, bool noreplace)
/* parent replaced in this atomic set? */
if (newest != parent) {
aa_get_profile(newest);
- aa_put_profile(parent);
rcu_assign_pointer(ent->new->parent, newest);
+ aa_put_profile(parent);
}
/* aafs interface uses replacedby */
rcu_assign_pointer(ent->new->replacedby->profile,
--
2.7.4

View File

@@ -1,87 +0,0 @@
From f671b902943f83f0fbc8c8b7bf8bbfb817d124f1 Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Sat, 16 Apr 2016 14:16:50 -0700
Subject: [PATCH 10/27] apparmor: fix log failures for all profiles in a set
currently only the profile that is causing the failure is logged. This
makes it more confusing than necessary about which profiles loaded
and which didn't. So make sure to log success and failure messages for
all profiles in the set being loaded.
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
---
security/apparmor/policy.c | 29 +++++++++++++++++++----------
1 file changed, 19 insertions(+), 10 deletions(-)
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
index 455c9f8..db31bc5 100644
--- a/security/apparmor/policy.c
+++ b/security/apparmor/policy.c
@@ -1067,7 +1067,7 @@ static int __lookup_replace(struct aa_namespace *ns, const char *hname,
*/
ssize_t aa_replace_profiles(void *udata, size_t size, bool noreplace)
{
- const char *ns_name, *name = NULL, *info = NULL;
+ const char *ns_name, *info = NULL;
struct aa_namespace *ns = NULL;
struct aa_load_ent *ent, *tmp;
int op = OP_PROF_REPL;
@@ -1082,18 +1082,15 @@ ssize_t aa_replace_profiles(void *udata, size_t size, bool noreplace)
/* released below */
ns = aa_prepare_namespace(ns_name);
if (!ns) {
- info = "failed to prepare namespace";
- error = -ENOMEM;
- name = ns_name;
- goto fail;
+ error = audit_policy(op, GFP_KERNEL, ns_name,
+ "failed to prepare namespace", -ENOMEM);
+ goto free;
}
mutex_lock(&ns->lock);
/* setup parent and ns info */
list_for_each_entry(ent, &lh, list) {
struct aa_policy *policy;
-
- name = ent->new->base.hname;
error = __lookup_replace(ns, ent->new->base.hname, noreplace,
&ent->old, &info);
if (error)
@@ -1121,7 +1118,6 @@ ssize_t aa_replace_profiles(void *udata, size_t size, bool noreplace)
if (!p) {
error = -ENOENT;
info = "parent does not exist";
- name = ent->new->base.hname;
goto fail_lock;
}
rcu_assign_pointer(ent->new->parent, aa_get_profile(p));
@@ -1214,9 +1210,22 @@ out:
fail_lock:
mutex_unlock(&ns->lock);
-fail:
- error = audit_policy(op, GFP_KERNEL, name, info, error);
+ /* audit cause of failure */
+ op = (!ent->old) ? OP_PROF_LOAD : OP_PROF_REPL;
+ audit_policy(op, GFP_KERNEL, ent->new->base.hname, info, error);
+ /* audit status that rest of profiles in the atomic set failed too */
+ info = "valid profile in failed atomic policy load";
+ list_for_each_entry(tmp, &lh, list) {
+ if (tmp == ent) {
+ info = "unchecked profile in failed atomic policy load";
+ /* skip entry that caused failure */
+ continue;
+ }
+ op = (!ent->old) ? OP_PROF_LOAD : OP_PROF_REPL;
+ audit_policy(op, GFP_KERNEL, tmp->new->base.hname, info, error);
+ }
+free:
list_for_each_entry_safe(ent, tmp, &lh, list) {
list_del_init(&ent->list);
aa_load_ent_free(ent);
--
2.7.4

View File

@@ -1,33 +0,0 @@
From bc3c7d342bf53afdfdf46bc92dac5c624c89fb91 Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Sat, 16 Apr 2016 14:19:38 -0700
Subject: [PATCH 11/27] apparmor: fix audit full profile hname on successful
load
Currently logging of a successful profile load only logs the basename
of the profile. This can result in confusion when a child profile has
the same name as the another profile in the set. Logging the hname
will ensure there is no confusion.
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
---
security/apparmor/policy.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
index db31bc5..ca402d0 100644
--- a/security/apparmor/policy.c
+++ b/security/apparmor/policy.c
@@ -1159,7 +1159,7 @@ ssize_t aa_replace_profiles(void *udata, size_t size, bool noreplace)
list_del_init(&ent->list);
op = (!ent->old && !ent->rename) ? OP_PROF_LOAD : OP_PROF_REPL;
- audit_policy(op, GFP_ATOMIC, ent->new->base.name, NULL, error);
+ audit_policy(op, GFP_ATOMIC, ent->new->base.hname, NULL, error);
if (ent->old) {
__replace_profile(ent->old, ent->new, 1);
--
2.7.4

View File

@@ -1,112 +0,0 @@
From 848da0479e5b9da3dc2ae4c64e0cca77a0abf02a Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Wed, 20 Apr 2016 14:18:18 -0700
Subject: [PATCH 12/27] apparmor: ensure the target profile name is always
audited
The target profile name was not being correctly audited in a few
cases because the target variable was not being set and gotos
passed the code to set it at apply:
Since it is always based on new_profile just drop the target var
and conditionally report based on new_profile.
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
---
security/apparmor/domain.c | 20 +++++++++-----------
1 file changed, 9 insertions(+), 11 deletions(-)
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
index 67a7418..fc3036b 100644
--- a/security/apparmor/domain.c
+++ b/security/apparmor/domain.c
@@ -346,7 +346,7 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
file_inode(bprm->file)->i_uid,
file_inode(bprm->file)->i_mode
};
- const char *name = NULL, *target = NULL, *info = NULL;
+ const char *name = NULL, *info = NULL;
int error = 0;
if (bprm->cred_prepared)
@@ -399,6 +399,7 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
if (cxt->onexec) {
struct file_perms cp;
info = "change_profile onexec";
+ new_profile = aa_get_newest_profile(cxt->onexec);
if (!(perms.allow & AA_MAY_ONEXEC))
goto audit;
@@ -413,7 +414,6 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
if (!(cp.allow & AA_MAY_ONEXEC))
goto audit;
- new_profile = aa_get_newest_profile(cxt->onexec);
goto apply;
}
@@ -445,10 +445,8 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
if (!new_profile) {
error = -ENOMEM;
info = "could not create null profile";
- } else {
+ } else
error = -EACCES;
- target = new_profile->base.hname;
- }
perms.xindex |= AA_X_UNSAFE;
} else
/* fail exec */
@@ -459,7 +457,6 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
* fail the exec.
*/
if (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS) {
- aa_put_profile(new_profile);
error = -EPERM;
goto cleanup;
}
@@ -474,10 +471,8 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
if (bprm->unsafe & (LSM_UNSAFE_PTRACE | LSM_UNSAFE_PTRACE_CAP)) {
error = may_change_ptraced_domain(new_profile);
- if (error) {
- aa_put_profile(new_profile);
+ if (error)
goto audit;
- }
}
/* Determine if secure exec is needed.
@@ -498,7 +493,6 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
bprm->unsafe |= AA_SECURE_X_NEEDED;
}
apply:
- target = new_profile->base.hname;
/* when transitioning profiles clear unsafe personality bits */
bprm->per_clear |= PER_CLEAR_ON_SETID;
@@ -506,15 +500,19 @@ x_clear:
aa_put_profile(cxt->profile);
/* transfer new profile reference will be released when cxt is freed */
cxt->profile = new_profile;
+ new_profile = NULL;
/* clear out all temporary/transitional state from the context */
aa_clear_task_cxt_trans(cxt);
audit:
error = aa_audit_file(profile, &perms, GFP_KERNEL, OP_EXEC, MAY_EXEC,
- name, target, cond.uid, info, error);
+ name,
+ new_profile ? new_profile->base.hname : NULL,
+ cond.uid, info, error);
cleanup:
+ aa_put_profile(new_profile);
aa_put_profile(profile);
kfree(buffer);
--
2.7.4

View File

@@ -1,27 +0,0 @@
From 706473f3ead5cdffe5ad159adfbc090e0fda81d6 Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Thu, 17 Mar 2016 12:02:54 -0700
Subject: [PATCH 13/27] apparmor: check that xindex is in trans_table bounds
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
---
security/apparmor/policy_unpack.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
index a689f10..c841b12 100644
--- a/security/apparmor/policy_unpack.c
+++ b/security/apparmor/policy_unpack.c
@@ -676,7 +676,7 @@ static bool verify_xindex(int xindex, int table_size)
int index, xtype;
xtype = xindex & AA_X_TYPE_MASK;
index = xindex & AA_X_INDEX_MASK;
- if (xtype == AA_X_TABLE && index > table_size)
+ if (xtype == AA_X_TABLE && index >= table_size)
return 0;
return 1;
}
--
2.7.4

View File

@@ -1,27 +0,0 @@
From 05a64c434466029b298ee1e78a988cd6a7f80c0e Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Wed, 18 Nov 2015 11:41:05 -0800
Subject: [PATCH 14/27] apparmor: fix ref count leak when profile sha1 hash is
read
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
---
security/apparmor/apparmorfs.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
index 45a6199..0d8dd71 100644
--- a/security/apparmor/apparmorfs.c
+++ b/security/apparmor/apparmorfs.c
@@ -331,6 +331,7 @@ static int aa_fs_seq_hash_show(struct seq_file *seq, void *v)
seq_printf(seq, "%.2x", profile->hash[i]);
seq_puts(seq, "\n");
}
+ aa_put_profile(profile);
return 0;
}
--
2.7.4

View File

@@ -1,37 +0,0 @@
From 6b0b8b91f454bd021e27abe0e611a6764e4806c1 Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Wed, 16 Dec 2015 18:09:10 -0800
Subject: [PATCH 15/27] apparmor: fix refcount race when finding a child
profile
When finding a child profile via an rcu critical section, the profile
may be put and scheduled for deletion after the child is found but
before its refcount is incremented.
Protect against this by repeating the lookup if the profiles refcount
is 0 and is one its way to deletion.
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
---
security/apparmor/policy.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
index ca402d0..7807125 100644
--- a/security/apparmor/policy.c
+++ b/security/apparmor/policy.c
@@ -766,7 +766,9 @@ struct aa_profile *aa_find_child(struct aa_profile *parent, const char *name)
struct aa_profile *profile;
rcu_read_lock();
- profile = aa_get_profile(__find_child(&parent->base.profiles, name));
+ do {
+ profile = __find_child(&parent->base.profiles, name);
+ } while (profile && !aa_get_profile_not0(profile));
rcu_read_unlock();
/* refcount released by caller */
--
2.7.4

View File

@@ -1,59 +0,0 @@
From 84acc6aa6976e62756e14d3a00c5634724cbaa59 Mon Sep 17 00:00:00 2001
From: Geliang Tang <geliangtang@163.com>
Date: Mon, 16 Nov 2015 21:46:33 +0800
Subject: [PATCH 16/27] apparmor: use list_next_entry instead of
list_entry_next
list_next_entry has been defined in list.h, so I replace list_entry_next
with it.
Signed-off-by: Geliang Tang <geliangtang@163.com>
Acked-by: Serge Hallyn <serge.hallyn@canonical.com>
Signed-off-by: John Johansen <john.johansen@canonical.com>
---
security/apparmor/apparmorfs.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
index 0d8dd71..729e595 100644
--- a/security/apparmor/apparmorfs.c
+++ b/security/apparmor/apparmorfs.c
@@ -553,8 +553,6 @@ fail2:
}
-#define list_entry_next(pos, member) \
- list_entry(pos->member.next, typeof(*pos), member)
#define list_entry_is_head(pos, head, member) (&pos->member == (head))
/**
@@ -585,7 +583,7 @@ static struct aa_namespace *__next_namespace(struct aa_namespace *root,
parent = ns->parent;
while (ns != root) {
mutex_unlock(&ns->lock);
- next = list_entry_next(ns, base.list);
+ next = list_next_entry(ns, base.list);
if (!list_entry_is_head(next, &parent->sub_ns, base.list)) {
mutex_lock(&next->lock);
return next;
@@ -639,7 +637,7 @@ static struct aa_profile *__next_profile(struct aa_profile *p)
parent = rcu_dereference_protected(p->parent,
mutex_is_locked(&p->ns->lock));
while (parent) {
- p = list_entry_next(p, base.list);
+ p = list_next_entry(p, base.list);
if (!list_entry_is_head(p, &parent->base.profiles, base.list))
return p;
p = parent;
@@ -648,7 +646,7 @@ static struct aa_profile *__next_profile(struct aa_profile *p)
}
/* is next another profile in the namespace */
- p = list_entry_next(p, base.list);
+ p = list_next_entry(p, base.list);
if (!list_entry_is_head(p, &ns->base.profiles, base.list))
return p;
--
2.7.4

View File

@@ -1,50 +0,0 @@
From a3896605318b86d8cf288c122e03604e349d5dd7 Mon Sep 17 00:00:00 2001
From: Jeff Mahoney <jeffm@suse.com>
Date: Fri, 6 Nov 2015 15:17:30 -0500
Subject: [PATCH 17/27] apparmor: allow SYS_CAP_RESOURCE to be sufficient to
prlimit another task
While using AppArmor, SYS_CAP_RESOURCE is insufficient to call prlimit
on another task. The only other example of a AppArmor mediating access to
another, already running, task (ignoring fork+exec) is ptrace.
The AppArmor model for ptrace is that one of the following must be true:
1) The tracer is unconfined
2) The tracer is in complain mode
3) The tracer and tracee are confined by the same profile
4) The tracer is confined but has SYS_CAP_PTRACE
1), 2, and 3) are already true for setrlimit.
We can match the ptrace model just by allowing CAP_SYS_RESOURCE.
We still test the values of the rlimit since it can always be overridden
using a value that means unlimited for a particular resource.
Signed-off-by: Jeff Mahoney <jeffm@suse.com>
Signed-off-by: John Johansen <john.johansen@canonical.com>
---
security/apparmor/resource.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/security/apparmor/resource.c b/security/apparmor/resource.c
index 748bf0c..67a6072 100644
--- a/security/apparmor/resource.c
+++ b/security/apparmor/resource.c
@@ -101,9 +101,11 @@ int aa_task_setrlimit(struct aa_profile *profile, struct task_struct *task,
/* TODO: extend resource control to handle other (non current)
* profiles. AppArmor rules currently have the implicit assumption
* that the task is setting the resource of a task confined with
- * the same profile.
+ * the same profile or that the task setting the resource of another
+ * task has CAP_SYS_RESOURCE.
*/
- if (profile != task_profile ||
+ if ((profile != task_profile &&
+ aa_capable(profile, CAP_SYS_RESOURCE, 1)) ||
(profile->rlimits.mask & (1 << resource) &&
new_rlim->rlim_max > profile->rlimits.limits[resource].rlim_max))
error = -EACCES;
--
2.7.4

View File

@@ -1,40 +0,0 @@
From 6fdcc3cfecd4d89457036627d59ebe5154d094c5 Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Thu, 2 Jun 2016 02:37:02 -0700
Subject: [PATCH 18/27] apparmor: add missing id bounds check on dfa
verification
Signed-off-by: John Johansen <john.johansen@canonical.com>
---
security/apparmor/include/match.h | 1 +
security/apparmor/match.c | 2 ++
2 files changed, 3 insertions(+)
diff --git a/security/apparmor/include/match.h b/security/apparmor/include/match.h
index 001c43a..a1c04fe 100644
--- a/security/apparmor/include/match.h
+++ b/security/apparmor/include/match.h
@@ -62,6 +62,7 @@ struct table_set_header {
#define YYTD_ID_ACCEPT2 6
#define YYTD_ID_NXT 7
#define YYTD_ID_TSIZE 8
+#define YYTD_ID_MAX 8
#define YYTD_DATA8 1
#define YYTD_DATA16 2
diff --git a/security/apparmor/match.c b/security/apparmor/match.c
index 727eb42..f9f57c6 100644
--- a/security/apparmor/match.c
+++ b/security/apparmor/match.c
@@ -47,6 +47,8 @@ static struct table_header *unpack_table(char *blob, size_t bsize)
* it every time we use td_id as an index
*/
th.td_id = be16_to_cpu(*(u16 *) (blob)) - 1;
+ if (th.td_id > YYTD_ID_MAX)
+ goto out;
th.td_flags = be16_to_cpu(*(u16 *) (blob + 2));
th.td_lolen = be32_to_cpu(*(u32 *) (blob + 8));
blob += sizeof(struct table_header);
--
2.7.4

View File

@@ -1,38 +0,0 @@
From 95d203cfb59627a86483a279ba82f1aa75297e07 Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Wed, 15 Jun 2016 09:57:55 +0300
Subject: [PATCH 19/27] apparmor: don't check for vmalloc_addr if kvzalloc()
failed
Signed-off-by: John Johansen <john.johansen@canonical.com>
---
security/apparmor/match.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/security/apparmor/match.c b/security/apparmor/match.c
index f9f57c6..32b72eb 100644
--- a/security/apparmor/match.c
+++ b/security/apparmor/match.c
@@ -75,14 +75,14 @@ static struct table_header *unpack_table(char *blob, size_t bsize)
u32, be32_to_cpu);
else
goto fail;
+ /* if table was vmalloced make sure the page tables are synced
+ * before it is used, as it goes live to all cpus.
+ */
+ if (is_vmalloc_addr(table))
+ vm_unmap_aliases();
}
out:
- /* if table was vmalloced make sure the page tables are synced
- * before it is used, as it goes live to all cpus.
- */
- if (is_vmalloc_addr(table))
- vm_unmap_aliases();
return table;
fail:
kvfree(table);
--
2.7.4

View File

@@ -1,33 +0,0 @@
From e925f976c7a9c85455f67c360671254bac2d9a91 Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Wed, 15 Jun 2016 10:00:55 +0300
Subject: [PATCH 20/27] apparmor: fix oops in profile_unpack() when policy_db
is not present
BugLink: http://bugs.launchpad.net/bugs/1592547
If unpack_dfa() returns NULL due to the dfa not being present,
profile_unpack() is not checking if the dfa is not present (NULL).
Signed-off-by: John Johansen <john.johansen@canonical.com>
---
security/apparmor/policy_unpack.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
index c841b12..dac2121 100644
--- a/security/apparmor/policy_unpack.c
+++ b/security/apparmor/policy_unpack.c
@@ -583,6 +583,9 @@ static struct aa_profile *unpack_profile(struct aa_ext *e)
error = PTR_ERR(profile->policy.dfa);
profile->policy.dfa = NULL;
goto fail;
+ } else if (!profile->policy.dfa) {
+ error = -EPROTO;
+ goto fail;
}
if (!unpack_u32(e, &profile->policy.start[0], "start"))
/* default start state */
--
2.7.4

View File

@@ -1,162 +0,0 @@
From 45774028820fe2ffbbc94667165f04749821d529 Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Wed, 22 Jun 2016 18:01:08 -0700
Subject: [PATCH 21/27] apparmor: fix module parameters can be changed after
policy is locked
the policy_lock parameter is a one way switch that prevents policy
from being further modified. Unfortunately some of the module parameters
can effectively modify policy by turning off enforcement.
split policy_admin_capable into a view check and a full admin check,
and update the admin check to test the policy_lock parameter.
Signed-off-by: John Johansen <john.johansen@canonical.com>
---
security/apparmor/include/policy.h | 2 ++
security/apparmor/lsm.c | 22 ++++++++++------------
security/apparmor/policy.c | 18 +++++++++++++++++-
3 files changed, 29 insertions(+), 13 deletions(-)
diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h
index c28b0f2..52275f0 100644
--- a/security/apparmor/include/policy.h
+++ b/security/apparmor/include/policy.h
@@ -403,6 +403,8 @@ static inline int AUDIT_MODE(struct aa_profile *profile)
return profile->audit;
}
+bool policy_view_capable(void);
+bool policy_admin_capable(void);
bool aa_may_manage_policy(int op);
#endif /* __AA_POLICY_H */
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index 5ee8201..bd40b12 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -751,51 +751,49 @@ __setup("apparmor=", apparmor_enabled_setup);
/* set global flag turning off the ability to load policy */
static int param_set_aalockpolicy(const char *val, const struct kernel_param *kp)
{
- if (!capable(CAP_MAC_ADMIN))
+ if (!policy_admin_capable())
return -EPERM;
- if (aa_g_lock_policy)
- return -EACCES;
return param_set_bool(val, kp);
}
static int param_get_aalockpolicy(char *buffer, const struct kernel_param *kp)
{
- if (!capable(CAP_MAC_ADMIN))
+ if (!policy_view_capable())
return -EPERM;
return param_get_bool(buffer, kp);
}
static int param_set_aabool(const char *val, const struct kernel_param *kp)
{
- if (!capable(CAP_MAC_ADMIN))
+ if (!policy_admin_capable())
return -EPERM;
return param_set_bool(val, kp);
}
static int param_get_aabool(char *buffer, const struct kernel_param *kp)
{
- if (!capable(CAP_MAC_ADMIN))
+ if (!policy_view_capable())
return -EPERM;
return param_get_bool(buffer, kp);
}
static int param_set_aauint(const char *val, const struct kernel_param *kp)
{
- if (!capable(CAP_MAC_ADMIN))
+ if (!policy_admin_capable())
return -EPERM;
return param_set_uint(val, kp);
}
static int param_get_aauint(char *buffer, const struct kernel_param *kp)
{
- if (!capable(CAP_MAC_ADMIN))
+ if (!policy_view_capable())
return -EPERM;
return param_get_uint(buffer, kp);
}
static int param_get_audit(char *buffer, struct kernel_param *kp)
{
- if (!capable(CAP_MAC_ADMIN))
+ if (!policy_view_capable())
return -EPERM;
if (!apparmor_enabled)
@@ -807,7 +805,7 @@ static int param_get_audit(char *buffer, struct kernel_param *kp)
static int param_set_audit(const char *val, struct kernel_param *kp)
{
int i;
- if (!capable(CAP_MAC_ADMIN))
+ if (!policy_admin_capable())
return -EPERM;
if (!apparmor_enabled)
@@ -828,7 +826,7 @@ static int param_set_audit(const char *val, struct kernel_param *kp)
static int param_get_mode(char *buffer, struct kernel_param *kp)
{
- if (!capable(CAP_MAC_ADMIN))
+ if (!policy_admin_capable())
return -EPERM;
if (!apparmor_enabled)
@@ -840,7 +838,7 @@ static int param_get_mode(char *buffer, struct kernel_param *kp)
static int param_set_mode(const char *val, struct kernel_param *kp)
{
int i;
- if (!capable(CAP_MAC_ADMIN))
+ if (!policy_admin_capable())
return -EPERM;
if (!apparmor_enabled)
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
index 7807125..179e68d 100644
--- a/security/apparmor/policy.c
+++ b/security/apparmor/policy.c
@@ -918,6 +918,22 @@ static int audit_policy(int op, gfp_t gfp, const char *name, const char *info,
&sa, NULL);
}
+bool policy_view_capable(void)
+{
+ struct user_namespace *user_ns = current_user_ns();
+ bool response = false;
+
+ if (ns_capable(user_ns, CAP_MAC_ADMIN))
+ response = true;
+
+ return response;
+}
+
+bool policy_admin_capable(void)
+{
+ return policy_view_capable() && !aa_g_lock_policy;
+}
+
/**
* aa_may_manage_policy - can the current task manage policy
* @op: the policy manipulation operation being done
@@ -932,7 +948,7 @@ bool aa_may_manage_policy(int op)
return 0;
}
- if (!capable(CAP_MAC_ADMIN)) {
+ if (!policy_admin_capable()) {
audit_policy(op, GFP_KERNEL, NULL, "not policy admin", -EACCES);
return 0;
}
--
2.7.4

View File

@@ -1,31 +0,0 @@
From 7fcfc22cd04261ac35a579c99bcc804db7eb3e83 Mon Sep 17 00:00:00 2001
From: Heinrich Schuchardt <xypron.glpk@gmx.de>
Date: Fri, 10 Jun 2016 23:34:26 +0200
Subject: [PATCH 22/27] apparmor: do not expose kernel stack
Do not copy uninitalized fields th.td_hilen, th.td_data.
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: John Johansen <john.johansen@canonical.com>
---
security/apparmor/match.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/security/apparmor/match.c b/security/apparmor/match.c
index 32b72eb..3f900fc 100644
--- a/security/apparmor/match.c
+++ b/security/apparmor/match.c
@@ -63,7 +63,9 @@ static struct table_header *unpack_table(char *blob, size_t bsize)
table = kvzalloc(tsize);
if (table) {
- *table = th;
+ table->td_id = th.td_id;
+ table->td_flags = th.td_flags;
+ table->td_lolen = th.td_lolen;
if (th.td_flags == YYTD_DATA8)
UNPACK_ARRAY(table->td_data, blob, th.td_lolen,
u8, byte_to_byte);
--
2.7.4

View File

@@ -1,27 +0,0 @@
From 1b98560066c26fecb0a61aeb9249e141af2e63f9 Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Sat, 9 Jul 2016 23:46:33 -0700
Subject: [PATCH 23/27] apparmor: fix arg_size computation for when setprocattr
is null terminated
Signed-off-by: John Johansen <john.johansen@canonical.com>
---
security/apparmor/lsm.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index bd40b12..1bf6c53 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -552,7 +552,7 @@ static int apparmor_setprocattr(struct task_struct *task, char *name,
if (!*args)
goto out;
- arg_size = size - (args - (char *) value);
+ arg_size = size - (args - (largs ? largs : (char *) value));
if (strcmp(name, "current") == 0) {
if (strcmp(command, "changehat") == 0) {
error = aa_setprocattr_changehat(args, arg_size,
--
2.7.4

View File

@@ -1,603 +0,0 @@
From 8d7c032e7798fa1c46449728874b64fff882368b Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Mon, 4 Oct 2010 15:03:36 -0700
Subject: [PATCH 24/27] UBUNTU: SAUCE: AppArmor: basic networking rules
Base support for network mediation.
Signed-off-by: John Johansen <john.johansen@canonical.com>
---
security/apparmor/.gitignore | 1 +
security/apparmor/Makefile | 42 +++++++++-
security/apparmor/apparmorfs.c | 1 +
security/apparmor/include/audit.h | 4 +
security/apparmor/include/net.h | 44 ++++++++++
security/apparmor/include/policy.h | 3 +
security/apparmor/lsm.c | 112 +++++++++++++++++++++++++
security/apparmor/net.c | 162 +++++++++++++++++++++++++++++++++++++
security/apparmor/policy.c | 1 +
security/apparmor/policy_unpack.c | 46 +++++++++++
10 files changed, 414 insertions(+), 2 deletions(-)
create mode 100644 security/apparmor/include/net.h
create mode 100644 security/apparmor/net.c
diff --git a/security/apparmor/.gitignore b/security/apparmor/.gitignore
index 9cdec70..d5b291e 100644
--- a/security/apparmor/.gitignore
+++ b/security/apparmor/.gitignore
@@ -1,5 +1,6 @@
#
# Generated include files
#
+net_names.h
capability_names.h
rlim_names.h
diff --git a/security/apparmor/Makefile b/security/apparmor/Makefile
index d693df8..5dbb72f 100644
--- a/security/apparmor/Makefile
+++ b/security/apparmor/Makefile
@@ -4,10 +4,10 @@ obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o
apparmor-y := apparmorfs.o audit.o capability.o context.o ipc.o lib.o match.o \
path.o domain.o policy.o policy_unpack.o procattr.o lsm.o \
- resource.o sid.o file.o
+ resource.o sid.o file.o net.o
apparmor-$(CONFIG_SECURITY_APPARMOR_HASH) += crypto.o
-clean-files := capability_names.h rlim_names.h
+clean-files := capability_names.h rlim_names.h net_names.h
# Build a lower case string table of capability names
@@ -25,6 +25,38 @@ cmd_make-caps = echo "static const char *const capability_names[] = {" > $@ ;\
-e 's/^\#define[ \t]+CAP_([A-Z0-9_]+)[ \t]+([0-9]+)/\L\1/p' | \
tr '\n' ' ' | sed -e 's/ $$/"\n/' >> $@
+# Build a lower case string table of address family names
+# Transform lines from
+# define AF_LOCAL 1 /* POSIX name for AF_UNIX */
+# #define AF_INET 2 /* Internet IP Protocol */
+# to
+# [1] = "local",
+# [2] = "inet",
+#
+# and build the securityfs entries for the mapping.
+# Transforms lines from
+# #define AF_INET 2 /* Internet IP Protocol */
+# to
+# #define AA_FS_AF_MASK "local inet"
+quiet_cmd_make-af = GEN $@
+cmd_make-af = echo "static const char *address_family_names[] = {" > $@ ;\
+ sed $< >>$@ -r -n -e "/AF_MAX/d" -e "/AF_LOCAL/d" -e \
+ 's/^\#define[ \t]+AF_([A-Z0-9_]+)[ \t]+([0-9]+)(.*)/[\2] = "\L\1",/p';\
+ echo "};" >> $@ ;\
+ echo -n '\#define AA_FS_AF_MASK "' >> $@ ;\
+ sed -r -n 's/^\#define[ \t]+AF_([A-Z0-9_]+)[ \t]+([0-9]+)(.*)/\L\1/p'\
+ $< | tr '\n' ' ' | sed -e 's/ $$/"\n/' >> $@
+
+# Build a lower case string table of sock type names
+# Transform lines from
+# SOCK_STREAM = 1,
+# to
+# [1] = "stream",
+quiet_cmd_make-sock = GEN $@
+cmd_make-sock = echo "static const char *sock_type_names[] = {" >> $@ ;\
+ sed $^ >>$@ -r -n \
+ -e 's/^\tSOCK_([A-Z0-9_]+)[\t]+=[ \t]+([0-9]+)(.*)/[\2] = "\L\1",/p';\
+ echo "};" >> $@
# Build a lower case string table of rlimit names.
# Transforms lines from
@@ -61,6 +93,7 @@ cmd_make-rlim = echo "static const char *const rlim_names[RLIM_NLIMITS] = {" \
tr '\n' ' ' | sed -e 's/ $$/"\n/' >> $@
$(obj)/capability.o : $(obj)/capability_names.h
+$(obj)/net.o : $(obj)/net_names.h
$(obj)/resource.o : $(obj)/rlim_names.h
$(obj)/capability_names.h : $(srctree)/include/uapi/linux/capability.h \
$(src)/Makefile
@@ -68,3 +101,8 @@ $(obj)/capability_names.h : $(srctree)/include/uapi/linux/capability.h \
$(obj)/rlim_names.h : $(srctree)/include/uapi/asm-generic/resource.h \
$(src)/Makefile
$(call cmd,make-rlim)
+$(obj)/net_names.h : $(srctree)/include/linux/socket.h \
+ $(srctree)/include/linux/net.h \
+ $(src)/Makefile
+ $(call cmd,make-af)
+ $(call cmd,make-sock)
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
index 729e595..181d961 100644
--- a/security/apparmor/apparmorfs.c
+++ b/security/apparmor/apparmorfs.c
@@ -807,6 +807,7 @@ static struct aa_fs_entry aa_fs_entry_features[] = {
AA_FS_DIR("policy", aa_fs_entry_policy),
AA_FS_DIR("domain", aa_fs_entry_domain),
AA_FS_DIR("file", aa_fs_entry_file),
+ AA_FS_DIR("network", aa_fs_entry_network),
AA_FS_FILE_U64("capability", VFS_CAP_FLAGS_MASK),
AA_FS_DIR("rlimit", aa_fs_entry_rlimit),
AA_FS_DIR("caps", aa_fs_entry_caps),
diff --git a/security/apparmor/include/audit.h b/security/apparmor/include/audit.h
index ba3dfd1..5d3c419 100644
--- a/security/apparmor/include/audit.h
+++ b/security/apparmor/include/audit.h
@@ -125,6 +125,10 @@ struct apparmor_audit_data {
u32 denied;
kuid_t ouid;
} fs;
+ struct {
+ int type, protocol;
+ struct sock *sk;
+ } net;
};
};
diff --git a/security/apparmor/include/net.h b/security/apparmor/include/net.h
new file mode 100644
index 0000000..cb8a121
--- /dev/null
+++ b/security/apparmor/include/net.h
@@ -0,0 +1,44 @@
+/*
+ * AppArmor security module
+ *
+ * This file contains AppArmor network mediation definitions.
+ *
+ * Copyright (C) 1998-2008 Novell/SUSE
+ * Copyright 2009-2012 Canonical Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ */
+
+#ifndef __AA_NET_H
+#define __AA_NET_H
+
+#include <net/sock.h>
+
+#include "apparmorfs.h"
+
+/* struct aa_net - network confinement data
+ * @allowed: basic network families permissions
+ * @audit_network: which network permissions to force audit
+ * @quiet_network: which network permissions to quiet rejects
+ */
+struct aa_net {
+ u16 allow[AF_MAX];
+ u16 audit[AF_MAX];
+ u16 quiet[AF_MAX];
+};
+
+extern struct aa_fs_entry aa_fs_entry_network[];
+
+extern int aa_net_perm(int op, struct aa_profile *profile, u16 family,
+ int type, int protocol, struct sock *sk);
+extern int aa_revalidate_sk(int op, struct sock *sk);
+
+static inline void aa_free_net_rules(struct aa_net *new)
+{
+ /* NOP */
+}
+
+#endif /* __AA_NET_H */
diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h
index 52275f0..4fc4dac 100644
--- a/security/apparmor/include/policy.h
+++ b/security/apparmor/include/policy.h
@@ -27,6 +27,7 @@
#include "capability.h"
#include "domain.h"
#include "file.h"
+#include "net.h"
#include "resource.h"
extern const char *const aa_profile_mode_names[];
@@ -176,6 +177,7 @@ struct aa_replacedby {
* @policy: general match rules governing policy
* @file: The set of rules governing basic file access and domain transitions
* @caps: capabilities for the profile
+ * @net: network controls for the profile
* @rlimits: rlimits for the profile
*
* @dents: dentries for the profiles file entries in apparmorfs
@@ -217,6 +219,7 @@ struct aa_profile {
struct aa_policydb policy;
struct aa_file_rules file;
struct aa_caps caps;
+ struct aa_net net;
struct aa_rlimit rlimits;
unsigned char *hash;
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index 1bf6c53..284ddda 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -32,6 +32,7 @@
#include "include/context.h"
#include "include/file.h"
#include "include/ipc.h"
+#include "include/net.h"
#include "include/path.h"
#include "include/policy.h"
#include "include/procattr.h"
@@ -607,6 +608,104 @@ static int apparmor_task_setrlimit(struct task_struct *task,
return error;
}
+static int apparmor_socket_create(int family, int type, int protocol, int kern)
+{
+ struct aa_profile *profile;
+ int error = 0;
+
+ if (kern)
+ return 0;
+
+ profile = __aa_current_profile();
+ if (!unconfined(profile))
+ error = aa_net_perm(OP_CREATE, profile, family, type, protocol,
+ NULL);
+ return error;
+}
+
+static int apparmor_socket_bind(struct socket *sock,
+ struct sockaddr *address, int addrlen)
+{
+ struct sock *sk = sock->sk;
+
+ return aa_revalidate_sk(OP_BIND, sk);
+}
+
+static int apparmor_socket_connect(struct socket *sock,
+ struct sockaddr *address, int addrlen)
+{
+ struct sock *sk = sock->sk;
+
+ return aa_revalidate_sk(OP_CONNECT, sk);
+}
+
+static int apparmor_socket_listen(struct socket *sock, int backlog)
+{
+ struct sock *sk = sock->sk;
+
+ return aa_revalidate_sk(OP_LISTEN, sk);
+}
+
+static int apparmor_socket_accept(struct socket *sock, struct socket *newsock)
+{
+ struct sock *sk = sock->sk;
+
+ return aa_revalidate_sk(OP_ACCEPT, sk);
+}
+
+static int apparmor_socket_sendmsg(struct socket *sock,
+ struct msghdr *msg, int size)
+{
+ struct sock *sk = sock->sk;
+
+ return aa_revalidate_sk(OP_SENDMSG, sk);
+}
+
+static int apparmor_socket_recvmsg(struct socket *sock,
+ struct msghdr *msg, int size, int flags)
+{
+ struct sock *sk = sock->sk;
+
+ return aa_revalidate_sk(OP_RECVMSG, sk);
+}
+
+static int apparmor_socket_getsockname(struct socket *sock)
+{
+ struct sock *sk = sock->sk;
+
+ return aa_revalidate_sk(OP_GETSOCKNAME, sk);
+}
+
+static int apparmor_socket_getpeername(struct socket *sock)
+{
+ struct sock *sk = sock->sk;
+
+ return aa_revalidate_sk(OP_GETPEERNAME, sk);
+}
+
+static int apparmor_socket_getsockopt(struct socket *sock, int level,
+ int optname)
+{
+ struct sock *sk = sock->sk;
+
+ return aa_revalidate_sk(OP_GETSOCKOPT, sk);
+}
+
+static int apparmor_socket_setsockopt(struct socket *sock, int level,
+ int optname)
+{
+ struct sock *sk = sock->sk;
+
+ return aa_revalidate_sk(OP_SETSOCKOPT, sk);
+}
+
+static int apparmor_socket_shutdown(struct socket *sock, int how)
+{
+ struct sock *sk = sock->sk;
+
+ return aa_revalidate_sk(OP_SOCK_SHUTDOWN, sk);
+}
+
static struct security_hook_list apparmor_hooks[] = {
LSM_HOOK_INIT(ptrace_access_check, apparmor_ptrace_access_check),
LSM_HOOK_INIT(ptrace_traceme, apparmor_ptrace_traceme),
@@ -636,6 +735,19 @@ static struct security_hook_list apparmor_hooks[] = {
LSM_HOOK_INIT(getprocattr, apparmor_getprocattr),
LSM_HOOK_INIT(setprocattr, apparmor_setprocattr),
+ LSM_HOOK_INIT(socket_create, apparmor_socket_create),
+ LSM_HOOK_INIT(socket_bind, apparmor_socket_bind),
+ LSM_HOOK_INIT(socket_connect, apparmor_socket_connect),
+ LSM_HOOK_INIT(socket_listen, apparmor_socket_listen),
+ LSM_HOOK_INIT(socket_accept, apparmor_socket_accept),
+ LSM_HOOK_INIT(socket_sendmsg, apparmor_socket_sendmsg),
+ LSM_HOOK_INIT(socket_recvmsg, apparmor_socket_recvmsg),
+ LSM_HOOK_INIT(socket_getsockname, apparmor_socket_getsockname),
+ LSM_HOOK_INIT(socket_getpeername, apparmor_socket_getpeername),
+ LSM_HOOK_INIT(socket_getsockopt, apparmor_socket_getsockopt),
+ LSM_HOOK_INIT(socket_setsockopt, apparmor_socket_setsockopt),
+ LSM_HOOK_INIT(socket_shutdown, apparmor_socket_shutdown),
+
LSM_HOOK_INIT(cred_alloc_blank, apparmor_cred_alloc_blank),
LSM_HOOK_INIT(cred_free, apparmor_cred_free),
LSM_HOOK_INIT(cred_prepare, apparmor_cred_prepare),
diff --git a/security/apparmor/net.c b/security/apparmor/net.c
new file mode 100644
index 0000000..003dd18
--- /dev/null
+++ b/security/apparmor/net.c
@@ -0,0 +1,162 @@
+/*
+ * AppArmor security module
+ *
+ * This file contains AppArmor network mediation
+ *
+ * Copyright (C) 1998-2008 Novell/SUSE
+ * Copyright 2009-2012 Canonical Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ */
+
+#include "include/apparmor.h"
+#include "include/audit.h"
+#include "include/context.h"
+#include "include/net.h"
+#include "include/policy.h"
+
+#include "net_names.h"
+
+struct aa_fs_entry aa_fs_entry_network[] = {
+ AA_FS_FILE_STRING("af_mask", AA_FS_AF_MASK),
+ { }
+};
+
+/* audit callback for net specific fields */
+static void audit_cb(struct audit_buffer *ab, void *va)
+{
+ struct common_audit_data *sa = va;
+
+ audit_log_format(ab, " family=");
+ if (address_family_names[sa->u.net->family]) {
+ audit_log_string(ab, address_family_names[sa->u.net->family]);
+ } else {
+ audit_log_format(ab, "\"unknown(%d)\"", sa->u.net->family);
+ }
+ audit_log_format(ab, " sock_type=");
+ if (sock_type_names[sa->aad->net.type]) {
+ audit_log_string(ab, sock_type_names[sa->aad->net.type]);
+ } else {
+ audit_log_format(ab, "\"unknown(%d)\"", sa->aad->net.type);
+ }
+ audit_log_format(ab, " protocol=%d", sa->aad->net.protocol);
+}
+
+/**
+ * audit_net - audit network access
+ * @profile: profile being enforced (NOT NULL)
+ * @op: operation being checked
+ * @family: network family
+ * @type: network type
+ * @protocol: network protocol
+ * @sk: socket auditing is being applied to
+ * @error: error code for failure else 0
+ *
+ * Returns: %0 or sa->error else other errorcode on failure
+ */
+static int audit_net(struct aa_profile *profile, int op, u16 family, int type,
+ int protocol, struct sock *sk, int error)
+{
+ int audit_type = AUDIT_APPARMOR_AUTO;
+ struct common_audit_data sa;
+ struct apparmor_audit_data aad = { };
+ struct lsm_network_audit net = { };
+ if (sk) {
+ sa.type = LSM_AUDIT_DATA_NET;
+ } else {
+ sa.type = LSM_AUDIT_DATA_NONE;
+ }
+ /* todo fill in socket addr info */
+ sa.aad = &aad;
+ sa.u.net = &net;
+ sa.aad->op = op,
+ sa.u.net->family = family;
+ sa.u.net->sk = sk;
+ sa.aad->net.type = type;
+ sa.aad->net.protocol = protocol;
+ sa.aad->error = error;
+
+ if (likely(!sa.aad->error)) {
+ u16 audit_mask = profile->net.audit[sa.u.net->family];
+ if (likely((AUDIT_MODE(profile) != AUDIT_ALL) &&
+ !(1 << sa.aad->net.type & audit_mask)))
+ return 0;
+ audit_type = AUDIT_APPARMOR_AUDIT;
+ } else {
+ u16 quiet_mask = profile->net.quiet[sa.u.net->family];
+ u16 kill_mask = 0;
+ u16 denied = (1 << sa.aad->net.type) & ~quiet_mask;
+
+ if (denied & kill_mask)
+ audit_type = AUDIT_APPARMOR_KILL;
+
+ if ((denied & quiet_mask) &&
+ AUDIT_MODE(profile) != AUDIT_NOQUIET &&
+ AUDIT_MODE(profile) != AUDIT_ALL)
+ return COMPLAIN_MODE(profile) ? 0 : sa.aad->error;
+ }
+
+ return aa_audit(audit_type, profile, GFP_KERNEL, &sa, audit_cb);
+}
+
+/**
+ * aa_net_perm - very course network access check
+ * @op: operation being checked
+ * @profile: profile being enforced (NOT NULL)
+ * @family: network family
+ * @type: network type
+ * @protocol: network protocol
+ *
+ * Returns: %0 else error if permission denied
+ */
+int aa_net_perm(int op, struct aa_profile *profile, u16 family, int type,
+ int protocol, struct sock *sk)
+{
+ u16 family_mask;
+ int error;
+
+ if ((family < 0) || (family >= AF_MAX))
+ return -EINVAL;
+
+ if ((type < 0) || (type >= SOCK_MAX))
+ return -EINVAL;
+
+ /* unix domain and netlink sockets are handled by ipc */
+ if (family == AF_UNIX || family == AF_NETLINK)
+ return 0;
+
+ family_mask = profile->net.allow[family];
+
+ error = (family_mask & (1 << type)) ? 0 : -EACCES;
+
+ return audit_net(profile, op, family, type, protocol, sk, error);
+}
+
+/**
+ * aa_revalidate_sk - Revalidate access to a sock
+ * @op: operation being checked
+ * @sk: sock being revalidated (NOT NULL)
+ *
+ * Returns: %0 else error if permission denied
+ */
+int aa_revalidate_sk(int op, struct sock *sk)
+{
+ struct aa_profile *profile;
+ int error = 0;
+
+ /* aa_revalidate_sk should not be called from interrupt context
+ * don't mediate these calls as they are not task related
+ */
+ if (in_interrupt())
+ return 0;
+
+ profile = __aa_current_profile();
+ if (!unconfined(profile))
+ error = aa_net_perm(op, profile, sk->sk_family, sk->sk_type,
+ sk->sk_protocol, sk);
+
+ return error;
+}
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
index 179e68d..f1a8541 100644
--- a/security/apparmor/policy.c
+++ b/security/apparmor/policy.c
@@ -603,6 +603,7 @@ void aa_free_profile(struct aa_profile *profile)
aa_free_file_rules(&profile->file);
aa_free_cap_rules(&profile->caps);
+ aa_free_net_rules(&profile->net);
aa_free_rlimit_rules(&profile->rlimits);
kzfree(profile->dirname);
diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
index dac2121..0107bc4 100644
--- a/security/apparmor/policy_unpack.c
+++ b/security/apparmor/policy_unpack.c
@@ -193,6 +193,19 @@ fail:
return 0;
}
+static bool unpack_u16(struct aa_ext *e, u16 *data, const char *name)
+{
+ if (unpack_nameX(e, AA_U16, name)) {
+ if (!inbounds(e, sizeof(u16)))
+ return 0;
+ if (data)
+ *data = le16_to_cpu(get_unaligned((u16 *) e->pos));
+ e->pos += sizeof(u16);
+ return 1;
+ }
+ return 0;
+}
+
static bool unpack_u32(struct aa_ext *e, u32 *data, const char *name)
{
if (unpack_nameX(e, AA_U32, name)) {
@@ -476,6 +489,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e)
{
struct aa_profile *profile = NULL;
const char *name = NULL;
+ size_t size = 0;
int i, error = -EPROTO;
kernel_cap_t tmpcap;
u32 tmp;
@@ -576,6 +590,38 @@ static struct aa_profile *unpack_profile(struct aa_ext *e)
if (!unpack_rlimits(e, profile))
goto fail;
+ size = unpack_array(e, "net_allowed_af");
+ if (size) {
+
+ for (i = 0; i < size; i++) {
+ /* discard extraneous rules that this kernel will
+ * never request
+ */
+ if (i >= AF_MAX) {
+ u16 tmp;
+ if (!unpack_u16(e, &tmp, NULL) ||
+ !unpack_u16(e, &tmp, NULL) ||
+ !unpack_u16(e, &tmp, NULL))
+ goto fail;
+ continue;
+ }
+ if (!unpack_u16(e, &profile->net.allow[i], NULL))
+ goto fail;
+ if (!unpack_u16(e, &profile->net.audit[i], NULL))
+ goto fail;
+ if (!unpack_u16(e, &profile->net.quiet[i], NULL))
+ goto fail;
+ }
+ if (!unpack_nameX(e, AA_ARRAYEND, NULL))
+ goto fail;
+ }
+ /*
+ * allow unix domain and netlink sockets they are handled
+ * by IPC
+ */
+ profile->net.allow[AF_UNIX] = 0xffff;
+ profile->net.allow[AF_NETLINK] = 0xffff;
+
if (unpack_nameX(e, AA_STRUCT, "policydb")) {
/* generic policy dfa - optional and may be NULL */
profile->policy.dfa = unpack_dfa(e);
--
2.7.4

View File

@@ -1,38 +0,0 @@
From aa45ba104003404efb59e6f7178045ade756035d Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Fri, 29 Jun 2012 17:34:00 -0700
Subject: [PATCH 25/27] apparmor: Fix quieting of audit messages for network
mediation
If a profile specified a quieting of network denials for a given rule by
either the quiet or deny rule qualifiers, the resultant quiet mask for
denied requests was applied incorrectly, resulting in two potential bugs.
1. The misapplied quiet mask would prevent denials from being correctly
tested against the kill mask/mode. Thus network access requests that
should have resulted in the application being killed did not.
2. The actual quieting of the denied network request was not being applied.
This would result in network rejections always being logged even when
they had been specifically marked as quieted.
Signed-off-by: John Johansen <john.johansen@canonical.com>
---
security/apparmor/net.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/security/apparmor/net.c b/security/apparmor/net.c
index 003dd18..6e6e5c9 100644
--- a/security/apparmor/net.c
+++ b/security/apparmor/net.c
@@ -88,7 +88,7 @@ static int audit_net(struct aa_profile *profile, int op, u16 family, int type,
} else {
u16 quiet_mask = profile->net.quiet[sa.u.net->family];
u16 kill_mask = 0;
- u16 denied = (1 << sa.aad->net.type) & ~quiet_mask;
+ u16 denied = (1 << sa.aad->net.type);
if (denied & kill_mask)
audit_type = AUDIT_APPARMOR_KILL;
--
2.7.4

View File

@@ -1,180 +0,0 @@
From 1eff686074a6af0cf47fc24c45ebb001c570a98b Mon Sep 17 00:00:00 2001
From: kbuild test robot <fengguang.wu@intel.com>
Date: Fri, 29 Jul 2016 12:44:43 +0800
Subject: [PATCH 27/27] UBUNTU: SAUCE: AppArmor: fix boolreturn.cocci warnings
security/apparmor/policy_unpack.c:143:9-10: WARNING: return of 0/1 in function 'unpack_X' with return type bool
security/apparmor/policy_unpack.c:189:9-10: WARNING: return of 0/1 in function 'unpack_nameX' with return type bool
security/apparmor/policy_unpack.c:475:8-9: WARNING: return of 0/1 in function 'unpack_rlimits' with return type bool
security/apparmor/policy_unpack.c:440:8-9: WARNING: return of 0/1 in function 'unpack_trans_table' with return type bool
security/apparmor/policy_unpack.c:200:10-11: WARNING: return of 0/1 in function 'unpack_u16' with return type bool
security/apparmor/policy_unpack.c:213:10-11: WARNING: return of 0/1 in function 'unpack_u32' with return type bool
security/apparmor/policy_unpack.c:226:10-11: WARNING: return of 0/1 in function 'unpack_u64' with return type bool
security/apparmor/policy_unpack.c:325:10-11: WARNING: return of 0/1 in function 'verify_accept' with return type bool
security/apparmor/policy_unpack.c:739:10-11: WARNING: return of 0/1 in function 'verify_dfa_xindex' with return type bool
security/apparmor/policy_unpack.c:729:9-10: WARNING: return of 0/1 in function 'verify_xindex' with return type bool
Return statements in functions returning bool should use
true/false instead of 1/0.
Generated by: scripts/coccinelle/misc/boolreturn.cocci
Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
Signed-off-by: John Johansen <john.johansen@canonical.com>
---
security/apparmor/policy_unpack.c | 52 +++++++++++++++++++--------------------
1 file changed, 26 insertions(+), 26 deletions(-)
diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
index 0107bc4..af14626 100644
--- a/security/apparmor/policy_unpack.c
+++ b/security/apparmor/policy_unpack.c
@@ -140,11 +140,11 @@ static size_t unpack_u16_chunk(struct aa_ext *e, char **chunk)
static bool unpack_X(struct aa_ext *e, enum aa_code code)
{
if (!inbounds(e, 1))
- return 0;
+ return false;
if (*(u8 *) e->pos != code)
- return 0;
+ return false;
e->pos++;
- return 1;
+ return true;
}
/**
@@ -186,50 +186,50 @@ static bool unpack_nameX(struct aa_ext *e, enum aa_code code, const char *name)
/* now check if type code matches */
if (unpack_X(e, code))
- return 1;
+ return true;
fail:
e->pos = pos;
- return 0;
+ return false;
}
static bool unpack_u16(struct aa_ext *e, u16 *data, const char *name)
{
if (unpack_nameX(e, AA_U16, name)) {
if (!inbounds(e, sizeof(u16)))
- return 0;
+ return false;
if (data)
*data = le16_to_cpu(get_unaligned((u16 *) e->pos));
e->pos += sizeof(u16);
- return 1;
+ return true;
}
- return 0;
+ return false;
}
static bool unpack_u32(struct aa_ext *e, u32 *data, const char *name)
{
if (unpack_nameX(e, AA_U32, name)) {
if (!inbounds(e, sizeof(u32)))
- return 0;
+ return false;
if (data)
*data = le32_to_cpu(get_unaligned((u32 *) e->pos));
e->pos += sizeof(u32);
- return 1;
+ return true;
}
- return 0;
+ return false;
}
static bool unpack_u64(struct aa_ext *e, u64 *data, const char *name)
{
if (unpack_nameX(e, AA_U64, name)) {
if (!inbounds(e, sizeof(u64)))
- return 0;
+ return false;
if (data)
*data = le64_to_cpu(get_unaligned((u64 *) e->pos));
e->pos += sizeof(u64);
- return 1;
+ return true;
}
- return 0;
+ return false;
}
static size_t unpack_array(struct aa_ext *e, const char *name)
@@ -322,12 +322,12 @@ static bool verify_accept(struct aa_dfa *dfa, int flags)
int mode = ACCEPT_TABLE(dfa)[i];
if (mode & ~DFA_VALID_PERM_MASK)
- return 0;
+ return false;
if (ACCEPT_TABLE2(dfa)[i] & ~DFA_VALID_PERM2_MASK)
- return 0;
+ return false;
}
- return 1;
+ return true;
}
/**
@@ -437,12 +437,12 @@ static bool unpack_trans_table(struct aa_ext *e, struct aa_profile *profile)
if (!unpack_nameX(e, AA_STRUCTEND, NULL))
goto fail;
}
- return 1;
+ return true;
fail:
aa_free_domain_entries(&profile->file.trans);
e->pos = pos;
- return 0;
+ return false;
}
static bool unpack_rlimits(struct aa_ext *e, struct aa_profile *profile)
@@ -472,11 +472,11 @@ static bool unpack_rlimits(struct aa_ext *e, struct aa_profile *profile)
if (!unpack_nameX(e, AA_STRUCTEND, NULL))
goto fail;
}
- return 1;
+ return true;
fail:
e->pos = pos;
- return 0;
+ return false;
}
/**
@@ -726,8 +726,8 @@ static bool verify_xindex(int xindex, int table_size)
xtype = xindex & AA_X_TYPE_MASK;
index = xindex & AA_X_INDEX_MASK;
if (xtype == AA_X_TABLE && index >= table_size)
- return 0;
- return 1;
+ return false;
+ return true;
}
/* verify dfa xindexes are in range of transition tables */
@@ -736,11 +736,11 @@ static bool verify_dfa_xindex(struct aa_dfa *dfa, int table_size)
int i;
for (i = 0; i < dfa->tables[YYTD_ID_ACCEPT]->td_lolen; i++) {
if (!verify_xindex(dfa_user_xindex(dfa, i), table_size))
- return 0;
+ return false;
if (!verify_xindex(dfa_other_xindex(dfa, i), table_size))
- return 0;
+ return false;
}
- return 1;
+ return true;
}
/**
--
2.7.4

View File

@@ -1,118 +0,0 @@
From 24b6ac149a57c2d3d5a9920e64d914e8ff00d346 Mon Sep 17 00:00:00 2001
From: Vegard Nossum <vegard.nossum@oracle.com>
Date: Thu, 7 Jul 2016 13:41:11 -0700
Subject: [PATCH 01/27] apparmor: fix oops, validate buffer size in
apparmor_setprocattr()
When proc_pid_attr_write() was changed to use memdup_user apparmor's
(interface violating) assumption that the setprocattr buffer was always
a single page was violated.
The size test is not strictly speaking needed as proc_pid_attr_write()
will reject anything larger, but for the sake of robustness we can keep
it in.
SMACK and SELinux look safe to me, but somebody else should probably
have a look just in case.
Based on original patch from Vegard Nossum <vegard.nossum@oracle.com>
modified for the case that apparmor provides null termination.
Fixes: bb646cdb12e75d82258c2f2e7746d5952d3e321a
Reported-by: Vegard Nossum <vegard.nossum@oracle.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: John Johansen <john.johansen@canonical.com>
Cc: Paul Moore <paul@paul-moore.com>
Cc: Stephen Smalley <sds@tycho.nsa.gov>
Cc: Eric Paris <eparis@parisplace.org>
Cc: Casey Schaufler <casey@schaufler-ca.com>
Cc: stable@kernel.org
Signed-off-by: John Johansen <john.johansen@canonical.com>
Reviewed-by: Tyler Hicks <tyhicks@canonical.com>
Signed-off-by: James Morris <james.l.morris@oracle.com>
---
security/apparmor/lsm.c | 36 +++++++++++++++++++-----------------
1 file changed, 19 insertions(+), 17 deletions(-)
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index dec607c..5ee8201 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -523,34 +523,34 @@ static int apparmor_setprocattr(struct task_struct *task, char *name,
{
struct common_audit_data sa;
struct apparmor_audit_data aad = {0,};
- char *command, *args = value;
+ char *command, *largs = NULL, *args = value;
size_t arg_size;
int error;
if (size == 0)
return -EINVAL;
- /* args points to a PAGE_SIZE buffer, AppArmor requires that
- * the buffer must be null terminated or have size <= PAGE_SIZE -1
- * so that AppArmor can null terminate them
- */
- if (args[size - 1] != '\0') {
- if (size == PAGE_SIZE)
- return -EINVAL;
- args[size] = '\0';
- }
-
/* task can only write its own attributes */
if (current != task)
return -EACCES;
- args = value;
+ /* AppArmor requires that the buffer must be null terminated atm */
+ if (args[size - 1] != '\0') {
+ /* null terminate */
+ largs = args = kmalloc(size + 1, GFP_KERNEL);
+ if (!args)
+ return -ENOMEM;
+ memcpy(args, value, size);
+ args[size] = '\0';
+ }
+
+ error = -EINVAL;
args = strim(args);
command = strsep(&args, " ");
if (!args)
- return -EINVAL;
+ goto out;
args = skip_spaces(args);
if (!*args)
- return -EINVAL;
+ goto out;
arg_size = size - (args - (char *) value);
if (strcmp(name, "current") == 0) {
@@ -576,10 +576,12 @@ static int apparmor_setprocattr(struct task_struct *task, char *name,
goto fail;
} else
/* only support the "current" and "exec" process attributes */
- return -EINVAL;
+ goto fail;
if (!error)
error = size;
+out:
+ kfree(largs);
return error;
fail:
@@ -588,9 +590,9 @@ fail:
aad.profile = aa_current_profile();
aad.op = OP_SETPROCATTR;
aad.info = name;
- aad.error = -EINVAL;
+ aad.error = error = -EINVAL;
aa_audit_msg(AUDIT_APPARMOR_DENIED, &sa, NULL);
- return -EINVAL;
+ goto out;
}
static int apparmor_task_setrlimit(struct task_struct *task,
--
2.7.4

View File

@@ -1,33 +0,0 @@
From 444bc4f95ec283cd0fb9777f4890bd9bc307809d Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Mon, 11 Apr 2016 16:55:10 -0700
Subject: [PATCH 02/27] apparmor: fix refcount bug in profile replacement
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
---
security/apparmor/policy.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
index 705c287..222052f 100644
--- a/security/apparmor/policy.c
+++ b/security/apparmor/policy.c
@@ -1189,12 +1189,12 @@ ssize_t aa_replace_profiles(void *udata, size_t size, bool noreplace)
aa_get_profile(newest);
aa_put_profile(parent);
rcu_assign_pointer(ent->new->parent, newest);
- } else
- aa_put_profile(newest);
+ }
/* aafs interface uses replacedby */
rcu_assign_pointer(ent->new->replacedby->profile,
aa_get_profile(ent->new));
__list_add_profile(&parent->base.profiles, ent->new);
+ aa_put_profile(newest);
} else {
/* aafs interface uses replacedby */
rcu_assign_pointer(ent->new->replacedby->profile,
--
2.7.4

View File

@@ -1,38 +0,0 @@
From 1224a06778b89dcbf0ca85bd961c2fcdd8765a69 Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Mon, 11 Apr 2016 16:57:19 -0700
Subject: [PATCH 03/27] apparmor: fix replacement bug that adds new child to
old parent
When set atomic replacement is used and the parent is updated before the
child, and the child did not exist in the old parent so there is no
direct replacement then the new child is incorrectly added to the old
parent. This results in the new parent not having the child(ren) that
it should and the old parent when being destroyed asserting the
following error.
AppArmor: policy_destroy: internal error, policy '<profile/name>' still
contains profiles
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
---
security/apparmor/policy.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
index 222052f..c92a9f6 100644
--- a/security/apparmor/policy.c
+++ b/security/apparmor/policy.c
@@ -1193,7 +1193,7 @@ ssize_t aa_replace_profiles(void *udata, size_t size, bool noreplace)
/* aafs interface uses replacedby */
rcu_assign_pointer(ent->new->replacedby->profile,
aa_get_profile(ent->new));
- __list_add_profile(&parent->base.profiles, ent->new);
+ __list_add_profile(&newest->base.profiles, ent->new);
aa_put_profile(newest);
} else {
/* aafs interface uses replacedby */
--
2.7.4

View File

@@ -1,87 +0,0 @@
From 15d921647676fdc2c3ee1cf9aa8f578b1012ecff Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Sun, 8 Jun 2014 11:20:54 -0700
Subject: [PATCH 04/27] apparmor: fix uninitialized lsm_audit member
BugLink: http://bugs.launchpad.net/bugs/1268727
The task field in the lsm_audit struct needs to be initialized if
a change_hat fails, otherwise the following oops will occur
BUG: unable to handle kernel paging request at 0000002fbead7d08
IP: [<ffffffff8171153e>] _raw_spin_lock+0xe/0x50
PGD 1e3f35067 PUD 0
Oops: 0002 [#1] SMP
Modules linked in: pppox crc_ccitt p8023 p8022 psnap llc ax25 btrfs raid6_pq xor xfs libcrc32c dm_multipath scsi_dh kvm_amd dcdbas kvm microcode amd64_edac_mod joydev edac_core psmouse edac_mce_amd serio_raw k10temp sp5100_tco i2c_piix4 ipmi_si ipmi_msghandler acpi_power_meter mac_hid lp parport hid_generic usbhid hid pata_acpi mpt2sas ahci raid_class pata_atiixp bnx2 libahci scsi_transport_sas [last unloaded: tipc]
CPU: 2 PID: 699 Comm: changehat_twice Tainted: GF O 3.13.0-7-generic #25-Ubuntu
Hardware name: Dell Inc. PowerEdge R415/08WNM9, BIOS 1.8.6 12/06/2011
task: ffff8802135c6000 ti: ffff880212986000 task.ti: ffff880212986000
RIP: 0010:[<ffffffff8171153e>] [<ffffffff8171153e>] _raw_spin_lock+0xe/0x50
RSP: 0018:ffff880212987b68 EFLAGS: 00010006
RAX: 0000000000020000 RBX: 0000002fbead7500 RCX: 0000000000000000
RDX: 0000000000000292 RSI: ffff880212987ba8 RDI: 0000002fbead7d08
RBP: ffff880212987b68 R08: 0000000000000246 R09: ffff880216e572a0
R10: ffffffff815fd677 R11: ffffea0008469580 R12: ffffffff8130966f
R13: ffff880212987ba8 R14: 0000002fbead7d08 R15: ffff8800d8c6b830
FS: 00002b5e6c84e7c0(0000) GS:ffff880216e40000(0000) knlGS:0000000055731700
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000002fbead7d08 CR3: 000000021270f000 CR4: 00000000000006e0
Stack:
ffff880212987b98 ffffffff81075f17 ffffffff8130966f 0000000000000009
0000000000000000 0000000000000000 ffff880212987bd0 ffffffff81075f7c
0000000000000292 ffff880212987c08 ffff8800d8c6b800 0000000000000026
Call Trace:
[<ffffffff81075f17>] __lock_task_sighand+0x47/0x80
[<ffffffff8130966f>] ? apparmor_cred_prepare+0x2f/0x50
[<ffffffff81075f7c>] do_send_sig_info+0x2c/0x80
[<ffffffff81075fee>] send_sig_info+0x1e/0x30
[<ffffffff8130242d>] aa_audit+0x13d/0x190
[<ffffffff8130c1dc>] aa_audit_file+0xbc/0x130
[<ffffffff8130966f>] ? apparmor_cred_prepare+0x2f/0x50
[<ffffffff81304cc2>] aa_change_hat+0x202/0x530
[<ffffffff81308fc6>] aa_setprocattr_changehat+0x116/0x1d0
[<ffffffff8130a11d>] apparmor_setprocattr+0x25d/0x300
[<ffffffff812cee56>] security_setprocattr+0x16/0x20
[<ffffffff8121fc87>] proc_pid_attr_write+0x107/0x130
[<ffffffff811b7604>] vfs_write+0xb4/0x1f0
[<ffffffff811b8039>] SyS_write+0x49/0xa0
[<ffffffff8171a1bf>] tracesys+0xe1/0xe6
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
---
security/apparmor/audit.c | 3 ++-
security/apparmor/file.c | 3 ++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/security/apparmor/audit.c b/security/apparmor/audit.c
index 89c7865..3a7f1da 100644
--- a/security/apparmor/audit.c
+++ b/security/apparmor/audit.c
@@ -200,7 +200,8 @@ int aa_audit(int type, struct aa_profile *profile, gfp_t gfp,
if (sa->aad->type == AUDIT_APPARMOR_KILL)
(void)send_sig_info(SIGKILL, NULL,
- sa->u.tsk ? sa->u.tsk : current);
+ sa->type == LSM_AUDIT_DATA_TASK && sa->u.tsk ?
+ sa->u.tsk : current);
if (sa->aad->type == AUDIT_APPARMOR_ALLOWED)
return complain_error(sa->aad->error);
diff --git a/security/apparmor/file.c b/security/apparmor/file.c
index 913f377..43d6ae7 100644
--- a/security/apparmor/file.c
+++ b/security/apparmor/file.c
@@ -110,7 +110,8 @@ int aa_audit_file(struct aa_profile *profile, struct file_perms *perms,
int type = AUDIT_APPARMOR_AUTO;
struct common_audit_data sa;
struct apparmor_audit_data aad = {0,};
- sa.type = LSM_AUDIT_DATA_NONE;
+ sa.type = LSM_AUDIT_DATA_TASK;
+ sa.u.tsk = NULL;
sa.aad = &aad;
aad.op = op,
aad.fs.request = request;
--
2.7.4

View File

@@ -1,32 +0,0 @@
From c1216728b7d644443eef31e4bd9d01b4a0a51d61 Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Fri, 25 Jul 2014 04:02:03 -0700
Subject: [PATCH 05/27] apparmor: exec should not be returning ENOENT when it
denies
The current behavior is confusing as it causes exec failures to report
the executable is missing instead of identifying that apparmor
caused the failure.
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
---
security/apparmor/domain.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
index dc0027b..67a7418 100644
--- a/security/apparmor/domain.c
+++ b/security/apparmor/domain.c
@@ -433,7 +433,7 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
new_profile = aa_get_newest_profile(ns->unconfined);
info = "ux fallback";
} else {
- error = -ENOENT;
+ error = -EACCES;
info = "profile not found";
/* remove MAY_EXEC to audit as failure */
perms.allow &= ~MAY_EXEC;
--
2.7.4

View File

@@ -1,28 +0,0 @@
From 2d3389de6c8ab6b3ad2cef4ea460c8fce2a226b9 Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Fri, 25 Jul 2014 04:01:56 -0700
Subject: [PATCH 06/27] apparmor: fix update the mtime of the profile file on
replacement
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
---
security/apparmor/apparmorfs.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
index ad4fa49..45a6199 100644
--- a/security/apparmor/apparmorfs.c
+++ b/security/apparmor/apparmorfs.c
@@ -379,6 +379,8 @@ void __aa_fs_profile_migrate_dents(struct aa_profile *old,
for (i = 0; i < AAFS_PROF_SIZEOF; i++) {
new->dents[i] = old->dents[i];
+ if (new->dents[i])
+ new->dents[i]->d_inode->i_mtime = CURRENT_TIME;
old->dents[i] = NULL;
}
}
--
2.7.4

View File

@@ -1,36 +0,0 @@
From 9caa96e30a1b2bb191a29af872285c8d0b078c10 Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Fri, 25 Jul 2014 04:02:08 -0700
Subject: [PATCH 07/27] apparmor: fix disconnected bind mnts reconnection
Bind mounts can fail to be properly reconnected when PATH_CONNECT is
specified. Ensure that when PATH_CONNECT is specified the path has
a root.
BugLink: http://bugs.launchpad.net/bugs/1319984
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
---
security/apparmor/path.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/security/apparmor/path.c b/security/apparmor/path.c
index 71e0e3a..bb2f2c6 100644
--- a/security/apparmor/path.c
+++ b/security/apparmor/path.c
@@ -141,7 +141,10 @@ static int d_namespace_path(struct path *path, char *buf, int buflen,
error = -EACCES;
if (*res == '/')
*name = res + 1;
- }
+ } else if (*res != '/')
+ /* CONNECT_PATH with missing root */
+ error = prepend(name, *name - buf, "/", 1);
+
}
out:
--
2.7.4

View File

@@ -1,114 +0,0 @@
From 11702a732e149380e05e2ab8ae1b743ac89f892f Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Fri, 25 Jul 2014 04:02:10 -0700
Subject: [PATCH 08/27] apparmor: internal paths should be treated as
disconnected
Internal mounts are not mounted anywhere and as such should be treated
as disconnected paths.
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
---
security/apparmor/path.c | 64 +++++++++++++++++++++++++++---------------------
1 file changed, 36 insertions(+), 28 deletions(-)
diff --git a/security/apparmor/path.c b/security/apparmor/path.c
index bb2f2c6..596f799 100644
--- a/security/apparmor/path.c
+++ b/security/apparmor/path.c
@@ -25,7 +25,6 @@
#include "include/path.h"
#include "include/policy.h"
-
/* modified from dcache.c */
static int prepend(char **buffer, int buflen, const char *str, int namelen)
{
@@ -39,6 +38,38 @@ static int prepend(char **buffer, int buflen, const char *str, int namelen)
#define CHROOT_NSCONNECT (PATH_CHROOT_REL | PATH_CHROOT_NSCONNECT)
+/* If the path is not connected to the expected root,
+ * check if it is a sysctl and handle specially else remove any
+ * leading / that __d_path may have returned.
+ * Unless
+ * specifically directed to connect the path,
+ * OR
+ * if in a chroot and doing chroot relative paths and the path
+ * resolves to the namespace root (would be connected outside
+ * of chroot) and specifically directed to connect paths to
+ * namespace root.
+ */
+static int disconnect(const struct path *path, char *buf, char **name,
+ int flags)
+{
+ int error = 0;
+
+ if (!(flags & PATH_CONNECT_PATH) &&
+ !(((flags & CHROOT_NSCONNECT) == CHROOT_NSCONNECT) &&
+ our_mnt(path->mnt))) {
+ /* disconnected path, don't return pathname starting
+ * with '/'
+ */
+ error = -EACCES;
+ if (**name == '/')
+ *name = *name + 1;
+ } else if (**name != '/')
+ /* CONNECT_PATH with missing root */
+ error = prepend(name, *name - buf, "/", 1);
+
+ return error;
+}
+
/**
* d_namespace_path - lookup a name associated with a given path
* @path: path to lookup (NOT NULL)
@@ -74,7 +105,8 @@ static int d_namespace_path(struct path *path, char *buf, int buflen,
* control instead of hard coded /proc
*/
return prepend(name, *name - buf, "/proc", 5);
- }
+ } else
+ return disconnect(path, buf, name, flags);
return 0;
}
@@ -120,32 +152,8 @@ static int d_namespace_path(struct path *path, char *buf, int buflen,
goto out;
}
- /* If the path is not connected to the expected root,
- * check if it is a sysctl and handle specially else remove any
- * leading / that __d_path may have returned.
- * Unless
- * specifically directed to connect the path,
- * OR
- * if in a chroot and doing chroot relative paths and the path
- * resolves to the namespace root (would be connected outside
- * of chroot) and specifically directed to connect paths to
- * namespace root.
- */
- if (!connected) {
- if (!(flags & PATH_CONNECT_PATH) &&
- !(((flags & CHROOT_NSCONNECT) == CHROOT_NSCONNECT) &&
- our_mnt(path->mnt))) {
- /* disconnected path, don't return pathname starting
- * with '/'
- */
- error = -EACCES;
- if (*res == '/')
- *name = res + 1;
- } else if (*res != '/')
- /* CONNECT_PATH with missing root */
- error = prepend(name, *name - buf, "/", 1);
-
- }
+ if (!connected)
+ error = disconnect(path, buf, name, flags);
out:
return error;
--
2.7.4

View File

@@ -1,29 +0,0 @@
From c70811d9e6234c96d0ef405cd8ad78b70efb8637 Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Sat, 16 Apr 2016 13:59:02 -0700
Subject: [PATCH 09/27] apparmor: fix put() parent ref after updating the
active ref
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
---
security/apparmor/policy.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
index c92a9f6..455c9f8 100644
--- a/security/apparmor/policy.c
+++ b/security/apparmor/policy.c
@@ -1187,8 +1187,8 @@ ssize_t aa_replace_profiles(void *udata, size_t size, bool noreplace)
/* parent replaced in this atomic set? */
if (newest != parent) {
aa_get_profile(newest);
- aa_put_profile(parent);
rcu_assign_pointer(ent->new->parent, newest);
+ aa_put_profile(parent);
}
/* aafs interface uses replacedby */
rcu_assign_pointer(ent->new->replacedby->profile,
--
2.7.4

View File

@@ -1,87 +0,0 @@
From f671b902943f83f0fbc8c8b7bf8bbfb817d124f1 Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Sat, 16 Apr 2016 14:16:50 -0700
Subject: [PATCH 10/27] apparmor: fix log failures for all profiles in a set
currently only the profile that is causing the failure is logged. This
makes it more confusing than necessary about which profiles loaded
and which didn't. So make sure to log success and failure messages for
all profiles in the set being loaded.
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
---
security/apparmor/policy.c | 29 +++++++++++++++++++----------
1 file changed, 19 insertions(+), 10 deletions(-)
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
index 455c9f8..db31bc5 100644
--- a/security/apparmor/policy.c
+++ b/security/apparmor/policy.c
@@ -1067,7 +1067,7 @@ static int __lookup_replace(struct aa_namespace *ns, const char *hname,
*/
ssize_t aa_replace_profiles(void *udata, size_t size, bool noreplace)
{
- const char *ns_name, *name = NULL, *info = NULL;
+ const char *ns_name, *info = NULL;
struct aa_namespace *ns = NULL;
struct aa_load_ent *ent, *tmp;
int op = OP_PROF_REPL;
@@ -1082,18 +1082,15 @@ ssize_t aa_replace_profiles(void *udata, size_t size, bool noreplace)
/* released below */
ns = aa_prepare_namespace(ns_name);
if (!ns) {
- info = "failed to prepare namespace";
- error = -ENOMEM;
- name = ns_name;
- goto fail;
+ error = audit_policy(op, GFP_KERNEL, ns_name,
+ "failed to prepare namespace", -ENOMEM);
+ goto free;
}
mutex_lock(&ns->lock);
/* setup parent and ns info */
list_for_each_entry(ent, &lh, list) {
struct aa_policy *policy;
-
- name = ent->new->base.hname;
error = __lookup_replace(ns, ent->new->base.hname, noreplace,
&ent->old, &info);
if (error)
@@ -1121,7 +1118,6 @@ ssize_t aa_replace_profiles(void *udata, size_t size, bool noreplace)
if (!p) {
error = -ENOENT;
info = "parent does not exist";
- name = ent->new->base.hname;
goto fail_lock;
}
rcu_assign_pointer(ent->new->parent, aa_get_profile(p));
@@ -1214,9 +1210,22 @@ out:
fail_lock:
mutex_unlock(&ns->lock);
-fail:
- error = audit_policy(op, GFP_KERNEL, name, info, error);
+ /* audit cause of failure */
+ op = (!ent->old) ? OP_PROF_LOAD : OP_PROF_REPL;
+ audit_policy(op, GFP_KERNEL, ent->new->base.hname, info, error);
+ /* audit status that rest of profiles in the atomic set failed too */
+ info = "valid profile in failed atomic policy load";
+ list_for_each_entry(tmp, &lh, list) {
+ if (tmp == ent) {
+ info = "unchecked profile in failed atomic policy load";
+ /* skip entry that caused failure */
+ continue;
+ }
+ op = (!ent->old) ? OP_PROF_LOAD : OP_PROF_REPL;
+ audit_policy(op, GFP_KERNEL, tmp->new->base.hname, info, error);
+ }
+free:
list_for_each_entry_safe(ent, tmp, &lh, list) {
list_del_init(&ent->list);
aa_load_ent_free(ent);
--
2.7.4

View File

@@ -1,33 +0,0 @@
From bc3c7d342bf53afdfdf46bc92dac5c624c89fb91 Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Sat, 16 Apr 2016 14:19:38 -0700
Subject: [PATCH 11/27] apparmor: fix audit full profile hname on successful
load
Currently logging of a successful profile load only logs the basename
of the profile. This can result in confusion when a child profile has
the same name as the another profile in the set. Logging the hname
will ensure there is no confusion.
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
---
security/apparmor/policy.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
index db31bc5..ca402d0 100644
--- a/security/apparmor/policy.c
+++ b/security/apparmor/policy.c
@@ -1159,7 +1159,7 @@ ssize_t aa_replace_profiles(void *udata, size_t size, bool noreplace)
list_del_init(&ent->list);
op = (!ent->old && !ent->rename) ? OP_PROF_LOAD : OP_PROF_REPL;
- audit_policy(op, GFP_ATOMIC, ent->new->base.name, NULL, error);
+ audit_policy(op, GFP_ATOMIC, ent->new->base.hname, NULL, error);
if (ent->old) {
__replace_profile(ent->old, ent->new, 1);
--
2.7.4

View File

@@ -1,112 +0,0 @@
From 848da0479e5b9da3dc2ae4c64e0cca77a0abf02a Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Wed, 20 Apr 2016 14:18:18 -0700
Subject: [PATCH 12/27] apparmor: ensure the target profile name is always
audited
The target profile name was not being correctly audited in a few
cases because the target variable was not being set and gotos
passed the code to set it at apply:
Since it is always based on new_profile just drop the target var
and conditionally report based on new_profile.
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
---
security/apparmor/domain.c | 20 +++++++++-----------
1 file changed, 9 insertions(+), 11 deletions(-)
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
index 67a7418..fc3036b 100644
--- a/security/apparmor/domain.c
+++ b/security/apparmor/domain.c
@@ -346,7 +346,7 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
file_inode(bprm->file)->i_uid,
file_inode(bprm->file)->i_mode
};
- const char *name = NULL, *target = NULL, *info = NULL;
+ const char *name = NULL, *info = NULL;
int error = 0;
if (bprm->cred_prepared)
@@ -399,6 +399,7 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
if (cxt->onexec) {
struct file_perms cp;
info = "change_profile onexec";
+ new_profile = aa_get_newest_profile(cxt->onexec);
if (!(perms.allow & AA_MAY_ONEXEC))
goto audit;
@@ -413,7 +414,6 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
if (!(cp.allow & AA_MAY_ONEXEC))
goto audit;
- new_profile = aa_get_newest_profile(cxt->onexec);
goto apply;
}
@@ -445,10 +445,8 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
if (!new_profile) {
error = -ENOMEM;
info = "could not create null profile";
- } else {
+ } else
error = -EACCES;
- target = new_profile->base.hname;
- }
perms.xindex |= AA_X_UNSAFE;
} else
/* fail exec */
@@ -459,7 +457,6 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
* fail the exec.
*/
if (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS) {
- aa_put_profile(new_profile);
error = -EPERM;
goto cleanup;
}
@@ -474,10 +471,8 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
if (bprm->unsafe & (LSM_UNSAFE_PTRACE | LSM_UNSAFE_PTRACE_CAP)) {
error = may_change_ptraced_domain(new_profile);
- if (error) {
- aa_put_profile(new_profile);
+ if (error)
goto audit;
- }
}
/* Determine if secure exec is needed.
@@ -498,7 +493,6 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
bprm->unsafe |= AA_SECURE_X_NEEDED;
}
apply:
- target = new_profile->base.hname;
/* when transitioning profiles clear unsafe personality bits */
bprm->per_clear |= PER_CLEAR_ON_SETID;
@@ -506,15 +500,19 @@ x_clear:
aa_put_profile(cxt->profile);
/* transfer new profile reference will be released when cxt is freed */
cxt->profile = new_profile;
+ new_profile = NULL;
/* clear out all temporary/transitional state from the context */
aa_clear_task_cxt_trans(cxt);
audit:
error = aa_audit_file(profile, &perms, GFP_KERNEL, OP_EXEC, MAY_EXEC,
- name, target, cond.uid, info, error);
+ name,
+ new_profile ? new_profile->base.hname : NULL,
+ cond.uid, info, error);
cleanup:
+ aa_put_profile(new_profile);
aa_put_profile(profile);
kfree(buffer);
--
2.7.4

Some files were not shown because too many files have changed in this diff Show More