2
0
mirror of https://gitlab.com/apparmor/apparmor synced 2025-09-02 15:25:27 +00:00

Compare commits

..

106 Commits

Author SHA1 Message Date
John Johansen
4633658232 parser: ignore feature abi rules
AppArmor 3.0 requires policy to use a feature abi rule for access to
new features. However some policy may start using abi rules even if
they don't have rules that require new features.  This is especially
true for out of tree policy being shipped in other packages.

Add enough support to older releases that the parser will ignore the
abi rule and warn that it is falling back to the apparmor 2.x
technique of using the system abi.

If the profile contains rules that the older parser does not
understand it will fail policy compilation at the unknown rule instead
of the abi rule.

PR: https://gitlab.com/apparmor/apparmor/merge_requests/196
(backported form commit 83df7c4747)
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
2018-10-13 22:18:05 -07:00
Christian Boltz
e48533b156 Add most abi/bad_*.sd tests to "exception not raised" list
Interestingly, abi/bad_6.sd is detected as invalid, and therefore not
added to the list.

PR: https://gitlab.com/apparmor/apparmor/merge_requests/238
(cherry picked from commit 5c54f66279)
Signed-off-by: John Johansen <john.johansen@canonical.com>
2018-10-13 14:34:40 -07:00
John Johansen
c5f45ab3fc Merge branch 'cboltz-nmbd-systemd' into 'master'
References: https://bugs.launchpad.net/ubuntu/+source/samba/+bug/1719354
(comment 8)

PR: https://gitlab.com/apparmor/apparmor/merge_requests/236
Acked-by: John Johansen <john.johansen@canonical.com>


(cherry picked from commit 924d4e87ad)

d4afbccb nmbd profile: allow writing to /run/systemd/notify
2018-10-12 23:17:27 +00:00
John Johansen
963c896d91 parser: do not output cache warning for stdin if not using cache
Currently if stdin is used the warning
  apparmor_parser: cannot use or update cache, disable, or force-complain via stdin

is always displayed but if caching has been disabled there is no need for
this message.

(backported from commit c421a29c61)
PR: https://gitlab.com/apparmor/apparmor/merge_requests/233
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Christian Boltz <apparmor@cboltz.de>
2018-10-11 22:15:52 -07:00
Christian Boltz
70733be5c2 Merge branch 'cboltz-mergeprof-hasher-fun' into 'master'
Fix aa-mergeprof crash caused by accidentially initialzed hat

See merge request apparmor/apparmor!234

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

(cherry picked from commit 93445ca02d)

bc492533 Fix aa-mergeprof crash caused by accidentially initialzed hat
2018-10-11 19:49:53 +00:00
Christian Boltz
8020e36be9 .gitignore profiles/apparmor.d/local/* except README
The old patter *.* doesn't match lsb_release and nvidia_modprobe, and
the only file we ship in local is a README. This patch adjusts the
pattern to ignore everything except README.

(cherry picked from commit aeee9a1aab)
PR: https://gitlab.com/apparmor/apparmor/merge_requests/227
Signed-off-by: John Johansen <john.johansen@canonical.com>
2018-10-11 10:27:31 -07:00
Christian Boltz
a12e1b31dd Merge branch 'cboltz-2.12-cache.d' into 'apparmor-2.12'
2.12: is_skippable_dir(): add 'cache.d' to exclude list

See merge request apparmor/apparmor!232
2018-10-11 10:21:09 +00:00
Christian Boltz
d57f775d73 is_skippable_dir(): add 'cache.d' to exclude list
This excludes the /etc/apparmor.d/cache.d/ directory from aa-logprof
parsing because parsing the binary cache, well, takes a while :-/

Reported on the opensuse-factory mailinglist by Frank Krüger and
confirmed by others.

(cherry picked from commit 5b9497a8c6)
2018-10-10 22:56:10 +02:00
Christian Boltz
9ae7b1059f add new location for ssl-params file
(probably Ubuntu-only? The ssl-params file doesn't exist on my openSUSE
installation)

References: https://bugs.launchpad.net/apparmor-profiles/+bug/1796966
(cherry picked from commit 16a98d26d0)
Signed-off-by: John Johansen <john.johansen@canonical.com>
2018-10-09 16:55:28 -07:00
John Johansen
a1ca25db2d libapparmor: Finish removing LD_RUN_PATH from Makefile.perl
commit 94dfe15b28 attempted to remove
LD_RUN_PATH unfortunately

   But all it actually does is cause the Makefile.perl to embed the rpath
    "" instead. Which is still an rpath, only I guess an even worse one.

    --
    Eli Schwartz
    Arch Linux Bug Wrangler and Trusted User

This is because it cleared the setting of the variable LD_RUN_PATH
which was expanded in the command

$(INST_DYNAMIC) : $(OBJECT) $(MYEXTLIB) $(INST_ARCHAUTODIR)$(DFSEP).exists $(EXPORT_LIST) $(PERL_ARCHIVEDEP) $(PERL_ARCHIVE_AFTER) $(INST_DYNAMIC_DEP)
	$(RM_F) $@
	 LD_RUN_PATH="$(LD_RUN_PATH)" $(LD)  $(LDDLFLAGS) $(LDFROM) $(OTHERLDFLAGS) -o $@ $(MYEXTLIB) \
	  $(PERL_ARCHIVE) $(LDLOADLIBS) $(PERL_ARCHIVE_AFTER) $(EXPORT_LIST) \
	  $(INST_DYNAMIC_FIX)
	$(CHMOD) $(PERM_RWX) $@

resulting in LD_RUN_PATH="" being passed to the command.

Finish removing LD_RUN_PATH from Makefile.perl by removing it from
the command invocation if it is present.

Note: we use \x24 instead of $ in the regex as there seems to be a bug
and no level of escaping $ would allow it to be used.

PR: https://gitlab.com/apparmor/apparmor/merge_requests/207
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Christian Boltz <apparmor@cboltz.de>
(cherry picked from commit 958cc28876)
2018-10-09 16:45:49 -07:00
Christian Boltz
362a2db73c Merge branch 'sys-by-default' into 'master'
Make @{sys} available by default

See merge request apparmor/apparmor!228

Acked-by: Christian Boltz <apparmor@cboltz.de> for 2.10..master

(cherry picked from commit 772a8702e0)

aa065287 Make @{sys} available by default
2018-10-09 22:30:36 +00:00
Petr Vorel
7c1a704c78 dnsmasq: Add permission to open log files
--log-facility option needs to have permission to open files.
Use '*' to allow using more files (for using more dnsmasq instances).

Signed-off-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Jamie Strandboge <jamie@canonical.com>
(cherry picked from commit 025c7dc6a1)
Signed-off-by: Steve Beattie <steve.beattie@canonical.com>
2018-10-09 09:06:47 -07:00
Christian Boltz
e1a8793ea1 Merge branch 'fix-bison' into 'master'
parser: fix Makefile hardcoded paths to flex and bison

Closes #4

See merge request apparmor/apparmor!224

Acked-by: Christian Boltz <apparmor@cboltz.de> for 2.10..master

(cherry picked from commit 34cf085036)

17e059a2 parser: fix Makefile hardcoded paths to flex and bison
2018-10-05 19:03:56 +00:00
John Johansen
0ed6607dc2 Merge branch 'cboltz-2.12-minitools-alternations' into 'apparmor-2.12'
backport "Set flags for profiles represented by a glob" to 2.12

Backport/cherry-pick 5e187daa ("Set flags for profiles represented by a glob") and the follow-up fixes f472b6bb and 0dca959c to 2.12.

Besides backporting this "bugfix feature" to 2.12, this is needed to fix minitools_test.py.

See merge request apparmor/apparmor!218

Acked-by: John Johansen <john.johansen@canonical.com>
2018-10-05 06:44:09 +00:00
nl6720
06b0a9ad37 aa-notify: Read user's configuration file from XDG_CONFIG_HOME
Legacy path ~/.apparmor/notify.conf is preferred if it exists, otherwise
$XDG_CONFIG_HOME/apparmor/notify.conf, with fallback to
~/.config/apparmor/notify.conf, is used.

PR: https://gitlab.com/apparmor/apparmor/merge_requests/215
Signed-off-by: nl6720 <nl6720@gmail.com>
(cherry picked from commit 1fb9acc59e)
Signed-off-by: John Johansen <john.johansen@canonical.com>
2018-10-04 23:39:43 -07:00
Christian Boltz
32e226fe71 Merge branch 'profile-usr.sbin.smbd' into 'master'
Add missing paths to usr.sbin.nmbd, usr.sbin.smbd and abstractions/samba

See merge request apparmor/apparmor!210

Acked-by: Christian Boltz <apparmor@cboltz.de> for 2.10..master

(cherry picked from commit f76a718f28)

80e98f2d Update usr.sbin.nmbd & usr.sbin.smbd
2018-10-04 20:34:30 +00:00
Christian Boltz
d68c4f5ac9 set_profile_flags(): allow named profiles without attachment
Named profiles can come without an attachment path specified, for
example
    profile foo {...}

This patch fixes set_profile_flags() to actually allow that instead of
erroring out.

References:
- https://bugzilla.opensuse.org/show_bug.cgi?id=1096269 comment #3 and #4
- https://bugs.launchpad.net/apparmor/+bug/1775591

(cherry picked from commit 0dca959c6b)
2018-10-03 18:18:08 +02:00
Christian Boltz
ebe3b8408a fix regression in {get,set}_profile_flags()
Since the latest change, calling {get,set}_profile_flags() with the
profile name failed when attachment was specified ("profile foo /bar").

Catched by the unittests.

Also fix a whitespace issue.

(cherry picked from commit f472b6bb34)
2018-10-03 18:18:03 +02:00
Goldwyn
dc2e7d4a45 Set flags for profiles represented by a glob
Getting and Setting profile represented by a glob does not work correctly
because they are checked for equality. Use a glob match to check for them.
Also, add a warning stating that the profile being set represents multiple programs.

traceroute is an example whose profile name is represented as
/usr/{sbin/traceroute,bin/traceroute.db} and exhibits the issue:

Setting /usr/sbin/traceroute to enforce mode.

ERROR: /etc/apparmor.d/usr.sbin.traceroute contains no profile

Signed-off-by: Goldwyn <goldwyn@fiona.lan>
(cherry picked from commit 5e187daa0b)
2018-10-03 18:17:52 +02:00
Christian Boltz
fa82a51523 Merge branch 'cboltz-2.12-fix-utils-po' into 'apparmor-2.12'
Remove accidently added text from utils/po/Makefile

See merge request apparmor/apparmor!217

Acked-by: Tyler Hicks <tyhicks@canonical.com>
2018-10-03 15:52:17 +00:00
Christian Boltz
15770576f8 Remove accidently added text from utils/po/Makefile
This reverts the faulty part of fc058486d7
("all: Use HTTPS links for apparmor.net")
2018-10-03 17:19:21 +02:00
John Johansen
b28ce5a2a0 Merge branch 'cboltz-abi-2.13' into 'apparmor-2.13'
2.13: Add basic support for abi rules to the tools

Add basic "understand and keep" support for abi rules, where
"understand" means to not error out when seeing an abi rule, and "keep"
simply means to keep the original abi rule when serializing a profile.

On the long term, abi rules should be parsed (similar to include rules),
but for now, this patch is the smallest possible changeset and easy to
backport.

Note that the only added test is via cleanprof_test.* which is used by
minitools_test.py - and does not run if you do a 'make check'.
Oh, and of course the simple_tests/abi/ files also get parsed by
test-parser-simple-tests.py.

BTW: Even serialize_profile_from_old_profile() can handle abi rules :-)

This is a backport of 072d3e04 / !202 (merged) to
2.13 (with some adjustments because that commit didn't appy cleanly)

I propose this patch for 2.10..2.13

PR: https://gitlab.com/apparmor/apparmor/merge_requests/216
Acked-by: John Johansen <john.johansen@canonical.com>


(cherry picked from commit ab91f7bfa3)

420aea62 Add basic support for abi rules to the tools
2018-10-03 15:03:51 +00:00
Vincas Dargis
69e0c2010a Add qt5-compose-cache-write abstraction
Qt GUI applications that uses "platforminputcontexts"-class of plugins
might need reading and/or writing compose cache. Add read-only rule in
qt5 abstraction and create new writing dedicated for compose cache
writing.

PR: https://gitlab.com/apparmor/apparmor/merge_requests/159
(cherry picked from commit 67816c42cf)
Signed-off-by: John Johansen <john.johansen@canonical.com>
2018-10-02 23:07:34 -07:00
Vincas Dargis
0865aa2301 Add qt5-write abstraction
Qt-based applications stores QFileDialog (latest browsed directory) and
other shared user settings inside ~/.config/QtProject.conf. Currently
available qt abstraction only allows to read it (by design), so this
patch introduces abstraction that grants permissions for writing.

PR: https://gitlab.com/apparmor/apparmor/merge_requests/159
(cherry picked from commit 69c4cabb93)
Signed-off-by: John Johansen <john.johansen@canonical.com>
2018-10-02 23:07:34 -07:00
Vincas Dargis
9db3bba874 Add qt5 abstraction
Create abtractions/qt5 with common rules needed for Qt5-based
applications.

PR: https://gitlab.com/apparmor/apparmor/merge_requests/99
(cherry picked from commit 6a85ffe00e)
Signed-off-by: John Johansen <john.johansen@canonical.com>
2018-10-02 23:07:34 -07:00
Vincas Dargis
e3d924755b Include qt5 into kde abstraction
Currently, kde abstraction has rules relevant to Qt 3 and Qt 4
libraries, but are missing rules against latest Qt 5.

Include read-only Qt 5 abstraction to fix styling and similar issues for
software running on KDE 5 desktop.

PR: https://gitlab.com/apparmor/apparmor/merge_requests/209
Fixes https://bugs.launchpad.net/apparmor/+bug/1787201
(cherry picked from commit bd33cdd19a)
Signed-off-by: John Johansen <john.johansen@canonical.com>
2018-10-01 08:52:29 -07:00
Vincas Dargis
897072ce66 Add uid and uids kernel var placeholders
Add @{uid} and @{uids} variables to allow migrating profiles in advance
while awaiting path mediation implementation, based on current user id,
in kernel side.

PR: https://gitlab.com/apparmor/apparmor/merge_requests/208
(cherry picked from commit cba10db7e7)
Signed-off-by: John Johansen <john.johansen@canonical.com>
2018-10-01 08:52:29 -07:00
John Johansen
9ae44d3791 Merge branch 'harden-abstractions-part-ii' into 'apparmor-2.12'
Harden abstractions part ii

- abstractions/private-files: disallow access to the dirs of private files
- private-files{,-strict}: disallow writes to parent dirs too
- user-files: disallow writes to parents dirs

PR: https://gitlab.com/apparmor/apparmor/merge_requests/206
Signed-off-by: John Johansen <john.johansen@canonical.com>
2018-09-27 13:49:42 -07:00
Jamie Strandboge
e32c437bfd similar change for user-files 2018-09-27 13:49:26 -07:00
Jamie Strandboge
ae7471667c private-files{,-strict}: disallow writes to parent dirs too 2018-09-27 13:49:26 -07:00
Emerson Bernier
5bbe6b769a abstractions/private-files: disallow access to the dirs of private files
Reference:
https://launchpad.net/bugs/1794820
2018-09-27 13:49:26 -07:00
Vincas Dargis
2dea9d6dc9 ubuntu-email: allow running Thunderbird wrapper script
gio-launch-desktop helper tries to execute /usr/bin/thunderbird wrapper
script, not the /usr/lib/thunderbird... directly.

Add rule allowing to execute /usr/bin/thunderbird.

PR: https://gitlab.com/apparmor/apparmor/merge_requests/204
(cherry picked from commit cee9527fa8)
Signed-off-by: John Johansen <john.johansen@canonical.com>
2018-09-27 12:19:04 -07:00
John Johansen
a5e4fa835d Merge branch 'harden-abstractions' into 'apparmor-2.12'
Harden abstractions

Harden abstractions

    remove antiquated abstractions/launchpad-integration
    abstractions/private-files-strict: disallow access to the dirs of private files
    abstractions/private-files: disallow writes to thumbnailer dir (LP: #1788929)
    ubuntu-browsers.d/user-files: disallow access to the dirs of private files

    Nominating launchpad-integration and opencl-nvidia for 2.13. Nominating private-files-strict, private-files and user-files for 2.10 and higher

PR: https://gitlab.com/apparmor/apparmor/merge_requests/203
Signed-off-by: John Johansen <john.johansen@canonical.com>
2018-09-27 10:55:51 -07:00
Jamie Strandboge
531e53b577 we don't need to adjust keyring**. Thanks cboltz 2018-09-27 10:51:52 -07:00
Jamie Strandboge
410352c5ae ubuntu-browsers.d/user-files: disallow access to the dirs of private files 2018-09-27 10:51:52 -07:00
Jamie Strandboge
0f6554a851 abstractions/private-files: disallow writes to thumbnailer dir (LP: #1788929) 2018-09-27 10:51:52 -07:00
Jamie Strandboge
ac66f9cbea abstractions/private-files-strict: disallow access to the dirs of private files
Reference:
https://launchpad.net/bugs/1794820
2018-09-27 10:51:52 -07:00
Jamie Strandboge
6896017481 remove antiquated abstractions/launchpad-integration 2018-09-27 10:49:20 -07:00
Christian Boltz
5b7209c040 Merge branch 'zsh' into 'master'
add zsh to logprof.conf

See merge request apparmor/apparmor!201

Acked-by: Christian Boltz <apparmor@cboltz.de> for 2.10..master

(cherry picked from commit 7e22b0a894)

00871696 add zsh to logprof.conf
2018-09-24 17:35:21 +00:00
nl6720
549bdef505 usr.sbin.dnsmasq: add paths for NetworkManager connection sharing
Also add /usr/share/dnsmasq/, DNSSEC trust anchors are kept there.

(cherry picked from commit 5bc7a9fbd6)
Signed-off-by: John Johansen <john.johansen@canonical.com>
2018-09-19 00:10:02 -07:00
nl6720
da47860e77 usr.sbin.ntpd: add openntpd drift and socket files
(cherry picked from commit b3c4a73e2f)
Signed-off-by: John Johansen <john.johansen@canonical.com>
2018-09-19 00:10:02 -07:00
Cameron Nemo
3c74f77b8d profiles: support void-specific binary names for openntpd, traceroute, and ping
(cherry picked from commit 6e28a94ace)
Signed-off-by: John Johansen <john.johansen@canonical.com>
2018-09-19 00:10:02 -07:00
Cameron Nemo
bb6505e8fc profiles: support distributions which merge sbin into bin
Closes #8

(cherry picked from commit 9ab45d811e)
Signed-off-by: John Johansen <john.johansen@canonical.com>
2018-09-19 00:09:28 -07:00
Christian Boltz
5d4b4ae3c7 add python3.7 to logprof.conf
(cherry picked from commit db096135eb)
Signed-off-by: John Johansen <john.johansen@canonical.com>
2018-09-14 16:56:53 -07:00
John Johansen
de7796957d infrastructure: fix branch name for release builds
When backporting the gitlab infrastructure patch the branch name
was not updated. Fix it.

Signed-off-by: John Johansen <john.johansen@canonical.com>
2018-09-13 16:02:29 -07:00
John Johansen
21015d2e7b Documentation: Move README to README.md and sync with master branch
Move README to README.md to provide better integration with gitlab
and sync changes from master branch so we have badges, build info
etc.

Signed-off-by: John Johansen <john.johansen@canonical.com>
2018-09-13 15:47:26 -07:00
Tyler Hicks
325139f435 README: Point to the security vuln section of the wiki
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
2018-09-13 11:51:04 -07:00
Tyler Hicks
1c656dfebd README: Point to the new email address for security bug reports
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
2018-09-13 11:51:04 -07:00
Tyler Hicks
18cf8d86bc README: Improve the bug reporting instructions
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
2018-09-13 11:51:04 -07:00
Tyler Hicks
bd3f0e5ffe README: Move project contact info into the main README
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
2018-09-13 11:51:04 -07:00
Tyler Hicks
f4c2ac7342 parser: Remove mention of wiretrip vulnerability handling policy
It looks as if the wiretrip domain has changed hands. The linked policy
page no longer exists.

Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
2018-09-13 11:51:04 -07:00
Tyler Hicks
5d397373b5 utils: Point to the correct Profiles wiki page
The URL redirect ends up at a page in the new wiki that doesn't exist.
We have to link directly to the gitlab URL here since the current URL
redirect doesn't let us use a wiki.apparmor.net URL and still reach the
expected Profiles page.

Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
2018-09-13 11:51:04 -07:00
Tyler Hicks
fc058486d7 all: Use HTTPS links for apparmor.net
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
2018-09-13 11:51:04 -07:00
John Johansen
7ecceb9e12 Merge branch 'cboltz-revert-cboltz-fix-complain-named-profiles-in-2.12' into 'apparmor-2.12'
Revert backporting cboltz-fix-complain-named-profiles to 2.12

See merge request apparmor/apparmor!186

Revert commit 995c0e96 in the 2.12 branch
set_profile_flags(): allow named profiles without attachment

See merge request apparmor/apparmor!142
This commit/fix is only needed in 2.13+ because of changes introduced in
2.13 (matching profile names with globs in aa-complain), and actually
breaks 2.12.
(The alternative is to backport the profile name glob matching to 2.12.)

Acked-by: John Johansen <john.johansen@canonical.com>
2018-09-12 23:26:24 +00:00
Christian Boltz
a1b08c2f65 Revert backporting cboltz-fix-complain-named-profiles
Revert commit 995c0e96f8 in the 2.12 branch

    set_profile_flags(): allow named profiles without attachment

    See merge request apparmor/apparmor!142

This commit/fix is only needed in 2.13+ because of changes introduced in
2.13 (matching profile names with globs in aa-complain), and actually
breaks 2.12.
2018-09-12 12:30:56 +02:00
Christian Boltz
e490484b90 abstractions/php: allow ICU (unicode support) data tables
Reported by darix on IRC, and also something I noticed in my own usage
of PHP.

PR: https://gitlab.com/apparmor/apparmor/merge_requests/184
(cherry picked from commit e396f9dae9)
Signed-off-by: John Johansen <john.johansen@canonical.com>
2018-09-11 18:27:27 -07:00
Christian Boltz
d303ee9393 remove unused exception binding in sandbox.py
pyflakes 2.0 is more strict and found that 'e' is never used.

References: https://build.opensuse.org/request/show/629206 (comment
section)

PR: https://gitlab.com/apparmor/apparmor/merge_requests/178
(cherry picked from commit 51482c33f5)
Signed-off-by: John Johansen <john.johansen@canonical.com>
2018-09-11 18:27:27 -07:00
John Johansen
995c0e96f8 Merge branch 'cboltz-fix-complain-named-profiles' into 'master'
set_profile_flags(): allow named profiles without attachment

See merge request apparmor/apparmor!142

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


(cherry picked from commit c66a1a972c)

0dca959c set_profile_flags(): allow named profiles without attachment
2018-09-11 17:08:54 -07:00
Christian Boltz
baee295e63 let change_profile_flags() change flags in child profiles
... instead of overwriting them with the flags of the main profile.

This fixes a longstanding issue with aa-complain, aa-enforce and
aa-audit which broke the flags of child profiles and hats if they
differed from the main profile.

It also fixes several issues documented in the tests (which obviously
need adjustment to match the fixed behaviour).

Also change the "no profile found" cases to AppArmorException - errors
in a profile are not worth triggering AppArmorBug ;-)

(cherry picked from commit b00aab0843)
2018-09-11 17:03:51 -07:00
Christian Boltz
99b3c562be change_profile_flags: raise AppArmorBug on empty new flag
(cherry picked from commit d26ffbdd29)
2018-09-11 17:03:51 -07:00
Christian Boltz
173b8cd70a merge set_profile_flags() into change_profile_flags()
(and adjust a few comments in profile_storage.py)

(cherry picked from commit c016fc6656)
2018-09-11 17:03:51 -07:00
Christian Boltz
b22faedbfc rewrite set_profile_flags() tests to use change_profile_flags()
All callers call change_profile_flags(), so it makes sense to test this
function instead of set_profile_flags().

Besides that, set_profile_flags() will be merged into
change_profile_flags() in the next commit ;-)

Note that this commit adds some '# XXX' notes to the tests. These will
be addressed in later commits.

(cherry picked from commit abd124c00d)
2018-09-11 17:03:51 -07:00
Christian Boltz
bda6b297b8 change_profile_flags: use ', ' as flags delimiter
This looks better than a comma without whitespace.

Also adjust minitools_test.py to follow this change.

(cherry picked from commit 4a021ec203)
2018-09-11 17:03:51 -07:00
Christian Boltz
57e5d6cc4e extend add_or_remove_flag() to handle str for old flags
If the old flags are given as str (or None), call split_flags() to
convert them to a list.

This allows to simplify change_profile_flags() which now doesn't need to
call split_flags() on its own.

Also add some tests with a str for the old flags

(cherry picked from commit e80caa130a +
 conflict resolution)
2018-09-11 17:03:51 -07:00
Christian Boltz
43bf2028c4 split off add_or_remove_flag() from change_profile_flags()
Also add some tests for add_or_remove_flag()

(cherry picked from commit 604004c2b6 +
 conflict resolution)
2018-09-11 17:03:51 -07:00
Christian Boltz
ab3e53d7f7 move splitting flags into profile_storage split_flags() function
... and change change_profile_flags() to use it instead of doing it
itsself

Also add some tests for split_flags()

Cherry-picked from ce7ea062c5 + conflict
resolution
2018-09-11 17:03:51 -07:00
Christian Boltz
0fb49edfcd activate_repo_profiles(): use change_profile_flags
... instead of set_profile_flags() to keep possibly existing flags like
attach_disconnected.

Note that this function is unused (meant to be used with the
no-longer-existing profile repo), therefore nobody noticed that
set_profile_flags() was called with the wrong number of parameters ;-)
2018-09-11 17:03:51 -07:00
Christian Boltz
01bc13dee4 add dehydrated certificate location to ssl_* abstractions
I don't use dehydrated myself, therefore this is based on the comments
on https://build.opensuse.org/request/show/533380

(cherry picked from commit 2e8b902248)
Signed-off-by: John Johansen <john.johansen@canonical.com>
2018-08-07 23:55:57 -07:00
Christian Boltz
fccfaa6bfc aa-genprof: don't crash if setting printk_ratelimit fails
When running aa-genprof in a lxd instance, printk_ratelimit is readonly
and writing to it fails. Instead of crashing with a backtrace, only
print a warning.

References: https://bugs.launchpad.net/apparmor/+bug/1785391
(cherry picked from commit 961e69afe5)
Signed-off-by: John Johansen <john.johansen@canonical.com>
2018-08-07 03:04:53 -07:00
Steve Beattie
1aaffa6e1b coverity build: capture separate log files for each coverity invocation
Each coverity command writes its debugging output to
cov-int/build-log.txt, which means that multiple runs of cov-build
overwrite previous logs, resulting in only the last invocation's output
remaining at the end of the build, making debugging why failures to
capture coverity output difficult. Fix this by renaming the build-log to
per-directory log files.

(This would still be an issue even if we had a single build command
for the entire tree, as capturing python and other interpreted
files requires a second invocation of cov-build to scan for those
file types.)

Signed-off-by: Steve Beattie <steve.beattie@canonical.com>
PR: https://gitlab.com/apparmor/apparmor/merge_requests/145
(cherry picked from commit fed101920b)
Signed-off-by: John Johansen <john.johansen@canonical.com>
2018-08-07 02:42:24 -07:00
Christian Boltz
612701ec4d make message about notify-send package cross-distro compatible
PR: !144
References: https://bugzilla.opensuse.org/show_bug.cgi?id=1100779
(cherry picked from commit 44ee1d5090)
Signed-off-by: John Johansen <john.johansen@canonical.com>
2018-08-07 02:31:34 -07:00
Christian Boltz
29102a2d04 Fix unsetting filename in get_profile()
When creating a new profile with aa-genprof, get_profile() searches for
an inactive ("extra") profile and, if it finds one, removes the filename
from that profile so that it gets stored in /etc/apparmor.d/ later.

However, it used .pop() to remove the filename, which explodes since
ProfileStorage is a class now.

This patch fixes this (tested manually).

PR: !140
(cherry picked from commit 73b33bdf36)
Signed-off-by: John Johansen <john.johansen@canonical.com>
2018-08-07 02:31:21 -07:00
Christian Boltz
02193447bf Merge branch 'add-path-to-abstractions-python' into 'master'
Allow /usr/local/lib/python3/dist-packages in abstractions/python

See merge request apparmor/apparmor!160

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

Acked-by: Christian Boltz <apparmor@cboltz.de> for 2.10..master

(cherry picked from commit 763a6787d8)

6a10f076 Allow /usr/local/lib/python3/dist-packages in abstractions/python
2018-08-06 18:12:02 +00:00
Steve Beattie
8f58475e94 common/Version: update to show 2.12.1 would be next apparmor-2.12 release
Signed-off-by: Steve Beattie <steve.beattie@canonical.com>
2018-07-25 16:13:52 -07:00
Christian Boltz
0078215941 comment out use_group to remove group restrictions
use_group is only honored if it is defined.

The "real" permission check is reading the logfile - the group check
in aa-notify is just an annoying additional check, and the default
"admin" only works on Ubuntu (other distributions typically use
"wheel").

This commit comments out use_group in the default config, which allows
everybody to use aa-notify. Permissions for reading the log file are of
course still needed.

PR: https://gitlab.com/apparmor/apparmor/merge_requests/82
References: https://bugzilla.opensuse.org/show_bug.cgi?id=1058787
(cherry picked from commit 86ec3dd658)
Acked-by: Christian Boltz <apparmor@cboltz.de>
Signed-off-by: John Johansen <john.johansen@canonical.com>
2018-07-11 22:42:44 -07:00
Christian Boltz
e05e08a00e profiles: adjust abstractions/python for python 3.7
Python 3.7 was released yesterday - and to make the abstraction
future-proof, also cover 3.8 and 3.9 in advance ;-)

(cherry picked from commit 01f41fbff8)

Signed-off-by: Steve Beattie <steve.beattie@canonical.com>
PR: https://gitlab.com/apparmor/apparmor/merge_requests/139
2018-06-29 11:23:24 -07:00
Christian Boltz
35febe2c82 Merge branch 'cboltz-nested-child-error' into 'master'
parse_profile_start(): Error out on nested child profiles

See merge request apparmor/apparmor!136

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

(cherry picked from commit b7a4f37cbb)

8462c39b parse_profile_start(): Error out on nested child profiles
2018-06-21 10:20:30 +00:00
Christian Boltz
81e5699248 utils: update samba profiles
- allow smbd to load new shared libraries
- allow winbindd to read and write new kerberos cache location

Based on a patch by "Samuel Cabrero" <scabrero@suse.com>

(cherry picked from commit 23b5f29b80)

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

Acked-by: Steve Beattie <steve@nxnw.org>
PR: https://gitlab.com/apparmor/apparmor/merge_requests/121
2018-05-09 14:04:44 -07:00
Christian Boltz
2c85212428 utils: fix writing alias rules
write_pair() ignored the 'tail' parameter, which resulted in writing
invalid alias rules (without the trailing comma).

Also add an alias to test/cleanprof.* to ensure it doesn't break again.

(cherry picked from commit ae4ab62855)

Acked-by: John Johansen <john.johansen@canonical.com>
Acked-by: Steve Beattie <steve@nxnw.org>
PR: https://gitlab.com/apparmor/apparmor/merge_requests/119
2018-05-08 07:56:26 -07:00
Christian Boltz
e73079b46a utils: fix writing "link subset" rules
Writing a "link subset" rule missed a space, which resulted in something
like
  link subset/foo -> /bar,

Also add a test rule to tests/cleanprof.* to ensure this doesn't break
again.

(cherry picked from commit 514535608f)

Acked-by: Steve Beattie <steve@nxnw.org>
PR: https://gitlab.com/apparmor/apparmor/merge_requests/117
2018-05-06 22:37:26 -07:00
Steve Beattie
d8d80d8111 mount regression test: convert mount test to use MS_NODEV
The mount regression test passes MS_MANDLOCK to the mount(2) syscall in
the test program. When the kernel is configured without
CONFIG_MANDATORY_FILE_LOCKING set, attempting to mount a filesystem with
this option always fails with EPERM. To fix, convert the test program to
use the MS_NODEV option instead.

(cherry picked from commit 49ba6af2bf)

Signed-off-by: Steve Beattie <steve.beattie@canonical.com>
Acked-by: John Johansen <john.johansen@canonical.com>

Bug: https://bugs.launchpad.net/apparmor/+bug/1765025
PR: https://gitlab.com/apparmor/apparmor/merge_requests/109
2018-04-30 13:35:46 -07:00
John Johansen
03af33b1d5 Merge branch 'cboltz-dovecot-config' into 'master'
dovecot/config: allow dac_read_search and reading ssl-parameters.dat

See merge request apparmor/apparmor!95

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


(cherry picked from commit 5d973c2657)

c4e60719 dovecot/config: allow dac_read_search and reading ssl-parameters.dat
2018-04-14 21:24:14 +00:00
Christian Boltz
efd52522a6 Merge branch 'cboltz-dovecot-profiles' into 'master'
Dovecot profile updates

See merge request apparmor/apparmor!90

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

(cherry picked from commit 6b78daf25b)

36bdd6ea add dovecot/stats profile, and allow dovecot to run it
26a8b722 allow dovecot/auth to write /run/dovecot/old-stats-user
2018-04-13 13:57:00 +00:00
Christian Boltz
968adf9467 Merge branch 'opensuse_browsers' into 'master'
Fix ubuntu-browsers for 64bit openSUSE

See merge request apparmor/apparmor!87

Acked-by: Christian Boltz <apparmor@cboltz.de> for 2.9..master

(cherry picked from commit 06069cc47a)

0c2690d8 Fix ubuntu-browsers for 64bit openSUSE
2018-04-01 15:35:17 +00:00
Christian Boltz
d788de3787 Merge branch 'master' into 'master'
Fix typo in apparmor_parser.pod

See merge request apparmor/apparmor!85

Acked-by: Christian Boltz <apparmor@cboltz.de> for 2.9..master

(cherry picked from commit 47da50b7e6)

50ee50f9 Fix typo in apparmor_parser.pod
2018-03-26 19:50:44 +00:00
Christian Boltz
608f230c75 Merge branch 'cboltz-fix-make-C-profiles' into 'master'
Fix $(PWD) when using "make -C profiles"

See merge request apparmor/apparmor!80

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

(cherry picked from commit 14096cb3a7)

20893382 Fix $(PWD) when using "make -C profiles"
2018-03-18 18:28:43 +00:00
Christian Boltz
d8c315114b Merge branch 'cboltz-utils-test-ignore-include-if-exists' into 'master'
utils tests: ignore tests for 'include if exists'

See merge request apparmor/apparmor!78

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

(cherry picked from commit e6ef536957)

dc7c7021 utils tests: ignore tests for 'include if exists'
2018-03-16 21:38:25 +00:00
Christian Boltz
cbd68a6126 Merge branch 'cboltz-skip-git-dir' into 'master'
ignore .git in is_skippable_dir()

See merge request apparmor/apparmor!77

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

(cherry picked from commit 3b5683be29)

f9eb3fea ignore .git in is_skippable_dir()
2018-03-16 21:36:04 +00:00
Steve Beattie
f8dc00d915 tests: Allow shell helper test read the locale
Merge branch 'sh-helper-read-locale' into 'master'

See merge request apparmor/apparmor!76

Signed-off-by: Steve Beattie <steve@nxnw.org>

(cherry picked from commit 130958a4a4)

2bc64070 tests: Allow shell helper test read the locale
2018-03-09 15:01:00 +00:00
Steve Beattie
f0f2933f49 build: support coverity python scan
Coverity now supports scanning python (and other languages). Apply the
fs-capture-search option to the libapparmor and utils directpries to
capture the python source.

Signed-off-by: Steve Beattie <steve.beattie@canonical.com>
Signed-off-by: John Johansen <john.johansen@canonical.com>
(cherry picked from commit d66720ef07)
2018-03-05 23:59:39 -08:00
intrigeri
cc022e61a4 dnsmasq profile: allow chown capability.
dnsmasq on Debian sid now chown's its PID file.

Bug-Debian: https://bugs.debian.org/889806
Signed-off-by: John Johansen <john.johansen@canonical.com>
2018-03-05 23:51:59 -08:00
Kees Cook
deaada8dd2 aa-status: split profile from exec name
Right now, if you have a named profile with regular expressions to
match binaries, the profile will be shown in aa-status under the
"process list", which doesn't make sense. Instead, show the actual
executable name, and if the profile name differs, report it at the
end (or as a separate field in the json output mode).

Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: John Johansen <john.johansen@canonical.com>
2018-03-01 15:56:30 -08:00
Steve Beattie
e1174d196b mlmmj-sub: fix moderated subscription
Merge branch 'cboltz-mlmmj-sub' into 'master'

See merge request apparmor/apparmor!70

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

(cherry picked from commit 41b6182019)

8ef7b594 mlmmj-sub: fix moderated subscription
2018-02-22 23:04:42 +00:00
Christian Boltz
f9bd0b4c5d Merge branch 'cboltz-notify-dbus-env' into 'master'
set DBUS_SESSION_BUS_ADDRESS, needed by notify-send

See merge request apparmor/apparmor!53


Acked-by: intrigeri <intrigeri@debian.org> for 2.9..master

(cherry picked from commit 0eefeeb0e7)

cb5cdf26 set DBUS_SESSION_BUS_ADDRESS, needed by notify-send
2018-02-17 16:03:34 +00:00
Christian Boltz
2755f5e9c6 Merge branch 'fix-nvidia-dir' into 'master'
Allow to create .nv directory

See merge request apparmor/apparmor!69

Acked-by: Jamie Strandboge <jamie@canonical.com>
Acked-by: Christian Boltz <apparmor@cboltz.de> for 2.9..master

(cherry picked from commit 21b0d14ea4)

11e7dab9 Allow to create .nv directory
2018-02-17 15:58:44 +00:00
Christian Boltz
3954504651 Merge branch 'update-base-abstraction' into 'master'
Update base abstraction for ld.so.conf and friends.

See merge request apparmor/apparmor!62

Acked-by: Christian Boltz <apparmor@cboltz.de> for 2.9..master

(cherry picked from commit e88af93322)

6d22c871 Update base abstraction for ld.so.conf and friends.
2018-02-15 20:14:55 +00:00
intrigeri
e0249e219e apparmor(7): clarify the effect of reloading a profile.
LP: #1608075

Partly fixes: https://bugs.debian.org/826218

(cherry picked from commit 967d394ef4)
Signed-off-by: John Johansen <john.johansen@canonical.com>
2018-01-31 10:59:45 +01:00
Christian Boltz
441ecdd434 tools: Mark profiles with multiple rules in one line as known-failing
The tools don't support having multiple rules in one line (they expect
\n after each rule), therefore mark some of the bare_include_tests as
known failures.

(cherry picked from commit 26af640fda)
Signed-off-by: John Johansen <john.johansen@canonical.com>
2018-01-24 00:18:11 -08:00
Christian Boltz
0a657f4acd Merge branch 'cboltz-ntpd' into 'master'
allow access to ntp clockstats

See merge request apparmor/apparmor!54

(cherry picked from commit 85f8cace12)

1b58f226 allow access to ntp clockstats
2018-01-23 23:02:31 +00:00
Christian Boltz
6eac722531 Merge branch 'master' into 'master'
abstractions/gnupg: allow pubring.kbx

See merge request apparmor/apparmor!58

Acked-by: Christian Boltz <apparmor@cboltz.de> for 2.9..trunk

(cherry picked from commit e1929298ac)

8fc3dcb3 abstractions/gnupg: allow pubring.kbx
2018-01-20 22:59:35 +00:00
John Johansen
5578276177 regression tests: fix regression tests to pass on 4.14 upstream kernel
Some of the regression tests are missing conditionals or have the
wrong conditionals so that they fail on current upstream kernels.

Fix this by adding and changing conditionals and requires where
appropriate. With the patches the tests report passing on 4.14 and
4.15 kernels.

Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Time out
(cherry picked from commit 6f1d054468)
2018-01-20 01:46:40 -08:00
John Johansen
520dd4fab0 parser: add support for conditional includes
This is a minimal patch to add conditional includes to the profile
language.

The syntax for conditional includes is similar to regular includes
except with the addition of "if exists" after "include"

  include if exists <foo/bar>
  include if exists "foo/bar"
  include if exists "/foo/bar"
  include if exists foo/bar

Note: The patch is designed to be backportable with minimum
effort. Cleanups and code refactoring are planned for follow up
patches that won't be back ported.

Signed-off-by: John Johansen <john.johansen@canonical.com>
(cherry picked from commit 2ea3309942)
2018-01-20 00:44:56 -08:00
John Johansen
84391104f4 parser tests: fix includes to allow white space
includes were not handling WS in path names correctly. Allow WS within
quotes. Eg
  include "foo bar"
  include <"foo bar">

BugLink: http://bugs.launchpad.net/bugs/1738880
Signed-off-by: John Johansen <john.johansen@canonical.com>
(cherry picked from commit 8d142809f5)
2018-01-20 00:44:42 -08:00
John Johansen
f7f3d4e6f2 parser tests: add tests for relative path includes
Signed-off-by: John Johansen <john.johansen@canonical.com>
(cherry picked from commit efd8eedd52)
Signed-off-by: John Johansen <john.johansen@canonical.com>
2018-01-20 00:44:07 -08:00
Thorsten Kukuk
e3d4200453 disable write cache if filesystem is read-only
... and don't bail out

Patch by Thorsten Kukuk <kukuk@suse.com>

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

(cherry picked from commit 924983e702)
Signed-off-by: John Johansen <john.johansen@canonical.com>
2018-01-16 11:34:22 -08:00
John Johansen
6f31a83c5a parser: fix parser so that cache creation failure doesn't cause load failure
This is a minimal patch so that it can be backported to 2.11 and 2.10
which reverts the abort on error failure when the cache can not be
created and write-cache is set.

This is meant as a temporary fix for
https://bugzilla.suse.com/show_bug.cgi?id=1069906
https://bugzilla.opensuse.org/show_bug.cgi?id=1074429

where the cache location is being mounted readonly and the cache
creation failure is causing policy to not be loaded. And the
thrown parser error to cause issues for openQA.

Note: A cache failure warning will be reported after the policy load.

Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Christian Boltz apparmor@cboltz.de
(cherry picked from commit 42b68b65fe1861609ffe31e05be02a007d11ca1c)
2018-01-05 01:14:57 -08:00
99 changed files with 615 additions and 6119 deletions

View File

@@ -19,7 +19,7 @@ DIRS=libraries/libapparmor \
# with conversion to git, we don't export from the remote
REPO_URL?=git@gitlab.com:apparmor/apparmor.git
REPO_BRANCH?=apparmor-2.13
REPO_BRANCH?=apparmor-2.12
COVERITY_DIR=cov-int
RELEASE_DIR=apparmor-${VERSION}

View File

@@ -8,14 +8,14 @@ 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: 2018-02-09 23:55+0000\n"
"Last-Translator: Tobias Bannert <tobannert@gmail.com>\n"
"PO-Revision-Date: 2017-12-21 12:20+0000\n"
"Last-Translator: Christian Boltz <Unknown>\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: 2018-02-11 05:14+0000\n"
"X-Generator: Launchpad (build 18544)\n"
"X-Launchpad-Export-Date: 2017-12-22 05:12+0000\n"
"X-Generator: Launchpad (build 18521)\n"
"Language: de\n"
#: ../aa_enabled.c:26
@@ -59,15 +59,15 @@ msgstr "Nein beim Start deaktiviert.\n"
#: ../aa_enabled.c:77
#, c-format
msgid "Maybe - policy interface not available.\n"
msgstr "Vielleicht Richtlinienschnittstelle nicht verfügbar.\n"
msgstr ""
#: ../aa_enabled.c:81
#, c-format
msgid "Maybe - insufficient permissions to determine availability.\n"
msgstr ""
"Vielleicht ungenügende Berechtigungen, um die Verfügbarkeit zu prüfen\n"
"Vielleicht - ungenügende Berechtigungen, um die Verfügbarkeit zu prüfen\n"
#: ../aa_enabled.c:84
#, c-format
msgid "Error - '%s'\n"
msgstr "Fehler »%s«\n"
msgstr "Fehler - »%s«\n"

View File

@@ -82,7 +82,7 @@ SECDIR ?= ${DESTDIR}/lib/security
.PHONY: install
install: $(NAME).so
install -m 755 -d $(SECDIR)
install -m 755 $(NAME).so $(SECDIR)/
install -m 555 $(NAME).so $(SECDIR)/
.PHONY: clean
clean:

View File

@@ -1 +1 @@
2.13.1
2.12.1

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

View File

@@ -1,13 +1,12 @@
From 2e7f6d0dc0f1d3642950f529b451af73fa1baf9c Mon Sep 17 00:00:00 2001
From a3b0cb6676a04cdad5cc357bc422d0398083b435 Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen@canonical.com>
Date: Tue, 18 Jul 2017 23:27:23 -0700
Subject: [PATCH 2/2] apparmor: af_unix mediation
Subject: [PATCH 17/17] UBUNTU: SAUCE: apparmor: af_unix mediation
af_socket mediation did not make it into 4.14 so add remaining out
of tree patch
Signed-off-by: John Johansen <john.johansen@canonical.com>
Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
---
security/apparmor/Makefile | 3 +-
security/apparmor/af_unix.c | 651 ++++++++++++++++++++++++++++++++++++
@@ -24,10 +23,10 @@ Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
create mode 100644 security/apparmor/include/af_unix.h
diff --git a/security/apparmor/Makefile b/security/apparmor/Makefile
index e7ff2183532a..90c118f39e13 100644
index dafdd387d42b..ef39226ff4aa 100644
--- a/security/apparmor/Makefile
+++ b/security/apparmor/Makefile
@@ -5,7 +5,8 @@ obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o
@@ -4,7 +4,8 @@ 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 \
@@ -695,7 +694,7 @@ index 000000000000..c6876db2dbde
+ return error;
+}
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
index 518d5928661b..63a8a462fc96 100644
index 125dad5c3fde..20cdb1c4b266 100644
--- a/security/apparmor/apparmorfs.c
+++ b/security/apparmor/apparmorfs.c
@@ -2187,6 +2187,11 @@ static struct aa_sfs_entry aa_sfs_entry_ns[] = {
@@ -921,7 +920,7 @@ index 4364088a0b9e..26660a1a50b0 100644
if (!state)
return 0;
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index 72b915dfcaf7..5533d2f1d9de 100644
index cc5ab23a2d84..0ede66d80a53 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -26,6 +26,7 @@
@@ -1391,5 +1390,5 @@ index 33d54435f8d6..dd1953b08e58 100644
+ aa_label_sk_perm(label, op, request, sock->sk));
}
--
2.14.1
2.11.0

View File

@@ -1,4 +1,4 @@
This is based on v4.14 final
This series is based on what is currently in linux-next scheduled for
inclusion in 4.14
base socket mediation and af_unix-mediation are the last two remaining
patches that are out of tree
af_unix-mediation is the last remaining patch that is out of tree

File diff suppressed because it is too large Load Diff

View File

@@ -81,7 +81,7 @@ AM_CONDITIONAL(HAVE_RUBY, test x$with_ruby = xyes)
AC_HEADER_STDC
AC_CHECK_HEADERS(unistd.h stdint.h syslog.h)
AC_CHECK_FUNCS([asprintf __secure_getenv secure_getenv reallocarray])
AC_CHECK_FUNCS([asprintf __secure_getenv secure_getenv])
AM_PROG_CC_C_O
AC_C_CONST

View File

@@ -40,8 +40,6 @@ aa_features_is_equal - equality test for two aa_features objects
aa_features_supports - provides aa_features object support status
aa_features_id - provides unique identifier for an aa_features object
=head1 SYNOPSIS
B<#include E<lt>sys/apparmor.hE<gt>>
@@ -64,8 +62,6 @@ B<bool aa_features_is_equal(aa_features *features1, aa_features *features2);>
B<bool aa_features_supports(aa_features *features, const char *str);>
B<char *aa_features_id(aa_features *features);>
Link with B<-lapparmor> when compiling.
=head1 DESCRIPTION
@@ -112,12 +108,6 @@ the path, relative to the "apparmor/features/" directory of securityfs, of the
feature to query. For example, to test if policy version 6 is supported, I<str>
would be "policy/versions/v6".
The aa_features_id() function returns a string representation of an
identifier that can be used to uniquely identify an I<aa_features> object.
The mechanism for generating the string representation is internal to
libapparmor and subject to change but an example implementation is
applying a hash function to the features string.
=head1 RETURN VALUE
The aa_features_new() family of functions return 0 on success and I<*features>
@@ -136,20 +126,15 @@ and false if they are not equal.
aa_features_supports() returns true if the feature represented by I<str> is
supported and false if it is not supported.
aa_features_id() returns a string identifying I<features> which must be
freed by the caller. NULL is returned on error, with errno set
appropriately.
=head1 ERRORS
The errno value will be set according to the underlying error in the
I<aa_features> family of functions that return -1 or NULL on error.
I<aa_features> family of functions that return -1 on error.
=head1 NOTES
The aa_features_id() function can be found in libapparmor version
2.13. All the other aa_feature functions described above are present
in libapparmor version 2.10.
All aa_features functions described above are present in libapparmor version
2.10 and newer.
aa_features_unref() saves the value of errno when called and restores errno
before exiting in libapparmor version 2.12 and newer.

View File

@@ -34,10 +34,6 @@ aa_policy_cache_remove - removes all policy cache files under a path
aa_policy_cache_replace_all - performs a kernel policy replacement of all cached policies
aa_policy_cache_dir_path - returns the path to the aa_policy_cache directory
aa_policy_cache_dir_path_preview - returns a preview of the path to the aa_policy_cache directory without an existing aa_policy_cache object
=head1 SYNOPSIS
B<#include E<lt>sys/apparmor.hE<gt>>
@@ -46,8 +42,6 @@ B<typedef struct aa_policy_cache aa_policy_cache;>
B<int aa_policy_cache_new(aa_policy_cache **policy_cache, aa_features *kernel_features, int dirfd, const char *path, uint16_t max_caches);>
B<int aa_policy_cache_add_ro_dir(aa_policy_cache *policy_cache, int dirfd, const char *path);>
B<aa_policy_cache *aa_policy_cache_ref(aa_policy_cache *policy_cache);>
B<void aa_policy_cache_unref(aa_policy_cache *policy_cache);>
@@ -56,10 +50,6 @@ B<int aa_policy_cache_remove(int dirfd, const char *path);>
B<int aa_policy_cache_replace_all(aa_policy_cache *policy_cache, aa_kernel_interface *kernel_interface);>
B<char *aa_policy_cache_dir_path(aa_policy_cache *policy_cache, int level);>
B<char *aa_policy_cache_dir_path_preview(aa_features *kernel_features, int dirfd, const char *path);>
Link with B<-lapparmor> when compiling.
=head1 DESCRIPTION
@@ -69,35 +59,19 @@ policy cache files. The policy cache files are the binary representation of a
human-readable AppArmor profile. The binary representation is the form that is
loaded into the kernel.
The aa_policy_cache_new() function creates an I<aa_policy_cache>
object based upon a directory file descriptor and path. See the
openat(2) man page for examples of I<dirfd> and I<path>. The I<path>
must point to a directory and it will be used as the basis for the
location of policy cache files. See I<aa_policy_cache_dir_path> to
find out which directory will be used to store the binary policy cache
files. If additional overlay cache directories are used (see
I<aa_policy_cache_add_ro_dir>) the directory specified in
I<aa_policy_cache_new> is the first directory searched and is the
writable overlay. If I<kernel_features> is NULL, then the features of
the current kernel are used. When specifying a valid
I<kernel_features> object, it must be compatible with the features
of the kernel of interest. The value of I<max_caches> should be equal
to the number of caches that should be allowed before old caches are
automatically reaped. The definition of what is considered to be an
old cache is private to libapparmor. Specifying 0 means that no new
caches should be created and only existing, valid caches may be used.
Specifying UINT16_MAX means that a new cache may be created and that
the reaping of old caches is disabled. The allocated
I<aa_policy_cache> object must be freed using aa_policy_cache_unref().
The aa_policy_cache_add_ro_dir() function adds an existing cache directory
to the policy cache, as a readonly layer under the primary directory
the cache was created with. When the cache is searched for an existing
cache file the primary directory will be searched and then the readonly
directories in the order that they were added to the policy cache.
This allows the policy cache to be seeded with precompiled policy
that can be updated by overlaying the read only cache file with one
written to the primary cache dir.
The aa_policy_cache_new() function creates an I<aa_policy_cache> object based
upon a directory file descriptor and path. The I<path> must point to a
directory. See the openat(2) man page for examples of I<dirfd> and I<path>. If
I<kernel_features> is NULL, then the features of the current kernel are used.
When specifying a valid I<kernel_features> object, it must be the compatible
with the features of the kernel of interest. The value of I<max_caches> should
be equal to the number of caches that should be allowed before old caches are
automatically reaped. The definition of what is considered to be an old cache
is private to libapparmor. Specifying 0 means that no new caches should be
created and only existing, valid caches may be used. Specifying UINT16_MAX
means that a new cache may be created and that the reaping of old caches is
disabled. The allocated I<aa_policy_cache> object must be freed using
aa_policy_cache_unref().
aa_policy_cache_ref() increments the reference count on the I<policy_cache>
object.
@@ -116,18 +90,6 @@ the I<policy_cache> object. If I<kernel_interface> is NULL, then the current
kernel interface is used. When specifying a valid I<kernel_interface> object,
it must be the interface of the currently running kernel.
The aa_policy_cache_dir_path() function provides the path to the cache
directory for a I<policy_cache> object at I<level> in the policy cache
overlay of cache directories. A I<level> of 0 will always be present
and is the first directory to search in an overlay of cache
directories, and will also be the writable cache directory
layer. Binary policy cache files will be located in the directory
returned by this function.
The aa_policy_cache_dir_levels() function provides access to the number
of directories that are being overlayed to create the policy cache.
=head1 RETURN VALUE
The aa_policy_cache_new() function returns 0 on success and I<*policy_cache>
@@ -140,29 +102,15 @@ aa_policy_cache_ref() returns the value of I<policy_cache>.
aa_policy_cache_remove() and aa_policy_cache_replace_all() return 0 on success.
-1 is returned on error, with errno set appropriately.
aa_policy_cache_dir_path() returns a path string which must be freed by the
caller. NULL is returned on error, with errno set appropriately.
aa_policy_cache_dir_levels() returns a number indicating the number of
directory levels there are associated with the I<policy_cache>.
aa_policy_cache_dir_path_preview() is the same as
aa_policy_cache_dir_path() except that it doesn't require an existing
I<aa_policy_cache> object. This is useful if the calling program cannot
create an I<aa_policy_cache> object due to lack of privileges needed to
create the cache directory.
=head1 ERRORS
The errno value will be set according to the underlying error in the
I<aa_policy_cache> family of functions that return -1 or NULL on error.
I<aa_policy_cache> family of functions that return -1 on error.
=head1 NOTES
All aa_policy_cache functions described above, except for the
aa_policy_cache_dir_path() function was added in libapparmor version
2.13. All the other aa_policy_cache functions described above are
present in libapparmor version 2.10.
All aa_policy_cache functions described above are present in libapparmor
version 2.10 and newer.
aa_policy_cache_unref() saves the value of errno when called and restores errno
before exiting in libapparmor version 2.12 and newer.

View File

@@ -154,7 +154,6 @@ extern int aa_features_write_to_file(aa_features *features,
extern bool aa_features_is_equal(aa_features *features1,
aa_features *features2);
extern bool aa_features_supports(aa_features *features, const char *str);
extern char *aa_features_id(aa_features *features);
typedef struct aa_kernel_interface aa_kernel_interface;
extern int aa_kernel_interface_new(aa_kernel_interface **kernel_interface,
@@ -187,22 +186,12 @@ extern int aa_policy_cache_new(aa_policy_cache **policy_cache,
aa_features *kernel_features,
int dirfd, const char *path,
uint16_t max_caches);
extern int aa_policy_cache_add_ro_dir(aa_policy_cache *policy_cache, int dirfd,
const char *path);
extern aa_policy_cache *aa_policy_cache_ref(aa_policy_cache *policy_cache);
extern void aa_policy_cache_unref(aa_policy_cache *policy_cache);
extern int aa_policy_cache_remove(int dirfd, const char *path);
extern int aa_policy_cache_replace_all(aa_policy_cache *policy_cache,
aa_kernel_interface *kernel_interface);
extern int aa_policy_cache_no_dirs(aa_policy_cache *policy_cache);
extern char *aa_policy_cache_dir_path(aa_policy_cache *policy_cache, int n);
extern int aa_policy_cache_dirfd(aa_policy_cache *policy_cache, int dir);
extern int aa_policy_cache_open(aa_policy_cache *policy_cache, const char *name,
int flags);
extern char *aa_policy_cache_filename(aa_policy_cache *policy_cache, const char *name);
extern char *aa_policy_cache_dir_path_preview(aa_features *kernel_features,
int dirfd, const char *path);
#ifdef __cplusplus
}

View File

@@ -34,8 +34,6 @@ int _aa_asprintf(char **strp, const char *fmt, ...);
int _aa_dirat_for_each(int dirfd, const char *name, void *data,
int (* cb)(int, const char *, struct stat *, void *));
int _aa_overlaydirat_for_each(int dirfd[], int n, void *data,
int (* cb)(int, const char *, struct stat *, void *));
#ifdef __cplusplus
}

View File

@@ -26,9 +26,9 @@ INCLUDES = $(all_includes)
# For more information, see:
# http://www.gnu.org/software/libtool/manual/html_node/Libtool-versioning.html
#
AA_LIB_CURRENT = 7
AA_LIB_REVISION = 0
AA_LIB_AGE = 6
AA_LIB_CURRENT = 5
AA_LIB_REVISION = 2
AA_LIB_AGE = 4
SUFFIXES = .pc.in .pc
@@ -46,9 +46,9 @@ af_protos.h: /usr/include/netinet/in.h
LC_ALL=C sed -n -e "/IPPROTO_MAX/d" -e "s/^\#define[ \\t]\\+IPPROTO_\\([A-Z0-9_]\\+\\)\\(.*\\)$$/AA_GEN_PROTO_ENT(\\UIPPROTO_\\1, \"\\L\\1\")/p" $< > $@
lib_LTLIBRARIES = libapparmor.la
noinst_HEADERS = grammar.h parser.h scanner.h af_protos.h private.h PMurHash.h
noinst_HEADERS = grammar.h parser.h scanner.h af_protos.h private.h
libapparmor_la_SOURCES = grammar.y libaalogparse.c kernel.c scanner.c private.c features.c kernel_interface.c policy_cache.c PMurHash.c
libapparmor_la_SOURCES = grammar.y libaalogparse.c kernel.c scanner.c private.c features.c kernel_interface.c policy_cache.c
libapparmor_la_LDFLAGS = -version-info $(AA_LIB_CURRENT):$(AA_LIB_REVISION):$(AA_LIB_AGE) -XCClinker -dynamic -pthread \
-Wl,--version-script=$(top_srcdir)/src/libapparmor.map

View File

@@ -1,317 +0,0 @@
/*-----------------------------------------------------------------------------
* MurmurHash3 was written by Austin Appleby, and is placed in the public
* domain.
*
* This implementation was written by Shane Day, and is also public domain.
*
* This is a portable ANSI C implementation of MurmurHash3_x86_32 (Murmur3A)
* with support for progressive processing.
*/
/*-----------------------------------------------------------------------------
If you want to understand the MurmurHash algorithm you would be much better
off reading the original source. Just point your browser at:
http://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp
What this version provides?
1. Progressive data feeding. Useful when the entire payload to be hashed
does not fit in memory or when the data is streamed through the application.
Also useful when hashing a number of strings with a common prefix. A partial
hash of a prefix string can be generated and reused for each suffix string.
2. Portability. Plain old C so that it should compile on any old compiler.
Both CPU endian and access-alignment neutral, but avoiding inefficient code
when possible depending on CPU capabilities.
3. Drop in. I personally like nice self contained public domain code, making it
easy to pilfer without loads of refactoring to work properly in the existing
application code & makefile structure and mucking around with licence files.
Just copy PMurHash.h and PMurHash.c and you're ready to go.
How does it work?
We can only process entire 32 bit chunks of input, except for the very end
that may be shorter. So along with the partial hash we need to give back to
the caller a carry containing up to 3 bytes that we were unable to process.
This carry also needs to record the number of bytes the carry holds. I use
the low 2 bits as a count (0..3) and the carry bytes are shifted into the
high byte in stream order.
To handle endianess I simply use a macro that reads a uint32_t and define
that macro to be a direct read on little endian machines, a read and swap
on big endian machines, or a byte-by-byte read if the endianess is unknown.
-----------------------------------------------------------------------------*/
#include "PMurHash.h"
/* I used ugly type names in the header to avoid potential conflicts with
* application or system typedefs & defines. Since I'm not including any more
* headers below here I can rename these so that the code reads like C99 */
#undef uint32_t
#define uint32_t MH_UINT32
#undef uint8_t
#define uint8_t MH_UINT8
/* MSVC warnings we choose to ignore */
#if defined(_MSC_VER)
#pragma warning(disable: 4127) /* conditional expression is constant */
#endif
/*-----------------------------------------------------------------------------
* Endianess, misalignment capabilities and util macros
*
* The following 3 macros are defined in this section. The other macros defined
* are only needed to help derive these 3.
*
* READ_UINT32(x) Read a little endian unsigned 32-bit int
* UNALIGNED_SAFE Defined if READ_UINT32 works on non-word boundaries
* ROTL32(x,r) Rotate x left by r bits
*/
/* Convention is to define __BYTE_ORDER == to one of these values */
#if !defined(__BIG_ENDIAN)
#define __BIG_ENDIAN 4321
#endif
#if !defined(__LITTLE_ENDIAN)
#define __LITTLE_ENDIAN 1234
#endif
/* I386 */
#if defined(_M_IX86) || defined(__i386__) || defined(__i386) || defined(i386)
#define __BYTE_ORDER __LITTLE_ENDIAN
#define UNALIGNED_SAFE
#endif
/* gcc 'may' define __LITTLE_ENDIAN__ or __BIG_ENDIAN__ to 1 (Note the trailing __),
* or even _LITTLE_ENDIAN or _BIG_ENDIAN (Note the single _ prefix) */
#if !defined(__BYTE_ORDER)
#if defined(__LITTLE_ENDIAN__) && __LITTLE_ENDIAN__==1 || defined(_LITTLE_ENDIAN) && _LITTLE_ENDIAN==1
#define __BYTE_ORDER __LITTLE_ENDIAN
#elif defined(__BIG_ENDIAN__) && __BIG_ENDIAN__==1 || defined(_BIG_ENDIAN) && _BIG_ENDIAN==1
#define __BYTE_ORDER __BIG_ENDIAN
#endif
#endif
/* gcc (usually) defines xEL/EB macros for ARM and MIPS endianess */
#if !defined(__BYTE_ORDER)
#if defined(__ARMEL__) || defined(__MIPSEL__)
#define __BYTE_ORDER __LITTLE_ENDIAN
#endif
#if defined(__ARMEB__) || defined(__MIPSEB__)
#define __BYTE_ORDER __BIG_ENDIAN
#endif
#endif
/* Now find best way we can to READ_UINT32 */
#if __BYTE_ORDER==__LITTLE_ENDIAN
/* CPU endian matches murmurhash algorithm, so read 32-bit word directly */
#define READ_UINT32(ptr) (*((uint32_t*)(ptr)))
#elif __BYTE_ORDER==__BIG_ENDIAN
/* TODO: Add additional cases below where a compiler provided bswap32 is available */
#if defined(__GNUC__) && (__GNUC__>4 || (__GNUC__==4 && __GNUC_MINOR__>=3))
#define READ_UINT32(ptr) (__builtin_bswap32(*((uint32_t*)(ptr))))
#else
/* Without a known fast bswap32 we're just as well off doing this */
#define READ_UINT32(ptr) (ptr[0]|ptr[1]<<8|ptr[2]<<16|ptr[3]<<24)
#define UNALIGNED_SAFE
#endif
#else
/* Unknown endianess so last resort is to read individual bytes */
#define READ_UINT32(ptr) (ptr[0]|ptr[1]<<8|ptr[2]<<16|ptr[3]<<24)
/* Since we're not doing word-reads we can skip the messing about with realignment */
#define UNALIGNED_SAFE
#endif
/* Find best way to ROTL32 */
#if defined(_MSC_VER)
#include <stdlib.h> /* Microsoft put _rotl declaration in here */
#define ROTL32(x,r) _rotl(x,r)
#else
/* gcc recognises this code and generates a rotate instruction for CPUs with one */
#define ROTL32(x,r) (((uint32_t)x << r) | ((uint32_t)x >> (32 - r)))
#endif
/*-----------------------------------------------------------------------------
* Core murmurhash algorithm macros */
#define C1 (0xcc9e2d51)
#define C2 (0x1b873593)
/* This is the main processing body of the algorithm. It operates
* on each full 32-bits of input. */
#define DOBLOCK(h1, k1) do{ \
k1 *= C1; \
k1 = ROTL32(k1,15); \
k1 *= C2; \
\
h1 ^= k1; \
h1 = ROTL32(h1,13); \
h1 = h1*5+0xe6546b64; \
}while(0)
/* Append unaligned bytes to carry, forcing hash churn if we have 4 bytes */
/* cnt=bytes to process, h1=name of h1 var, c=carry, n=bytes in c, ptr/len=payload */
#define DOBYTES(cnt, h1, c, n, ptr, len) do{ \
int _i = cnt; \
while(_i--) { \
c = c>>8 | *ptr++<<24; \
n++; len--; \
if(n==4) { \
DOBLOCK(h1, c); \
n = 0; \
} \
} }while(0)
/*---------------------------------------------------------------------------*/
/* Main hashing function. Initialise carry to 0 and h1 to 0 or an initial seed
* if wanted. Both ph1 and pcarry are required arguments. */
void PMurHash32_Process(uint32_t *ph1, uint32_t *pcarry, const void *key, int len)
{
uint32_t h1 = *ph1;
uint32_t c = *pcarry;
const uint8_t *ptr = (uint8_t*)key;
const uint8_t *end;
/* Extract carry count from low 2 bits of c value */
int n = c & 3;
#if defined(UNALIGNED_SAFE)
/* This CPU handles unaligned word access */
/* Consume any carry bytes */
int i = (4-n) & 3;
if(i && i <= len) {
DOBYTES(i, h1, c, n, ptr, len);
}
/* Process 32-bit chunks */
end = ptr + len/4*4;
for( ; ptr < end ; ptr+=4) {
uint32_t k1 = READ_UINT32(ptr);
DOBLOCK(h1, k1);
}
#else /*UNALIGNED_SAFE*/
/* This CPU does not handle unaligned word access */
/* Consume enough so that the next data byte is word aligned */
int i = -(long)ptr & 3;
if(i && i <= len) {
DOBYTES(i, h1, c, n, ptr, len);
}
/* We're now aligned. Process in aligned blocks. Specialise for each possible carry count */
end = ptr + len/4*4;
switch(n) { /* how many bytes in c */
case 0: /* c=[----] w=[3210] b=[3210]=w c'=[----] */
for( ; ptr < end ; ptr+=4) {
uint32_t k1 = READ_UINT32(ptr);
DOBLOCK(h1, k1);
}
break;
case 1: /* c=[0---] w=[4321] b=[3210]=c>>24|w<<8 c'=[4---] */
for( ; ptr < end ; ptr+=4) {
uint32_t k1 = c>>24;
c = READ_UINT32(ptr);
k1 |= c<<8;
DOBLOCK(h1, k1);
}
break;
case 2: /* c=[10--] w=[5432] b=[3210]=c>>16|w<<16 c'=[54--] */
for( ; ptr < end ; ptr+=4) {
uint32_t k1 = c>>16;
c = READ_UINT32(ptr);
k1 |= c<<16;
DOBLOCK(h1, k1);
}
break;
case 3: /* c=[210-] w=[6543] b=[3210]=c>>8|w<<24 c'=[654-] */
for( ; ptr < end ; ptr+=4) {
uint32_t k1 = c>>8;
c = READ_UINT32(ptr);
k1 |= c<<24;
DOBLOCK(h1, k1);
}
}
#endif /*UNALIGNED_SAFE*/
/* Advance over whole 32-bit chunks, possibly leaving 1..3 bytes */
len -= len/4*4;
/* Append any remaining bytes into carry */
DOBYTES(len, h1, c, n, ptr, len);
/* Copy out new running hash and carry */
*ph1 = h1;
*pcarry = (c & ~0xff) | n;
}
/*---------------------------------------------------------------------------*/
/* Finalize a hash. To match the original Murmur3A the total_length must be provided */
uint32_t PMurHash32_Result(uint32_t h, uint32_t carry, uint32_t total_length)
{
uint32_t k1;
int n = carry & 3;
if(n) {
k1 = carry >> (4-n)*8;
k1 *= C1; k1 = ROTL32(k1,15); k1 *= C2; h ^= k1;
}
h ^= total_length;
/* fmix */
h ^= h >> 16;
h *= 0x85ebca6b;
h ^= h >> 13;
h *= 0xc2b2ae35;
h ^= h >> 16;
return h;
}
/*---------------------------------------------------------------------------*/
/* Murmur3A compatable all-at-once */
uint32_t PMurHash32(uint32_t seed, const void *key, int len)
{
uint32_t h1=seed, carry=0;
PMurHash32_Process(&h1, &carry, key, len);
return PMurHash32_Result(h1, carry, len);
}
/*---------------------------------------------------------------------------*/
/* Provide an API suitable for smhasher */
void PMurHash32_test(const void *key, int len, uint32_t seed, void *out)
{
uint32_t h1=seed, carry=0;
const uint8_t *ptr = (uint8_t*)key;
const uint8_t *end = ptr + len;
#if 0 /* Exercise the progressive processing */
while(ptr < end) {
//const uint8_t *mid = ptr + rand()%(end-ptr)+1;
const uint8_t *mid = ptr + (rand()&0xF);
mid = mid<end?mid:end;
PMurHash32_Process(&h1, &carry, ptr, mid-ptr);
ptr = mid;
}
#else
PMurHash32_Process(&h1, &carry, ptr, (int)(end-ptr));
#endif
h1 = PMurHash32_Result(h1, carry, len);
*(uint32_t*)out = h1;
}
/*---------------------------------------------------------------------------*/

View File

@@ -1,64 +0,0 @@
/*-----------------------------------------------------------------------------
* MurmurHash3 was written by Austin Appleby, and is placed in the public
* domain.
*
* This implementation was written by Shane Day, and is also public domain.
*
* This is a portable ANSI C implementation of MurmurHash3_x86_32 (Murmur3A)
* with support for progressive processing.
*/
/* ------------------------------------------------------------------------- */
/* Determine what native type to use for uint32_t */
/* We can't use the name 'uint32_t' here because it will conflict with
* any version provided by the system headers or application. */
/* First look for special cases */
#if defined(_MSC_VER)
#define MH_UINT32 unsigned long
#endif
/* If the compiler says it's C99 then take its word for it */
#if !defined(MH_UINT32) && ( \
defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L )
#include <stdint.h>
#define MH_UINT32 uint32_t
#endif
/* Otherwise try testing against max value macros from limit.h */
#if !defined(MH_UINT32)
#include <limits.h>
#if (USHRT_MAX == 0xffffffffUL)
#define MH_UINT32 unsigned short
#elif (UINT_MAX == 0xffffffffUL)
#define MH_UINT32 unsigned int
#elif (ULONG_MAX == 0xffffffffUL)
#define MH_UINT32 unsigned long
#endif
#endif
#if !defined(MH_UINT32)
#error Unable to determine type name for unsigned 32-bit int
#endif
/* I'm yet to work on a platform where 'unsigned char' is not 8 bits */
#define MH_UINT8 unsigned char
/* ------------------------------------------------------------------------- */
/* Prototypes */
#ifdef __cplusplus
extern "C" {
#endif
void PMurHash32_Process(MH_UINT32 *ph1, MH_UINT32 *pcarry, const void *key, int len);
MH_UINT32 PMurHash32_Result(MH_UINT32 h1, MH_UINT32 carry, MH_UINT32 total_length);
MH_UINT32 PMurHash32(MH_UINT32 seed, const void *key, int len);
void PMurHash32_test(const void *key, int len, MH_UINT32 seed, void *out);
#ifdef __cplusplus
}
#endif

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2017
* Copyright (c) 2014
* Canonical, Ltd. (All rights reserved)
*
* This program is free software; you can redistribute it and/or
@@ -20,7 +20,6 @@
#include <ctype.h>
#include <dirent.h>
#include <fcntl.h>
#include <inttypes.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
@@ -32,16 +31,13 @@
#include <sys/apparmor.h>
#include "private.h"
#include "PMurHash.h"
#define FEATURES_FILE "/sys/kernel/security/apparmor/features"
#define HASH_SIZE (8 + 1) /* 32 bits binary to hex + NUL terminator */
#define STRING_SIZE 8192
struct aa_features {
unsigned int ref_count;
char hash[HASH_SIZE];
char string[STRING_SIZE];
};
@@ -209,29 +205,6 @@ static ssize_t load_features_dir(int dirfd, const char *path,
return 0;
}
static int init_features_hash(aa_features *features)
{
const char *string = features->string;
uint32_t seed = 5381;
uint32_t hash = seed, carry = 0;
size_t len = strlen(string);
/* portable murmur3 hash
* https://github.com/aappleby/smhasher/wiki/MurmurHash3
*/
PMurHash32_Process(&hash, &carry, features, len);
hash = PMurHash32_Result(hash, carry, len);
if (snprintf(features->hash, HASH_SIZE,
"%08" PRIx32, hash) >= HASH_SIZE) {
errno = ENOBUFS;
PERROR("Hash buffer full.");
return -1;
}
return 0;
}
static bool islbrace(int c)
{
return c == '{';
@@ -435,14 +408,6 @@ int aa_features_new(aa_features **features, int dirfd, const char *path)
return -1;
}
if (init_features_hash(f) == -1) {
int save = errno;
aa_features_unref(f);
errno = save;
return -1;
}
*features = f;
return 0;
@@ -478,15 +443,6 @@ int aa_features_new_from_string(aa_features **features,
memcpy(f->string, string, size);
f->string[size] = '\0';
if (init_features_hash(f) == -1) {
int save = errno;
aa_features_unref(f);
errno = save;
return -1;
}
*features = f;
return 0;
@@ -621,21 +577,3 @@ bool aa_features_supports(aa_features *features, const char *str)
return true;
}
/**
* aa_features_id - provides unique identifier for an aa_features object
* @features: the features
*
* Allocates and returns a string representation of an identifier that can
* be used to uniquely identify an aa_features object. The mechanism for
* generating the string representation is internal to libapparmor and
* subject to change but an example implementation is applying a hash
* function to the features string.
*
* Returns: a string identifying @features which must be freed by the
* caller or NULL, with errno set, upon error
*/
char *aa_features_id(aa_features *features)
{
return strdup(features->hash);
}

View File

@@ -95,26 +95,6 @@ APPARMOR_2.11 {
*;
} APPARMOR_2.10;
APPARMOR_2.13 {
global:
aa_policy_cache_dir_path;
aa_policy_cache_dir_path_preview;
aa_policy_cache_no_dirs;
aa_policy_cache_dirfd;
aa_policy_cache_open;
aa_policy_cache_filename;
aa_features_id;
local:
*;
} APPARMOR_2.11;
APPARMOR_2.13.1 {
global:
aa_policy_cache_add_ro_dir;
local:
*;
} APPARMOR_2.13;
PRIVATE {
global:
_aa_is_blacklisted;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2017
* Copyright (c) 2014
* Canonical, Ltd. (All rights reserved)
*
* This program is free software; you can redistribute it and/or
@@ -16,11 +16,8 @@
* Ltd.
*/
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <fnmatch.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -32,155 +29,31 @@
#include "private.h"
#define CACHE_FEATURES_FILE ".features"
#define MAX_POLICY_CACHE_OVERLAY_DIRS 4
struct aa_policy_cache {
unsigned int ref_count;
aa_features *features;
aa_features *kernel_features;
int n;
int dirfd[MAX_POLICY_CACHE_OVERLAY_DIRS];
int dirfd;
};
static int clear_cache_cb(int dirfd, const char *path, struct stat *st,
void *data unused)
{
if (S_ISREG(st->st_mode)) {
/* remove regular files */
/* remove regular files */
if (S_ISREG(st->st_mode))
return unlinkat(dirfd, path, 0);
} else if (S_ISDIR(st->st_mode)) {
int retval;
retval = _aa_dirat_for_each(dirfd, path, NULL, clear_cache_cb);
if (retval)
return retval;
return unlinkat(dirfd, path, AT_REMOVEDIR);
}
/* do nothing with other file types */
return 0;
}
struct replace_all_cb_data {
aa_policy_cache *policy_cache;
aa_kernel_interface *kernel_interface;
};
static int replace_all_cb(int dirfd, const char *name, struct stat *st,
void *cb_data)
{
int retval = 0;
if (S_ISLNK(st->st_mode)) {
/*
* symlinks in that cache are used to track file merging.
* In the scanned overlay situation they can be skipped
* as the combined entry will be one of none skipped
* entries
*/
} else if (S_ISREG(st->st_mode) && st->st_size == 0) {
/*
* empty file in the cache dir is used as a whiteout
* to hide files in a lower layer. skip
*/
} else if (!S_ISDIR(st->st_mode) && !_aa_is_blacklisted(name)) {
struct replace_all_cb_data *data;
data = (struct replace_all_cb_data *) cb_data;
retval = aa_kernel_interface_replace_policy_from_file(data->kernel_interface,
dirfd,
name);
}
return retval;
}
static char *path_from_fd(int fd)
{
autofree char *proc_path = NULL;
autoclose int proc_fd = -1;
struct stat proc_stat;
char *path;
ssize_t size, path_len;
if (asprintf(&proc_path, "/proc/self/fd/%d", fd) == -1) {
proc_path = NULL;
errno = ENOMEM;
return NULL;
}
proc_fd = open(proc_path, O_RDONLY | O_CLOEXEC | O_PATH | O_NOFOLLOW);
if (proc_fd == -1)
return NULL;
if (fstat(proc_fd, &proc_stat) == -1)
return NULL;
if (!S_ISLNK(proc_stat.st_mode)) {
errno = EINVAL;
return NULL;
}
size = proc_stat.st_size;
repeat:
path = malloc(size + 1);
if (!path)
return NULL;
/**
* Since 2.6.39, symlink file descriptors opened with
* (O_PATH | O_NOFOLLOW) can be used as the dirfd with an empty string
* as the path. readlinkat() will operate on the symlink inode.
*/
path_len = readlinkat(proc_fd, "", path, size);
if (path_len == -1)
return NULL;
if (path_len == size) {
free(path);
size = size * 2;
goto repeat;
}
path[path_len] = '\0';
return path;
}
static int cache_check_features(int dirfd, const char *cache_name,
aa_features *features)
{
aa_features *local_features = NULL;
autofree char *name = NULL;
bool rc;
int len;
len = asprintf(&name, "%s/%s", cache_name, CACHE_FEATURES_FILE);
if (len == -1) {
errno = ENOMEM;
return -1;
}
/* verify that cache dir .features matches */
if (aa_features_new(&local_features, dirfd, name)) {
PDEBUG("could not setup new features object for dirfd '%d' '%s'\n", dirfd, name);
return -1;
}
rc = aa_features_is_equal(local_features, features);
aa_features_unref(local_features);
if (!rc) {
errno = EEXIST;
return -1;
}
return 0;
}
static int create_cache(aa_policy_cache *policy_cache, aa_features *features)
{
if (aa_policy_cache_remove(policy_cache->dirfd[0], "."))
if (aa_policy_cache_remove(policy_cache->dirfd, "."))
return -1;
if (aa_features_write_to_file(features, policy_cache->dirfd[0],
if (aa_features_write_to_file(features, policy_cache->dirfd,
CACHE_FEATURES_FILE) == -1)
return -1;
@@ -192,176 +65,51 @@ static int create_cache(aa_policy_cache *policy_cache, aa_features *features)
static int init_cache_features(aa_policy_cache *policy_cache,
aa_features *kernel_features, bool create)
{
if (cache_check_features(policy_cache->dirfd[0], ".",
kernel_features)) {
/* EEXIST must come before ENOENT for short circuit eval */
if (!create || errno == EEXIST || errno != ENOENT)
bool call_create_cache = false;
if (aa_features_new(&policy_cache->features, policy_cache->dirfd,
CACHE_FEATURES_FILE)) {
policy_cache->features = NULL;
if (!create || errno != ENOENT)
return -1;
} else
return 0;
return create_cache(policy_cache, kernel_features);
}
struct miss_cb_data {
aa_features *features;
const char *path;
char *pattern;
char *cache_name; /* return */
long n;
};
/* called on cache collision or miss where cache isn't present */
static int cache_miss_cb(int dirfd, const struct dirent *ent, void *arg)
{
struct miss_cb_data *data = arg;
char *cache_name, *pos, *tmp;
long n;
int len;
/* TODO: update to tighter pattern match of just trailing #s */
if (fnmatch(data->pattern, ent->d_name, 0))
return 0;
/* entry matches <feature_id>.<n> pattern */
len = asprintf(&cache_name, "%s/%s", data->path, ent->d_name);
if (len == -1) {
errno = ENOMEM;
return -1;
}
if (!cache_check_features(dirfd, cache_name, data->features) || errno == ENOENT) {
/* found cache dir matching pattern */
data->cache_name = cache_name;
/* return 1 to stop iteration and signal dir found */
return 1;
} else if (errno != EEXIST) {
PDEBUG("cache_check_features() failed for dirfd '%d' '%s'\n", dirfd, cache_name);
free(cache_name);
return -1;
}
free(cache_name);
/* check the cache dir # */
pos = strchr(ent->d_name, '.');
n = strtol(pos+1, &tmp, 10);
if (n == LONG_MIN || n == LONG_MAX || tmp == pos + 1)
return -1;
if (n > data->n)
data->n = n;
/* continue processing */
return 0;
}
/* will return cache_path on error if there is a collision */
static int cache_dir_from_path_and_features(char **cache_path,
int dirfd, const char *path,
aa_features *features)
{
autofree const char *features_id = NULL;
char *cache_dir;
size_t len;
int rc;
features_id = aa_features_id(features);
if (!features_id)
return -1;
len = asprintf(&cache_dir, "%s/%s.0", path, features_id);
if (len == -1)
return -1;
if (!cache_check_features(dirfd, cache_dir, features) || errno == ENOENT) {
PDEBUG("cache_dir_from_path_and_features() found '%s'\n", cache_dir);
*cache_path = cache_dir;
return 0;
} else if (errno != EEXIST) {
PDEBUG("cache_check_features() failed for dirfd '%d' %s\n", dirfd, cache_dir);
free(cache_dir);
return -1;
}
PDEBUG("Cache collision '%s' falling back to next dir on fd '%d' path %s", cache_dir, dirfd, path);
free(cache_dir);
struct miss_cb_data data = {
.features = features,
.path = path,
.cache_name = NULL,
.n = -1,
};
if (asprintf(&data.pattern, "%s.*", features_id) == -1)
return -1;
rc = _aa_dirat_for_each2(dirfd, path, &data, cache_miss_cb);
free(data.pattern);
if (rc == 1) {
/* found matching feature dir */
PDEBUG("cache_dir_from_path_and_features() callback found '%s'\n", data.cache_name);
*cache_path = data.cache_name;
return 0;
} else if (rc) {
PDEBUG("cache_dir_from_path_and_features() callback returned an error'%m'\n");
return -1;
}
/* no dir found use 1 higher than highest dir n searched */
len = asprintf(&cache_dir, "%s/%s.%d", path, features_id, data.n + 1);
if (len == -1)
return -1;
PDEBUG("Cache collision no dir found using %d + 1 = %s\n", data.n + 1, cache_dir);
*cache_path = cache_dir;
return 0;
}
/* will return the cache_dir or NULL */
static int open_or_create_cache_dir(aa_features *features, int dirfd,
const char *path, bool create,
char **cache_dir)
{
int fd;
*cache_dir = NULL;
if (cache_dir_from_path_and_features(cache_dir, dirfd, path,
features))
return -1;
open:
fd = openat(dirfd, *cache_dir, O_RDONLY | O_CLOEXEC | O_DIRECTORY);
if (fd < 0) {
/* does the dir exist? */
if (create && errno == ENOENT) {
/**
* 1) Attempt to create the cache location, such as
* /etc/apparmor.d/cache.d/
* 2) Attempt to create the cache directory, for the
* passed in aa_features, such as
* /etc/apparmor.d/cache.d/<features_id>/
* 3) Try to reopen the cache directory
*/
if (mkdirat(dirfd, path, 0700) == -1 &&
errno != EEXIST) {
PERROR("Can't create cache location '%s': %m\n",
path);
} else if (mkdirat(dirfd, *cache_dir, 0700) == -1 &&
errno != EEXIST) {
PERROR("Can't create cache directory '%s': %m\n",
*cache_dir);
} else {
goto open;
}
} else if (create) {
PERROR("Can't update cache directory '%s': %m\n", *cache_dir);
} else {
PDEBUG("Cache directory '%s' does not exist\n", *cache_dir);
/* The cache directory needs to be created */
call_create_cache = true;
} else if (!aa_features_is_equal(policy_cache->features,
kernel_features)) {
if (!create) {
errno = EEXIST;
return -1;
}
PDEBUG("Could not open cache_dir: %m");
return -1;
/* The cache directory needs to be refreshed */
call_create_cache = true;
}
return fd;
return call_create_cache ?
create_cache(policy_cache, kernel_features) : 0;
}
struct replace_all_cb_data {
aa_policy_cache *policy_cache;
aa_kernel_interface *kernel_interface;
};
static int replace_all_cb(int dirfd unused, const char *name, struct stat *st,
void *cb_data)
{
int retval = 0;
if (!S_ISDIR(st->st_mode) && !_aa_is_blacklisted(name)) {
struct replace_all_cb_data *data;
data = (struct replace_all_cb_data *) cb_data;
retval = aa_kernel_interface_replace_policy_from_file(data->kernel_interface,
data->policy_cache->dirfd,
name);
}
return retval;
}
/**
@@ -385,11 +133,8 @@ int aa_policy_cache_new(aa_policy_cache **policy_cache,
aa_features *kernel_features,
int dirfd, const char *path, uint16_t max_caches)
{
autofree char *cache_dir = NULL;
aa_policy_cache *pc;
bool create = max_caches > 0;
autofree const char *features_id = NULL;
int i, fd;
*policy_cache = NULL;
@@ -398,79 +143,55 @@ int aa_policy_cache_new(aa_policy_cache **policy_cache,
return -1;
}
/* TODO: currently no reaping of caches in excess of max_caches */
if (max_caches > 1) {
errno = ENOTSUP;
return -1;
}
pc = calloc(1, sizeof(*pc));
if (!pc) {
errno = ENOMEM;
return -1;
}
pc->n = 0;
for (i = 0; i < MAX_POLICY_CACHE_OVERLAY_DIRS; i++)
pc->dirfd[i] = -1;
pc->dirfd = -1;
aa_policy_cache_ref(pc);
open:
pc->dirfd = openat(dirfd, path, O_RDONLY | O_CLOEXEC | O_DIRECTORY);
if (pc->dirfd < 0) {
/* does the dir exist? */
if (create && errno == ENOENT) {
if (mkdirat(dirfd, path, 0700) == 0)
goto open;
PERROR("Can't create cache directory '%s': %m\n", path);
} else if (create) {
PERROR("Can't update cache directory '%s': %m\n", path);
} else {
PDEBUG("Cache directory '%s' does not exist\n", path);
}
aa_policy_cache_unref(pc);
return -1;
}
if (kernel_features) {
aa_features_ref(kernel_features);
} else if (aa_features_new_from_kernel(&kernel_features) == -1) {
aa_policy_cache_unref(pc);
PDEBUG("%s: Failed to obtain features %m\n", __FUNCTION__);
return -1;
}
pc->features = kernel_features;
fd = open_or_create_cache_dir(kernel_features, dirfd, path, create,
&cache_dir);
if (fd == -1) {
aa_policy_cache_unref(pc);
PDEBUG("%s: Failed to open_or_create_dir %m\n", __FUNCTION__);
return -1;
}
pc->dirfd[0] = fd;
pc->n = 1;
pc->kernel_features = kernel_features;
if (init_cache_features(pc, kernel_features, create)) {
PDEBUG("%s: failed init_cache_features for dirfd '%d' name '%s' opened as pc->dirfd '%d'\n", __FUNCTION__, dirfd, cache_dir, pc->dirfd);
aa_policy_cache_unref(pc);
return -1;
}
PDEBUG("%s: created policy_cache for dirfd '%d' name '%s' opened as pc->dirfd '%d'\n", __FUNCTION__, dirfd, cache_dir, pc->dirfd);
*policy_cache = pc;
return 0;
}
/**
* aa_policy_cache_add_ro_dir - add an readonly dir layer to the policy cache
* @policy_cache: policy_cache to add the readonly dir to
* @dirfd: directory file descriptor or AT_FDCWD (see openat(2))
* @path: path to the readonly policy cache
*
* Returns: 0 on success, -1 on error with errno set
*/
int aa_policy_cache_add_ro_dir(aa_policy_cache *policy_cache, int dirfd,
const char *path)
{
autofree char *cache_dir = NULL;
int fd;
if (policy_cache->n >= MAX_POLICY_CACHE_OVERLAY_DIRS) {
errno = ENOSPC;
PDEBUG("%s: exceeded number of supported cache overlays\n", __FUNCTION__);
return -1;
}
fd = open_or_create_cache_dir(policy_cache->features, dirfd, path,
false, &cache_dir);
if (fd == -1) {
PDEBUG("%s: failed to open_or_create_cache_dir %m\n", __FUNCTION__);
return -1;
}
policy_cache->dirfd[policy_cache->n++] = fd;
return 0;
}
/**
* aa_policy_cache_ref - increments the ref count of an aa_policy_cache object
* @policy_cache: the policy_cache
@@ -489,14 +210,13 @@ aa_policy_cache *aa_policy_cache_ref(aa_policy_cache *policy_cache)
*/
void aa_policy_cache_unref(aa_policy_cache *policy_cache)
{
int i, save = errno;
int save = errno;
if (policy_cache && atomic_dec_and_test(&policy_cache->ref_count)) {
aa_features_unref(policy_cache->features);
for (i = 0; i < MAX_POLICY_CACHE_OVERLAY_DIRS; i++) {
if (policy_cache->dirfd[i] != -1)
close(policy_cache->dirfd[i]);
}
aa_features_unref(policy_cache->kernel_features);
if (policy_cache->dirfd != -1)
close(policy_cache->dirfd);
free(policy_cache);
}
@@ -534,7 +254,7 @@ int aa_policy_cache_replace_all(aa_policy_cache *policy_cache,
if (kernel_interface) {
aa_kernel_interface_ref(kernel_interface);
} else if (aa_kernel_interface_new(&kernel_interface,
policy_cache->features,
policy_cache->kernel_features,
NULL) == -1) {
kernel_interface = NULL;
return -1;
@@ -542,158 +262,10 @@ int aa_policy_cache_replace_all(aa_policy_cache *policy_cache,
cb_data.policy_cache = policy_cache;
cb_data.kernel_interface = kernel_interface;
retval = _aa_overlaydirat_for_each(policy_cache->dirfd, policy_cache->n,
&cb_data, replace_all_cb);
retval = _aa_dirat_for_each(policy_cache->dirfd, ".", &cb_data,
replace_all_cb);
aa_kernel_interface_unref(kernel_interface);
return retval;
}
/**
* aa_policy_cache_no_dirs - return the number of dirs making up the cache
* @policy_cache: the policy_cache
*
* Returns: The number of directories that the policy cache is composed of
*/
int aa_policy_cache_no_dirs(aa_policy_cache *policy_cache)
{
return policy_cache->n;
}
/**
* aa_policy_cache_dir_path - returns the path to the aa_policy_cache directory
* @policy_cache: the policy_cache
* @dir: which dir in the policy cache to return the name of
*
* Returns: The path to the policy cache directory on success, NULL on
* error with errno set.
*/
char *aa_policy_cache_dir_path(aa_policy_cache *policy_cache, int dir)
{
char *path = NULL;
if (dir < 0 || dir >= policy_cache->n) {
PERROR("aa_policy_cache directory: %d does not exist\n", dir);
errno = ERANGE;
} else {
path = path_from_fd(policy_cache->dirfd[dir]);
}
if (!path)
PERROR("Can't return the path to the aa_policy_cache directory: %m\n");
return path;
}
/**
* aa_policy_cache_dirfd - returns the dirfd for a aa_policy_cache directory
* @policy_cache: the policy_cache
* @dir: which dir in the policy cache to return the dirfd of
*
* Returns: The dirfd to the @dir policy cache directory on success, -1 on
* error with errno set.
*
* caller is responsible for closing the returned dirfd
*/
int aa_policy_cache_dirfd(aa_policy_cache *policy_cache, int dir)
{
if (dir < 0 || dir >= policy_cache->n) {
PERROR("aa_policy_cache directory: %d does not exist\n", dir);
errno = ERANGE;
return -1;
}
return dup(policy_cache->dirfd[dir]);
}
/* open cache file corresponding to name */
int aa_policy_cache_open(aa_policy_cache *policy_cache, const char *name,
int flags)
{
int i, fd;
for (i = 0; i < policy_cache->n; i++) {
fd = openat(policy_cache->dirfd[i], name, flags);
if (fd != -1)
return fd;
}
return -1;
}
char *aa_policy_cache_filename(aa_policy_cache *policy_cache, const char *name)
{
char *path;
autoclose int fd = aa_policy_cache_open(policy_cache, name, O_RDONLY);
if (fd == -1)
return NULL;
path = path_from_fd(fd);
if (!path)
PERROR("Can't return the path to the aa_policy_cache cachename: %m\n");
return path;
}
/**
* aa_policy_cache_dir_path_preview - returns the path to the aa_policy_cache directory
* @kernel_features: features representing a kernel (may be NULL if you want to
* use the features of the currently running kernel)
* @dirfd: directory file descriptor or AT_FDCWD (see openat(2))
* @path: path to the policy cache
*
* Returns: The path to the policy cache directory on success, NULL on
* error with errno set.
*/
char *aa_policy_cache_dir_path_preview(aa_features *kernel_features,
int dirfd, const char *path)
{
autofree char *cache_loc = NULL;
autofree char *cache_dir = NULL;
char *dir_path;
if (kernel_features) {
aa_features_ref(kernel_features);
} else if (aa_features_new_from_kernel(&kernel_features) == -1) {
return NULL;
}
/**
* Leave cache_loc set to NULL if dirfd is AT_FDCWD and handle a
* NULL cache_loc in the asprintf() below
*/
if (dirfd != AT_FDCWD) {
cache_loc = path_from_fd(dirfd);
if (!cache_loc) {
int save = errno;
PERROR("Can't return the path to the aa_policy_cache cache location: %m\n");
aa_features_unref(kernel_features);
errno = save;
return NULL;
}
}
PDEBUG("Looking up cachedir path for AT_FDCWD\n");
if (cache_dir_from_path_and_features(&cache_dir, dirfd, path,
kernel_features)) {
int save = errno;
PERROR("Can't return the path to the aa_policy_cache directory: %m\n");
aa_features_unref(kernel_features);
errno = save;
return NULL;
}
aa_features_unref(kernel_features);
if (asprintf(&dir_path, "%s%s%s",
cache_loc ? : "", cache_loc ? "/" : "", cache_dir) == -1) {
errno = ENOMEM;
return NULL;
}
PDEBUG("aa_policy_cache_dir_path_preview() returning '%s'\n", dir_path);
return dir_path;
}

View File

@@ -38,24 +38,11 @@
#ifndef HAVE_SECURE_GETENV
#ifdef HAVE___SECURE_GETENV
#define secure_getenv __secure_getenv
#elif ENABLE_DEBUG_OUTPUT
#error Debug output is not possible without a secure_getenv() implementation.
#else
#define secure_getenv(env) NULL
#error neither secure_getenv nor __secure_getenv is available
#endif
#endif
/**
* Allow libapparmor to build on older glibcs and other libcs that do
* not support reallocarray.
*/
#ifndef HAVE_REALLOCARRY
void *reallocarray(void *ptr, size_t nmemb, size_t size)
{
return realloc(ptr, nmemb * size);
}
#endif
struct ignored_suffix_t {
const char * text;
int len;
@@ -69,10 +56,6 @@ static struct ignored_suffix_t ignored_suffixes[] = {
{ ".dpkg-old", 9, 1 },
{ ".dpkg-dist", 10, 1 },
{ ".dpkg-bak", 9, 1 },
{ ".dpkg-remove", 12, 1 },
/* Archlinux packaging files */
{ ".pacsave", 8, 1 },
{ ".pacnew", 7, 1 },
/* RPM packaging files have traditionally not been silently
ignored */
{ ".rpmnew", 7, 0 },
@@ -186,252 +169,13 @@ int _aa_asprintf(char **strp, const char *fmt, ...)
return rc;
}
/* stops on first error, can use errno or return value to communicate
* the goal is to use this to replace _aa_dirat_for_each, but that will
* be a different patch.
*/
int _aa_dirat_for_each2(int dirfd, const char *name, void *data,
int (* cb)(int, const struct dirent *, void *))
static int dot_or_dot_dot_filter(const struct dirent *ent)
{
autoclose int cb_dirfd = -1;
int fd_for_dir = -1;
const struct dirent *ent;
DIR *dir;
int save, rc;
if (strcmp(ent->d_name, ".") == 0 ||
strcmp(ent->d_name, "..") == 0)
return 0;
if (!cb || !name) {
errno = EINVAL;
return -1;
}
save = errno;
cb_dirfd = openat(dirfd, name, O_RDONLY | O_CLOEXEC | O_DIRECTORY);
if (cb_dirfd == -1) {
PDEBUG("could not open directory fd '%d' '%s': %m\n", dirfd, name);
return -1;
}
/* dup cd_dirfd because fdopendir has claimed the fd passed to it */
fd_for_dir = dup(cb_dirfd);
if (fd_for_dir == -1) {
PDEBUG("could not dup directory fd '%s': %m\n", name);
return -1;
}
dir = fdopendir(fd_for_dir);
if (!dir) {
PDEBUG("could not open directory '%s' from fd '%d': %m\n", name, fd_for_dir);
close(fd_for_dir);
return -1;
}
while ((ent = readdir(dir))) {
if (cb) {
rc = (*cb)(cb_dirfd, ent, data);
if (rc) {
PDEBUG("dir_for_each callback failed for '%s'\n",
ent->d_name);
goto out;
}
}
}
errno = save;
out:
closedir(dir);
return rc;
}
#define max(a, b) \
({ __typeof__ (a) _a = (a); \
__typeof__ (b) _b = (b); \
_a > _b ? _a : _b; })
#define CHUNK 32
struct overlaydir {
int dirfd;
struct dirent *dent;
};
static int insert(struct overlaydir **overlayptr, int *max_size, int *size,
int pos, int remaining, int dirfd, struct dirent *ent)
{
struct overlaydir *overlay = *overlayptr;
int i, chunk = max(remaining, CHUNK);
if (size + 1 >= max_size) {
struct overlaydir *tmp = reallocarray(overlay,
*max_size + chunk,
sizeof(*overlay));
if (tmp == NULL)
return -1;
overlay = tmp;
}
*max_size += chunk;
(*size)++;
for (i = *size; i > pos; i--)
overlay[i] = overlay[i - 1];
overlay[pos].dirfd = dirfd;
overlay[pos].dent = ent;
*overlayptr = overlay;
return 0;
}
#define merge(overlay, n_overlay, max_size, list, n_list, dirfd) \
({ \
int i, j; \
int rc = 0; \
\
for (i = 0, j = 0; i < n_overlay && j < n_list; ) { \
int res = strcmp(overlay[i].dent->d_name, list[j]->d_name);\
if (res < 0) { \
i++; \
continue; \
} else if (res == 0) { \
free(list[j]); \
list[j] = NULL; \
i++; \
j++; \
} else { \
if ((rc = insert(&overlay, &max_size, &n_overlay, i,\
n_list - j, dirfd, list[j]))) \
goto fail; \
i++; \
list[j++] = NULL; \
} \
} \
while (j < n_list) { \
if ((rc = insert(&overlay, &max_size, &n_overlay, i, \
n_list - j, dirfd,list[j]))) \
goto fail; \
i++; \
list[j++] = NULL; \
} \
\
fail: \
rc; \
})
static ssize_t readdirfd(int dirfd, struct dirent ***out,
int (*dircmp)(const struct dirent **, const struct dirent **))
{
struct dirent **dents = NULL, *dent;
ssize_t n = 0;
size_t i;
int save;
DIR *dir;
*out = NULL;
/*
* closedir(dir) will close the underlying fd, so we need
* to dup first
*/
if ((dirfd = dup(dirfd)) < 0) {
PDEBUG("dup of dirfd failed: %m\n");
return -1;
}
if ((dir = fdopendir(dirfd)) == NULL) {
PDEBUG("fdopendir of dirfd failed: %m\n");
close(dirfd);
return -1;
}
/* Get number of directory entries */
while ((dent = readdir(dir)) != NULL) {
if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, ".."))
continue;
n++;
}
rewinddir(dir);
dents = calloc(n, sizeof(struct dirent *));
if (!dents)
goto fail;
for (i = 0; i < n; ) {
if ((dent = readdir(dir)) == NULL) {
PDEBUG("readdir of entry[%d] failed: %m\n", i);
goto fail;
}
if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, ".."))
continue;
dents[i] = malloc(sizeof(*dents[i]));
if (!dents[i])
goto fail;
memcpy(dents[i], dent, sizeof(*dent));
i++;
}
if (dircmp)
qsort(dents, n, sizeof(*dent), (int (*)(const void *, const void *))dircmp);
*out = dents;
closedir(dir);
return n;
fail:
save = errno;
if (dents) {
for (i = 0; i < n; i++)
free(dents[i]);
}
free(dents);
closedir(dir);
errno = save;
return -1;
}
int _aa_overlaydirat_for_each(int dirfd[], int n, void *data,
int (* cb)(int, const char *, struct stat *, void *))
{
autofree struct dirent **list = NULL;
autofree struct overlaydir *overlay = NULL;
int i, k;
int n_list, size = 0, max_size = 0;
int rc = 0;
for (i = 0; i < n; i++) {
n_list = readdirfd(dirfd[i], &list, alphasort);
if (n_list == -1) {
PDEBUG("scandirat of dirfd[%d] failed: %m\n", i);
return -1;
}
if (merge(overlay, size, max_size, list, n_list, dirfd[i])) {
for (k = 0; k < n_list; k++)
free(list[i]);
for (k = 0; k < size; k++)
free(overlay[k].dent);
return -1;
}
}
for (rc = 0, i = 0; i < size; i++) {
/* Must cycle through all dirs so that each one is autofreed */
autofree struct dirent *dent = overlay[i].dent;
struct stat my_stat;
if (rc)
continue;
if (fstatat(overlay[i].dirfd, dent->d_name, &my_stat,
AT_SYMLINK_NOFOLLOW)) {
PDEBUG("stat failed for '%s': %m\n", dent->d_name);
rc = -1;
continue;
}
if (cb(overlay[i].dirfd, dent->d_name, &my_stat, data)) {
PDEBUG("dir_for_each callback failed for '%s'\n",
dent->d_name);
rc = -1;
continue;
}
}
return rc;
return 1;
}
/**
@@ -475,7 +219,8 @@ int _aa_dirat_for_each(int dirfd, const char *name, void *data,
return -1;
}
num_dirs = readdirfd(cb_dirfd, &namelist, NULL);
num_dirs = scandirat(cb_dirfd, ".", &namelist,
dot_or_dot_dot_filter, NULL);
if (num_dirs == -1) {
PDEBUG("scandirat of directory '%s' failed: %m\n", name);
return -1;

View File

@@ -17,7 +17,6 @@
#ifndef _AA_PRIVATE_H
#define _AA_PRIVATE_H 1
#include <dirent.h>
#include <stdbool.h>
#include <sys/apparmor_private.h>
@@ -52,7 +51,4 @@ void print_debug(const char *fmt, ...);
void atomic_inc(unsigned int *v);
bool atomic_dec_and_test(unsigned int *v);
int _aa_dirat_for_each2(int dirfd, const char *name, void *data,
int (* cb)(int, const struct dirent *, void *));
#endif /* _AA_PRIVATE_H */

View File

@@ -2,8 +2,6 @@
# Copyright (c) 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007
# NOVELL (All rights reserved)
#
# Copyright (c) Christian Boltz 2018
#
# 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.
@@ -24,11 +22,10 @@ include $(COMMONDIR)/Make.rules
DESTDIR=/
APPARMOR_BIN_PREFIX=${DESTDIR}/lib/apparmor
SYSTEMD_UNIT_DIR=${DESTDIR}/usr/lib/systemd/system
CONFDIR=/etc/apparmor
INSTALL_CONFDIR=${DESTDIR}${CONFDIR}
LOCALEDIR=/usr/share/locale
MANPAGES=apparmor.d.5 apparmor.7 apparmor_parser.8 subdomain.conf.5 aa-teardown.8
MANPAGES=apparmor.d.5 apparmor.7 apparmor_parser.8 subdomain.conf.5
YACC := bison
YFLAGS := -d
@@ -317,9 +314,12 @@ install-redhat:
install -m 755 rc.apparmor.$(subst install-,,$@) $(DESTDIR)/etc/init.d/apparmor
.PHONY: install-suse
install-suse: install-systemd
install-suse:
install -m 755 -d $(DESTDIR)/etc/init.d
install -m 755 rc.apparmor.$(subst install-,,$(@)) $(DESTDIR)/etc/init.d/boot.apparmor
install -m 755 -d $(DESTDIR)/sbin
ln -sf service $(DESTDIR)/sbin/rcapparmor
ln -sf /etc/init.d/boot.apparmor $(DESTDIR)/sbin/rcapparmor
ln -sf rcapparmor $(DESTDIR)/sbin/rcsubdomain
.PHONY: install-slackware
install-slackware:
@@ -379,14 +379,6 @@ install-indep: indep
$(MAKE) -C po install NAME=${NAME} DESTDIR=${DESTDIR}
$(MAKE) install_manpages DESTDIR=${DESTDIR}
.PHONY: install-systemd
install-systemd:
install -m 755 -d $(SYSTEMD_UNIT_DIR)
install -m 644 apparmor.service $(SYSTEMD_UNIT_DIR)
install -m 755 apparmor.systemd $(APPARMOR_BIN_PREFIX)
install -m 755 -d $(DESTDIR)/usr/sbin
install -m 755 aa-teardown $(DESTDIR)/usr/sbin
ifndef VERBOSE
.SILENT: clean
endif

View File

@@ -1,10 +0,0 @@
#!/bin/bash
test $# = 0 || {
echo "Usage: $0"
echo
echo "Unloads all AppArmor profiles"
exit 1
}
/lib/apparmor/apparmor.systemd stop

View File

@@ -1,40 +0,0 @@
# ----------------------------------------------------------------------
# Copyright (c) 2018 Christian Boltz
#
# 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.
# ----------------------------------------------------------------------
=pod
=head1 NAME
aa-teardown - unload all AppArmor profiles
=head1 SYNOPSIS
B<aa-teardown>
=head1 DESCRIPTION
aa-teardown unloads all AppArmor profiles
=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), and L<https://wiki.apparmor.net>.
=cut

View File

@@ -1,26 +0,0 @@
[Unit]
Description=Load AppArmor profiles
DefaultDependencies=no
Before=sysinit.target
After=systemd-journald-audit.socket
# profile cache
After=var.mount var-lib.mount
ConditionSecurity=apparmor
[Service]
Type=oneshot
ExecStart=/lib/apparmor/apparmor.systemd reload
ExecReload=/lib/apparmor/apparmor.systemd reload
# systemd maps 'restart' to 'stop; start' which means removing AppArmor confinement
# from running processes (and not being able to re-apply it later).
# Upstream systemd developers refused to implement an option that allows overriding
# this behaviour, therefore we have to make ExecStop a no-op to error out on the
# safe side.
#
# If you really want to unload all AppArmor profiles, run aa-teardown
ExecStop=/bin/true
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target

View File

@@ -1,100 +0,0 @@
#!/bin/sh
# ----------------------------------------------------------------------
# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
#
# 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.
# ----------------------------------------------------------------------
APPARMOR_FUNCTIONS=/lib/apparmor/rc.apparmor.functions
aa_action()
{
echo $1
shift
"$@"
return $?
}
aa_log_warning_msg()
{
echo "Warning: $@"
}
aa_log_failure_msg()
{
echo "Error: $@"
}
aa_log_action_start()
{
echo "$@"
}
aa_log_action_end()
{
echo -n
}
aa_log_daemon_msg()
{
echo "$@"
}
aa_log_skipped_msg()
{
echo "Skipped: $@"
}
aa_log_end_msg()
{
echo -n
}
# source apparmor function library
if [ -f "${APPARMOR_FUNCTIONS}" ]; then
. ${APPARMOR_FUNCTIONS}
else
aa_log_failure_msg "Unable to find AppArmor initscript functions"
exit 1
fi
case "$1" in
start)
apparmor_start
rc=$?
;;
stop)
apparmor_stop
rc=$?
;;
restart|reload|force-reload)
apparmor_restart
rc=$?
;;
try-restart)
apparmor_try_restart
rc=$?
;;
kill)
apparmor_kill
rc=$?
;;
status)
apparmor_status
rc=$?
;;
*)
exit 1
;;
esac
exit $rc

View File

@@ -46,10 +46,9 @@ program. The B<profiles> may be specified by file name or a directory
name containing a set of profiles. If a directory is specified then the
B<apparmor_parser> will try to do a profile load for each file in the
directory that is not a dot file, or explicitly black listed (*.dpkg-new,
*.dpkg-old, *.dpkg-dist, *.dpkg-bak, *.dpkg-remove, *.pacsave, *.pacnew,
*.rpmnew, *.rpmsave, *.orig, *.rej, *~).
The B<apparmor_parser> will fall back to taking input from standard input if
a profile or directory is not supplied.
*.dpkg-old, *.dpkg-dist, *-dpkg-bak, *.rpmnew, *.rpmsave, *orig, *.rej,
*~). The B<apparmor_parser> will fall back to taking input from standard
input if a profile or directory is not supplied.
The input supplied to B<apparmor_parser> should be in the format described in
apparmor.d(5).
@@ -233,28 +232,8 @@ inconsistent state
=item -L, --cache-loc
Set the location(s) of the cache directory. This option can accept a
comma separated list of directories, which will be searched in order
to find a matching cache. The first matching cache file found is used
even if a directory later in the search order may contain a newer cache
file.
If multiple directories are specified and --write-cache has been specified
then cache writes will be made to the first directory in the list, all
other directories will be treated as read only.
If a cache directory name needs to have a comma as part of the name, it
can be specified by using a backslash to escape the comma character in
the directory name.
If not specified the cache location defaults to /var/cache/apparmor
=item --print-cache-dir
Print the cache directory location. This path will be a subdirectory of the
directory specified by --cache-loc. The subdirectory used will be influenced by
the features available in the currently running kernel or by the features
specified with the --match-string or --features-file options.
Set the location of the cache directory. If not specified the cache location
defaults to /etc/apparmor.d/cache
=item -Q, --skip-kernel-load
@@ -355,17 +334,6 @@ This option tells the parser to not attempt to rebuild the cache on
failure, instead the parser continues on with processing the remaining
profiles.
=item --config-file
Specify the config file to use instead of
/etc/apparmor/parser.conf. This option will be processed early before
regular options regardless of the order it is specified in.
=item --print-config-file
Print the config file location that will be used.
=back
=head1 CONFIG FILE

View File

@@ -25,8 +25,6 @@
#include "parser.h"
#include "profile.h"
typedef int (*comparison_fn_t)(const void *, const void *);
struct alias_rule {
char *from;
char *to;

View File

@@ -2,7 +2,7 @@
* Copyright (c) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
* NOVELL (All rights reserved)
*
* Copyright (c) 2010 - 2018
* Copyright (c) 2010 - 2013
* Canonical Ltd. (All rights reserved)
*
* This program is free software; you can redistribute it and/or
@@ -59,10 +59,8 @@
#define PRIVILEGED_OPS (kernel_load)
#define UNPRIVILEGED_OPS (!(PRIVILEGED_OPS))
#define EARLY_ARG_CONFIG_FILE 141
const char *parser_title = "AppArmor parser";
const char *parser_copyright = "Copyright (C) 1999-2008 Novell Inc.\nCopyright 2009-2018 Canonical Ltd.";
const char *parser_copyright = "Copyright (C) 1999-2008 Novell Inc.\nCopyright 2009-2012 Canonical Ltd.";
int opt_force_complain = 0;
int binary_input = 0;
@@ -99,20 +97,12 @@ long jobs_scale = 0; /* number of chance to resample online
*/
bool debug_jobs = false;
#define MAX_CACHE_LOCS 4
struct timespec cache_tstamp, mru_policy_tstamp;
static char *apparmorfs = NULL;
static const char *cacheloc[MAX_CACHE_LOCS];
static int cacheloc_n = 0;
static bool print_cache_dir = false;
static aa_features *compile_features = NULL;
static aa_features *kernel_features = NULL;
static const char *config_file = "/etc/apparmor/parser.conf";
static char *cacheloc = NULL;
static aa_features *features = NULL;
/* Make sure to update BOTH the short and long_options */
static const char *short_options = "ad::f:h::rRVvI:b:BCD:NSm:M:qQn:XKTWkL:O:po:j:";
@@ -143,6 +133,9 @@ struct option long_options[] = {
{"skip-read-cache", 0, 0, 'T'},
{"write-cache", 0, 0, 'W'},
{"show-cache", 0, 0, 'k'},
{"skip-bad-cache", 0, 0, 129}, /* no short option */
{"purge-cache", 0, 0, 130}, /* no short option */
{"create-cache-dir", 0, 0, 131}, /* no short option */
{"cache-loc", 1, 0, 'L'},
{"debug", 2, 0, 'd'},
{"dump", 1, 0, 'D'},
@@ -150,21 +143,12 @@ struct option long_options[] = {
{"optimize", 1, 0, 'O'},
{"Optimize", 1, 0, 'O'},
{"preprocess", 0, 0, 'p'},
{"jobs", 1, 0, 'j'},
{"skip-bad-cache", 0, 0, 129}, /* no short option */
{"purge-cache", 0, 0, 130}, /* no short option */
{"create-cache-dir", 0, 0, 131}, /* no short option */
{"abort-on-error", 0, 0, 132}, /* no short option */
{"skip-bad-cache-rebuild", 0, 0, 133}, /* no short option */
{"warn", 1, 0, 134}, /* no short option */
{"debug-cache", 0, 0, 135}, /* no short option */
{"jobs", 1, 0, 'j'},
{"max-jobs", 1, 0, 136}, /* no short option */
{"print-cache-dir", 0, 0, 137}, /* no short option */
{"kernel-features", 1, 0, 138}, /* no short option */
{"compile-features", 1, 0, 139}, /* no short option */
{"print-config-file", 0, 0, 140}, /* no short option */
{"config-file", 1, 0, EARLY_ARG_CONFIG_FILE}, /* early option, no short option */
{NULL, 0, 0, 0},
};
@@ -194,8 +178,7 @@ static void display_usage(const char *command)
"-I n, --Include n Add n to the search path\n"
"-f n, --subdomainfs n Set location of apparmor filesystem\n"
"-m n, --match-string n Use only features n\n"
"-M n, --features-file n Compile features set in file n\n"
"--kernel-features n Kernel features set in file n\n"
"-M n, --features-file n Use only features in file n\n"
"-n n, --namespace n Set Namespace for the profile\n"
"-X, --readimpliesX Map profile read permissions to mr\n"
"-k, --show-cache Report cache hit/miss details\n"
@@ -205,8 +188,7 @@ static void display_usage(const char *command)
" --skip-bad-cache Don't clear cache if out of sync\n"
" --purge-cache Clear cache regardless of its state\n"
" --debug-cache Debug cache file checks\n"
" --print-cache_dir Print the cache directory path\n"
"-L, --cache-loc n Set the location of the profile caches\n"
"-L, --cache-loc n Set the location of the profile cache\n"
"-q, --quiet Don't emit warnings\n"
"-v, --verbose Show profile names as they load\n"
"-Q, --skip-kernel-load Do everything except loading into kernel\n"
@@ -220,8 +202,6 @@ static void display_usage(const char *command)
"--max-jobs n Hard cap on --jobs. Default 8*cpus\n"
"--abort-on-error Abort processing of profiles on first error\n"
"--skip-bad-cache-rebuild Do not try rebuilding the cache if it is rejected by the kernel\n"
"--config-file n Specify the parser config file location, processed early before other options.\n"
"--print-config Print config file location\n"
"--warn n Enable warnings (see --help=warn)\n"
,command);
}
@@ -242,55 +222,6 @@ void display_warn(const char *command)
print_flag_table(warnflag_table);
}
/* Parse comma separated cachelocations. Commas can be escaped by \, */
static int parse_cacheloc(const char *arg, const char **cacheloc, int max_size)
{
const char *s = arg;
const char *p = arg;
int n = 0;
while(*p) {
if (*p == '\\') {
if (*(p + 1) != 0)
p++;
} else if (*p == ',') {
if (p != s) {
char *tmp;
if (n == max_size) {
errno = E2BIG;
return -1;
}
tmp = (char *) malloc(p - s + 1);
if (tmp == NULL)
return -1;
memcpy(tmp, s, p - s);
tmp[p - s] = 0;
cacheloc[n] = tmp;
n++;
}
p++;
s = p;
} else
p++;
}
if (p != s) {
char *tmp;
if (n == max_size) {
errno = E2BIG;
return -1;
}
tmp = (char *) malloc(p - s + 1);
if (tmp == NULL)
return -1;
memcpy(tmp, s, p - s);
tmp[p - s] = 0;
cacheloc[n] = tmp;
n++;
}
return n;
}
/* Treat conf file like options passed on command line
*/
static int getopt_long_file(FILE *f, const struct option *longopts,
@@ -388,16 +319,6 @@ static long process_jobs_arg(const char *arg, const char *val) {
return n;
}
bool early_arg(int c) {
switch(c) {
case EARLY_ARG_CONFIG_FILE:
return true;
}
return false;
}
/* process a single argment from getopt_long
* Returns: 1 if an action arg, else 0
*/
@@ -408,7 +329,8 @@ static int process_arg(int c, char *optarg)
switch (c) {
case 0:
PERROR("Assert, in getopt_long handling\n");
exit(1);
display_usage(progname);
exit(0);
break;
case 'a':
count++;
@@ -527,7 +449,7 @@ static int process_arg(int c, char *optarg)
}
break;
case 'm':
if (aa_features_new_from_string(&compile_features,
if (aa_features_new_from_string(&features,
optarg, strlen(optarg))) {
fprintf(stderr,
"Failed to parse features string: %m\n");
@@ -535,21 +457,13 @@ static int process_arg(int c, char *optarg)
}
break;
case 'M':
if (aa_features_new(&compile_features, AT_FDCWD, optarg)) {
if (aa_features_new(&features, AT_FDCWD, optarg)) {
fprintf(stderr,
"Failed to load features from '%s': %m\n",
optarg);
exit(1);
}
break;
case 138:
if (aa_features_new(&kernel_features, AT_FDCWD, optarg)) {
fprintf(stderr,
"Failed to load kernel features from '%s': %m\n",
optarg);
exit(1);
}
break;
case 'q':
conf_verbose = 0;
conf_quiet = 1;
@@ -593,11 +507,7 @@ static int process_arg(int c, char *optarg)
skip_bad_cache_rebuild = 1;
break;
case 'L':
cacheloc_n = parse_cacheloc(optarg, cacheloc, MAX_CACHE_LOCS);
if (cacheloc_n == -1) {
PERROR("%s: Invalid --cacheloc option '%s' %m\n", progname, optarg);
exit(1);
}
cacheloc = strdup(optarg);
break;
case 'Q':
kernel_load = 0;
@@ -626,22 +536,8 @@ static int process_arg(int c, char *optarg)
case 136:
jobs_max = process_jobs_arg("max-jobs", optarg);
break;
case 137:
kernel_load = 0;
print_cache_dir = true;
break;
case EARLY_ARG_CONFIG_FILE:
config_file = strdup(optarg);
if (!config_file) {
PERROR("%s: %m", progname);
exit(1);
}
break;
case 140:
printf("%s\n", config_file);
break;
default:
/* 'unrecognized option' error message gets printed by getopt_long() */
display_usage(progname);
exit(1);
break;
}
@@ -649,36 +545,21 @@ static int process_arg(int c, char *optarg)
return count;
}
static void process_early_args(int argc, char *argv[])
{
int c, o;
while ((c = getopt_long(argc, argv, short_options, long_options, &o)) != -1)
{
if (early_arg(c))
process_arg(c, optarg);
}
/* reset args, so we are ready for a second pass */
optind = 1;
}
static int process_args(int argc, char *argv[])
{
int c, o;
int count = 0;
option = OPTION_ADD;
opterr = 1;
while ((c = getopt_long(argc, argv, short_options, long_options, &o)) != -1)
{
if (!early_arg(c))
count += process_arg(c, optarg);
count += process_arg(c, optarg);
}
if (count > 1) {
PERROR("%s: Too many actions given on the command line.\n",
progname);
display_usage(progname);
exit(1);
}
@@ -693,10 +574,8 @@ static int process_config_file(const char *name)
int c, o;
f = fopen(name, "r");
if (!f) {
pwarn("config file '%s' not found\n", name);
if (!f)
return 0;
}
while ((c = getopt_long_file(f, long_options, &optarg, &o)) != -1)
process_arg(c, optarg);
@@ -713,6 +592,7 @@ int have_enough_privilege(void)
if (uid != 0 && euid != 0) {
PERROR(_("%s: Sorry. You need root privileges to run this program.\n\n"),
progname);
display_usage(progname);
return EPERM;
}
@@ -743,37 +623,33 @@ no_match:
perms_create = 1;
}
static void set_supported_features(aa_features *kernel_features unused)
static void set_supported_features(void)
{
/* has process_args() already assigned a match string? */
if (!compile_features && aa_features_new_from_kernel(&compile_features) == -1) {
if (!features && aa_features_new_from_kernel(&features) == -1) {
set_features_by_match_file();
return;
}
/*
* TODO: intersect with actual kernel features to get proper
* rule down grades for a give kernel
*/
perms_create = 1;
kernel_supports_policydb = aa_features_supports(compile_features, "file");
kernel_supports_network = aa_features_supports(compile_features, "network");
kernel_supports_unix = aa_features_supports(compile_features,
kernel_supports_policydb = aa_features_supports(features, "file");
kernel_supports_network = aa_features_supports(features, "network");
kernel_supports_unix = aa_features_supports(features,
"network/af_unix");
kernel_supports_mount = aa_features_supports(compile_features, "mount");
kernel_supports_dbus = aa_features_supports(compile_features, "dbus");
kernel_supports_signal = aa_features_supports(compile_features, "signal");
kernel_supports_ptrace = aa_features_supports(compile_features, "ptrace");
kernel_supports_setload = aa_features_supports(compile_features,
kernel_supports_mount = aa_features_supports(features, "mount");
kernel_supports_dbus = aa_features_supports(features, "dbus");
kernel_supports_signal = aa_features_supports(features, "signal");
kernel_supports_ptrace = aa_features_supports(features, "ptrace");
kernel_supports_setload = aa_features_supports(features,
"policy/set_load");
kernel_supports_diff_encode = aa_features_supports(compile_features,
kernel_supports_diff_encode = aa_features_supports(features,
"policy/diff_encode");
kernel_supports_stacking = aa_features_supports(compile_features,
kernel_supports_stacking = aa_features_supports(features,
"domain/stack");
if (aa_features_supports(compile_features, "policy/versions/v7"))
if (aa_features_supports(features, "policy/versions/v7"))
kernel_abi_version = 7;
else if (aa_features_supports(compile_features, "policy/versions/v6"))
else if (aa_features_supports(features, "policy/versions/v6"))
kernel_abi_version = 6;
if (!kernel_supports_diff_encode)
@@ -781,33 +657,6 @@ static void set_supported_features(aa_features *kernel_features unused)
dfaflags &= ~DFA_CONTROL_DIFF_ENCODE;
}
static bool do_print_cache_dir(aa_features *features, int dirfd, const char *path)
{
autofree char *cache_dir = NULL;
cache_dir = aa_policy_cache_dir_path_preview(features, dirfd, path);
if (!cache_dir) {
PERROR(_("Unable to print the cache directory: %m\n"));
return false;
}
printf("%s\n", cache_dir);
return true;
}
static bool do_print_cache_dirs(aa_features *features, const char **cacheloc,
int cacheloc_n)
{
int i;
for (i = 0; i < cacheloc_n; i++) {
if (!do_print_cache_dir(features, AT_FDCWD, cacheloc[i]))
return false;
}
return true;
}
int process_binary(int option, aa_kernel_interface *kernel_interface,
const char *profilename)
{
@@ -892,11 +741,10 @@ int test_for_dir_mode(const char *basename, const char *linkdir)
}
int process_profile(int option, aa_kernel_interface *kernel_interface,
const char *profilename, aa_policy_cache *pc)
const char *profilename, const char *cachedir)
{
int retval = 0;
autofree const char *cachename = NULL;
autofree const char *writecachename = NULL;
autofree const char *cachetmpname = NULL;
autoclose int cachetmp = -1;
const char *basename = NULL;
@@ -913,7 +761,6 @@ int process_profile(int option, aa_kernel_interface *kernel_interface,
} else {
if (write_cache)
pwarn("%s: cannot use or update cache, disable, or force-complain via stdin\n", progname);
skip_cache = write_cache = 0;
}
reset_parser(profilename);
@@ -938,17 +785,9 @@ int process_profile(int option, aa_kernel_interface *kernel_interface,
}
/* setup cachename and tstamp */
if (!force_complain && pc) {
cachename = aa_policy_cache_filename(pc, basename);
if (!cachename) {
autoclose int fd = aa_policy_cache_open(pc,
basename,
O_RDONLY);
if (fd != -1)
pwarn(_("Could not get cachename for '%s'\n"), basename);
} else {
valid_read_cache(cachename);
}
if (!force_complain && !skip_cache) {
cachename = cache_filename(cachedir, basename);
valid_read_cache(cachename);
}
}
@@ -980,6 +819,8 @@ int process_profile(int option, aa_kernel_interface *kernel_interface,
if (!retval || skip_bad_cache_rebuild)
return retval;
}
cachetmp = setup_cache_tmp(&cachetmpname, cachename);
}
if (show_cache)
@@ -1015,27 +856,15 @@ int process_profile(int option, aa_kernel_interface *kernel_interface,
goto out;
}
if (pc && write_cache && !force_complain) {
writecachename = cache_filename(pc, 0, basename);
if (!writecachename) {
pwarn("Cache write disabled: Cannot create cache file name '%s': %m\n", basename);
write_cache = 0;
}
cachetmp = setup_cache_tmp(&cachetmpname, writecachename);
if (cachetmp == -1) {
pwarn("Cache write disabled: Cannot create setup tmp cache file '%s': %m\n", writecachename);
write_cache = 0;
}
}
/* cache file generated by load_policy */
retval = load_policy(option, kernel_interface, cachetmp);
if (retval == 0 && write_cache) {
if (cachetmp == -1) {
unlink(cachetmpname);
pwarn("Warning failed to create cache: %s\n",
PERROR("Warning failed to create cache: %s\n",
basename);
} else {
install_cache(cachetmpname, writecachename);
install_cache(cachetmpname, cachename);
}
}
out:
@@ -1177,7 +1006,7 @@ static void setup_parallel_compile(void)
struct dir_cb_data {
aa_kernel_interface *kernel_interface;
const char *dirname; /* name of the parent dir */
aa_policy_cache *policy_cache; /* policy_cache to use */
const char *cachedir; /* path to the cache sub directory */
};
/* data - pointer to a dir_cb_data */
@@ -1192,7 +1021,7 @@ static int profile_dir_cb(int dirfd unused, const char *name, struct stat *st,
if (asprintf(&path, "%s/%s", cb_data->dirname, name) < 0)
PERROR(_("Out of memory"));
work_spawn(process_profile(option, cb_data->kernel_interface,
path, cb_data->policy_cache),
path, cb_data->cachedir),
handle_work_result);
}
return rc;
@@ -1218,17 +1047,17 @@ static int binary_dir_cb(int dirfd unused, const char *name, struct stat *st,
static void setup_flags(void)
{
/* Get the match string to determine type of regex support needed */
set_supported_features();
/* Gracefully handle AppArmor kernel without compatibility patch */
if (!kernel_features && aa_features_new_from_kernel(&kernel_features) == -1) {
if (!features) {
PERROR("Cache read/write disabled: interface file missing. "
"(Kernel needs AppArmor 2.4 compatibility patch.)\n");
write_cache = 0;
skip_read_cache = 1;
return;
}
/* Get the match string to determine type of regex support needed */
set_supported_features(kernel_features);
}
int main(int argc, char *argv[])
@@ -1244,8 +1073,7 @@ int main(int argc, char *argv[])
init_base_dir();
process_early_args(argc, argv);
process_config_file(config_file);
process_config_file("/etc/apparmor/parser.conf");
optind = process_args(argc, argv);
setup_parallel_compile();
@@ -1265,7 +1093,7 @@ int main(int argc, char *argv[])
setup_flags();
if (!(UNPRIVILEGED_OPS) &&
aa_kernel_interface_new(&kernel_interface, kernel_features, apparmorfs) == -1) {
aa_kernel_interface_new(&kernel_interface, features, apparmorfs) == -1) {
PERROR(_("Warning: unable to find a suitable fs in %s, is it "
"mounted?\nUse --subdomainfs to override.\n"),
MOUNTED_FS);
@@ -1273,22 +1101,18 @@ int main(int argc, char *argv[])
}
if ((!skip_cache && (write_cache || !skip_read_cache)) ||
print_cache_dir || force_clear_cache) {
uint16_t max_caches = write_cache && cond_clear_cache ? (uint16_t) (-1) : 0;
force_clear_cache) {
uint16_t max_caches = write_cache && cond_clear_cache ? 1 : 0;
if (!cacheloc[0]) {
cacheloc[0] = "/var/cache/apparmor";
cacheloc_n = 1;
if (!cacheloc && asprintf(&cacheloc, "%s/cache", basedir) == -1) {
PERROR(_("Memory allocation error."));
return 1;
}
if (print_cache_dir)
return do_print_cache_dirs(kernel_features, cacheloc,
cacheloc_n) ? 0 : 1;
if (force_clear_cache) {
/* only ever write to the first cacheloc location */
if (aa_policy_cache_remove(AT_FDCWD, cacheloc[0])) {
if (aa_policy_cache_remove(AT_FDCWD, cacheloc)) {
PERROR(_("Failed to clear cache files (%s): %s\n"),
cacheloc[0], strerror(errno));
cacheloc, strerror(errno));
return 1;
}
@@ -1297,34 +1121,26 @@ int main(int argc, char *argv[])
if (create_cache_dir)
pwarn(_("The --create-cache-dir option is deprecated. Please use --write-cache.\n"));
retval = aa_policy_cache_new(&policy_cache, kernel_features,
AT_FDCWD, cacheloc[0], max_caches);
retval = aa_policy_cache_new(&policy_cache, features,
AT_FDCWD, cacheloc, max_caches);
if (retval) {
if (errno != ENOENT && errno != EEXIST && errno != EROFS) {
PERROR(_("Failed setting up policy cache (%s): %s\n"),
cacheloc[0], strerror(errno));
cacheloc, strerror(errno));
return 1;
}
if (show_cache) {
if (max_caches > 0)
PERROR("Cache write disabled: Cannot create cache '%s': %m\n",
cacheloc[0]);
cacheloc);
else
PERROR("Cache read/write disabled: Policy cache is invalid: %m\n");
PERROR("Cache read/write disabled: Policy cache is invalid\n");
}
write_cache = 0;
} else {
if (show_cache)
PERROR("Cache: added primary location '%s'\n", cacheloc[0]);
for (i = 1; i < cacheloc_n; i++) {
if (aa_policy_cache_add_ro_dir(policy_cache, AT_FDCWD,
cacheloc[i])) {
pwarn("Cache: failed to add read only location '%s', does not contain valid cache directory for the specified feature set\n", cacheloc[i]);
} else if (show_cache)
pwarn("Cache: added readonly location '%s'\n", cacheloc[i]);
}
skip_read_cache = 1;
}
}
@@ -1355,7 +1171,7 @@ int main(int argc, char *argv[])
memset(&cb_data, 0, sizeof(struct dir_cb_data));
cb_data.dirname = profilename;
cb_data.policy_cache = policy_cache;
cb_data.cachedir = cacheloc;
cb_data.kernel_interface = kernel_interface;
cb = binary_input ? binary_dir_cb : profile_dir_cb;
if ((retval = dirat_for_each(AT_FDCWD, profilename,
@@ -1369,7 +1185,7 @@ int main(int argc, char *argv[])
handle_work_result);
} else {
work_spawn(process_profile(option, kernel_interface,
profilename, policy_cache),
profilename, cacheloc),
handle_work_result);
}

View File

@@ -25,9 +25,6 @@
#include "immunix.h"
#include "parser.h"
typedef int (*comparison_fn_t)(const void *, const void *);
typedef void (*__free_fn_t)(void *);
enum var_type {
sd_boolean,
sd_set,

View File

@@ -6,24 +6,24 @@ msgstr ""
"Project-Id-Version: apparmor-parser\n"
"Report-Msgid-Bugs-To: <apparmor@lists.ubuntu.com>\n"
"POT-Creation-Date: 2014-09-13 00:11-0700\n"
"PO-Revision-Date: 2018-04-06 14:39+0000\n"
"PO-Revision-Date: 2015-09-05 20:55+0000\n"
"Last-Translator: Tobias Bannert <tobannert@gmail.com>\n"
"Language-Team: Novell Language <language@novell.com>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2018-04-07 05:20+0000\n"
"X-Generator: Launchpad (build 18599)\n"
"X-Launchpad-Export-Date: 2016-06-01 05:15+0000\n"
"X-Generator: Launchpad (build 18053)\n"
"Language: de\n"
#: ../parser_include.c:113 ../parser_include.c:111
#: ../parser_include.c:113
msgid "Error: Out of memory.\n"
msgstr "Fehler: nicht genügend Speicher!\n"
msgstr "Fehler: Kein Speicher vorhanden.\n"
#: ../parser_include.c:123 ../parser_include.c:121
#: ../parser_include.c:123
#, c-format
msgid "Error: basedir %s is not a directory, skipping.\n"
msgstr "Fehler: basedir »%s« ist kein Verzeichnis, es wird übersprungen.\n"
msgstr "Fehler: basedir »%s« ist kein Verzeichnis - es wird übersprungen.\n"
#: ../parser_include.c:137
#, c-format
@@ -31,108 +31,99 @@ msgid "Error: Could not add directory %s to search path.\n"
msgstr ""
"Fehler: Verzeichnis »%s« konnte nicht zu Suchpfad hinzugefügt werden.\n"
#: ../parser_include.c:147 ../parser_include.c:151
#: ../parser_include.c:147
msgid "Error: Could not allocate memory.\n"
msgstr "Fehler: Es konnte kein Speicher zugeordnet werden.\n"
#: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49
#: ../parser_interface.c:69 ../parser_interface.c:72
msgid "Bad write position\n"
msgstr "Ungültige Schreibposition\n"
#: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52
#: ../parser_interface.c:72 ../parser_interface.c:75
msgid "Permission denied\n"
msgstr "Zugriff verweigert\n"
#: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55
#: ../parser_interface.c:75 ../parser_interface.c:78
msgid "Out of memory\n"
msgstr "Nicht genügend Speicher!\n"
msgstr "Kein Speicher vorhanden\n"
#: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58
#: ../parser_interface.c:78 ../parser_interface.c:81
msgid "Couldn't copy profile: Bad memory address\n"
msgstr "Profil konnte nicht kopiert werden: falsche Speicheradresse\n"
msgstr "Profil konnte nicht kopiert werden: Keine Speicheradresse\n"
#: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61
#: ../parser_interface.c:81 ../parser_interface.c:84
msgid "Profile doesn't conform to protocol\n"
msgstr "Das Profil entspricht nicht dem Protokoll\n"
#: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64
#: ../parser_interface.c:84 ../parser_interface.c:87
msgid "Profile does not match signature\n"
msgstr "Das Profil stimmt nicht mit der Signatur überein\n"
#: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67
#: ../parser_interface.c:87 ../parser_interface.c:90
msgid "Profile version not supported by Apparmor module\n"
msgstr "Profilversion wird vom Apparmor-Modul nicht unterstützt\n"
#: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70
#: ../parser_interface.c:90 ../parser_interface.c:93
msgid "Profile already exists\n"
msgstr "Profil ist bereits vorhanden\n"
#: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73
#: ../parser_interface.c:93 ../parser_interface.c:96
msgid "Profile doesn't exist\n"
msgstr "Profil ist nicht vorhanden\n"
#: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76
#: ../parser_interface.c:96 ../parser_interface.c:99
msgid "Permission denied; attempted to load a profile while confined?\n"
msgstr ""
"Zugriff verweigert! Haben Sie versucht ein Profil zu laden, während Sie "
"eingeschränkt waren?\n"
#: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79
#: ../parser_interface.c:99 ../parser_interface.c:102
#, c-format
msgid "Unknown error (%d): %s\n"
msgstr "Unbekannter Fehler (%d): %s\n"
#: ../parser_interface.c:116 ../parser_interface.c:119
#: ../parser_interface.c:96
#, c-format
msgid "%s: Unable to add \"%s\". "
msgstr "%s: Hinzufügen von »%s« nicht möglich. "
#: ../parser_interface.c:121 ../parser_interface.c:124
#: ../parser_interface.c:101
#, c-format
msgid "%s: Unable to replace \"%s\". "
msgstr "%s: »%s« kann nicht ersetzt werden. "
#: ../parser_interface.c:126 ../parser_interface.c:129
#: ../parser_interface.c:106
#, c-format
msgid "%s: Unable to remove \"%s\". "
msgstr "%s: »%s« kann nicht entfernt werden. "
#: ../parser_interface.c:131 ../parser_interface.c:134
#: ../parser_interface.c:111
#, c-format
msgid "%s: Unable to write to stdout\n"
msgstr "%s: Schreiben in Standardausgabe nicht möglich\n"
#: ../parser_interface.c:135 ../parser_interface.c:138
#: ../parser_interface.c:115
#, c-format
msgid "%s: Unable to write to output file\n"
msgstr "%s: Schreiben in Ausgabedatei nicht möglich\n"
#: ../parser_interface.c:138 ../parser_interface.c:162
#: ../parser_interface.c:141 ../parser_interface.c:165
#: ../parser_interface.c:118 ../parser_interface.c:142
#, c-format
msgid "%s: ASSERT: Invalid option: %d\n"
msgstr "%s: ASSERT: Ungültige Option: %d\n"
#: ../parser_interface.c:147 ../parser_interface.c:150
#: ../parser_interface.c:127
#, c-format
msgid "Addition succeeded for \"%s\".\n"
msgstr "Hinzufügen für »%s« erfolgreich.\n"
#: ../parser_interface.c:151 ../parser_interface.c:154
#: ../parser_interface.c:131
#, c-format
msgid "Replacement succeeded for \"%s\".\n"
msgstr "Ersetzungsvorgang für »%s« erfolgreich.\n"
#: ../parser_interface.c:155 ../parser_interface.c:158
#: ../parser_interface.c:135
#, c-format
msgid "Removal succeeded for \"%s\".\n"
msgstr "Entfernen für »%s« erfolgreich.\n"
@@ -145,7 +136,6 @@ msgstr ""
"Auflösung %p\n"
#: ../parser_interface.c:656 ../parser_interface.c:658
#: ../parser_interface.c:446
#, c-format
msgid "profile %s network rules not enforced\n"
msgstr "Netzwerkregeln für Profil %s werden nicht erzwungen\n"
@@ -156,19 +146,16 @@ msgstr "Unbekannter Mustertyp\n"
#: ../parser_interface.c:750 ../parser_interface.c:902
#: ../parser_interface.c:743 ../parser_interface.c:894
#: ../parser_interface.c:518 ../parser_interface.c:669
#, c-format
msgid "Unable to open %s - %s\n"
msgstr "%s kann nicht geöffnet werden %s\n"
msgstr "%s kann nicht geöffnet werden - %s\n"
#: ../parser_interface.c:776 ../parser_interface.c:768
#: ../parser_interface.c:543
#, c-format
msgid "Memory Allocation Error: Unable to remove ^%s\n"
msgstr "Speicherzuordnungsfehler: ^%s kann nicht entfernt werden\n"
#: ../parser_interface.c:789 ../parser_interface.c:781
#: ../parser_interface.c:556
#, c-format
msgid "Memory Allocation Error: Unable to remove %s:%s."
msgstr "Speicherzuordnungsfehler: %s:%s kann nicht entfernt werden."
@@ -184,24 +171,22 @@ msgstr "Serialisierung von Profil %s nicht möglich\n"
#: ../parser_interface.c:829 ../parser_interface.c:916
#: ../parser_interface.c:821 ../parser_interface.c:908
#: ../parser_interface.c:582
#, c-format
msgid "%s: Unable to write entire profile entry\n"
msgstr "%s: Profileintrag kann nicht geschrieben werden\n"
#: ../parser_interface.c:839 ../parser_interface.c:831
#: ../parser_interface.c:593
#, c-format
msgid "%s: Unable to write entire profile entry to cache\n"
msgstr ""
"%s: Schreiben des gesamten Profileintrags in den Puffer nicht möglich\n"
#: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169
#: parser_lex.l:100 parser_lex.l:163
#, c-format
msgid "Could not open '%s'"
msgstr "»%s« konnte nicht geöffnet werden"
#: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173
#: parser_lex.l:104 parser_lex.l:167
#, c-format
msgid "fstat failed for '%s'"
msgstr "fstat fehlgeschlagen für »%s«"
@@ -216,18 +201,18 @@ msgstr "opendir fehlgeschlagen für »%s«"
msgid "stat failed for '%s'"
msgstr "stat fehlgeschlagen für »%s«"
#: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139
#: parser_lex.l:155 parser_lex.l:133
#, c-format
msgid "Could not open '%s' in '%s'"
msgstr "»%s« konnte nicht in »%s« geöffnet werden"
#: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399
#: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638
#: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586
#, c-format
msgid "Found unexpected character: '%s'"
msgstr "Unerwartetes Zeichen gefunden: »%s«"
#: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428
#: parser_lex.l:386 parser_lex.l:418
msgid "Variable declarations do not accept trailing commas"
msgstr "Variablendeklarationen dürfen nicht mit Kommata enden"
@@ -236,7 +221,7 @@ msgstr "Variablendeklarationen dürfen nicht mit Kommata enden"
msgid "(network_mode) Found unexpected character: '%s'"
msgstr "(network_mode) Unerwartetes Zeichen gefunden: »%s«"
#: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106
#: ../parser_main.c:333 ../parser_common.c:61
#, c-format
msgid "Warning from %s (%s%sline %d): %s"
msgstr "Warnung aus %s (%s%sZeile %d): %s"
@@ -248,7 +233,7 @@ msgstr ""
"%s: Dem Einhängepunkt der Unterdomänenbasis konnte kein Speicher zugeordnet "
"werden\n"
#: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479
#: ../parser_main.c:577 ../parser_main.c:616
#, c-format
msgid ""
"Warning: unable to find a suitable fs in %s, is it mounted?\n"
@@ -258,7 +243,7 @@ msgstr ""
"es eingehängt?\n"
"Verwenden Sie --subdomainfs, um es außer Kraft zu setzen.\n"
#: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498
#: ../parser_main.c:597 ../parser_main.c:635
#, c-format
msgid ""
"%s: Sorry. You need root privileges to run this program.\n"
@@ -267,7 +252,7 @@ msgstr ""
"»%s«: Sie benötigen Systemverwalterrechte zum Ausführen dieses Programms.\n"
"\n"
#: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505
#: ../parser_main.c:604 ../parser_main.c:642
#, c-format
msgid ""
"%s: Warning! You've set this program setuid root.\n"
@@ -280,7 +265,7 @@ msgstr ""
"\n"
#: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836
#: ../parser_main.c:946 ../parser_main.c:860
#: ../parser_main.c:946
#, c-format
msgid "Error: Could not read profile %s: %s.\n"
msgstr "Fehler: Profil »%s« konnte nicht gelesen werden: »%s«.\n"
@@ -296,33 +281,26 @@ msgstr "Fehler: Profil »%s« konnte nicht gelesen werden: »%s«.\n"
#: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092
#: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234
#: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385
#: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133
#: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472
#: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130
#: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190
#: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490
#: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639
#: ../network.c:314 ../af_unix.cc:203
msgid "Memory allocation error."
msgstr "Speicherzuordnungsfehler."
#: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757
#: ../parser_main.c:740 ../parser_main.c:872
#, c-format
msgid "Cached load succeeded for \"%s\".\n"
msgstr "Zwischengespeichertes Laden für »%s« erfolgreich.\n"
#: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761
#: ../parser_main.c:744 ../parser_main.c:876
#, c-format
msgid "Cached reload succeeded for \"%s\".\n"
msgstr "Zwischengespeichertes Neuladen für »%s« erfolgreich.\n"
#: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967
#: ../parser_main.c:910 ../parser_main.c:1058
#, c-format
msgid "%s: Errors found in file. Aborting.\n"
msgstr ""
"%s: In der Datei wurde ein Fehler gefunden. Der Vorgang wird abgebrochen.\n"
#: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339
#: ../parser_misc.c:426 ../parser_misc.c:597
msgid ""
"Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n"
"See the apparmor.d(5) manpage for details.\n"
@@ -332,17 +310,17 @@ msgstr ""
"Weitere Informationen auf der Handbuchseite apparmor.d(5).\n"
#: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638
#: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387
#: ../parser_misc.c:645
msgid "Conflict 'a' and 'w' perms are mutually exclusive."
msgstr "Die Parameter »a« und »w« schließen sich gegenseitig aus."
#: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404
#: ../parser_misc.c:491 ../parser_misc.c:662
msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified"
msgstr ""
"Ausführungskennzeichner »i« ist ungültig, ein Kennzeichner, mit dem ein "
"Konflikt besteht, wurde bereits angegeben."
#: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415
#: ../parser_misc.c:502 ../parser_misc.c:673
#, c-format
msgid ""
"Unconfined exec qualifier (%c%c) allows some dangerous environment variables "
@@ -353,7 +331,7 @@ msgstr ""
"Einzelheiten mit »man 5 apparmor.d«.\n"
#: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681
#: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464
#: ../parser_misc.c:722
#, c-format
msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified"
msgstr ""
@@ -361,7 +339,7 @@ msgstr ""
"Konflikt besteht, wurde bereits angegeben."
#: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708
#: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458
#: ../parser_misc.c:716
#, c-format
msgid ""
"Exec qualifier '%c%c' invalid, conflicting qualifier already specified"
@@ -369,12 +347,12 @@ msgstr ""
"Ausführungskennzeichner »%c%c« ist ungültig, ein Kennzeichner, mit dem ein "
"Konflikt besteht, wurde bereits angegeben."
#: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506
#: ../parser_misc.c:593 ../parser_misc.c:764
#, c-format
msgid "Internal: unexpected mode character '%c' in input"
msgstr "Intern: Unerwartetes Moduszeichen »%c« in der Eingabe"
#: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528
#: ../parser_misc.c:615 ../parser_misc.c:786
#, c-format
msgid "Internal error generated invalid perm 0x%llx\n"
msgstr "Interner Fehler erzeugte ungültige Zugriffsrechte 0x%llx\n"
@@ -385,69 +363,68 @@ msgstr "Interner Fehler erzeugte ungültige Zugriffsrechte 0x%llx\n"
msgid "AppArmor parser error: %s\n"
msgstr "AppArmor-Analysefehler: %s\n"
#: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83
#: ../parser_merge.c:92 ../parser_merge.c:91
msgid "Couldn't merge entries. Out of Memory\n"
msgstr ""
"Einträge konnten nicht zusammengeführt werden. Kein Speicher vorhanden\n"
#: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105
#: ../parser_merge.c:111 ../parser_merge.c:113
#, c-format
msgid "profile %s: has merged rule %s with conflicting x modifiers\n"
msgstr ""
"Profil %s: enthält zusammengeführte Regel %s mit in Konflikt stehenden x-"
"Modifizierern\n"
#: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320
#: parser_yacc.y:236 parser_yacc.y:277
msgid "Profile attachment must begin with a '/'."
msgstr "Profilanhang muss mit einem »/« beginnen."
#: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348
#: parser_yacc.y:260 parser_yacc.y:302
msgid ""
"Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'."
msgstr ""
"Profilnamen müssen mit einem »/«, Namensraum oder dem Schlüsselwort "
"»profile« oder »hat« beginnen."
#: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384
#: parser_yacc.y:296 parser_yacc.y:338
#, c-format
msgid "Failed to create alias %s -> %s\n"
msgstr "Alias %s → %s konnte nicht erstellt werden\n"
#: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506
#: parser_yacc.y:417 parser_yacc.y:460
msgid "Profile flag chroot_relative conflicts with namespace_relative"
msgstr ""
"Profil-Marker chroot_relative steht in Konflikt mit namespace_relative"
#: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510
#: parser_yacc.y:421 parser_yacc.y:464
msgid "Profile flag mediate_deleted conflicts with delegate_deleted"
msgstr "Profil-Marker mediate_deleted steht in Konflikt mit delegate_deleted"
#: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513
#: parser_yacc.y:424 parser_yacc.y:467
msgid ""
"Profile flag attach_disconnected conflicts with no_attach_disconnected"
msgstr ""
"Profil-Marker attach_disconnected steht in Konflikt mit "
"no_attach_disconnected"
#: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516
#: parser_yacc.y:427 parser_yacc.y:470
msgid "Profile flag chroot_attach conflicts with chroot_no_attach"
msgstr "Profil-Marker chroot_attach steht in Konflikt mit chroot_no_attach"
#: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530
#: parser_yacc.y:441 parser_yacc.y:484
msgid "Profile flag 'debug' is no longer valid."
msgstr "Profil-Marker »debug« ist nicht mehr gültig."
#: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552
#: parser_yacc.y:463 parser_yacc.y:506
#, c-format
msgid "Invalid profile flag: %s."
msgstr "Ungültiger Profil-Marker: %s."
#: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594
#: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548
msgid "Assert: `rule' returned NULL."
msgstr "Assert: Für »rule« wurde NULL zurückgegeben."
#: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584
#: parser_yacc.y:598 parser_yacc.y:630
msgid ""
"Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', "
"'p', or 'u'"
@@ -455,81 +432,80 @@ msgstr ""
"Ungültiger Modus, in den Verweigernregeln darf vor »x« keiner der "
"Ausführungskennzeichner »i«, »p« oder »u« stehen"
#: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602
#: parser_yacc.y:524 parser_yacc.y:556
msgid ""
"Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'"
msgstr ""
"Ungültiger Modus, in Verbotsregeln muss vor »x« einer der exec-Qualifier "
"»i«, »p«, »c« oder »u« stehen"
#: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633
#: parser_yacc.y:549 parser_yacc.y:587
msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'"
msgstr ""
"Ungültiger Modus, in Verbotsregeln muss vor »x« einer der exec-Qualifier "
"»i«, »p« oder »u« stehen"
#: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660
#: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614
msgid "Assert: `network_rule' return invalid protocol."
msgstr "Assert: Für »network_rule« wurde NULL zurückgegeben."
#: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786
#: parser_yacc.y:649 parser_yacc.y:696
msgid "Assert: `change_profile' returned NULL."
msgstr "Assert: Für »change_profile« wurde NULL zurückgegeben."
#: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810
#: parser_yacc.y:680 parser_yacc.y:720
msgid "Assert: 'hat rule' returned NULL."
msgstr "Assert: Für »hat rule« wurde NULL zurückgegeben."
#: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819
#: parser_yacc.y:689 parser_yacc.y:729
msgid "Assert: 'local_profile rule' returned NULL."
msgstr "Assert: Für »local_profile rule« wurde NULL zurückgegeben."
#: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992
#: parser_yacc.y:824 parser_yacc.y:885
#, c-format
msgid "Unset boolean variable %s used in if-expression"
msgstr "In Bedingungssatz verwendete Boolsche-Variable »%s« deaktivieren"
#: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092
#: parser_yacc.y:882 parser_yacc.y:986
msgid "unsafe rule missing exec permissions"
msgstr "Fehlende Ausführungsrechte bei unsicherer Regel"
#: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060
#: parser_yacc.y:901 parser_yacc.y:954
msgid "subset can only be used with link rules."
msgstr "subset kann nur mit Link-Regeln verwendet werden."
#: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062
#: parser_yacc.y:903 parser_yacc.y:956
msgid "link and exec perms conflict on a file rule using ->"
msgstr ""
"Verknüpfungs- und Ausführungsberechtigungen stehen in Konflikt mit einer "
"Dateiregel, in der »->« verwendet wird"
#: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064
#: parser_yacc.y:905 parser_yacc.y:958
msgid "link perms are not allowed on a named profile transition.\n"
msgstr ""
"Verknüpfungsberechtigungen sind bei einem benannten Profilübergang nicht "
"erlaubt.\n"
#: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109
#: parser_yacc.y:921 parser_yacc.y:1003
#, c-format
msgid "missing an end of line character? (entry: %s)"
msgstr "Fehlt ein Zeilenumbruch? (Eintrag: %s)"
#: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067
#: parser_yacc.y:1145 parser_yacc.y:1155
msgid "Invalid network entry."
msgstr "Ungültiger Netzwerkeintrag."
#: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510
#: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254
#, c-format
msgid "Invalid capability %s."
msgstr "Ungültige Fähigkeit %s."
#: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525
#: parser_yacc.y:1066 parser_yacc.y:1269
#, c-format
msgid "AppArmor parser error for %s%s%s at line %d: %s\n"
msgstr "AppArmor-Analysefehler für %s%s%s in Zeile %d: %s\n"
#: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531
#: parser_yacc.y:1072 parser_yacc.y:1275
#, c-format
msgid "AppArmor parser error,%s%s line %d: %s\n"
msgstr "AppArmor-Analysefehler,%s%s Zeile %d: %s\n"
@@ -540,13 +516,13 @@ msgid "%s: Illegal open {, nesting groupings not allowed\n"
msgstr ""
"%s: Öffnen mit { ungültig, verschachtelte Gruppierungen sind nicht zulässig\n"
#: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278
#: ../parser_regex.c:265 ../parser_regex.c:274
#, c-format
msgid "%s: Regex grouping error: Invalid number of items between {}\n"
msgstr ""
"%s: Regex-Gruppierungsfehler: Ungültige Anzahl an Einträgen zwischen {}\n"
#: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284
#: ../parser_regex.c:271 ../parser_regex.c:280
#, c-format
msgid ""
"%s: Regex grouping error: Invalid close }, no matching open { detected\n"
@@ -554,7 +530,7 @@ msgstr ""
"%s: Regex-Gruppierungsfehler: Ungültiges schließendes Zeichen }, kein "
"passendes öffnendes Zeichen { gefunden\n"
#: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361
#: ../parser_regex.c:337 ../parser_regex.c:343
#, c-format
msgid ""
"%s: Regex grouping error: Unclosed grouping or character class, expecting "
@@ -568,17 +544,17 @@ msgstr ""
msgid "%s: Internal buffer overflow detected, %d characters exceeded\n"
msgstr "%s: Interner Pufferüberlauf erkannt, %d Zeichen überschritten\n"
#: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377
#: ../parser_regex.c:355 ../parser_regex.c:361
#, c-format
msgid "%s: Unable to parse input line '%s'\n"
msgstr "%s: Eingabezeile »%s« kann nicht analysiert werden\n"
#: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421
#: ../parser_regex.c:397 ../parser_regex.c:405
#, c-format
msgid "%s: Invalid profile name '%s' - bad regular expression\n"
msgstr "%s: Ungültiger Profilname »%s« Fehlerhafter regulärer Ausdruck\n"
#: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375
#: ../parser_policy.c:202 ../parser_policy.c:402
#, c-format
msgid "ERROR merging rules for profile %s, failed to load\n"
msgstr "FEHLER Vereinigungsregeln für Profil »%s«, Laden gescheitert\n"
@@ -596,18 +572,18 @@ msgstr ""
"erlaubt.\n"
"\t»**« kann am Ende einer Regel verwendet werden.\n"
#: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332
#: ../parser_policy.c:279 ../parser_policy.c:359
#, c-format
msgid "ERROR processing regexs for profile %s, failed to load\n"
msgstr "FEHLER Verarbeitung der Regexs für Profil »%s«, Laden gescheitert\n"
#: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362
#: ../parser_policy.c:306 ../parser_policy.c:389
#, c-format
msgid "ERROR expanding variables for profile %s, failed to load\n"
msgstr ""
"FEHLER beim Erweitern der Variablen für Profil »%s«, Laden gescheitert\n"
#: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355
#: ../parser_policy.c:390 ../parser_policy.c:382
#, c-format
msgid "ERROR adding hat access rule for profile %s\n"
msgstr "FEHLER Hinzufügen von »hat«-Zugriffsregel für Profil %s\n"
@@ -641,32 +617,31 @@ msgstr ""
"%s: Beim Kombinieren von Regeln in der Nachverarbeitung sind Fehler "
"aufgetreten. Der Vorgang wird abgebrochen.\n"
#: parser_lex.l:180 parser_lex.l:186
#: parser_lex.l:180
#, c-format
msgid "Could not process include directory '%s' in '%s'"
msgstr ""
"Das enthaltene Verzeichnis »%s« in »%s« kann nicht verarbeitet werden"
#: ../parser_main.c:660 ../parser_main.c:523
#: ../parser_main.c:660
msgid "Feature buffer full."
msgstr "Funktionspuffer ist voll."
#: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024
#: ../parser_main.c:1041
#: ../parser_main.c:1115 ../parser_main.c:1132
msgid "Out of memory"
msgstr "Nicht genügend Speicher!"
msgstr "Nicht genug Speicher"
#: ../parser_main.c:1182 ../parser_main.c:1091
#: ../parser_main.c:1182
#, c-format
msgid "Can't create cache directory: %s\n"
msgstr "Pufferverzeichnis kann nicht erstellt werden: %s\n"
#: ../parser_main.c:1185 ../parser_main.c:1094
#: ../parser_main.c:1185
#, c-format
msgid "File in cache directory location: %s\n"
msgstr "Datei im Pufferverzeichnisort: %s\n"
#: ../parser_main.c:1188 ../parser_main.c:1097
#: ../parser_main.c:1188
#, c-format
msgid "Can't update cache directory: %s\n"
msgstr "Pufferverzeichnis kann nicht aktualisiert werden: %s\n"
@@ -681,11 +656,11 @@ msgstr "Intern: Unerwartetes D-Bus-Moduszeichen »%c« in der Eingabe"
msgid "Internal error generated invalid DBus perm 0x%x\n"
msgstr "Interner Fehler hat ungültige D-Bus-Zugriffsrechte 0x%x erstellt\n"
#: parser_yacc.y:575 parser_yacc.y:621
#: parser_yacc.y:575
msgid "deny prefix not allowed"
msgstr "Verweigernpräfix nicht erlaubt"
#: parser_yacc.y:612 parser_yacc.y:658
#: parser_yacc.y:612
msgid "owner prefix not allowed"
msgstr "Eigentümerpräfix nicht erlaubt"
@@ -701,25 +676,25 @@ msgstr "Eigentümerpräfix nicht bei D-Bus-Regeln erlauben"
msgid "owner prefix not allow on capability rules"
msgstr "Eigentümerpräfix nicht bei Fähigkeitsregeln erlauben"
#: parser_yacc.y:1357 parser_yacc.y:1613
#: parser_yacc.y:1357
#, c-format
msgid "invalid mount conditional %s%s"
msgstr "Ungültige Einhängebedingung %s%s"
#: parser_yacc.y:1374 parser_yacc.y:1628
#: parser_yacc.y:1374
msgid "bad mount rule"
msgstr "Ungültige Einhängeregel"
#: parser_yacc.y:1381 parser_yacc.y:1635
#: parser_yacc.y:1381
msgid "mount point conditions not currently supported"
msgstr "Einhängepunktbedingungen werden derzeit nicht unterstützt"
#: parser_yacc.y:1398 parser_yacc.y:1650
#: parser_yacc.y:1398
#, c-format
msgid "invalid pivotroot conditional '%s'"
msgstr "Ungültige pivotroot-Bedingung »%s«"
#: ../parser_regex.c:241 ../parser_regex.c:236
#: ../parser_regex.c:241
#, c-format
msgid ""
"%s: Regex grouping error: Invalid close ], no matching open [ detected\n"
@@ -727,20 +702,20 @@ msgstr ""
"%s: Regex-Gruppierungsfehler: Ungültiges schließendes Zeichen ], kein "
"passendes öffnendes Zeichen [ gefunden\n"
#: ../parser_regex.c:257 ../parser_regex.c:256
#: ../parser_regex.c:257
#, c-format
msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n"
msgstr ""
"%s: Regex-Gruppierungsfehler: maximale Verschachtelung von {} überschritten\n"
#: ../parser_policy.c:366 ../parser_policy.c:339
#: ../parser_policy.c:366
#, c-format
msgid "ERROR processing policydb rules for profile %s, failed to load\n"
msgstr ""
"FEHLER beim Verarbeiten der policydb-Regeln für das Profil %s. Das Laden ist "
"fehlgeschlagen.\n"
#: ../parser_policy.c:396 ../parser_policy.c:369
#: ../parser_policy.c:396
#, c-format
msgid "ERROR replacing aliases for profile %s, failed to load\n"
msgstr ""

View File

@@ -95,15 +95,13 @@ void update_mru_tstamp(FILE *file, const char *name)
}
}
char *cache_filename(aa_policy_cache *pc, int dir, const char *basename)
char *cache_filename(const char *cachedir, const char *basename)
{
char *cachename;
autofree char *path;
path = aa_policy_cache_dir_path(pc, dir);
if (!path || asprintf(&cachename, "%s/%s", path, basename) < 0) {
if (asprintf(&cachename, "%s/%s", cachedir, basename) < 0) {
PERROR("Memory allocation error.");
return NULL;
exit(1);
}
return cachename;

View File

@@ -41,7 +41,7 @@ extern int debug_cache;
void set_cache_tstamp(struct timespec t);
void update_mru_tstamp(FILE *file, const char *path);
bool valid_cached_file_version(const char *cachename);
char *cache_filename(aa_policy_cache *pc, int dir, const char *basename);
char *cache_filename(const char *cachedir, const char *basename);
void valid_read_cache(const char *cachename);
int cache_hit(const char *cachename);
int setup_cache_tmp(const char **cachetmpname, const char *cachename);

View File

@@ -117,19 +117,13 @@ skip_profile() {
"${profile%\~}" != "${profile}" ] ; then
return 1
fi
# Silently ignore the dpkg, pacman, and xbps files
# Silently ignore the dpkg files
if [ "${profile%.dpkg-new}" != "${profile}" -o \
"${profile%.dpkg-old}" != "${profile}" -o \
"${profile%.dpkg-dist}" != "${profile}" -o \
"${profile%.dpkg-bak}" != "${profile}" -o \
"${profile%.dpkg-remove}" != "${profile}" -o \
"${profile%.pacsave}" != "${profile}" -o \
"${profile%.pacnew}" != "${profile}" ] ; then
"${profile%.dpkg-bak}" != "${profile}" ] ; then
return 2
fi
if echo "${profile}" | egrep -q '^.+\.new-[0-9\.]+_[0-9]+$'; then
return 2 ;;
fi
return 0
}

149
parser/rc.apparmor.suse Normal file
View File

@@ -0,0 +1,149 @@
#!/bin/sh
# ----------------------------------------------------------------------
# Copyright (c) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
# NOVELL (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.
# ----------------------------------------------------------------------
# rc.apparmor by Steve Beattie
#
# /etc/init.d/boot.apparmor
# and its symbolic link
# /sbin/rcapparmor
#
# chkconfig: 2345 01 99
# description: AppArmor rc file. This rc script inserts the apparmor \
# module and runs the parser on the /etc/apparmor.d/ \
# directory.
#
### BEGIN INIT INFO
# Provides: apparmor
# Required-Start: boot.cleanup
# Required-Stop: $null
# Should-Start: $local_fs
# Should-Stop: $null
# Default-Start: B
# Default-Stop:
# Short-Description: AppArmor initialization
# Description: AppArmor rc file. This rc script inserts the apparmor
# module and runs the parser on the /etc/apparmor.d/
# directory.
### END INIT INFO
APPARMOR_FUNCTIONS=/lib/apparmor/rc.apparmor.functions
# source function library
if [ -f /etc/init.d/functions ]; then
. /etc/init.d/functions
elif [ -f /etc/rc.d/init.d/functions ]; then
. /etc/rc.d/init.d/functions
elif [ -f /lib/lsb/init-functions ]; then
. /lib/lsb/init-functions
else
exit 0
fi
# Ugh, SUSE doesn't implement action
aa_action() { STRING=$1
shift
"$@"
rc=$?
if [ $rc -eq 0 ] ; then
log_success_msg $"$STRING "
else
log_failure_msg $"$STRING "
fi
return $rc
}
aa_log_success_msg() {
log_success_msg $*
}
aa_log_warning_msg() {
log_warning_msg $*
}
aa_log_failure_msg() {
log_failure_msg '\n'$*
}
aa_log_action_start() {
echo -n
}
aa_log_action_end() {
echo -n
}
aa_log_daemon_msg() {
echo -en "$@ "
}
aa_log_skipped_msg() {
echo -en "$@"
echo -e "$rc_skipped"
}
_set_status() {
return $1
}
aa_log_end_msg() {
_set_status $1
rc_status -v
}
usage() {
echo "Usage: $0 {start|stop|restart|try-restart|reload|force-reload|status|kill}"
}
# source apparmor function library
if [ -f "${APPARMOR_FUNCTIONS}" ]; then
. ${APPARMOR_FUNCTIONS}
else
aa_log_failure_msg "Unable to find AppArmor initscript functions"
exit 1
fi
case "$1" in
start)
apparmor_start
rc=$?
;;
stop)
apparmor_stop
rc=$?
;;
restart|reload|force-reload)
apparmor_restart
rc=$?
;;
try-restart)
apparmor_try_restart
rc=$?
;;
kill)
apparmor_kill
rc=$?
;;
status)
apparmor_status
rc=$?
;;
*)
usage
exit 1
;;
esac
exit $rc

View File

@@ -4,8 +4,6 @@ TESTS=simple.pl
PARSER_DIR=..
PARSER_BIN=apparmor_parser
PARSER=$(PARSER_DIR)/$(PARSER_BIN)
# parser.conf to use in tests. Note that some test scripts have the parser options hardcoded, so passing PARSER_ARGS=... is not enough to override it.
PARSER_ARGS=--config-file=./parser.conf
PROVE_ARG=-f
ifeq ($(VERBOSE),1)
@@ -32,14 +30,14 @@ gen_dbus: $(GEN_TRANS_DIRS)
./gen-dbus.pl
error_output: $(PARSER)
LANG=C $(PARSER) $(PARSER_ARGS) -S -I errors >/dev/null errors/okay.sd
LANG=C $(PARSER) $(PARSER_ARGS) -S -I errors 2>&1 >/dev/null errors/single.sd | \
LANG=C $(PARSER) -S -I errors >/dev/null errors/okay.sd
LANG=C $(PARSER) -S -I errors 2>&1 >/dev/null errors/single.sd | \
grep -q "AppArmor parser error for errors/single.sd in errors/single.sd at line 3: Could not open 'failure'"
LANG=C $(PARSER) $(PARSER_ARGS) -S -I errors 2>&1 >/dev/null errors/double.sd | \
LANG=C $(PARSER) -S -I errors 2>&1 >/dev/null errors/double.sd | \
grep -q "AppArmor parser error for errors/double.sd in errors/includes/busted at line 66: Could not open 'does-not-exist'"
LANG=C $(PARSER) $(PARSER_ARGS) -S -I errors 2>&1 >/dev/null errors/modefail.sd | \
LANG=C $(PARSER) -S -I errors 2>&1 >/dev/null errors/modefail.sd | \
grep -q "AppArmor parser error for errors/modefail.sd in errors/modefail.sd at line 6: syntax error"
LANG=C $(PARSER) $(PARSER_ARGS) -S -I errors 2>&1 >/dev/null errors/multi_include.sd | \
LANG=C $(PARSER) -S -I errors 2>&1 >/dev/null errors/multi_include.sd | \
grep -q "AppArmor parser error for errors/multi_include.sd in errors/multi_include.sd at line 12: Could not open 'failure'"
@echo "Error Output: PASS"
@@ -50,13 +48,13 @@ caching: $(PARSER)
LANG=C ./caching.py -p "$(PARSER)" $(PYTEST_ARG)
minimize: $(PARSER)
LANG=C APPARMOR_PARSER="$(PARSER) $(PARSER_ARGS)" ./minimize.sh
LANG=C APPARMOR_PARSER="$(PARSER)" ./minimize.sh
equality: $(PARSER)
LANG=C APPARMOR_PARSER="$(PARSER) $(PARSER_ARGS)" ./equality.sh
LANG=C APPARMOR_PARSER="$(PARSER)" ./equality.sh
valgrind: $(PARSER) gen_xtrans gen_dbus
LANG=C ./valgrind_simple.py -p "$(PARSER) $(PARSER_ARGS)" -v simple_tests
LANG=C ./valgrind_simple.py -p "$(PARSER)" -v simple_tests
$(PARSER):
$(MAKE) -C $(PARSER_DIR) $(PARSER_BIN)

View File

@@ -60,6 +60,13 @@ class AAParserCachingCommon(testlib.AATestTemplate):
self.tmp_dir = tempfile.mkdtemp(prefix='aa-caching-')
os.chmod(self.tmp_dir, 0o755)
# create directory for cached blobs
self.cache_dir = os.path.join(self.tmp_dir, 'cache')
os.mkdir(self.cache_dir)
# default path of the output cache file
self.cache_file = os.path.join(self.cache_dir, PROFILE)
# write our sample abstraction and profile out
self.abstraction = testlib.write_file(self.tmp_dir, ABSTRACTION, ABSTRACTION_CONTENTS)
self.profile = testlib.write_file(self.tmp_dir, PROFILE, PROFILE_CONTENTS)
@@ -68,26 +75,11 @@ class AAParserCachingCommon(testlib.AATestTemplate):
self.do_cleanup = False
self.debug = True
# Warnings break the test harness, but chroots may not be setup
# to have the config file, etc.
self.cmd_prefix = [config.parser, '--config-file=./parser.conf', '--base', self.tmp_dir, '--skip-kernel-load']
self.cmd_prefix = [config.parser, '--base', self.tmp_dir, '--skip-kernel-load']
if not self.is_apparmorfs_mounted():
self.cmd_prefix += ['-M', './features_files/features.all']
# Otherwise get_cache_dir() will try to create /var/cache/apparmor
# and will fail when the test suite is run as non-root.
self.cmd_prefix += [
'--cache-loc', os.path.join(self.tmp_dir, 'cache')
]
# create directory for cached blobs
# NOTE: get_cache_dir() requires cmd_prefix to be fully initialized
self.cache_dir = self.get_cache_dir(create=True)
# default path of the output cache file
self.cache_file = os.path.join(self.cache_dir, PROFILE)
def tearDown(self):
'''teardown for each test'''
@@ -97,22 +89,6 @@ class AAParserCachingCommon(testlib.AATestTemplate):
if os.path.exists(self.tmp_dir):
shutil.rmtree(self.tmp_dir)
def get_cache_dir(self, create=False):
cmd = [config.parser, '--print-cache-dir'] + self.cmd_prefix
rc, report = self.run_cmd(cmd)
if rc != 0:
if "unrecognized option '--print-cache-dir'" not in report:
self.fail('Unknown apparmor_parser error:\n%s' % report)
cache_dir = os.path.join(self.tmp_dir, 'cache')
else:
cache_dir = report.strip()
if create:
os.makedirs(cache_dir)
return cache_dir
def assert_path_exists(self, path, expected=True):
if expected is True:
self.assertTrue(os.path.exists(path),
@@ -202,16 +178,16 @@ class AAParserAltCacheBasicTests(AAParserBasicCachingTests):
def setUp(self):
super(AAParserAltCacheBasicTests, self).setUp()
alt_cache_loc = tempfile.mkdtemp(prefix='aa-alt-cache', dir=self.tmp_dir)
os.chmod(alt_cache_loc, 0o755)
alt_cache_dir = tempfile.mkdtemp(prefix='aa-alt-cache', dir=self.tmp_dir)
os.chmod(alt_cache_dir, 0o755)
self.unused_cache_loc = self.cache_dir
self.cmd_prefix.extend(['--cache-loc', alt_cache_loc])
self.cache_dir = self.get_cache_dir()
self.unused_cache_dir = self.cache_dir
self.cache_dir = alt_cache_dir
self.cmd_prefix.extend(['--cache-loc', alt_cache_dir])
def tearDown(self):
if len(os.listdir(self.unused_cache_loc)) > 0:
self.fail('original cache dir \'%s\' not empty' % self.unused_cache_loc)
if len(os.listdir(self.unused_cache_dir)) > 0:
self.fail('original cache dir \'%s\' not empty' % self.unused_cache_dir)
super(AAParserAltCacheBasicTests, self).tearDown()
@@ -338,22 +314,18 @@ class AAParserCachingTests(AAParserCachingCommon):
self.run_cmd_check(cmd, expected_string='Replacement succeeded for')
self.assert_path_exists(self.cache_file, expected=False)
def test_cache_writing_collision_of_features(self):
'''test cache writing collision of features'''
# cache dir with different features causes a collision resulting
# in a new cache dir
def test_cache_writing_updates_features(self):
'''test cache writing updates features'''
self.require_apparmorfs()
features_file = testlib.write_file(self.cache_dir, '.features', 'monkey\n')
new_file = self.get_cache_dir()
new_features_file = new_file + '/.features';
cmd = list(self.cmd_prefix)
cmd.extend(['-v', '--write-cache', '-r', self.profile])
self.run_cmd_check(cmd, expected_string='Replacement succeeded for')
self.assert_path_exists(features_file)
self.assert_path_exists(new_features_file)
self.compare_features_file(new_features_file)
self.compare_features_file(features_file)
def test_cache_writing_updates_cache_file(self):
'''test cache writing updates cache file'''
@@ -522,13 +494,13 @@ class AAParserAltCacheTests(AAParserCachingTests):
def setUp(self):
super(AAParserAltCacheTests, self).setUp()
alt_cache_loc = tempfile.mkdtemp(prefix='aa-alt-cache', dir=self.tmp_dir)
os.chmod(alt_cache_loc, 0o755)
alt_cache_dir = tempfile.mkdtemp(prefix='aa-alt-cache', dir=self.tmp_dir)
os.chmod(alt_cache_dir, 0o755)
self.orig_cache_dir = self.cache_dir
self.cmd_prefix.extend(['--cache-loc', alt_cache_loc])
self.cache_dir = self.get_cache_dir(create=True)
self.cache_dir = alt_cache_dir
self.cache_file = os.path.join(self.cache_dir, PROFILE)
self.cmd_prefix.extend(['--cache-loc', alt_cache_dir])
def tearDown(self):
if self.check_orig_cache and len(os.listdir(self.orig_cache_dir)) > 0:

View File

View File

@@ -81,7 +81,7 @@ sub test_profile {
# child
open(STDOUT, ">/dev/null") or die "Failed to redirect STDOUT";
open(STDERR, ">/dev/null") or die "Failed to redirect STDERR";
exec("$config{'parser'}", "--config-file=./parser.conf", "-M", "features_files/features.all", "-S", "-I", "$config{'includedir'}") or die "Bail out! couldn't open parser";
exec("$config{'parser'}", "-M", "features_files/features.all", "-S", "-I", "$config{'includedir'}") or die "Bail out! couldn't open parser";
# noreturn
}

View File

@@ -93,7 +93,7 @@ check-parser: local
@echo "*** Checking profiles from ${PROFILES_SOURCE} and ${EXTRAS_SOURCE} against apparmor_parser"
$(Q)for profile in ${CHECK_PROFILES} ; do \
[ -n "${VERBOSE}" ] && echo "Testing $${profile}" ; \
${PARSER} --config-file=../parser/tst/parser.conf -S -b ${PWD}/apparmor.d $${profile} > /dev/null || exit 1; \
${PARSER} -S -b ${PWD}/apparmor.d $${profile} > /dev/null || exit 1; \
done
.PHONY: check-logprof

View File

@@ -10,7 +10,6 @@
#
# ------------------------------------------------------------------
#include <abstractions/dri-common>
# .ICEauthority files required for X authentication, per user
@@ -46,6 +45,14 @@
# EGL
/usr/lib/@{multiarch}/egl/*.so* mr,
# DRI
/usr/lib{,32,64}/dri/** mr,
/usr/lib/@{multiarch}/dri/** mr,
/usr/lib/fglrx/dri/** mr,
/dev/dri/** rw,
/etc/drirc r,
owner @{HOME}/.drirc r,
# Xcompose
owner @{HOME}/.XCompose r,

View File

@@ -1,12 +0,0 @@
# vim:syntax=apparmor
# This file contains common DRI-specific rules useful for GUI applications
# (needed by libdrm and similar).
/usr/lib{,32,64}/dri/** mr,
/usr/lib/@{multiarch}/dri/** mr,
/usr/lib/fglrx/dri/** mr,
/dev/dri/** rw,
/etc/drirc r,
owner @{HOME}/.drirc r,

View File

@@ -1,9 +0,0 @@
# vim:syntax=apparmor
# This file contains common DRI-specific rules useful for GUI applications that
# needs to enumerate graphic devices (as with drmParsePciDeviceInfo() from
# libdrm).
# TODO: use @{sys} after it's moved into tunables/kernelvars (LP: #1728551)
/sys/devices/pci[0-9]*/**/{device,subsystem_device,subsystem_vendor,uevent,vendor} r,

View File

@@ -10,12 +10,21 @@
# ------------------------------------------------------------------
# system configuration
@{system_share_dirs}/applications/{**,} r,
@{system_share_dirs}/icons/{**,} r,
@{system_share_dirs}/pixmaps/{**,} r,
/usr/{,local/}share/applications/{*/,} r,
/usr/{,local/}share/applications/{*/,}defaults.list r,
/usr/{,local/}share/applications/{*/,}mimeinfo.cache r,
/usr/{,local/}share/applications/{*/,}*.desktop r,
/usr/share/icons/ r,
/usr/share/icons/** r,
/usr/share/pixmaps/ r,
/usr/share/pixmaps/** r,
/usr/local/share/icons/ r,
/usr/local/share/icons/** r,
/usr/local/share/pixmaps/ r,
/usr/local/share/pixmaps/** r,
# this should probably go elsewhere
@{system_share_dirs}/mime/** r,
/usr/share/mime/** r,
# per-user configurations
owner @{HOME}/.icons/ r,
@@ -23,6 +32,12 @@
owner @{HOME}/.local/share/recently-used.xbel* rw,
owner @{HOME}/.config/user-dirs.dirs r,
owner @{HOME}/.config/mimeapps.list r,
owner @{user_share_dirs}/applications/{**,} r,
owner @{user_share_dirs}/icons/{**,} r,
owner @{user_share_dirs}/mime/{**,} r,
owner @{HOME}/.local/share/applications/ r,
owner @{HOME}/.local/share/applications/*.desktop r,
owner @{HOME}/.local/share/applications/defaults.list r,
owner @{HOME}/.local/share/applications/mimeapps.list r,
owner @{HOME}/.local/share/applications/mimeinfo.cache r,
owner @{HOME}/.local/share/icons/ r,
owner @{HOME}/.local/share/icons/** r,
owner @{HOME}/.local/share/mime/ r,
owner @{HOME}/.local/share/mime/** r,

View File

@@ -33,6 +33,8 @@ owner @{HOME}/.kde{,4}/share/config/*.lock rwl,
owner @{HOME}/.qt/** rw,
owner @{HOME}/.config/Trolltech.conf rwk,
/usr/share/icons/ r,
/usr/share/icons/** r,
/usr/share/X11/XKeysymDB r,
# kde3

View File

@@ -1,10 +0,0 @@
# vim:syntax=apparmor
# Rules for changing KDE settings (for KFileDialog and other).
# User files
owner @{HOME}/.config/#[0-9]* rw,
owner @{HOME}/.config/kdeglobals rw,
owner @{HOME}/.config/kdeglobals.?????? rwl -> @{HOME}/.config/#[0-9]*,
owner @{HOME}/.config/kdeglobals.lock rwk,

View File

@@ -1,7 +0,0 @@
# vim:syntax=apparmor
# Rules for writing KDE icon cache
# User files
owner @{HOME}/.cache/icon-cache.kcache rw, # for KIconLoader

View File

@@ -1,12 +0,0 @@
# vim:syntax=apparmor
# Rules for changing per-application language settings on KDE. Some KDE
# applications have "Help -> Switch Application Language..." option, that needs
# write access to language settings file.
# User files
owner @{HOME}/.config/#[0-9]* rw,
owner @{HOME}/.config/klanguageoverridesrc rw,
owner @{HOME}/.config/klanguageoverridesrc.?????? rwl -> @{HOME}/.config/#[0-9]*,
owner @{HOME}/.config/klanguageoverridesrc.lock rwk,

View File

@@ -1,13 +0,0 @@
# vim:syntax=apparmor
# Rules for Mesa implementation of the OpenGL API
# System files
/dev/dri/ r, # libGLX_mesa.so calls drmGetDevice2()
# User files
owner @{HOME}/.cache/ w, # if user clears all caches
owner @{HOME}/.cache/mesa_shader_cache/ w,
owner @{HOME}/.cache/mesa_shader_cache/index rw,
owner @{HOME}/.cache/mesa_shader_cache/??/ w,
owner @{HOME}/.cache/mesa_shader_cache/??/* rwk,

View File

@@ -17,8 +17,6 @@
@{PROC}/driver/nvidia/params r,
@{PROC}/modules r,
/sys/devices/system/memory/block_size_bytes r,
owner @{HOME}/.nv/ w,
owner @{HOME}/.nv/GLCache/ rw,
owner @{HOME}/.nv/GLCache/** rwk,

View File

@@ -1,9 +0,0 @@
# vim:syntax=apparmor
# OpenCL access requirements
# TODO: use conditionals to select allowed implementations
#include <abstractions/opencl-intel>
#include <abstractions/opencl-mesa>
#include <abstractions/opencl-nvidia>
#include <abstractions/opencl-pocl>

View File

@@ -1,10 +0,0 @@
# vim:syntax=apparmor
# implementation-independent OpenCL access requirements
# System files
/etc/OpenCL/** r,
/sys/bus/pci/devices/ r, # libpocl.so -> libhwlock.so, libnvidia-opencl.so, beignet/libcl.so -> libdrm_intel.so
/sys/devices/system/node/ r, # for clGetPlatformIDs() from libOpenCL.so
/sys/devices/system/node/node[0-9]*/meminfo r, # for clGetPlatformIDs() from libOpenCL.so

View File

@@ -1,17 +0,0 @@
# vim:syntax=apparmor
# OpenCL access requirements for Intel implementation
#include <abstractions/opencl-common>
# for libcl.so (libOpenCL.so -> beignet/libcl.so calls XOpenDisplay())
#include <abstractions/X>
# for libOpenCL.so -> beignet/libcl.so -> libpciaccess.so
#include <abstractions/dri-enumerate>
# System files
/dev/dri/card[0-9]* rw, # beignet/libcl.so
/sys/devices/pci[0-9]*/**/{class,config,resource,revision} r, # libcl.so -> libdrm_intel.so -> libpciaccess.so (move to dri-enumerate ?)
/usr/lib/@{multiarch}/beignet/** r,

View File

@@ -1,20 +0,0 @@
# vim:syntax=apparmor
# OpenCL access requirements for Mesa implementation
#include <abstractions/opencl-common>
# Additional libraries
/usr/lib/@{multiarch}/gallium-pipe/*.so mr, # libMesaOpenCL.so
/usr/lib{,64}/gallium-pipe/*.so mr, # libMesaOpenCL.so on openSUSE
# System files
/dev/dri/ r, # libMesaOpenCL.so -> libdrm.so
/dev/dri/render* rw, # libMesaOpenCL.so
/etc/drirc r, # libMesaOpenCL.so
# User files
owner @{HOME}/.cache/mesa_shader_cache/{,**} rw, # libMesaOpenCL.so -> pipe_nouveau.so

View File

@@ -1,30 +0,0 @@
# vim:syntax=apparmor
# OpenCL access requirements for NVIDIA implementation
#include <abstractions/nvidia>
#include <abstractions/opencl-common>
# Executables
# https://github.com/NVIDIA/nvidia-modprobe
# This setuid executable is used to create various device files and load the
# the nvidia kernel module.
/usr/bin/nvidia-modprobe Px -> nvidia_modprobe,
# System files
# libnvidia-opencl.so rules:
/dev/nvidia-uvm rw,
/dev/nvidia-uvm-tools rw,
/sys/devices/pci[0-9]*/**/config r,
/sys/devices/system/memory/block_size_bytes r,
/usr/share/nvidia/** r,
@{PROC}/devices r,
@{PROC}/sys/vm/mmap_min_addr r,
# User files
owner @{HOME}/.nv/ComputeCache/ w,
owner @{HOME}/.nv/ComputeCache/** rw,
owner @{HOME}/.nv/ComputeCache/index rwk,

View File

@@ -1,76 +0,0 @@
# vim:syntax=apparmor
# OpenCL access requirements for POCL implementation
#include <abstractions/opencl-common>
# Executables
/usr/bin/{,@{multiarch}-}ld.bfd Cx -> opencl_pocl_ld,
/usr/lib/llvm-[0-9]*.[0-9]*/bin/clang Cx -> opencl_pocl_clang,
# System files
/ r, # libpocl.so -> libhwloc.so
/sys/bus/pci/slots/ r, # libpocl.so -> hwloc_topology_load() from libhwloc.so
/sys/bus/{cpu,node}/devices/ r, # libpocl.so -> libhwlock.so
/sys/class/net/ r, # libpocl.so -> hwloc_pci_traverse_lookuposdevices_cb() from libhwloc.so
/sys/devices/pci[0-9]*/**/ r, # for libpocl -> hwloc_linux_lookup_block_class() from libhwloc.so
/sys/devices/pci[0-9]*/**/block/*/dev r, # libpocl.so -> hwloc_linux_lookup_host_block_class() from libhwloc.so
/sys/devices/pci[0-9]*/**/{class,local_cpus} r, # libpocl.so -> libhwlock.so
/sys/devices/pci[0-9]*/*/net/*/address r, # libpocl.so -> hwloc_pci_traverse_lookuposdevices_cb() from libhwloc.so
/sys/devices/system/cpu/ r, # libpocl.so -> libnuma.so
/sys/devices/system/cpu/cpu[0-9]*/cache/index[0-9]*/* r, # libpocl.so -> libhwloc.so
/sys/devices/system/cpu/cpu[0-9]*/online r, # libpocl.so -> libhwlock.so
/sys/devices/system/cpu/cpu[0-9]*/topology/* r, # *_siblings, physical_package_id and lot's of others, for libpocl.so -> libhwloc.so
/sys/devices/system/cpu/cpufreq/policy[0-9]*/* r, # for clGetPlatformIDs() from libpocl.so
/sys/devices/system/cpu/possible r, # libpocl.so -> libhwloc.so
/sys/devices/virtual/dmi/id/{,*} r, # libpocl.so -> libhwloc.so
/sys/fs/cgroup/cpuset/cpuset.{cpus,mems} r, # libpocl.so -> libhwloc.so
/sys/kernel/mm/hugepages{/,/**} r, # libpocl.so -> libhwloc.so
/usr/share/pocl/** r,
/{,var/}run/udev/data/*:* r, # libpocl.so -> hwloc_linux_block_class_fillinfos() from libhwloc.so
# User files
owner @{HOME}/.cache/pocl/ w,
owner @{HOME}/.cache/pocl/kcache/ w,
owner @{HOME}/.cache/pocl/kcache/** rw,
owner @{HOME}/.cache/pocl/kcache/**.so mrw, # dangerous!
owner @{PROC}/@{pid}/{cgroup,cpuset,status} r, # libpocl.so -> libhwloc.so, status for libpocl.so -> libnuma.so
# Child profiles
profile opencl_pocl_ld {
#include <abstractions/base>
# Main executables
/usr/bin/{,@{multiarch}-}ld.bfd mr,
# User files
owner @{HOME}/.cache/pocl/kcache/tempfile*.so rw,
owner @{HOME}/.cache/pocl/kcache/**.so.o r,
}
profile opencl_pocl_clang {
#include <abstractions/base>
# Main executables
/usr/lib/llvm-[0-9]*.[0-9]*/bin/clang mr,
# Additional executables
/usr/bin/{,@{multiarch}-}ld.bfd ix, # TODO: transfer to opencl_ld child profile?
# System files
/etc/debian-version r,
/etc/lsb-release r,
# User files
owner @{HOME}/.cache/pocl/kcache/*/*/*/*/*.so{,.o} rw,
}

View File

@@ -1,10 +0,0 @@
# vim:syntax=apparmor
# Allow updating recent documents
# User files
owner @{HOME}/.local/share/RecentDocuments/ rw,
owner @{HOME}/.local/share/RecentDocuments/#[0-9]* rw,
owner @{HOME}/.local/share/RecentDocuments/*.desktop rwl -> @{HOME}/.local/share/RecentDocuments/#[0-9]*,
owner @{HOME}/.local/share/RecentDocuments/*.lock rwk,

View File

@@ -1,63 +0,0 @@
# vim:syntax=apparmor
#include <tunables/global>
profile nvidia_modprobe {
#include <abstractions/base>
# Capabilities
capability chown,
capability mknod,
capability setuid,
capability sys_admin,
# Main executable
/usr/bin/nvidia-modprobe mr,
# Other executables
/usr/bin/kmod Cx -> kmod,
# System files
/dev/nvidia-uvm w,
/dev/nvidia-uvm-tools w,
/sys/bus/pci/devices/ r,
/sys/devices/pci[0-9]*/**/config r,
@{PROC}/devices r,
@{PROC}/modules r,
@{PROC}/sys/kernel/modprobe r,
# Child profiles
profile kmod {
#include <abstractions/base>
# Capabilities
capability sys_module,
# Main executable
/usr/bin/kmod mrix,
# Other executables
/{,usr/}bin/{,ba,da}sh ix,
# System files
/etc/modprobe.d/{,*.conf} r,
/etc/nvidia/current/*.conf r,
/sys/module/ipmi_devintf/initstate r,
/sys/module/ipmi_msghandler/initstate r,
/sys/module/nvidia/initstate r,
@{PROC}/cmdline r,
}
# Site-specific additions and overrides. See local/README for details.
#include <local/nvidia_modprobe>
}

View File

@@ -18,4 +18,3 @@
#include <tunables/alias>
#include <tunables/kernelvars>
#include <tunables/xdg-user-dirs>
#include <tunables/share>

View File

@@ -1,15 +0,0 @@
@{flatpak_exports_root} = flatpak/exports flatpak/{app,runtime}/*/*/*/*/export
# System-wide directories with behaviour analogous to /usr/share
# in patterns like the freedesktop.org basedir spec. These are
# owned by root or a system user, appear in XDG_DATA_DIRS, and
# are the parent directory for `applications`, `themes`,
# `dbus-1/services`, etc.
@{system_share_dirs} = /usr/share /usr/local/share /var/lib/@{flatpak_exports_root}/share
# Per-user/personal directories with behaviour analogous to
# ~/.local/share in patterns like the freedesktop.org basedir spec.
# These are owned by the user running an application, appear in
# XDG_DATA_DIRS or XDG_DATA_HOME, and are the parent directory
# for the same subdirectories as @{system_share_dirs}
@{user_share_dirs} = @{HOME}/.local/share @{HOME}/.local/share/@{flatpak_exports_root}/share

View File

@@ -31,7 +31,6 @@
/usr/lib/dovecot/dovecot-lda mrix,
/usr/{bin,sbin}/sendmail Cx,
/usr/share/dovecot/protocols.d/ r,
/usr/share/dovecot/protocols.d/** r,
# Site-specific additions and overrides. See local/README for details.
#include <local/usr.lib.dovecot.dovecot-lda>

View File

@@ -20,7 +20,6 @@
#include <abstractions/ssl_keys>
capability dac_override,
capability dac_read_search,
capability setuid,
@{DOVECOT_MAILSTORE}/ rw,

View File

@@ -25,7 +25,6 @@
/var/spool/mlmmj/*/subscribers.d/* r,
/var/spool/mlmmj/*/digesters.d/ r,
/var/spool/mlmmj/*/digesters.d/* r,
/var/spool/mlmmj/*/moderation/* rwk,

View File

@@ -66,7 +66,7 @@
capability audit_write,
/{,usr/}sbin/pam_tally2 mr,
/sbin/pam_tally2 mr,
/var/log/tallylog rw,
}

View File

@@ -247,7 +247,7 @@ sub readconf {
s/\s+$//; # no trailing white
next unless length; # anything left?
my ($var, $value) = split(/\s*=\s*/, $_, 2);
if ($var eq "show_notifications" or $var eq "use_group" or $var eq "message_body" or $var eq "message_title" or $var eq "message_footer") {
if ($var eq "show_notifications" or $var eq "use_group") {
$value =~ s/^"(.*)"$/$1/g;
$prefs{$var} = $value;
}
@@ -298,16 +298,12 @@ sub format_message {
my ($profile, $operation, $name, $denied, $family, $sock_type, $date) = @_;
my $formatted = "";
if (defined($prefs{message_body})) {
$formatted .= $prefs{message_body};
} else {
defined($profile) and $formatted .= "Profile: $profile\n";
defined($operation) and $formatted .= "Operation: $operation\n";
defined($name) and $formatted .= "Name: $name\n";
defined($denied) and $formatted .= "Denied: $denied\n";
defined($family) and defined ($sock_type) and $formatted .= "Family: $family\nSocket type: $sock_type\n";
$formatted .= "Logfile: $logfile\n";
}
defined($profile) and $formatted .= "Profile: $profile\n";
defined($operation) and $formatted .= "Operation: $operation\n";
defined($name) and $formatted .= "Name: $name\n";
defined($denied) and $formatted .= "Denied: $denied\n";
defined($family) and defined ($sock_type) and $formatted .= "Family: $family\nSocket type: $sock_type\n";
$formatted .= "Logfile: $logfile\n";
return $formatted;
}
@@ -403,7 +399,7 @@ sub do_notify {
}
my $count = 0;
my $footer = exists $prefs{message_footer} ? $prefs{message_footer} : "For more information, please see:\n$url";
my $footer = "For more information, please see:\n$url";
my $first_run = 1;
my $since = $now;
if ($opt_s and int($opt_s) > 0) {

View File

@@ -92,12 +92,6 @@ System-wide configuration for B<aa-notify> is done via
# only people in use_group can use aa-notify
use_group="admin"
# OPTIONAL - custom notification message body
message_body="This is a custom notification message."
# OPTIONAL - custom notification message footer
message_footer="For more information visit https://foo.com"
Per-user configuration is done via ~/.apparmor/notify.conf:
# set to 'yes' to enable AppArmor DENIED notifications

View File

@@ -103,7 +103,7 @@ extras = hasher() # Inactive profiles from extras
### end our
log_pid = dict() # handed over to ReadLog, gets filled in logparser.py. The only case the previous content of this variable _might_(?) be used is aa-genprof (multiple do_logprof_pass() runs)
profile_changes = dict()
profile_changes = hasher()
prelog = hasher()
changed = dict()
created = []
@@ -709,7 +709,7 @@ def sync_profile():
repo_profiles = []
changed_profiles = []
new_profiles = []
serialize_opts = dict()
serialize_opts = hasher()
status_ok, ret = fetch_profiles_by_user(cfg['repository']['url'],
cfg['repository']['distro'], user)
if not status_ok:
@@ -796,7 +796,7 @@ def upload_profile(url, user, passw, distro, p, profile_string, changelog):
def console_select_and_upload_profiles(title, message, profiles_up):
url = cfg['repository']['url']
profiles = profiles_up[:]
profs = profiles_up[:]
q = aaui.PromptQuestion()
q.title = title
q.headers = ['Repository', url]
@@ -804,20 +804,20 @@ def console_select_and_upload_profiles(title, message, profiles_up):
q.functions = ['CMD_UPLOAD_CHANGES', 'CMD_VIEW_CHANGES', 'CMD_ASK_LATER',
'CMD_ASK_NEVER', 'CMD_ABORT']
q.default = 'CMD_VIEW_CHANGES'
q.options = [i[0] for i in profiles]
q.options = [i[0] for i in profs]
q.selected = 0
ans = ''
while 'CMD_UPLOAD_CHANGES' not in ans and 'CMD_ASK_NEVER' not in ans and 'CMD_ASK_LATER' not in ans:
ans, arg = q.promptUser()
if ans == 'CMD_VIEW_CHANGES':
aaui.UI_Changes(profiles[arg][2], profiles[arg][1])
aaui.UI_Changes(profs[arg][2], profs[arg][1])
if ans == 'CMD_NEVER_ASK':
set_profiles_local_only([i[0] for i in profiles])
set_profiles_local_only([i[0] for i in profs])
elif ans == 'CMD_UPLOAD_CHANGES':
changelog = aaui.UI_GetString(_('Changelog Entry: '), '')
user, passw = get_repo_user_pass()
if user and passw:
for p_data in profiles:
for p_data in profs:
prof = p_data[0]
prof_string = p_data[1]
status_ok, ret = upload_profile(url, user, passw,
@@ -836,10 +836,10 @@ def console_select_and_upload_profiles(title, message, profiles_up):
else:
aaui.UI_Important(_('Repository Error\nRegistration or Signin was unsuccessful. User login\ninformation is required to upload profiles to the repository.\nThese changes could not be sent.'))
def set_profiles_local_only(profiles):
for p in profiles:
aa[profiles][profiles]['repo']['neversubmit'] = True
write_profile_ui_feedback(profiles)
def set_profiles_local_only(profs):
for p in profs:
aa[profs][profs]['repo']['neversubmit'] = True
write_profile_ui_feedback(profs)
def build_x_functions(default, options, exec_toggle):
@@ -2019,7 +2019,7 @@ def is_skippable_file(path):
if not basename or basename[0] == '.' or basename == 'README':
return True
skippable_suffix = ('.dpkg-new', '.dpkg-old', '.dpkg-dist', '.dpkg-bak', '.dpkg-remove', '.pacsave', '.pacnew', '.rpmnew', '.rpmsave', '.orig', '.rej', '~')
skippable_suffix = ('.dpkg-new', '.dpkg-old', '.dpkg-dist', '.dpkg-bak', '.rpmnew', '.rpmsave', '.orig', '.rej', '~')
if basename.endswith(skippable_suffix):
return True
@@ -2599,6 +2599,26 @@ def write_header(prof_data, depth, name, embedded_hat, write_flags):
return data
def write_single(prof_data, depth, allow, name, prefix, tail):
pre = ' ' * depth
data = []
ref, allow = set_ref_allow(prof_data, allow)
if ref.get(name, False):
for key in sorted(ref[name].keys()):
if name == 'include':
if key.startswith('/'):
qkey = '"%s"' % key
else:
qkey = '<%s>' % quote_if_needed(key)
else:
qkey = quote_if_needed(key)
data.append('%s%s%s%s%s' % (pre, allow, prefix, qkey, tail))
if ref[name].keys():
data.append('')
return data
def set_allow_str(allow):
if allow == 'deny':
return 'deny '
@@ -2631,21 +2651,7 @@ def write_pair(prof_data, depth, allow, name, prefix, sep, tail, fn):
return data
def write_includes(prof_data, depth):
pre = ' ' * depth
data = []
for key in sorted(prof_data['include'].keys()):
if key.startswith('/'):
qkey = '"%s"' % key
else:
qkey = '<%s>' % quote_if_needed(key)
data.append('%s#include %s' % (pre, qkey))
if data:
data.append('')
return data
return write_single(prof_data, depth, '', 'include', '#include ', '')
def write_change_profile(prof_data, depth):
data = []

View File

@@ -12,7 +12,6 @@
# GNU General Public License for more details.
#
# ----------------------------------------------------------------------
import ctypes
import os
import re
import sys
@@ -119,7 +118,7 @@ class ReadLog:
ev['protocol'] = event.net_protocol
ev['sock_type'] = event.net_sock_type
if event.ouid != ctypes.c_ulong(-1).value: # ULONG_MAX
if event.ouid != 18446744073709551615: # 2^64 - 1
ev['fsuid'] = event.fsuid
ev['ouid'] = event.ouid

View File

@@ -14,9 +14,3 @@ show_notifications="yes"
# OPTIONAL - restrict using aa-notify to users in the given group
# (if not set, everybody who has permissions to read the logfile can use it)
# use_group="admin"
# OPTIONAL - custom notification message body
# message_body="This is a custom notification message."
# OPTIONAL - custom notification message footer
# message_footer="For more information visit https://foo.com"

View File

@@ -7,14 +7,14 @@ msgstr ""
"Project-Id-Version: apparmor-utils\n"
"Report-Msgid-Bugs-To: <apparmor@lists.ubuntu.com>\n"
"POT-Creation-Date: 2014-09-14 19:29+0530\n"
"PO-Revision-Date: 2018-04-06 21:54+0000\n"
"PO-Revision-Date: 2017-12-20 02:04+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: 2018-04-07 05:20+0000\n"
"X-Generator: Launchpad (build 18599)\n"
"X-Launchpad-Export-Date: 2017-12-21 05:12+0000\n"
"X-Generator: Launchpad (build 18511)\n"
"Language: de\n"
#: ../aa-genprof:56
@@ -320,15 +320,15 @@ msgstr "vorhandenes Profil überschreiben"
#: ../aa-audit:24
msgid "Switch the given programs to audit mode"
msgstr "Das angegebene Programm in den Prüfmodus versetzen"
msgstr "Das angegebene Programm in den Audit-Modus versetzen"
#: ../aa-audit:26
msgid "remove audit mode"
msgstr "Prüfmodus entfernen"
msgstr "Audit-Modus entfernen"
#: ../aa-audit:28
msgid "Show full trace"
msgstr "Die vollständige Spur anzeigen"
msgstr "Zeige die komplette Spur"
#: ../aa-complain:23
msgid "Switch the given program to complain mode"
@@ -662,13 +662,12 @@ msgstr "Profiländerungen"
#, python-format
msgid "Can't find existing profile %s to compare changes."
msgstr ""
"Es kann kein vorhandenes Profil %s gefunden werden, um Änderungen zu "
"vergleichen."
"Kann kein existierendes Profil %s finden um Änderungen zu vergleichen."
#: ../apparmor/aa.py:2566 ../apparmor/aa.py:2581
#, python-format
msgid "Can't read AppArmor profiles in %s"
msgstr "AppArmor-Profile in %s können nicht gelesen werden"
msgstr "Kann AppArmor-Profile in %s nicht lesen"
#: ../apparmor/aa.py:2677
#, python-format
@@ -890,7 +889,7 @@ msgstr "Vorhandenes Profil kann nicht zum Verändern gefunden werden"
#: ../apparmor/aa.py:4347
#, python-format
msgid "Writing updated profile for %s."
msgstr "Aktualisiertes Profil für %s wird geschrieben."
msgstr "Schreibe aktualisiertes Profil für %s."
#: ../apparmor/aa.py:4481
#, python-format
@@ -959,12 +958,12 @@ msgstr "%s wird deaktiviert."
#: ../apparmor/tools.py:198
#, python-format
msgid "Setting %s to audit mode."
msgstr "%s wird in den Prüfmodus versetzt."
msgstr "%s wird in den audit-Modus versetzt."
#: ../apparmor/tools.py:200
#, python-format
msgid "Removing audit mode from %s."
msgstr "Prüfmodus wird von %s entfernt."
msgstr "Audit-Modus wird von %s entfernt."
#: ../apparmor/tools.py:212
#, python-format
@@ -1003,7 +1002,7 @@ msgstr "Das Profil für %s existiert nicht. Nichts zu bereinigen."
#: ../apparmor/ui.py:61
msgid "Invalid hotkey for"
msgstr "Ungültiges Tastenkürzel für"
msgstr "Ungültiger Hotkey für"
#: ../apparmor/ui.py:77 ../apparmor/ui.py:121 ../apparmor/ui.py:275
msgid "(Y)es"
@@ -1035,7 +1034,7 @@ msgstr "Audi(t) aus"
#: ../apparmor/ui.py:227
msgid "Audit (A)ll"
msgstr "(A)lle überprüfen"
msgstr ""
#: ../apparmor/ui.py:229
msgid "(O)wner permissions on"

View File

@@ -159,4 +159,4 @@ class MinitoolsTest(AATest):
setup_aa(apparmor)
setup_all_loops(__name__)
if __name__ == '__main__':
unittest.main(verbosity=1)
unittest.main(verbosity=2)

View File

@@ -200,4 +200,4 @@ type=AVC msg=audit(1348982148.195:2933): apparmor="DENIED" operation="file_lock"
if __name__ == '__main__':
if 'APPARMOR_DECODE' in os.environ:
aadecode_bin = os.environ['APPARMOR_DECODE']
unittest.main(verbosity=1)
unittest.main(verbosity=2)

View File

@@ -2684,7 +2684,7 @@ if __name__ == '__main__':
# run the tests
suite = unittest.TestSuite()
suite.addTest(unittest.TestLoader().loadTestsFromTestCase(T))
rc = unittest.TextTestRunner(verbosity=1).run(suite)
rc = unittest.TextTestRunner(verbosity=2).run(suite)
if not rc.wasSuccessful():
sys.exit(1)

View File

@@ -447,28 +447,22 @@ class AaTest_is_skippable_file(AATest):
def test_skippable_04(self):
self.assertTrue(is_skippable_file('bin.ping..dpkg-bak'))
def test_skippable_05(self):
self.assertTrue(is_skippable_file('bin.ping.dpkg-remove'))
def test_skippable_06(self):
self.assertTrue(is_skippable_file('bin.ping.pacsave'))
def test_skippable_07(self):
self.assertTrue(is_skippable_file('bin.ping.pacnew'))
def test_skippable_08(self):
self.assertTrue(is_skippable_file('bin.ping.rpmnew'))
def test_skippable_09(self):
def test_skippable_06(self):
self.assertTrue(is_skippable_file('bin.ping.rpmsave'))
def test_skippable_10(self):
def test_skippable_07(self):
self.assertTrue(is_skippable_file('bin.ping.orig'))
def test_skippable_11(self):
def test_skippable_08(self):
self.assertTrue(is_skippable_file('bin.ping.rej'))
def test_skippable_12(self):
def test_skippable_09(self):
self.assertTrue(is_skippable_file('bin.ping~'))
def test_skippable_13(self):
def test_skippable_10(self):
self.assertTrue(is_skippable_file('.bin.ping'))
def test_skippable_14(self):
def test_skippable_11(self):
self.assertTrue(is_skippable_file('')) # empty filename
def test_skippable_15(self):
def test_skippable_12(self):
self.assertTrue(is_skippable_file('/etc/apparmor.d/')) # directory without filename
def test_skippable_16(self):
def test_skippable_13(self):
self.assertTrue(is_skippable_file('README'))
@@ -936,4 +930,4 @@ class AaTest_nonexistent_includes(AATest):
setup_aa(apparmor.aa)
setup_all_loops(__name__)
if __name__ == '__main__':
unittest.main(verbosity=1)
unittest.main(verbosity=2)

View File

@@ -111,4 +111,4 @@ class AamodeTest_validate_log_mode(AATest):
setup_all_loops(__name__)
if __name__ == '__main__':
unittest.main(verbosity=1)
unittest.main(verbosity=2)

View File

@@ -420,4 +420,4 @@ class TestAAREglobPathWithExt(AATest):
setup_all_loops(__name__)
if __name__ == '__main__':
unittest.main(verbosity=1)
unittest.main(verbosity=2)

View File

@@ -86,4 +86,4 @@ class TestBaserule(AATest):
setup_all_loops(__name__)
if __name__ == '__main__':
unittest.main(verbosity=1)
unittest.main(verbosity=2)

View File

@@ -989,4 +989,4 @@ class CapabilityDeleteTest(AATest):
setup_all_loops(__name__)
if __name__ == '__main__':
unittest.main(verbosity=1)
unittest.main(verbosity=2)

View File

@@ -484,4 +484,4 @@ class ChangeProfileDeleteTestAATest(AATest):
setup_all_loops(__name__)
if __name__ == '__main__':
unittest.main(verbosity=1)
unittest.main(verbosity=2)

View File

@@ -29,4 +29,4 @@ class TestIs_str_type(AATest):
setup_all_loops(__name__)
if __name__ == '__main__':
unittest.main(verbosity=1)
unittest.main(verbosity=2)

View File

@@ -870,4 +870,4 @@ class DbusGlobTest(AATest):
setup_all_loops(__name__)
if __name__ == '__main__':
unittest.main(verbosity=1)
unittest.main(verbosity=2)

View File

@@ -50,4 +50,4 @@ class TestBaz(AATest):
setup_all_loops(__name__)
if __name__ == '__main__':
unittest.main(verbosity=1)
unittest.main(verbosity=2)

View File

@@ -1123,4 +1123,4 @@ class FileGetExecConflictRules_1(AATest):
setup_all_loops(__name__)
if __name__ == '__main__':
unittest.main(verbosity=1)
unittest.main(verbosity=2)

View File

@@ -272,4 +272,4 @@ TestLogToProfile.tests = find_test_multi('../../libraries/libapparmor/testsuite/
setup_aa(apparmor.aa)
setup_all_loops(__name__)
if __name__ == '__main__':
unittest.main(verbosity=1)
unittest.main(verbosity=1) # reduced verbosity due to the big number of tests

View File

@@ -96,4 +96,4 @@ class TestParseEvent(unittest.TestCase):
if __name__ == "__main__":
unittest.main(verbosity=1)
unittest.main(verbosity=2)

View File

@@ -44,4 +44,4 @@ if __name__ == '__main__':
setup_regex_tests(AAParseMountTest)
setup_regex_tests(AAParseRemountTest)
setup_regex_tests(AAParseUmountTest)
unittest.main(verbosity=1)
unittest.main(verbosity=2)

View File

@@ -461,4 +461,4 @@ class NetworkRulesetReprTest(AATest):
setup_all_loops(__name__)
if __name__ == '__main__':
unittest.main(verbosity=1)
unittest.main(verbosity=2)

View File

@@ -528,4 +528,4 @@ find_and_setup_test_profiles('../../parser/tst/simple_tests/')
setup_all_loops(__name__)
if __name__ == '__main__':
unittest.main(verbosity=1)
unittest.main(verbosity=1) # reduced verbosity due to the big number of tests

View File

@@ -27,4 +27,4 @@ class AAParsePivotRootTest(AAParseTest):
setup_aa(aa)
if __name__ == '__main__':
setup_regex_tests(AAParsePivotRootTest)
unittest.main(verbosity=1)
unittest.main(verbosity=2)

View File

@@ -75,4 +75,4 @@ class AaTest_split_flags(AATest):
setup_all_loops(__name__)
if __name__ == '__main__':
unittest.main(verbosity=1)
unittest.main(verbosity=2)

View File

@@ -555,4 +555,4 @@ class PtraceGlobTestAATest(AATest):
setup_all_loops(__name__)
if __name__ == '__main__':
unittest.main(verbosity=1)
unittest.main(verbosity=2)

View File

@@ -564,4 +564,4 @@ if __name__ == '__main__':
setup_has_comma_testcases()
setup_split_comment_testcases()
unittest.main(verbosity=1)
unittest.main(verbosity=2)

View File

@@ -490,4 +490,4 @@ class RlimitTime_to_intTest(AATest):
setup_all_loops(__name__)
if __name__ == '__main__':
unittest.main(verbosity=1)
unittest.main(verbosity=2)

View File

@@ -174,4 +174,4 @@ class SeverityDBTest(AATest):
setup_all_loops(__name__)
if __name__ == '__main__':
unittest.main(verbosity=1)
unittest.main(verbosity=2)

View File

@@ -621,4 +621,4 @@ class SignalGlobTestAATest(AATest):
setup_all_loops(__name__)
if __name__ == '__main__':
unittest.main(verbosity=1)
unittest.main(verbosity=2)

View File

@@ -72,4 +72,4 @@ class TestHotkeyConflicts(AATest):
setup_all_loops(__name__)
if __name__ == '__main__':
unittest.main(verbosity=1)
unittest.main(verbosity=2)

View File

@@ -37,4 +37,4 @@ class AAParseUnixTest(AAParseTest):
setup_aa(aa)
if __name__ == '__main__':
setup_regex_tests(AAParseUnixTest)
unittest.main(verbosity=1)
unittest.main(verbosity=2)