mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-09-01 14:55:10 +00:00
Compare commits
218 Commits
git-conver
...
v2.13
Author | SHA1 | Date | |
---|---|---|---|
|
f97782b100 | ||
|
aa7dc70de3 | ||
|
3f1ed05da6 | ||
|
971908b730 | ||
|
481f59a39b | ||
|
9e48a5da5e | ||
|
4814763c97 | ||
|
1328a42d5a | ||
|
be94d7b27f | ||
|
2ad924f2b1 | ||
|
bf662b5594 | ||
|
110b96bd3d | ||
|
10a4b3b9fb | ||
|
419d82c13b | ||
|
26b6dc1306 | ||
|
63b7cb0660 | ||
|
30e0eacebc | ||
|
1f36505f3e | ||
|
8d9c904174 | ||
|
4c7924ec31 | ||
|
b4a5f44473 | ||
|
e9d9395f91 | ||
|
b950c76d66 | ||
|
95912e41bf | ||
|
64c196a487 | ||
|
df0a2335f2 | ||
|
f472b6bb34 | ||
|
059adcdf76 | ||
|
a7ffae4396 | ||
|
5d973c2657 | ||
|
c4e607199c | ||
|
e28d0a922a | ||
|
b74f224106 | ||
|
0b18e57cc5 | ||
|
b714cf1b0d | ||
|
b7732a2a30 | ||
|
6b78daf25b | ||
|
26a8b72225 | ||
|
36bdd6ea70 | ||
|
0d0a196077 | ||
|
5e187daa0b | ||
|
776975dc38 | ||
|
f3c39034ae | ||
|
45922c6d21 | ||
|
80d900d18c | ||
|
812d53b546 | ||
|
4ffcb2a8a9 | ||
|
96b339f870 | ||
|
b4fa0cf9f6 | ||
|
f0876ea92a | ||
|
06069cc47a | ||
|
0c2690d819 | ||
|
47da50b7e6 | ||
|
50ee50f931 | ||
|
566f656101 | ||
|
11ae3f6ecd | ||
|
671ddccf19 | ||
|
4395d6dea8 | ||
|
86ec3dd658 | ||
|
14096cb3a7 | ||
|
208933829f | ||
|
cea8e7cfa0 | ||
|
c9bf36dd2e | ||
|
e6ef536957 | ||
|
dc7c702188 | ||
|
3b5683be29 | ||
|
f9eb3fea0f | ||
|
130958a4a4 | ||
|
2bc64070c9 | ||
|
1f9085e5e7 | ||
|
46f88f5f0d | ||
|
f8c535801e | ||
|
8b3997aa0e | ||
|
7f643fbc31 | ||
|
275c7c0d50 | ||
|
d66720ef07 | ||
|
22e94633c3 | ||
|
ccef9161a8 | ||
|
b21b28f486 | ||
|
735afbc947 | ||
|
1c3839c39a | ||
|
86db2263b8 | ||
|
41b6182019 | ||
|
8ef7b59454 | ||
|
0eefeeb0e7 | ||
|
21b0d14ea4 | ||
|
11e7dab95e | ||
|
e88af93322 | ||
|
ad5e988efb | ||
|
b0456adbd8 | ||
|
8dd517f6dd | ||
|
547708bc99 | ||
|
8f6d94bf44 | ||
|
0b93a7f991 | ||
|
e2c1b21dec | ||
|
cb4f553d60 | ||
|
967d394ef4 | ||
|
705ce5ca3e | ||
|
6d22c871bf | ||
|
a3db7f8acb | ||
|
7f1007d13e | ||
|
f8a174c08b | ||
|
cab3210bd0 | ||
|
85f8cace12 | ||
|
26af640fda | ||
|
1bac9d2d79 | ||
|
e1929298ac | ||
|
8fc3dcb312 | ||
|
6f1d054468 | ||
|
ef718df685 | ||
|
2ea3309942 | ||
|
8d142809f5 | ||
|
efd8eedd52 | ||
|
62dbd29656 | ||
|
1b51dac4c9 | ||
|
1361116542 | ||
|
8b17fd1fa6 | ||
|
6ab19ea82f | ||
|
1541175c36 | ||
|
cb5cdf2656 | ||
|
1b58f226ce | ||
|
d71e46baaa | ||
|
924983e702 | ||
|
6344b8ecc3 | ||
|
7f72fd0fca | ||
|
0b719e4f86 | ||
|
3afbfed9ee | ||
|
e55583ff27 | ||
|
b5808e8aa8 | ||
|
a3693f56f3 | ||
|
81ca52d948 | ||
|
4d8fb33335 | ||
|
60f71930cd | ||
|
22fa0a3a77 | ||
|
c3b0a3e512 | ||
|
f8b208ee80 | ||
|
118ea834fd | ||
|
f2a84e5f1d | ||
|
bcfb735b9a | ||
|
7159538fc8 | ||
|
99f144f8c2 | ||
|
5c95e3bf39 | ||
|
515e40ec7f | ||
|
a7e79ffa3d | ||
|
9bbef8e307 | ||
|
ebf0cfe838 | ||
|
b8195dad31 | ||
|
c803c34558 | ||
|
06928db1ce | ||
|
426990cfaf | ||
|
e325e74b0f | ||
|
ba0cdbc013 | ||
|
da6db0c2b9 | ||
|
566218612c | ||
|
6713f9d94a | ||
|
23220af3b9 | ||
|
2431b1884a | ||
|
11147f965a | ||
|
24eaea19e3 | ||
|
bb96e38a90 | ||
|
f73627cbb5 | ||
|
6db30f8faf | ||
|
9f24650ef9 | ||
|
5653697df2 | ||
|
861d8b4349 | ||
|
56b55aa0dd | ||
|
b2df42f55b | ||
|
6483c627d2 | ||
|
a5e5185e15 | ||
|
b24a1c4d54 | ||
|
26431478a6 | ||
|
dcefc1baa4 | ||
|
7546413b43 | ||
|
c69acb81c9 | ||
|
c4a5e1d554 | ||
|
debc4e3ffe | ||
|
4b72ba29ed | ||
|
2c04f44a80 | ||
|
5bdacd2432 | ||
|
20e7f523ca | ||
|
13b1c7a5f6 | ||
|
a0d4e246ab | ||
|
1857f07d08 | ||
|
7a49f37c24 | ||
|
ca983811fb | ||
|
a1bad3a293 | ||
|
3d40bc6f23 | ||
|
4d4228d157 | ||
|
2aabf0c0f0 | ||
|
014695786c | ||
|
794d1c4a07 | ||
|
d7ffc37011 | ||
|
b307e535fa | ||
|
4ef505a6e7 | ||
|
455489c9fe | ||
|
42bd81df01 | ||
|
6f6b3c57fb | ||
|
d662c2be72 | ||
|
4b8b08562a | ||
|
9658471d38 | ||
|
852d26de6c | ||
|
051be5dec0 | ||
|
fe1fb7caa3 | ||
|
21bc71e576 | ||
|
2b02d7df83 | ||
|
543a6a6fed | ||
|
92752f56da | ||
|
745aa4d342 | ||
|
aa05cbdd1e | ||
|
ddbf6c24bb | ||
|
51764eda98 | ||
|
59a5bc088c | ||
|
b813beeb1b | ||
|
7fad3512f0 | ||
|
29c5c6b621 | ||
|
56394f8def | ||
|
19c6c3310b | ||
|
29b20fd688 |
71
.bzrignore → .gitignore
vendored
71
.bzrignore → .gitignore
vendored
@@ -1,4 +1,10 @@
|
||||
apparmor-*
|
||||
cscope.*
|
||||
binutils/aa-enabled
|
||||
binutils/aa-enabled.1
|
||||
binutils/aa-exec
|
||||
binutils/aa-exec.1
|
||||
binutils/po/*.mo
|
||||
parser/po/*.mo
|
||||
parser/af_names.h
|
||||
parser/cap_names.h
|
||||
@@ -13,6 +19,37 @@ parser/parser_version.h
|
||||
parser/parser_yacc.c
|
||||
parser/parser_yacc.h
|
||||
parser/pod2htm*.tmp
|
||||
parser/af_rule.o
|
||||
parser/af_unix.o
|
||||
parser/common_optarg.o
|
||||
parser/dbus.o
|
||||
parser/lib.o
|
||||
parser/libapparmor_re/aare_rules.o
|
||||
parser/libapparmor_re/chfa.o
|
||||
parser/libapparmor_re/expr-tree.o
|
||||
parser/libapparmor_re/hfa.o
|
||||
parser/libapparmor_re/libapparmor_re.a
|
||||
parser/libapparmor_re/parse.o
|
||||
parser/mount.o
|
||||
parser/network.o
|
||||
parser/parser_alias.o
|
||||
parser/parser_common.o
|
||||
parser/parser_include.o
|
||||
parser/parser_interface.o
|
||||
parser/parser_lex.o
|
||||
parser/parser_main.o
|
||||
parser/parser_merge.o
|
||||
parser/parser_misc.o
|
||||
parser/parser_policy.o
|
||||
parser/parser_regex.o
|
||||
parser/parser_symtab.o
|
||||
parser/parser_variable.o
|
||||
parser/parser_yacc.o
|
||||
parser/policy_cache.o
|
||||
parser/profile.o
|
||||
parser/ptrace.o
|
||||
parser/rule.o
|
||||
parser/signal.o
|
||||
parser/*.7
|
||||
parser/*.5
|
||||
parser/*.8
|
||||
@@ -60,14 +97,22 @@ libraries/libapparmor/src/Makefile.in
|
||||
libraries/libapparmor/src/af_protos.h
|
||||
libraries/libapparmor/src/change_hat.lo
|
||||
libraries/libapparmor/src/features.lo
|
||||
libraries/libapparmor/src/features.o
|
||||
libraries/libapparmor/src/grammar.lo
|
||||
libraries/libapparmor/src/grammar.o
|
||||
libraries/libapparmor/src/kernel.lo
|
||||
libraries/libapparmor/src/kernel.o
|
||||
libraries/libapparmor/src/kernel_interface.lo
|
||||
libraries/libapparmor/src/kernel_interface.o
|
||||
libraries/libapparmor/src/libaalogparse.lo
|
||||
libraries/libapparmor/src/libaalogparse.o
|
||||
libraries/libapparmor/src/libimmunix_warning.lo
|
||||
libraries/libapparmor/src/policy_cache.lo
|
||||
libraries/libapparmor/src/policy_cache.o
|
||||
libraries/libapparmor/src/private.lo
|
||||
libraries/libapparmor/src/private.o
|
||||
libraries/libapparmor/src/scanner.lo
|
||||
libraries/libapparmor/src/scanner.o
|
||||
libraries/libapparmor/src/libapparmor.pc
|
||||
libraries/libapparmor/src/libapparmor.la
|
||||
libraries/libapparmor/src/libimmunix.la
|
||||
@@ -75,7 +120,19 @@ libraries/libapparmor/src/grammar.c
|
||||
libraries/libapparmor/src/grammar.h
|
||||
libraries/libapparmor/src/scanner.c
|
||||
libraries/libapparmor/src/scanner.h
|
||||
libraries/libapparmor/src/test-suite.log
|
||||
libraries/libapparmor/src/tst_aalogmisc
|
||||
libraries/libapparmor/src/tst_aalogmisc.log
|
||||
libraries/libapparmor/src/tst_aalogmisc.o
|
||||
libraries/libapparmor/src/tst_aalogmisc.trs
|
||||
libraries/libapparmor/src/tst_features
|
||||
libraries/libapparmor/src/tst_features.log
|
||||
libraries/libapparmor/src/tst_features.o
|
||||
libraries/libapparmor/src/tst_features.trs
|
||||
libraries/libapparmor/src/tst_kernel
|
||||
libraries/libapparmor/src/tst_kernel.log
|
||||
libraries/libapparmor/src/tst_kernel.o
|
||||
libraries/libapparmor/src/tst_kernel.trs
|
||||
libraries/libapparmor/swig/Makefile
|
||||
libraries/libapparmor/swig/Makefile.in
|
||||
libraries/libapparmor/swig/perl/LibAppArmor.bs
|
||||
@@ -89,6 +146,7 @@ libraries/libapparmor/swig/perl/MYMETA.json
|
||||
libraries/libapparmor/swig/perl/MYMETA.yml
|
||||
libraries/libapparmor/swig/perl/blib
|
||||
libraries/libapparmor/swig/perl/libapparmor_wrap.c
|
||||
libraries/libapparmor/swig/perl/libapparmor_wrap.o
|
||||
libraries/libapparmor/swig/perl/pm_to_blib
|
||||
libraries/libapparmor/swig/python/LibAppArmor.py
|
||||
libraries/libapparmor/swig/python/build/
|
||||
@@ -98,6 +156,10 @@ libraries/libapparmor/swig/python/Makefile.in
|
||||
libraries/libapparmor/swig/python/setup.py
|
||||
libraries/libapparmor/swig/python/test/Makefile
|
||||
libraries/libapparmor/swig/python/test/Makefile.in
|
||||
libraries/libapparmor/swig/python/test/test-suite.log
|
||||
libraries/libapparmor/swig/python/test/test_python.py
|
||||
libraries/libapparmor/swig/python/test/test_python.py.log
|
||||
libraries/libapparmor/swig/python/test/test_python.py.trs
|
||||
libraries/libapparmor/swig/ruby/Makefile
|
||||
libraries/libapparmor/swig/ruby/Makefile.in
|
||||
libraries/libapparmor/testsuite/.deps
|
||||
@@ -115,6 +177,7 @@ libraries/libapparmor/testsuite/lib/Makefile.in
|
||||
libraries/libapparmor/testsuite/libaalogparse.test/Makefile
|
||||
libraries/libapparmor/testsuite/libaalogparse.test/Makefile.in
|
||||
libraries/libapparmor/testsuite/test_multi/out
|
||||
libraries/libapparmor/testsuite/test_multi_multi-test_multi.o
|
||||
changehat/mod_apparmor/.libs
|
||||
utils/*.8
|
||||
utils/*.8.html
|
||||
@@ -122,6 +185,14 @@ utils/*.5
|
||||
utils/*.5.html
|
||||
utils/*.tmp
|
||||
utils/po/*.mo
|
||||
utils/apparmor/*.pyc
|
||||
utils/apparmor/rule/*.pyc
|
||||
utils/test/.coverage
|
||||
utils/test/htmlcov/
|
||||
utils/vim/apparmor.vim
|
||||
utils/vim/apparmor.vim.5
|
||||
utils/vim/apparmor.vim.5.html
|
||||
utils/vim/pod2htmd.tmp
|
||||
tests/regression/apparmor/access
|
||||
tests/regression/apparmor/changehat
|
||||
tests/regression/apparmor/changehat_fail
|
40
Makefile
40
Makefile
@@ -17,12 +17,9 @@ DIRS=libraries/libapparmor \
|
||||
profiles \
|
||||
tests
|
||||
|
||||
#REPO_URL?=lp:apparmor
|
||||
# --per-file-timestamps is failing over SSH, https://bugs.launchpad.net/bzr/+bug/1257078
|
||||
REPO_URL?=https://code.launchpad.net/~apparmor-dev/apparmor/master
|
||||
# alternate possibilities to export from
|
||||
#REPO_URL=.
|
||||
#REPO_URL="bzr+ssh://bazaar.launchpad.net/~sbeattie/+junk/apparmor-dev/"
|
||||
# with conversion to git, we don't export from the remote
|
||||
REPO_URL?=git@gitlab.com:apparmor/apparmor.git
|
||||
REPO_BRANCH?=master
|
||||
|
||||
COVERITY_DIR=cov-int
|
||||
RELEASE_DIR=apparmor-${VERSION}
|
||||
@@ -31,7 +28,9 @@ __SETUP_DIR?=.
|
||||
# We create a separate version for tags because git can't handle tags
|
||||
# with embedded ~s in them. No spaces around '-' or they'll get
|
||||
# embedded in ${VERSION}
|
||||
TAG_VERSION=$(subst ~,-,${VERSION})
|
||||
# apparmor version tag format 'vX.Y.ZZ'
|
||||
# apparmor branch name format 'apparmor-X.Y'
|
||||
TAG_VERSION="v$(subst ~,-,${VERSION})"
|
||||
|
||||
# Add exclusion entries arguments for tar here, of the form:
|
||||
# --exclude dir_to_exclude --exclude other_dir
|
||||
@@ -40,49 +39,50 @@ TAR_EXCLUSIONS=
|
||||
.PHONY: tarball
|
||||
tarball: clean
|
||||
REPO_VERSION=`$(value REPO_VERSION_CMD)` && \
|
||||
make export_dir __EXPORT_DIR=${RELEASE_DIR} __REPO_VERSION=$${REPO_VERSION} && \
|
||||
make setup __SETUP_DIR=${RELEASE_DIR} && \
|
||||
$(MAKE) export_dir __EXPORT_DIR=${RELEASE_DIR} __REPO_VERSION=$${REPO_VERSION} && \
|
||||
$(MAKE) setup __SETUP_DIR=${RELEASE_DIR} && \
|
||||
tar ${TAR_EXCLUSIONS} -cvzf ${RELEASE_DIR}.tar.gz ${RELEASE_DIR}
|
||||
|
||||
.PHONY: snapshot
|
||||
snapshot: clean
|
||||
$(eval REPO_VERSION:=$(shell $(value REPO_VERSION_CMD)))
|
||||
$(eval SNAPSHOT_NAME=apparmor-$(VERSION)~$(REPO_VERSION))
|
||||
make export_dir __EXPORT_DIR=${SNAPSHOT_NAME} __REPO_VERSION=${REPO_VERSION} && \
|
||||
make setup __SETUP_DIR=${SNAPSHOT_NAME} && \
|
||||
$(eval SNAPSHOT_NAME=apparmor-$(VERSION)~$(shell echo $(REPO_VERSION) | cut -d '-' -f 2-))
|
||||
$(MAKE) export_dir __EXPORT_DIR=${SNAPSHOT_NAME} __REPO_VERSION=${REPO_VERSION} && \
|
||||
$(MAKE) setup __SETUP_DIR=${SNAPSHOT_NAME} && \
|
||||
tar ${TAR_EXCLUSIONS} -cvzf ${SNAPSHOT_NAME}.tar.gz ${SNAPSHOT_NAME}
|
||||
|
||||
.PHONY: coverity
|
||||
coverity: snapshot
|
||||
cd $(SNAPSHOT_NAME)/libraries/libapparmor && ./configure --with-python
|
||||
$(foreach dir, $(filter-out utils profiles tests, $(DIRS)), \
|
||||
cov-build --dir $(COVERITY_DIR) -- make -C $(SNAPSHOT_NAME)/$(dir);)
|
||||
cov-build --dir $(COVERITY_DIR) -- $(MAKE) -C $(SNAPSHOT_NAME)/$(dir);)
|
||||
$(foreach dir, libraries/libapparmor utils, \
|
||||
cov-build --dir $(COVERITY_DIR) --no-command --fs-capture-search $(SNAPSHOT_NAME)/$(dir);)
|
||||
tar -cvzf $(SNAPSHOT_NAME)-$(COVERITY_DIR).tar.gz $(COVERITY_DIR)
|
||||
|
||||
.PHONY: export_dir
|
||||
export_dir:
|
||||
mkdir $(__EXPORT_DIR)
|
||||
/usr/bin/bzr export --per-file-timestamps -r $(__REPO_VERSION) $(__EXPORT_DIR) $(REPO_URL)
|
||||
echo "$(REPO_URL) $(__REPO_VERSION)" > $(__EXPORT_DIR)/common/.stamp_rev
|
||||
/usr/bin/git archive --prefix=$(__EXPORT_DIR)/ --format tar $(__REPO_VERSION) | tar xv
|
||||
echo "$(REPO_URL) $(REPO_BRANCH) $(__REPO_VERSION)" > $(__EXPORT_DIR)/common/.stamp_rev
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
-rm -rf ${RELEASE_DIR} ./apparmor-${VERSION}~* ${COVERITY_DIR}
|
||||
for dir in $(DIRS); do \
|
||||
make -C $$dir clean; \
|
||||
$(MAKE) -C $$dir clean; \
|
||||
done
|
||||
|
||||
.PHONY: setup
|
||||
setup:
|
||||
cd $(__SETUP_DIR)/libraries/libapparmor && ./autogen.sh
|
||||
# parser has an extra doc to build
|
||||
make -C $(__SETUP_DIR)/parser extra_docs
|
||||
$(MAKE) -C $(__SETUP_DIR)/parser extra_docs
|
||||
# libraries/libapparmor needs configure to have run before
|
||||
# building docs
|
||||
$(foreach dir, $(filter-out libraries/libapparmor tests, $(DIRS)), \
|
||||
make -C $(__SETUP_DIR)/$(dir) docs;)
|
||||
$(MAKE) -C $(__SETUP_DIR)/$(dir) docs;)
|
||||
|
||||
.PHONY: tag
|
||||
tag:
|
||||
bzr tag apparmor_${TAG_VERSION}
|
||||
|
||||
git tag -m 'AppArmor $(VERSION)' -s $(TAG_VERSION)
|
||||
|
@@ -1,3 +1,9 @@
|
||||
# AppArmor
|
||||
|
||||
[](https://gitlab.com/apparmor/apparmor/commits/master)
|
||||
[](https://gitlab.com/apparmor/apparmor/pipelines)
|
||||
[](https://bestpractices.coreinfrastructure.org/projects/1699)
|
||||
|
||||
------------
|
||||
Introduction
|
||||
------------
|
||||
@@ -57,7 +63,14 @@ Building and Installing AppArmor Userspace
|
||||
------------------------------------------
|
||||
|
||||
To build and install AppArmor userspace on your system, build and install in
|
||||
the following order.
|
||||
the following order. Some systems may need to export various python-related
|
||||
environment variables to complete the build. For example, before building
|
||||
anything on these systems, use something along the lines of:
|
||||
|
||||
$ export PYTHONPATH=$(realpath libraries/libapparmor/swig/python)
|
||||
$ export PYTHON=/usr/bin/python3
|
||||
$ export PYTHON_VERSION=3
|
||||
$ export PYTHON_VERSIONS=python3
|
||||
|
||||
|
||||
libapparmor:
|
||||
@@ -79,16 +92,16 @@ $ make check
|
||||
$ make install
|
||||
|
||||
|
||||
Utilities:
|
||||
$ cd utils
|
||||
$ make
|
||||
parser:
|
||||
$ cd parser
|
||||
$ make # depends on libapparmor having been built first
|
||||
$ make check
|
||||
$ make install
|
||||
|
||||
|
||||
parser:
|
||||
$ cd parser
|
||||
$ make # depends on libapparmor having been built first
|
||||
Utilities:
|
||||
$ cd utils
|
||||
$ make
|
||||
$ make check
|
||||
$ make install
|
||||
|
@@ -114,7 +114,7 @@ $(LIBAPPARMOR_A):
|
||||
echo "error: $@ is missing. Pick one of these possible solutions:" 1>&2; \
|
||||
echo " 1) Build against the in-tree libapparmor by building it first and then trying again. See the top-level README for help." 1>&2; \
|
||||
echo " 2) Build against the system libapparmor by adding USE_SYSTEM=1 to your make command." 1>&2;\
|
||||
return 1; \
|
||||
exit 1; \
|
||||
fi
|
||||
endif
|
||||
|
||||
|
@@ -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: 2017-03-31 10:44+0000\n"
|
||||
"PO-Revision-Date: 2018-02-09 23:55+0000\n"
|
||||
"Last-Translator: Tobias Bannert <tobannert@gmail.com>\n"
|
||||
"Language-Team: German <de@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2017-04-05 05:23+0000\n"
|
||||
"X-Generator: Launchpad (build 18335)\n"
|
||||
"X-Launchpad-Export-Date: 2018-02-11 05:14+0000\n"
|
||||
"X-Generator: Launchpad (build 18544)\n"
|
||||
"Language: de\n"
|
||||
|
||||
#: ../aa_enabled.c:26
|
||||
@@ -26,6 +26,10 @@ msgid ""
|
||||
" -q | --quiet Don't print out any messages\n"
|
||||
" -h | --help Print help\n"
|
||||
msgstr ""
|
||||
"%s: [Optionen]\n"
|
||||
" Optionen:\n"
|
||||
" -q | --quiet Keine Nachrichten anzeigen\n"
|
||||
" -h | --help Hilfetext anzeigen\n"
|
||||
|
||||
#: ../aa_enabled.c:45
|
||||
#, c-format
|
||||
@@ -55,14 +59,15 @@ msgstr "Nein – beim Start deaktiviert.\n"
|
||||
#: ../aa_enabled.c:77
|
||||
#, c-format
|
||||
msgid "Maybe - policy interface not available.\n"
|
||||
msgstr ""
|
||||
msgstr "Vielleicht – Richtlinienschnittstelle nicht verfügbar.\n"
|
||||
|
||||
#: ../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"
|
||||
|
||||
#: ../aa_enabled.c:84
|
||||
#, c-format
|
||||
msgid "Error - '%s'\n"
|
||||
msgstr "Fehler - »%s«\n"
|
||||
msgstr "Fehler – »%s«\n"
|
||||
|
@@ -87,7 +87,7 @@ docs: ${MANPAGES} ${HTMLMANPAGES}
|
||||
install: ${TARGET} ${MANPAGES}
|
||||
mkdir -p ${DESTDIR}/${APXS_INSTALL_DIR}
|
||||
install -m 755 $< ${DESTDIR}/${APXS_INSTALL_DIR}
|
||||
make install_manpages DESTDIR=${DESTDIR}
|
||||
$(MAKE) install_manpages DESTDIR=${DESTDIR}
|
||||
|
||||
.PHONY: clean
|
||||
clean: pod_clean
|
||||
|
@@ -82,7 +82,7 @@ SECDIR ?= ${DESTDIR}/lib/security
|
||||
.PHONY: install
|
||||
install: $(NAME).so
|
||||
install -m 755 -d $(SECDIR)
|
||||
install -m 555 $(NAME).so $(SECDIR)/
|
||||
install -m 755 $(NAME).so $(SECDIR)/
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
|
@@ -42,10 +42,9 @@ endif
|
||||
|
||||
define nl
|
||||
|
||||
|
||||
endef
|
||||
|
||||
REPO_VERSION_CMD=[ -x /usr/bin/bzr ] && /usr/bin/bzr version-info --custom --template="{revno}" . 2> /dev/null || awk '{ print $2 }' common/.stamp_rev
|
||||
REPO_VERSION_CMD=[ -x /usr/bin/git ] && /usr/bin/git describe --tags --long --abbrev=16 --match 'v*' 2> /dev/null || awk '{ print $2 }' common/.stamp_rev
|
||||
|
||||
ifndef PYTHON_VERSIONS
|
||||
PYTHON_VERSIONS = $(call map, pathsearch, python2 python3)
|
||||
|
@@ -1 +1 @@
|
||||
2.11.95
|
||||
2.13
|
||||
|
BIN
documentation/toxie.png
Normal file
BIN
documentation/toxie.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 50 KiB |
File diff suppressed because it is too large
Load Diff
@@ -1,12 +1,13 @@
|
||||
From a3b0cb6676a04cdad5cc357bc422d0398083b435 Mon Sep 17 00:00:00 2001
|
||||
From 2e7f6d0dc0f1d3642950f529b451af73fa1baf9c 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 17/17] UBUNTU: SAUCE: apparmor: af_unix mediation
|
||||
Subject: [PATCH 2/2] 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 ++++++++++++++++++++++++++++++++++++
|
||||
@@ -23,10 +24,10 @@ Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
create mode 100644 security/apparmor/include/af_unix.h
|
||||
|
||||
diff --git a/security/apparmor/Makefile b/security/apparmor/Makefile
|
||||
index dafdd387d42b..ef39226ff4aa 100644
|
||||
index e7ff2183532a..90c118f39e13 100644
|
||||
--- a/security/apparmor/Makefile
|
||||
+++ b/security/apparmor/Makefile
|
||||
@@ -4,7 +4,8 @@ obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o
|
||||
@@ -5,7 +5,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 \
|
||||
@@ -694,7 +695,7 @@ index 000000000000..c6876db2dbde
|
||||
+ return error;
|
||||
+}
|
||||
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
|
||||
index 125dad5c3fde..20cdb1c4b266 100644
|
||||
index 518d5928661b..63a8a462fc96 100644
|
||||
--- a/security/apparmor/apparmorfs.c
|
||||
+++ b/security/apparmor/apparmorfs.c
|
||||
@@ -2187,6 +2187,11 @@ static struct aa_sfs_entry aa_sfs_entry_ns[] = {
|
||||
@@ -920,7 +921,7 @@ index 4364088a0b9e..26660a1a50b0 100644
|
||||
if (!state)
|
||||
return 0;
|
||||
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
|
||||
index cc5ab23a2d84..0ede66d80a53 100644
|
||||
index 72b915dfcaf7..5533d2f1d9de 100644
|
||||
--- a/security/apparmor/lsm.c
|
||||
+++ b/security/apparmor/lsm.c
|
||||
@@ -26,6 +26,7 @@
|
||||
@@ -1390,5 +1391,5 @@ index 33d54435f8d6..dd1953b08e58 100644
|
||||
+ aa_label_sk_perm(label, op, request, sock->sk));
|
||||
}
|
||||
--
|
||||
2.11.0
|
||||
2.14.1
|
||||
|
@@ -1,4 +1,4 @@
|
||||
This series is based on what is currently in linux-next scheduled for
|
||||
inclusion in 4.14
|
||||
This is based on v4.14 final
|
||||
|
||||
af_unix-mediation is the last remaining patch that is out of tree
|
||||
base socket mediation and af_unix-mediation are the last two remaining
|
||||
patches that are out of tree
|
||||
|
File diff suppressed because it is too large
Load Diff
1395
kernel-patches/v4.15/0002-apparmor-af_unix-mediation.patch
Normal file
1395
kernel-patches/v4.15/0002-apparmor-af_unix-mediation.patch
Normal file
File diff suppressed because it is too large
Load Diff
@@ -40,6 +40,8 @@ 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>>
|
||||
@@ -62,6 +64,8 @@ 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
|
||||
@@ -108,6 +112,12 @@ 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>
|
||||
@@ -126,15 +136,23 @@ 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 on error.
|
||||
I<aa_features> family of functions that return -1 or NULL on error.
|
||||
|
||||
=head1 NOTES
|
||||
|
||||
All aa_features functions described above are present in libapparmor version
|
||||
2.10 and newer.
|
||||
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.
|
||||
|
||||
aa_features_unref() saves the value of errno when called and restores errno
|
||||
before exiting in libapparmor version 2.12 and newer.
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
|
@@ -133,7 +133,7 @@ I<*kernel_interface> will point to an I<aa_kernel_interface> object that must
|
||||
be freed by aa_kernel_interface_unref(). -1 is returned on error, with errno
|
||||
set appropriately, and I<*kernel_interface> will be set to NULL.
|
||||
|
||||
aa_kernel_features_ref() returns the value of I<kernel_features>.
|
||||
aa_kernel_interface_ref() returns the value of I<kernel_interface>.
|
||||
|
||||
The aa_kernel_interface_load() family of functions, the
|
||||
aa_kernel_interface_replace() family of functions,
|
||||
@@ -150,6 +150,9 @@ I<aa_kernel_interface> family of functions that return -1 on error.
|
||||
All aa_kernel_interface functions described above are present in libapparmor
|
||||
version 2.10 and newer.
|
||||
|
||||
aa_kernel_interface_unref() saves the value of errno when called and restores
|
||||
errno before exiting in libapparmor version 2.12 and newer.
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
None known. If you find any, please report them at
|
||||
|
@@ -34,6 +34,10 @@ 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>>
|
||||
@@ -42,6 +46,8 @@ 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);>
|
||||
@@ -50,6 +56,10 @@ 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
|
||||
@@ -59,19 +69,35 @@ 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. 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().
|
||||
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.
|
||||
|
||||
aa_policy_cache_ref() increments the reference count on the I<policy_cache>
|
||||
object.
|
||||
@@ -90,6 +116,18 @@ 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>
|
||||
@@ -102,15 +140,32 @@ 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 on error.
|
||||
I<aa_policy_cache> family of functions that return -1 or NULL on error.
|
||||
|
||||
=head1 NOTES
|
||||
|
||||
All aa_policy_cache functions described above are present in libapparmor
|
||||
version 2.10 and newer.
|
||||
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.
|
||||
|
||||
aa_policy_cache_unref() saves the value of errno when called and restores errno
|
||||
before exiting in libapparmor version 2.12 and newer.
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
|
@@ -154,6 +154,7 @@ 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,
|
||||
@@ -186,12 +187,22 @@ 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
|
||||
}
|
||||
|
@@ -34,6 +34,8 @@ 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
|
||||
}
|
||||
|
@@ -26,13 +26,13 @@ INCLUDES = $(all_includes)
|
||||
# For more information, see:
|
||||
# http://www.gnu.org/software/libtool/manual/html_node/Libtool-versioning.html
|
||||
#
|
||||
AA_LIB_CURRENT = 5
|
||||
AA_LIB_CURRENT = 6
|
||||
AA_LIB_REVISION = 0
|
||||
AA_LIB_AGE = 4
|
||||
AA_LIB_AGE = 5
|
||||
|
||||
SUFFIXES = .pc.in .pc
|
||||
|
||||
BUILT_SOURCES = grammar.h scanner.h af_protos.h
|
||||
BUILT_SOURCES = grammar.h scanner.h af_protos.h PMurHash.h
|
||||
AM_LFLAGS = -v
|
||||
AM_YFLAGS = -d -p aalogparse_
|
||||
AM_CFLAGS = -Wall
|
||||
@@ -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
|
||||
noinst_HEADERS = grammar.h parser.h scanner.h af_protos.h private.h PMurHash.h
|
||||
|
||||
libapparmor_la_SOURCES = grammar.y libaalogparse.c kernel.c scanner.c private.c features.c kernel_interface.c policy_cache.c
|
||||
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_LDFLAGS = -version-info $(AA_LIB_CURRENT):$(AA_LIB_REVISION):$(AA_LIB_AGE) -XCClinker -dynamic -pthread \
|
||||
-Wl,--version-script=$(top_srcdir)/src/libapparmor.map
|
||||
|
||||
|
317
libraries/libapparmor/src/PMurHash.c
Normal file
317
libraries/libapparmor/src/PMurHash.c
Normal file
@@ -0,0 +1,317 @@
|
||||
/*-----------------------------------------------------------------------------
|
||||
* 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;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
64
libraries/libapparmor/src/PMurHash.h
Normal file
64
libraries/libapparmor/src/PMurHash.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/*-----------------------------------------------------------------------------
|
||||
* 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
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014
|
||||
* Copyright (c) 2014-2017
|
||||
* Canonical, Ltd. (All rights reserved)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <ctype.h>
|
||||
#include <dirent.h>
|
||||
#include <fcntl.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
@@ -31,13 +32,16 @@
|
||||
#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];
|
||||
};
|
||||
|
||||
@@ -205,6 +209,29 @@ 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 == '{';
|
||||
@@ -404,6 +431,11 @@ int aa_features_new(aa_features **features, int dirfd, const char *path)
|
||||
load_features_dir(dirfd, path, f->string, STRING_SIZE) :
|
||||
load_features_file(dirfd, path, f->string, STRING_SIZE);
|
||||
if (retval == -1) {
|
||||
aa_features_unref(f);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (init_features_hash(f) == -1) {
|
||||
int save = errno;
|
||||
|
||||
aa_features_unref(f);
|
||||
@@ -446,6 +478,15 @@ 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;
|
||||
@@ -482,8 +523,12 @@ aa_features *aa_features_ref(aa_features *features)
|
||||
*/
|
||||
void aa_features_unref(aa_features *features)
|
||||
{
|
||||
int save = errno;
|
||||
|
||||
if (features && atomic_dec_and_test(&features->ref_count))
|
||||
free(features);
|
||||
|
||||
errno = save;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -576,3 +621,21 @@ 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);
|
||||
}
|
||||
|
@@ -229,10 +229,7 @@ int aa_kernel_interface_new(aa_kernel_interface **kernel_interface,
|
||||
if (kernel_features) {
|
||||
aa_features_ref(kernel_features);
|
||||
} else if (aa_features_new_from_kernel(&kernel_features) == -1) {
|
||||
int save = errno;
|
||||
|
||||
aa_kernel_interface_unref(ki);
|
||||
errno = save;
|
||||
return -1;
|
||||
}
|
||||
ki->supports_setload = aa_features_supports(kernel_features, set_load);
|
||||
@@ -240,11 +237,8 @@ int aa_kernel_interface_new(aa_kernel_interface **kernel_interface,
|
||||
|
||||
if (!apparmorfs) {
|
||||
if (find_iface_dir(&alloced_apparmorfs) == -1) {
|
||||
int save = errno;
|
||||
|
||||
alloced_apparmorfs = NULL;
|
||||
aa_kernel_interface_unref(ki);
|
||||
errno = save;
|
||||
return -1;
|
||||
}
|
||||
/* alloced_apparmorfs will be autofree'ed */
|
||||
@@ -253,10 +247,7 @@ int aa_kernel_interface_new(aa_kernel_interface **kernel_interface,
|
||||
|
||||
ki->dirfd = open(apparmorfs, O_RDONLY | O_CLOEXEC | O_DIRECTORY);
|
||||
if (ki->dirfd < 0) {
|
||||
int save = errno;
|
||||
|
||||
aa_kernel_interface_unref(ki);
|
||||
errno = save;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -283,12 +274,16 @@ aa_kernel_interface *aa_kernel_interface_ref(aa_kernel_interface *kernel_interfa
|
||||
*/
|
||||
void aa_kernel_interface_unref(aa_kernel_interface *kernel_interface)
|
||||
{
|
||||
int save = errno;
|
||||
|
||||
if (kernel_interface &&
|
||||
atomic_dec_and_test(&kernel_interface->ref_count)) {
|
||||
if (kernel_interface->dirfd >= 0)
|
||||
close(kernel_interface->dirfd);
|
||||
free(kernel_interface);
|
||||
}
|
||||
|
||||
errno = save;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -95,6 +95,19 @@ 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;
|
||||
|
||||
PRIVATE {
|
||||
global:
|
||||
_aa_is_blacklisted;
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014
|
||||
* Copyright (c) 2014-2017
|
||||
* Canonical, Ltd. (All rights reserved)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
@@ -16,8 +16,11 @@
|
||||
* 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>
|
||||
@@ -29,31 +32,155 @@
|
||||
#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 dirfd;
|
||||
int n;
|
||||
int dirfd[MAX_POLICY_CACHE_OVERLAY_DIRS];
|
||||
};
|
||||
|
||||
static int clear_cache_cb(int dirfd, const char *path, struct stat *st,
|
||||
void *data unused)
|
||||
{
|
||||
/* remove regular files */
|
||||
if (S_ISREG(st->st_mode))
|
||||
if (S_ISREG(st->st_mode)) {
|
||||
/* remove regular files */
|
||||
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, "."))
|
||||
if (aa_policy_cache_remove(policy_cache->dirfd[0], "."))
|
||||
return -1;
|
||||
|
||||
if (aa_features_write_to_file(features, policy_cache->dirfd,
|
||||
if (aa_features_write_to_file(features, policy_cache->dirfd[0],
|
||||
CACHE_FEATURES_FILE) == -1)
|
||||
return -1;
|
||||
|
||||
@@ -65,51 +192,171 @@ 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)
|
||||
{
|
||||
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)
|
||||
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)
|
||||
return -1;
|
||||
} else
|
||||
return 0;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* The cache directory needs to be refreshed */
|
||||
call_create_cache = true;
|
||||
}
|
||||
|
||||
return call_create_cache ?
|
||||
create_cache(policy_cache, kernel_features) : 0;
|
||||
return create_cache(policy_cache, kernel_features);
|
||||
}
|
||||
|
||||
struct replace_all_cb_data {
|
||||
aa_policy_cache *policy_cache;
|
||||
aa_kernel_interface *kernel_interface;
|
||||
struct miss_cb_data {
|
||||
aa_features *features;
|
||||
const char *path;
|
||||
char *pattern;
|
||||
char *cache_name; /* return */
|
||||
long n;
|
||||
};
|
||||
|
||||
static int replace_all_cb(int dirfd unused, const char *name, struct stat *st,
|
||||
void *cb_data)
|
||||
/* called on cache collision or miss where cache isn't present */
|
||||
static int cache_miss_cb(int dirfd, const struct dirent *ent, void *arg)
|
||||
{
|
||||
int retval = 0;
|
||||
struct miss_cb_data *data = arg;
|
||||
char *cache_name, *pos, *tmp;
|
||||
long n;
|
||||
int len;
|
||||
|
||||
if (!S_ISDIR(st->st_mode) && !_aa_is_blacklisted(name)) {
|
||||
struct replace_all_cb_data *data;
|
||||
/* TODO: update to tighter pattern match of just trailing #s */
|
||||
if (fnmatch(data->pattern, ent->d_name, 0))
|
||||
return 0;
|
||||
|
||||
data = (struct replace_all_cb_data *) cb_data;
|
||||
retval = aa_kernel_interface_replace_policy_from_file(data->kernel_interface,
|
||||
data->policy_cache->dirfd,
|
||||
name);
|
||||
/* 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;
|
||||
}
|
||||
|
||||
return retval;
|
||||
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)
|
||||
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;
|
||||
}
|
||||
|
||||
static int open_or_create_cache_dir(aa_features *features, int dirfd,
|
||||
const char *path, bool create)
|
||||
{
|
||||
autofree char *cache_dir = NULL;
|
||||
int fd;
|
||||
|
||||
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(fd, 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);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -135,6 +382,8 @@ int aa_policy_cache_new(aa_policy_cache **policy_cache,
|
||||
{
|
||||
aa_policy_cache *pc;
|
||||
bool create = max_caches > 0;
|
||||
autofree const char *features_id = NULL;
|
||||
int i, fd;
|
||||
|
||||
*policy_cache = NULL;
|
||||
|
||||
@@ -143,65 +392,72 @@ int aa_policy_cache_new(aa_policy_cache **policy_cache,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (max_caches > 1) {
|
||||
errno = ENOTSUP;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* TODO: currently no reaping of caches in excess of max_caches */
|
||||
pc = calloc(1, sizeof(*pc));
|
||||
if (!pc) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
pc->dirfd = -1;
|
||||
pc->n = 0;
|
||||
for (i = 0; i < MAX_POLICY_CACHE_OVERLAY_DIRS; i++)
|
||||
pc->dirfd[i] = -1;
|
||||
aa_policy_cache_ref(pc);
|
||||
|
||||
open:
|
||||
pc->dirfd = openat(dirfd, path, O_RDONLY | O_CLOEXEC | O_DIRECTORY);
|
||||
if (pc->dirfd < 0) {
|
||||
int save;
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
save = errno;
|
||||
aa_policy_cache_unref(pc);
|
||||
errno = save;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (kernel_features) {
|
||||
aa_features_ref(kernel_features);
|
||||
} else if (aa_features_new_from_kernel(&kernel_features) == -1) {
|
||||
int save = errno;
|
||||
|
||||
aa_policy_cache_unref(pc);
|
||||
errno = save;
|
||||
return -1;
|
||||
}
|
||||
pc->kernel_features = kernel_features;
|
||||
pc->features = kernel_features;
|
||||
|
||||
fd = open_or_create_cache_dir(kernel_features, dirfd, path, create);
|
||||
if (fd == -1) {
|
||||
aa_policy_cache_unref(pc);
|
||||
return -1;
|
||||
}
|
||||
pc->dirfd[0] = fd;
|
||||
pc->n = 1;
|
||||
|
||||
if (init_cache_features(pc, kernel_features, create)) {
|
||||
int save = errno;
|
||||
|
||||
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);
|
||||
errno = save;
|
||||
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)
|
||||
{
|
||||
int fd;
|
||||
|
||||
if (policy_cache->n >= MAX_POLICY_CACHE_OVERLAY_DIRS) {
|
||||
errno = ENOSPC;
|
||||
return -1;
|
||||
}
|
||||
fd = open_or_create_cache_dir(policy_cache->features, dirfd, path,
|
||||
false);
|
||||
if (fd == -1)
|
||||
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
|
||||
@@ -220,13 +476,18 @@ 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;
|
||||
|
||||
if (policy_cache && atomic_dec_and_test(&policy_cache->ref_count)) {
|
||||
aa_features_unref(policy_cache->features);
|
||||
aa_features_unref(policy_cache->kernel_features);
|
||||
if (policy_cache->dirfd != -1)
|
||||
close(policy_cache->dirfd);
|
||||
for (i = 0; i < MAX_POLICY_CACHE_OVERLAY_DIRS; i++) {
|
||||
if (policy_cache->dirfd[i] != -1)
|
||||
close(policy_cache->dirfd[i]);
|
||||
}
|
||||
free(policy_cache);
|
||||
}
|
||||
|
||||
errno = save;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -260,7 +521,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->kernel_features,
|
||||
policy_cache->features,
|
||||
NULL) == -1) {
|
||||
kernel_interface = NULL;
|
||||
return -1;
|
||||
@@ -268,10 +529,158 @@ 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_dirat_for_each(policy_cache->dirfd, ".", &cb_data,
|
||||
replace_all_cb);
|
||||
retval = _aa_overlaydirat_for_each(policy_cache->dirfd, policy_cache->n,
|
||||
&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;
|
||||
}
|
||||
|
@@ -56,6 +56,10 @@ 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 },
|
||||
@@ -178,6 +182,181 @@ static int dot_or_dot_dot_filter(const struct dirent *ent)
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* 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 *))
|
||||
{
|
||||
autoclose int cb_dirfd = -1;
|
||||
const struct dirent *ent;
|
||||
DIR *dir;
|
||||
int save, rc;
|
||||
|
||||
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;
|
||||
}
|
||||
dir = fdopendir(cb_dirfd);
|
||||
if (!dir) {
|
||||
PDEBUG("could not open directory '%s' from fd '%d': %m\n", name, cb_dirfd);
|
||||
return -1;
|
||||
}
|
||||
/* dup cd_dirfd because fdopendir has claimed the fd passed to it */
|
||||
cb_dirfd = dup(cb_dirfd);
|
||||
if (!dir) {
|
||||
PDEBUG("could not dup directory fd '%s': %m\n", name);
|
||||
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; \
|
||||
})
|
||||
|
||||
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 = scandirat(dirfd[i], ".", &list, dot_or_dot_dot_filter,
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* _aa_dirat_for_each: iterate over a directory calling cb for each entry
|
||||
* @dirfd: already opened directory
|
||||
|
@@ -17,6 +17,7 @@
|
||||
#ifndef _AA_PRIVATE_H
|
||||
#define _AA_PRIVATE_H 1
|
||||
|
||||
#include <dirent.h>
|
||||
#include <stdbool.h>
|
||||
#include <sys/apparmor_private.h>
|
||||
|
||||
@@ -51,4 +52,7 @@ 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 */
|
||||
|
@@ -1,4 +1,4 @@
|
||||
/usr/sbin/cupsd {
|
||||
/boot/ r,
|
||||
owner /boot/ r,
|
||||
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
/home/ubuntu/bzr/apparmor/tests/regression/apparmor/mkdir {
|
||||
/tmp/sdtest.7283-14445-r31VAP/tmpdir/ w,
|
||||
owner /tmp/sdtest.7283-14445-r31VAP/tmpdir/ w,
|
||||
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
/home/ubuntu/bzr/apparmor/tests/regression/apparmor/link {
|
||||
/tmp/sdtest.19088-12382-HWH57d/linkfile l,
|
||||
owner /tmp/sdtest.19088-12382-HWH57d/linkfile l,
|
||||
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
"/home/steve/tmp/my prog.sh" {
|
||||
"/home/steve/tmp/my prog.sh" r,
|
||||
owner "/home/steve/tmp/my prog.sh" r,
|
||||
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
profile "test space" {
|
||||
/lib/x86_64-linux-gnu/libdl-2.13.so r,
|
||||
owner /lib/x86_64-linux-gnu/libdl-2.13.so r,
|
||||
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
/home/ubuntu/bzr/apparmor/tests/regression/apparmor/link {
|
||||
/tmp/sdtest.19088-12382-HWH57d/linkfile l,
|
||||
owner /tmp/sdtest.19088-12382-HWH57d/linkfile l,
|
||||
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
/usr/sbin/vsftpd {
|
||||
/home/bane/foo r,
|
||||
owner /home/bane/foo r,
|
||||
|
||||
}
|
||||
|
@@ -2,6 +2,8 @@
|
||||
# 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.
|
||||
@@ -22,10 +24,11 @@ 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
|
||||
MANPAGES=apparmor.d.5 apparmor.7 apparmor_parser.8 subdomain.conf.5 aa-teardown.8
|
||||
|
||||
YACC := /usr/bin/bison
|
||||
YFLAGS := -d
|
||||
@@ -179,7 +182,7 @@ $(LIBAPPARMOR_A):
|
||||
echo "error: $@ is missing. Pick one of these possible solutions:" 1>&2; \
|
||||
echo " 1) Build against the in-tree libapparmor by building it first and then trying again. See the top-level README for help." 1>&2; \
|
||||
echo " 2) Build against the system libapparmor by adding USE_SYSTEM=1 to your make command." 1>&2;\
|
||||
return 1; \
|
||||
exit 1; \
|
||||
fi
|
||||
endif
|
||||
|
||||
@@ -314,12 +317,9 @@ install-redhat:
|
||||
install -m 755 rc.apparmor.$(subst install-,,$@) $(DESTDIR)/etc/init.d/apparmor
|
||||
|
||||
.PHONY: install-suse
|
||||
install-suse:
|
||||
install -m 755 -d $(DESTDIR)/etc/init.d
|
||||
install -m 755 rc.apparmor.$(subst install-,,$(@)) $(DESTDIR)/etc/init.d/boot.apparmor
|
||||
install-suse: install-systemd
|
||||
install -m 755 -d $(DESTDIR)/sbin
|
||||
ln -sf /etc/init.d/boot.apparmor $(DESTDIR)/sbin/rcapparmor
|
||||
ln -sf rcapparmor $(DESTDIR)/sbin/rcsubdomain
|
||||
ln -sf service $(DESTDIR)/sbin/rcapparmor
|
||||
|
||||
.PHONY: install-slackware
|
||||
install-slackware:
|
||||
@@ -379,6 +379,14 @@ 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 644 apparmor.systemd $(APPARMOR_BIN_PREFIX)
|
||||
install -m 755 -d $(DESTDIR)/sbin
|
||||
install -m 755 aa-teardown $(DESTDIR)/sbin
|
||||
|
||||
ifndef VERBOSE
|
||||
.SILENT: clean
|
||||
endif
|
||||
|
10
parser/aa-teardown
Normal file
10
parser/aa-teardown
Normal file
@@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
|
||||
test $# = 0 || {
|
||||
echo "Usage: $0"
|
||||
echo
|
||||
echo "Unloads all AppArmor profiles"
|
||||
exit 1
|
||||
}
|
||||
|
||||
/lib/apparmor/apparmor.systemd stop
|
40
parser/aa-teardown.pod
Normal file
40
parser/aa-teardown.pod
Normal file
@@ -0,0 +1,40 @@
|
||||
# ----------------------------------------------------------------------
|
||||
# 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<http://wiki.apparmor.net>.
|
||||
|
||||
=cut
|
@@ -55,7 +55,7 @@ B<VARIABLE> = '@{' I<ALPHA> [ ( I<ALPHANUMERIC> | '_' ) ... ] '}'
|
||||
|
||||
B<ALIAS RULE> = 'alias' I<ABS PATH> '-E<gt>' I<REWRITTEN ABS PATH> ','
|
||||
|
||||
B<INCLUDE> = '#include' ( I<ABS PATH> | I<MAGIC PATH> )
|
||||
B<INCLUDE> = ( '#include' | 'include' ) [ 'if exists' ] ( I<ABS PATH> | I<MAGIC PATH> )
|
||||
|
||||
B<ABS PATH> = '"' path '"' (the path is passed to open(2))
|
||||
|
||||
@@ -1414,13 +1414,17 @@ rules into a rule block.
|
||||
|
||||
=head2 #include mechanism
|
||||
|
||||
AppArmor provides an easy abstraction mechanism to group common file
|
||||
AppArmor provides an easy abstraction mechanism to group common
|
||||
access requirements; this abstraction is an extremely flexible way to
|
||||
grant site-specific rights and makes writing new AppArmor profiles very
|
||||
simple by assembling the needed building blocks for any given program.
|
||||
|
||||
The use of '#include' is modelled directly after cpp(1); its use will
|
||||
replace the '#include' statement with the specified file's contents.
|
||||
The leading '#' is optional, and the '#include' keyword can be followed
|
||||
by an option conditional 'if exists' that specifies profile compilation
|
||||
should continue if the specified file or directory is not found.
|
||||
|
||||
B<#include "/absolute/path"> specifies that F</absolute/path> should be
|
||||
used. B<#include "relative/path"> specifies that F<relative/path> should
|
||||
be used, where the path is relative to the current working directory.
|
||||
|
@@ -70,9 +70,12 @@ with B<.> (except for the root B</>) so profiles are easier to manage
|
||||
(e.g. the F</usr/sbin/nscd> profile would be named F<usr.sbin.nscd>).
|
||||
|
||||
Profiles are applied to a process at exec(3) time (as seen through the
|
||||
execve(2) system call); an already running process cannot be confined.
|
||||
However, once a profile is loaded for a program, that program will be
|
||||
confined on the next exec(3).
|
||||
execve(2) system call): once a profile is loaded for a program, that
|
||||
program will be confined on the next exec(3). If a process is already
|
||||
running under a profile, when one replaces that profile in the kernel,
|
||||
the updated profile is applied immediately to that process.
|
||||
On the other hand, a process that is already running unconfined cannot
|
||||
be confined.
|
||||
|
||||
AppArmor supports the Linux kernel's securityfs filesystem, and makes
|
||||
available the list of the profiles currently loaded; to mount the
|
||||
|
26
parser/apparmor.service
Normal file
26
parser/apparmor.service
Normal file
@@ -0,0 +1,26 @@
|
||||
[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
|
100
parser/apparmor.systemd
Normal file
100
parser/apparmor.systemd
Normal file
@@ -0,0 +1,100 @@
|
||||
#!/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
|
@@ -46,9 +46,10 @@ 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, *.repnew, *.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, *.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.
|
||||
|
||||
The input supplied to B<apparmor_parser> should be in the format described in
|
||||
apparmor.d(5).
|
||||
@@ -232,8 +233,28 @@ inconsistent state
|
||||
|
||||
=item -L, --cache-loc
|
||||
|
||||
Set the location of the cache directory. If not specified the cache location
|
||||
defaults to /etc/apparmor.d/cache
|
||||
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 /etc/apparmor.d/cache.d
|
||||
|
||||
=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.
|
||||
|
||||
=item -Q, --skip-kernel-load
|
||||
|
||||
|
@@ -144,7 +144,7 @@ static int include_dir_cb(int dirfd unused, const char *name, struct stat *st,
|
||||
return 0;
|
||||
}
|
||||
|
||||
void include_filename(char *filename, int search)
|
||||
void include_filename(char *filename, int search, bool if_exists)
|
||||
{
|
||||
FILE *include_file = NULL;
|
||||
struct stat my_stat;
|
||||
@@ -161,11 +161,14 @@ void include_filename(char *filename, int search)
|
||||
include_file = fopen(fullpath, "r");
|
||||
}
|
||||
|
||||
if (!include_file)
|
||||
if (!include_file) {
|
||||
if (if_exists)
|
||||
return;
|
||||
yyerror(_("Could not open '%s'"),
|
||||
fullpath ? fullpath: filename);
|
||||
}
|
||||
|
||||
if (fstat(fileno(include_file), &my_stat))
|
||||
if (fstat(fileno(include_file), &my_stat))
|
||||
yyerror(_("fstat failed for '%s'"), fullpath);
|
||||
|
||||
if (S_ISREG(my_stat.st_mode)) {
|
||||
@@ -200,7 +203,7 @@ MODES {MODE_CHARS}+
|
||||
WS [[:blank:]]
|
||||
NUMBER [[:digit:]]+
|
||||
|
||||
ID_CHARS [^ \t\n"!,]
|
||||
ID_CHARS [^ \t\r\n"!,]
|
||||
ID {ID_CHARS}|(,{ID_CHARS}|\\[ ]|\\\t|\\\"|\\!|\\,)
|
||||
IDS {ID}+
|
||||
POST_VAR_ID_CHARS [^ \t\n"!,]{-}[=\+]
|
||||
@@ -257,6 +260,7 @@ LT_EQUAL <=
|
||||
%x UNIX_MODE
|
||||
%x CHANGE_PROFILE_MODE
|
||||
%x INCLUDE
|
||||
%x INCLUDE_EXISTS
|
||||
|
||||
%%
|
||||
|
||||
@@ -269,19 +273,44 @@ LT_EQUAL <=
|
||||
}
|
||||
%}
|
||||
|
||||
<INITIAL,SUB_ID_WS,INCLUDE,LIST_VAL_MODE,EXTCOND_MODE,LIST_COND_VAL,LIST_COND_PAREN_VAL,LIST_COND_MODE,EXTCONDLIST_MODE,ASSIGN_MODE,NETWORK_MODE,CHANGE_PROFILE_MODE,RLIMIT_MODE,MOUNT_MODE,DBUS_MODE,SIGNAL_MODE,PTRACE_MODE,UNIX_MODE>{
|
||||
<INITIAL,SUB_ID_WS,INCLUDE,INCLUDE_EXISTS,LIST_VAL_MODE,EXTCOND_MODE,LIST_COND_VAL,LIST_COND_PAREN_VAL,LIST_COND_MODE,EXTCONDLIST_MODE,ASSIGN_MODE,NETWORK_MODE,CHANGE_PROFILE_MODE,RLIMIT_MODE,MOUNT_MODE,DBUS_MODE,SIGNAL_MODE,PTRACE_MODE,UNIX_MODE>{
|
||||
{WS}+ { DUMP_PREPROCESS; /* Ignoring whitespace */ }
|
||||
}
|
||||
|
||||
<INCLUDE>{
|
||||
(\<([^\> \t\n]+)\>|\"([^\" \t\n]+)\") { /* <filename> */
|
||||
<INCLUDE_EXISTS>{
|
||||
(\<([^"\>\t\r\n]+)\>|{QUOTED_ID}) { /* <filename> | "filename" */
|
||||
autofree char *filename = strndup(yytext, yyleng - 1);
|
||||
include_filename(filename + 1, *filename == '<');
|
||||
include_filename(filename + 1, *filename == '<', true);
|
||||
POP_NODUMP();
|
||||
}
|
||||
|
||||
[^\<\>\" \t\n]+ { /* filename */
|
||||
include_filename(yytext, 0);
|
||||
(\<{QUOTED_ID}\>) { /* <"filename"> */
|
||||
autofree char *filename = strndup(yytext, yyleng - 2);
|
||||
include_filename(filename + 2, true, true);
|
||||
POP_NODUMP();
|
||||
}
|
||||
|
||||
({IDS}|{QUOTED_ID}) { /* filename */
|
||||
include_filename(yytext, 0, true);
|
||||
POP_NODUMP();
|
||||
}
|
||||
}
|
||||
|
||||
<INCLUDE>{
|
||||
(\<([^"\>\t\r\n]+)\>|{QUOTED_ID}) { /* <filename> | "filename" */
|
||||
autofree char *filename = strndup(yytext, yyleng - 1);
|
||||
include_filename(filename + 1, *filename == '<', false);
|
||||
POP_NODUMP();
|
||||
}
|
||||
|
||||
(\<{QUOTED_ID}\>) { /* <"filename"> */
|
||||
autofree char *filename = strndup(yytext, yyleng - 2);
|
||||
include_filename(filename + 2, true, false);
|
||||
POP_NODUMP();
|
||||
}
|
||||
|
||||
({IDS}|{QUOTED_ID}) { /* filename */
|
||||
include_filename(yytext, 0, false);
|
||||
POP_NODUMP();
|
||||
}
|
||||
}
|
||||
@@ -527,6 +556,20 @@ LT_EQUAL <=
|
||||
}
|
||||
}
|
||||
|
||||
#include{WS}+if{WS}+exists/{WS}.*\r?\n {
|
||||
/* Don't use PUSH() macro here as we don't want #include echoed out.
|
||||
* It needs to be handled specially
|
||||
*/
|
||||
yy_push_state(INCLUDE_EXISTS);
|
||||
}
|
||||
|
||||
include{WS}+if{WS}+exists/{WS} {
|
||||
/* Don't use PUSH() macro here as we don't want #include echoed out.
|
||||
* It needs to be handled specially
|
||||
*/
|
||||
yy_push_state(INCLUDE_EXISTS);
|
||||
}
|
||||
|
||||
#include/.*\r?\n {
|
||||
/* Don't use PUSH() macro here as we don't want #include echoed out.
|
||||
* It needs to be handled specially
|
||||
@@ -675,4 +718,5 @@ unordered_map<int, string> state_names = {
|
||||
STATE_TABLE_ENT(UNIX_MODE),
|
||||
STATE_TABLE_ENT(CHANGE_PROFILE_MODE),
|
||||
STATE_TABLE_ENT(INCLUDE),
|
||||
STATE_TABLE_ENT(INCLUDE_EXISTS),
|
||||
};
|
||||
|
@@ -2,7 +2,7 @@
|
||||
* Copyright (c) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
|
||||
* NOVELL (All rights reserved)
|
||||
*
|
||||
* Copyright (c) 2010 - 2013
|
||||
* Copyright (c) 2010 - 2018
|
||||
* Canonical Ltd. (All rights reserved)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
@@ -60,7 +60,7 @@
|
||||
#define UNPRIVILEGED_OPS (!(PRIVILEGED_OPS))
|
||||
|
||||
const char *parser_title = "AppArmor parser";
|
||||
const char *parser_copyright = "Copyright (C) 1999-2008 Novell Inc.\nCopyright 2009-2012 Canonical Ltd.";
|
||||
const char *parser_copyright = "Copyright (C) 1999-2008 Novell Inc.\nCopyright 2009-2018 Canonical Ltd.";
|
||||
|
||||
int opt_force_complain = 0;
|
||||
int binary_input = 0;
|
||||
@@ -97,12 +97,17 @@ 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 char *cacheloc = NULL;
|
||||
static char *cacheloc[MAX_CACHE_LOCS];
|
||||
static int cacheloc_n = 0;
|
||||
static bool print_cache_dir = false;
|
||||
|
||||
static aa_features *features = NULL;
|
||||
static aa_features *compile_features = NULL;
|
||||
static aa_features *kernel_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:";
|
||||
@@ -124,6 +129,7 @@ struct option long_options[] = {
|
||||
{"ofile", 1, 0, 'o'},
|
||||
{"match-string", 1, 0, 'm'},
|
||||
{"features-file", 1, 0, 'M'},
|
||||
{"kernel-features", 1, 0, 138}, /* no short option */
|
||||
{"quiet", 0, 0, 'q'},
|
||||
{"skip-kernel-load", 0, 0, 'Q'},
|
||||
{"verbose", 0, 0, 'v'},
|
||||
@@ -149,6 +155,7 @@ struct option long_options[] = {
|
||||
{"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 */
|
||||
{NULL, 0, 0, 0},
|
||||
};
|
||||
|
||||
@@ -178,7 +185,8 @@ 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 Use only features in file n\n"
|
||||
"-M n, --features-file n Compile features set in file n\n"
|
||||
"--kernel-features n Kernel features set 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"
|
||||
@@ -188,7 +196,8 @@ 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"
|
||||
"-L, --cache-loc n Set the location of the profile cache\n"
|
||||
" --print-cache_dir Print the cache directory path\n"
|
||||
"-L, --cache-loc n Set the location of the profile caches\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"
|
||||
@@ -222,6 +231,51 @@ 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, 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) {
|
||||
if (n == max_size) {
|
||||
errno = E2BIG;
|
||||
return -1;
|
||||
}
|
||||
cacheloc[n] = (char *) malloc(p - s + 1);
|
||||
if (cacheloc[n] == NULL)
|
||||
return -1;
|
||||
memcpy(cacheloc[n], s, p - s);
|
||||
cacheloc[n][p - s] = 0;
|
||||
n++;
|
||||
}
|
||||
p++;
|
||||
s = p;
|
||||
} else
|
||||
p++;
|
||||
}
|
||||
if (p != s) {
|
||||
if (n == max_size) {
|
||||
errno = E2BIG;
|
||||
return -1;
|
||||
}
|
||||
cacheloc[n] = (char *) malloc(p - s + 1);
|
||||
if (cacheloc[n] == NULL)
|
||||
return -1;
|
||||
memcpy(cacheloc[n], s, p - s);
|
||||
cacheloc[n][p - s] = 0;
|
||||
n++;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
/* Treat conf file like options passed on command line
|
||||
*/
|
||||
static int getopt_long_file(FILE *f, const struct option *longopts,
|
||||
@@ -329,8 +383,7 @@ static int process_arg(int c, char *optarg)
|
||||
switch (c) {
|
||||
case 0:
|
||||
PERROR("Assert, in getopt_long handling\n");
|
||||
display_usage(progname);
|
||||
exit(0);
|
||||
exit(1);
|
||||
break;
|
||||
case 'a':
|
||||
count++;
|
||||
@@ -449,7 +502,7 @@ static int process_arg(int c, char *optarg)
|
||||
}
|
||||
break;
|
||||
case 'm':
|
||||
if (aa_features_new_from_string(&features,
|
||||
if (aa_features_new_from_string(&compile_features,
|
||||
optarg, strlen(optarg))) {
|
||||
fprintf(stderr,
|
||||
"Failed to parse features string: %m\n");
|
||||
@@ -457,13 +510,21 @@ static int process_arg(int c, char *optarg)
|
||||
}
|
||||
break;
|
||||
case 'M':
|
||||
if (aa_features_new(&features, AT_FDCWD, optarg)) {
|
||||
if (aa_features_new(&compile_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;
|
||||
@@ -507,7 +568,11 @@ static int process_arg(int c, char *optarg)
|
||||
skip_bad_cache_rebuild = 1;
|
||||
break;
|
||||
case 'L':
|
||||
cacheloc = strdup(optarg);
|
||||
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);
|
||||
}
|
||||
break;
|
||||
case 'Q':
|
||||
kernel_load = 0;
|
||||
@@ -536,8 +601,12 @@ 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;
|
||||
default:
|
||||
display_usage(progname);
|
||||
/* 'unrecognized option' error message gets printed by getopt_long() */
|
||||
exit(1);
|
||||
break;
|
||||
}
|
||||
@@ -559,7 +628,6 @@ static int process_args(int argc, char *argv[])
|
||||
if (count > 1) {
|
||||
PERROR("%s: Too many actions given on the command line.\n",
|
||||
progname);
|
||||
display_usage(progname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -592,7 +660,6 @@ 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;
|
||||
}
|
||||
|
||||
@@ -623,33 +690,37 @@ no_match:
|
||||
perms_create = 1;
|
||||
}
|
||||
|
||||
static void set_supported_features(void)
|
||||
static void set_supported_features(aa_features *kernel_features unused)
|
||||
{
|
||||
/* has process_args() already assigned a match string? */
|
||||
if (!features && aa_features_new_from_kernel(&features) == -1) {
|
||||
if (!compile_features && aa_features_new_from_kernel(&compile_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(features, "file");
|
||||
kernel_supports_network = aa_features_supports(features, "network");
|
||||
kernel_supports_unix = aa_features_supports(features,
|
||||
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,
|
||||
"network/af_unix");
|
||||
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,
|
||||
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,
|
||||
"policy/set_load");
|
||||
kernel_supports_diff_encode = aa_features_supports(features,
|
||||
kernel_supports_diff_encode = aa_features_supports(compile_features,
|
||||
"policy/diff_encode");
|
||||
kernel_supports_stacking = aa_features_supports(features,
|
||||
kernel_supports_stacking = aa_features_supports(compile_features,
|
||||
"domain/stack");
|
||||
|
||||
if (aa_features_supports(features, "policy/versions/v7"))
|
||||
if (aa_features_supports(compile_features, "policy/versions/v7"))
|
||||
kernel_abi_version = 7;
|
||||
else if (aa_features_supports(features, "policy/versions/v6"))
|
||||
else if (aa_features_supports(compile_features, "policy/versions/v6"))
|
||||
kernel_abi_version = 6;
|
||||
|
||||
if (!kernel_supports_diff_encode)
|
||||
@@ -657,6 +728,33 @@ static void set_supported_features(void)
|
||||
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, 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)
|
||||
{
|
||||
@@ -741,10 +839,11 @@ int test_for_dir_mode(const char *basename, const char *linkdir)
|
||||
}
|
||||
|
||||
int process_profile(int option, aa_kernel_interface *kernel_interface,
|
||||
const char *profilename, const char *cachedir)
|
||||
const char *profilename, aa_policy_cache *pc)
|
||||
{
|
||||
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;
|
||||
@@ -784,9 +883,17 @@ int process_profile(int option, aa_kernel_interface *kernel_interface,
|
||||
}
|
||||
|
||||
/* setup cachename and tstamp */
|
||||
if (!force_complain && !skip_cache) {
|
||||
cachename = cache_filename(cachedir, basename);
|
||||
valid_read_cache(cachename);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -818,8 +925,6 @@ 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)
|
||||
@@ -855,15 +960,27 @@ 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);
|
||||
PERROR("Warning failed to create cache: %s\n",
|
||||
pwarn("Warning failed to create cache: %s\n",
|
||||
basename);
|
||||
} else {
|
||||
install_cache(cachetmpname, cachename);
|
||||
install_cache(cachetmpname, writecachename);
|
||||
}
|
||||
}
|
||||
out:
|
||||
@@ -1005,7 +1122,7 @@ static void setup_parallel_compile(void)
|
||||
struct dir_cb_data {
|
||||
aa_kernel_interface *kernel_interface;
|
||||
const char *dirname; /* name of the parent dir */
|
||||
const char *cachedir; /* path to the cache sub directory */
|
||||
aa_policy_cache *policy_cache; /* policy_cache to use */
|
||||
};
|
||||
|
||||
/* data - pointer to a dir_cb_data */
|
||||
@@ -1020,7 +1137,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->cachedir),
|
||||
path, cb_data->policy_cache),
|
||||
handle_work_result);
|
||||
}
|
||||
return rc;
|
||||
@@ -1046,17 +1163,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 (!features) {
|
||||
if (!kernel_features && aa_features_new_from_kernel(&kernel_features) == -1) {
|
||||
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[])
|
||||
@@ -1092,7 +1209,7 @@ int main(int argc, char *argv[])
|
||||
setup_flags();
|
||||
|
||||
if (!(UNPRIVILEGED_OPS) &&
|
||||
aa_kernel_interface_new(&kernel_interface, features, apparmorfs) == -1) {
|
||||
aa_kernel_interface_new(&kernel_interface, kernel_features, apparmorfs) == -1) {
|
||||
PERROR(_("Warning: unable to find a suitable fs in %s, is it "
|
||||
"mounted?\nUse --subdomainfs to override.\n"),
|
||||
MOUNTED_FS);
|
||||
@@ -1100,18 +1217,28 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
if ((!skip_cache && (write_cache || !skip_read_cache)) ||
|
||||
force_clear_cache) {
|
||||
uint16_t max_caches = write_cache && cond_clear_cache ? 1 : 0;
|
||||
print_cache_dir || force_clear_cache) {
|
||||
uint16_t max_caches = write_cache && cond_clear_cache ? (uint16_t) (-1) : 0;
|
||||
|
||||
if (!cacheloc && asprintf(&cacheloc, "%s/cache", basedir) == -1) {
|
||||
PERROR(_("Memory allocation error."));
|
||||
return 1;
|
||||
if (!cacheloc[0]) {
|
||||
char *tmp;
|
||||
|
||||
if (asprintf(&tmp, "%s/cache.d", basedir) == -1) {
|
||||
PERROR(_("Memory allocation error."));
|
||||
return 1;
|
||||
}
|
||||
cacheloc[0] = tmp;
|
||||
cacheloc_n = 1;
|
||||
}
|
||||
if (print_cache_dir)
|
||||
return do_print_cache_dirs(kernel_features, cacheloc,
|
||||
cacheloc_n) ? 0 : 1;
|
||||
|
||||
if (force_clear_cache) {
|
||||
if (aa_policy_cache_remove(AT_FDCWD, cacheloc)) {
|
||||
/* only ever write to the first cacheloc location */
|
||||
if (aa_policy_cache_remove(AT_FDCWD, cacheloc[0])) {
|
||||
PERROR(_("Failed to clear cache files (%s): %s\n"),
|
||||
cacheloc, strerror(errno));
|
||||
cacheloc[0], strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1121,25 +1248,34 @@ 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, features,
|
||||
AT_FDCWD, cacheloc, max_caches);
|
||||
retval = aa_policy_cache_new(&policy_cache, kernel_features,
|
||||
AT_FDCWD, cacheloc[0], max_caches);
|
||||
if (retval) {
|
||||
if (errno != ENOENT && errno != EEXIST) {
|
||||
if (errno != ENOENT && errno != EEXIST && errno != EROFS) {
|
||||
PERROR(_("Failed setting up policy cache (%s): %s\n"),
|
||||
cacheloc, strerror(errno));
|
||||
cacheloc[0], strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (show_cache) {
|
||||
if (max_caches > 0)
|
||||
PERROR("Cache write disabled: Cannot create cache '%s': %m\n",
|
||||
cacheloc);
|
||||
cacheloc[0]);
|
||||
else
|
||||
PERROR("Cache read/write disabled: Policy cache is invalid\n");
|
||||
PERROR("Cache read/write disabled: Policy cache is invalid: %m\n");
|
||||
}
|
||||
|
||||
write_cache = 0;
|
||||
skip_read_cache = 1;
|
||||
} 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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1170,7 +1306,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
memset(&cb_data, 0, sizeof(struct dir_cb_data));
|
||||
cb_data.dirname = profilename;
|
||||
cb_data.cachedir = cacheloc;
|
||||
cb_data.policy_cache = policy_cache;
|
||||
cb_data.kernel_interface = kernel_interface;
|
||||
cb = binary_input ? binary_dir_cb : profile_dir_cb;
|
||||
if ((retval = dirat_for_each(AT_FDCWD, profilename,
|
||||
@@ -1184,7 +1320,7 @@ int main(int argc, char *argv[])
|
||||
handle_work_result);
|
||||
} else {
|
||||
work_spawn(process_profile(option, kernel_interface,
|
||||
profilename, cacheloc),
|
||||
profilename, policy_cache),
|
||||
handle_work_result);
|
||||
}
|
||||
|
||||
|
217
parser/po/de.po
217
parser/po/de.po
@@ -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: 2015-09-05 20:55+0000\n"
|
||||
"PO-Revision-Date: 2018-04-06 14:39+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: 2016-06-01 05:15+0000\n"
|
||||
"X-Generator: Launchpad (build 18053)\n"
|
||||
"X-Launchpad-Export-Date: 2018-04-07 05:20+0000\n"
|
||||
"X-Generator: Launchpad (build 18599)\n"
|
||||
"Language: de\n"
|
||||
|
||||
#: ../parser_include.c:113
|
||||
#: ../parser_include.c:113 ../parser_include.c:111
|
||||
msgid "Error: Out of memory.\n"
|
||||
msgstr "Fehler: Kein Speicher vorhanden.\n"
|
||||
msgstr "Fehler: nicht genügend Speicher!\n"
|
||||
|
||||
#: ../parser_include.c:123
|
||||
#: ../parser_include.c:123 ../parser_include.c:121
|
||||
#, 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,99 +31,108 @@ 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:147 ../parser_include.c:151
|
||||
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:69 ../parser_interface.c:72 ../parser_interface.c:49
|
||||
msgid "Bad write position\n"
|
||||
msgstr "Ungültige Schreibposition\n"
|
||||
|
||||
#: ../parser_interface.c:72 ../parser_interface.c:75
|
||||
#: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52
|
||||
msgid "Permission denied\n"
|
||||
msgstr "Zugriff verweigert\n"
|
||||
|
||||
#: ../parser_interface.c:75 ../parser_interface.c:78
|
||||
#: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55
|
||||
msgid "Out of memory\n"
|
||||
msgstr "Kein Speicher vorhanden\n"
|
||||
msgstr "Nicht genügend Speicher!\n"
|
||||
|
||||
#: ../parser_interface.c:78 ../parser_interface.c:81
|
||||
#: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58
|
||||
msgid "Couldn't copy profile: Bad memory address\n"
|
||||
msgstr "Profil konnte nicht kopiert werden: Keine Speicheradresse\n"
|
||||
msgstr "Profil konnte nicht kopiert werden: falsche Speicheradresse\n"
|
||||
|
||||
#: ../parser_interface.c:81 ../parser_interface.c:84
|
||||
#: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61
|
||||
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:84 ../parser_interface.c:87 ../parser_interface.c:64
|
||||
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:87 ../parser_interface.c:90 ../parser_interface.c:67
|
||||
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:90 ../parser_interface.c:93 ../parser_interface.c:70
|
||||
msgid "Profile already exists\n"
|
||||
msgstr "Profil ist bereits vorhanden\n"
|
||||
|
||||
#: ../parser_interface.c:93 ../parser_interface.c:96
|
||||
#: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73
|
||||
msgid "Profile doesn't exist\n"
|
||||
msgstr "Profil ist nicht vorhanden\n"
|
||||
|
||||
#: ../parser_interface.c:96 ../parser_interface.c:99
|
||||
#: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76
|
||||
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:99 ../parser_interface.c:102 ../parser_interface.c:79
|
||||
#, 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"
|
||||
@@ -136,6 +145,7 @@ 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"
|
||||
@@ -146,16 +156,19 @@ 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."
|
||||
@@ -171,22 +184,24 @@ 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:100 parser_lex.l:163 parser_lex.l:169
|
||||
#, 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:104 parser_lex.l:167 parser_lex.l:173
|
||||
#, c-format
|
||||
msgid "fstat failed for '%s'"
|
||||
msgstr "fstat fehlgeschlagen für »%s«"
|
||||
@@ -201,18 +216,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:155 parser_lex.l:133 parser_lex.l:139
|
||||
#, 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:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638
|
||||
#, c-format
|
||||
msgid "Found unexpected character: '%s'"
|
||||
msgstr "Unerwartetes Zeichen gefunden: »%s«"
|
||||
|
||||
#: parser_lex.l:386 parser_lex.l:418
|
||||
#: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428
|
||||
msgid "Variable declarations do not accept trailing commas"
|
||||
msgstr "Variablendeklarationen dürfen nicht mit Kommata enden"
|
||||
|
||||
@@ -221,7 +236,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_main.c:333 ../parser_common.c:61 ../parser_common.c:106
|
||||
#, c-format
|
||||
msgid "Warning from %s (%s%sline %d): %s"
|
||||
msgstr "Warnung aus %s (%s%sZeile %d): %s"
|
||||
@@ -233,7 +248,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:577 ../parser_main.c:616 ../parser_main.c:479
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Warning: unable to find a suitable fs in %s, is it mounted?\n"
|
||||
@@ -243,7 +258,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:597 ../parser_main.c:635 ../parser_main.c:498
|
||||
#, c-format
|
||||
msgid ""
|
||||
"%s: Sorry. You need root privileges to run this program.\n"
|
||||
@@ -252,7 +267,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:604 ../parser_main.c:642 ../parser_main.c:505
|
||||
#, c-format
|
||||
msgid ""
|
||||
"%s: Warning! You've set this program setuid root.\n"
|
||||
@@ -265,7 +280,7 @@ msgstr ""
|
||||
"\n"
|
||||
|
||||
#: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836
|
||||
#: ../parser_main.c:946
|
||||
#: ../parser_main.c:946 ../parser_main.c:860
|
||||
#, c-format
|
||||
msgid "Error: Could not read profile %s: %s.\n"
|
||||
msgstr "Fehler: Profil »%s« konnte nicht gelesen werden: »%s«.\n"
|
||||
@@ -281,26 +296,33 @@ 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:740 ../parser_main.c:872 ../parser_main.c:757
|
||||
#, 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:744 ../parser_main.c:876 ../parser_main.c:761
|
||||
#, 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:910 ../parser_main.c:1058 ../parser_main.c:967
|
||||
#, 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:426 ../parser_misc.c:597 ../parser_misc.c:339
|
||||
msgid ""
|
||||
"Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n"
|
||||
"See the apparmor.d(5) manpage for details.\n"
|
||||
@@ -310,17 +332,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:645 ../parser_misc.c:380 ../parser_misc.c:387
|
||||
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:491 ../parser_misc.c:662 ../parser_misc.c:404
|
||||
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:502 ../parser_misc.c:673 ../parser_misc.c:415
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Unconfined exec qualifier (%c%c) allows some dangerous environment variables "
|
||||
@@ -331,7 +353,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:722 ../parser_misc.c:423 ../parser_misc.c:464
|
||||
#, c-format
|
||||
msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified"
|
||||
msgstr ""
|
||||
@@ -339,7 +361,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:716 ../parser_misc.c:450 ../parser_misc.c:458
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Exec qualifier '%c%c' invalid, conflicting qualifier already specified"
|
||||
@@ -347,12 +369,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:593 ../parser_misc.c:764 ../parser_misc.c:506
|
||||
#, 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:615 ../parser_misc.c:786 ../parser_misc.c:528
|
||||
#, c-format
|
||||
msgid "Internal error generated invalid perm 0x%llx\n"
|
||||
msgstr "Interner Fehler erzeugte ungültige Zugriffsrechte 0x%llx\n"
|
||||
@@ -363,68 +385,69 @@ 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:92 ../parser_merge.c:91 ../parser_merge.c:83
|
||||
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:111 ../parser_merge.c:113 ../parser_merge.c:105
|
||||
#, 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:236 parser_yacc.y:277 parser_yacc.y:320
|
||||
msgid "Profile attachment must begin with a '/'."
|
||||
msgstr "Profilanhang muss mit einem »/« beginnen."
|
||||
|
||||
#: parser_yacc.y:260 parser_yacc.y:302
|
||||
#: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348
|
||||
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:296 parser_yacc.y:338 parser_yacc.y:384
|
||||
#, 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:417 parser_yacc.y:460 parser_yacc.y:506
|
||||
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:421 parser_yacc.y:464 parser_yacc.y:510
|
||||
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:424 parser_yacc.y:467 parser_yacc.y:513
|
||||
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:427 parser_yacc.y:470 parser_yacc.y:516
|
||||
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:441 parser_yacc.y:484 parser_yacc.y:530
|
||||
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:463 parser_yacc.y:506 parser_yacc.y:552
|
||||
#, 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:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594
|
||||
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'"
|
||||
@@ -432,80 +455,81 @@ 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:524 parser_yacc.y:556 parser_yacc.y:602
|
||||
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:549 parser_yacc.y:587 parser_yacc.y:633
|
||||
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:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660
|
||||
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:649 parser_yacc.y:696 parser_yacc.y:786
|
||||
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:680 parser_yacc.y:720 parser_yacc.y:810
|
||||
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:689 parser_yacc.y:729 parser_yacc.y:819
|
||||
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:824 parser_yacc.y:885 parser_yacc.y:992
|
||||
#, 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:882 parser_yacc.y:986 parser_yacc.y:1092
|
||||
msgid "unsafe rule missing exec permissions"
|
||||
msgstr "Fehlende Ausführungsrechte bei unsicherer Regel"
|
||||
|
||||
#: parser_yacc.y:901 parser_yacc.y:954
|
||||
#: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060
|
||||
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:903 parser_yacc.y:956 parser_yacc.y:1062
|
||||
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:905 parser_yacc.y:958 parser_yacc.y:1064
|
||||
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:921 parser_yacc.y:1003 parser_yacc.y:1109
|
||||
#, 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:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510
|
||||
#, c-format
|
||||
msgid "Invalid capability %s."
|
||||
msgstr "Ungültige Fähigkeit %s."
|
||||
|
||||
#: parser_yacc.y:1066 parser_yacc.y:1269
|
||||
#: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525
|
||||
#, 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:1072 parser_yacc.y:1275 parser_yacc.y:1531
|
||||
#, c-format
|
||||
msgid "AppArmor parser error,%s%s line %d: %s\n"
|
||||
msgstr "AppArmor-Analysefehler,%s%s Zeile %d: %s\n"
|
||||
@@ -516,13 +540,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:265 ../parser_regex.c:274 ../parser_regex.c:278
|
||||
#, 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:271 ../parser_regex.c:280 ../parser_regex.c:284
|
||||
#, c-format
|
||||
msgid ""
|
||||
"%s: Regex grouping error: Invalid close }, no matching open { detected\n"
|
||||
@@ -530,7 +554,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:337 ../parser_regex.c:343 ../parser_regex.c:361
|
||||
#, c-format
|
||||
msgid ""
|
||||
"%s: Regex grouping error: Unclosed grouping or character class, expecting "
|
||||
@@ -544,17 +568,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:355 ../parser_regex.c:361 ../parser_regex.c:377
|
||||
#, 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:397 ../parser_regex.c:405 ../parser_regex.c:421
|
||||
#, 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:202 ../parser_policy.c:402 ../parser_policy.c:375
|
||||
#, c-format
|
||||
msgid "ERROR merging rules for profile %s, failed to load\n"
|
||||
msgstr "FEHLER Vereinigungsregeln für Profil »%s«, Laden gescheitert\n"
|
||||
@@ -572,18 +596,18 @@ msgstr ""
|
||||
"erlaubt.\n"
|
||||
"\t»**« kann am Ende einer Regel verwendet werden.\n"
|
||||
|
||||
#: ../parser_policy.c:279 ../parser_policy.c:359
|
||||
#: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332
|
||||
#, 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:306 ../parser_policy.c:389 ../parser_policy.c:362
|
||||
#, 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:390 ../parser_policy.c:382 ../parser_policy.c:355
|
||||
#, c-format
|
||||
msgid "ERROR adding hat access rule for profile %s\n"
|
||||
msgstr "FEHLER Hinzufügen von »hat«-Zugriffsregel für Profil %s\n"
|
||||
@@ -617,31 +641,32 @@ msgstr ""
|
||||
"%s: Beim Kombinieren von Regeln in der Nachverarbeitung sind Fehler "
|
||||
"aufgetreten. Der Vorgang wird abgebrochen.\n"
|
||||
|
||||
#: parser_lex.l:180
|
||||
#: parser_lex.l:180 parser_lex.l:186
|
||||
#, 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:660 ../parser_main.c:523
|
||||
msgid "Feature buffer full."
|
||||
msgstr "Funktionspuffer ist voll."
|
||||
|
||||
#: ../parser_main.c:1115 ../parser_main.c:1132
|
||||
#: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024
|
||||
#: ../parser_main.c:1041
|
||||
msgid "Out of memory"
|
||||
msgstr "Nicht genug Speicher"
|
||||
msgstr "Nicht genügend Speicher!"
|
||||
|
||||
#: ../parser_main.c:1182
|
||||
#: ../parser_main.c:1182 ../parser_main.c:1091
|
||||
#, 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:1185 ../parser_main.c:1094
|
||||
#, c-format
|
||||
msgid "File in cache directory location: %s\n"
|
||||
msgstr "Datei im Pufferverzeichnisort: %s\n"
|
||||
|
||||
#: ../parser_main.c:1188
|
||||
#: ../parser_main.c:1188 ../parser_main.c:1097
|
||||
#, c-format
|
||||
msgid "Can't update cache directory: %s\n"
|
||||
msgstr "Pufferverzeichnis kann nicht aktualisiert werden: %s\n"
|
||||
@@ -656,11 +681,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:575 parser_yacc.y:621
|
||||
msgid "deny prefix not allowed"
|
||||
msgstr "Verweigernpräfix nicht erlaubt"
|
||||
|
||||
#: parser_yacc.y:612
|
||||
#: parser_yacc.y:612 parser_yacc.y:658
|
||||
msgid "owner prefix not allowed"
|
||||
msgstr "Eigentümerpräfix nicht erlaubt"
|
||||
|
||||
@@ -676,25 +701,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:1357 parser_yacc.y:1613
|
||||
#, c-format
|
||||
msgid "invalid mount conditional %s%s"
|
||||
msgstr "Ungültige Einhängebedingung %s%s"
|
||||
|
||||
#: parser_yacc.y:1374
|
||||
#: parser_yacc.y:1374 parser_yacc.y:1628
|
||||
msgid "bad mount rule"
|
||||
msgstr "Ungültige Einhängeregel"
|
||||
|
||||
#: parser_yacc.y:1381
|
||||
#: parser_yacc.y:1381 parser_yacc.y:1635
|
||||
msgid "mount point conditions not currently supported"
|
||||
msgstr "Einhängepunktbedingungen werden derzeit nicht unterstützt"
|
||||
|
||||
#: parser_yacc.y:1398
|
||||
#: parser_yacc.y:1398 parser_yacc.y:1650
|
||||
#, c-format
|
||||
msgid "invalid pivotroot conditional '%s'"
|
||||
msgstr "Ungültige pivotroot-Bedingung »%s«"
|
||||
|
||||
#: ../parser_regex.c:241
|
||||
#: ../parser_regex.c:241 ../parser_regex.c:236
|
||||
#, c-format
|
||||
msgid ""
|
||||
"%s: Regex grouping error: Invalid close ], no matching open [ detected\n"
|
||||
@@ -702,20 +727,20 @@ msgstr ""
|
||||
"%s: Regex-Gruppierungsfehler: Ungültiges schließendes Zeichen ], kein "
|
||||
"passendes öffnendes Zeichen [ gefunden\n"
|
||||
|
||||
#: ../parser_regex.c:257
|
||||
#: ../parser_regex.c:257 ../parser_regex.c:256
|
||||
#, 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:366 ../parser_policy.c:339
|
||||
#, 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:396 ../parser_policy.c:369
|
||||
#, c-format
|
||||
msgid "ERROR replacing aliases for profile %s, failed to load\n"
|
||||
msgstr ""
|
||||
|
@@ -95,13 +95,15 @@ void update_mru_tstamp(FILE *file, const char *name)
|
||||
}
|
||||
}
|
||||
|
||||
char *cache_filename(const char *cachedir, const char *basename)
|
||||
char *cache_filename(aa_policy_cache *pc, int dir, const char *basename)
|
||||
{
|
||||
char *cachename;
|
||||
autofree char *path;
|
||||
|
||||
if (asprintf(&cachename, "%s/%s", cachedir, basename) < 0) {
|
||||
path = aa_policy_cache_dir_path(pc, dir);
|
||||
if (!path || asprintf(&cachename, "%s/%s", path, basename) < 0) {
|
||||
PERROR("Memory allocation error.");
|
||||
exit(1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return cachename;
|
||||
@@ -147,13 +149,13 @@ int setup_cache_tmp(const char **cachetmpname, const char *cachename)
|
||||
*cachetmpname = NULL;
|
||||
if (write_cache) {
|
||||
/* Otherwise, set up to save a cached copy */
|
||||
if (asprintf(&tmpname, "%s-XXXXXX", cachename)<0) {
|
||||
if (asprintf(&tmpname, "%s-XXXXXX", cachename) < 0) {
|
||||
perror("asprintf");
|
||||
exit(1);
|
||||
return -1;
|
||||
}
|
||||
if ((cache_fd = mkstemp(tmpname)) < 0) {
|
||||
perror("mkstemp");
|
||||
exit(1);
|
||||
return -1;
|
||||
}
|
||||
*cachetmpname = tmpname;
|
||||
}
|
||||
|
@@ -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(const char *cachedir, const char *basename);
|
||||
char *cache_filename(aa_policy_cache *pc, int dir, 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);
|
||||
|
@@ -117,11 +117,14 @@ skip_profile() {
|
||||
"${profile%\~}" != "${profile}" ] ; then
|
||||
return 1
|
||||
fi
|
||||
# Silently ignore the dpkg files
|
||||
# Silently ignore the dpkg and pacman files
|
||||
if [ "${profile%.dpkg-new}" != "${profile}" -o \
|
||||
"${profile%.dpkg-old}" != "${profile}" -o \
|
||||
"${profile%.dpkg-dist}" != "${profile}" -o \
|
||||
"${profile%.dpkg-bak}" != "${profile}" ] ; then
|
||||
"${profile%.dpkg-bak}" != "${profile}" -o \
|
||||
"${profile%.dpkg-remove}" != "${profile}" -o \
|
||||
"${profile%.pacsave}" != "${profile}" -o \
|
||||
"${profile%.pacnew}" != "${profile}" ] ; then
|
||||
return 2
|
||||
fi
|
||||
|
||||
|
@@ -1,149 +0,0 @@
|
||||
#!/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
|
||||
|
@@ -57,7 +57,7 @@ valgrind: $(PARSER) gen_xtrans gen_dbus
|
||||
LANG=C ./valgrind_simple.py -p "$(PARSER)" -v simple_tests
|
||||
|
||||
$(PARSER):
|
||||
make -C $(PARSER_DIR) $(PARSER_BIN)
|
||||
$(MAKE) -C $(PARSER_DIR) $(PARSER_BIN)
|
||||
|
||||
clean:
|
||||
find $(GEN_TRANS_DIRS) -type f | xargs rm -f
|
||||
|
@@ -60,13 +60,6 @@ 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)
|
||||
@@ -80,6 +73,13 @@ class AAParserCachingCommon(testlib.AATestTemplate):
|
||||
if not self.is_apparmorfs_mounted():
|
||||
self.cmd_prefix += ['-M', './features_files/features.all']
|
||||
|
||||
# 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'''
|
||||
|
||||
@@ -89,6 +89,22 @@ 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),
|
||||
@@ -178,16 +194,16 @@ class AAParserAltCacheBasicTests(AAParserBasicCachingTests):
|
||||
def setUp(self):
|
||||
super(AAParserAltCacheBasicTests, self).setUp()
|
||||
|
||||
alt_cache_dir = tempfile.mkdtemp(prefix='aa-alt-cache', dir=self.tmp_dir)
|
||||
os.chmod(alt_cache_dir, 0o755)
|
||||
alt_cache_loc = tempfile.mkdtemp(prefix='aa-alt-cache', dir=self.tmp_dir)
|
||||
os.chmod(alt_cache_loc, 0o755)
|
||||
|
||||
self.unused_cache_dir = self.cache_dir
|
||||
self.cache_dir = alt_cache_dir
|
||||
self.cmd_prefix.extend(['--cache-loc', alt_cache_dir])
|
||||
self.unused_cache_loc = self.cache_dir
|
||||
self.cmd_prefix.extend(['--cache-loc', alt_cache_loc])
|
||||
self.cache_dir = self.get_cache_dir()
|
||||
|
||||
def tearDown(self):
|
||||
if len(os.listdir(self.unused_cache_dir)) > 0:
|
||||
self.fail('original cache dir \'%s\' not empty' % self.unused_cache_dir)
|
||||
if len(os.listdir(self.unused_cache_loc)) > 0:
|
||||
self.fail('original cache dir \'%s\' not empty' % self.unused_cache_loc)
|
||||
super(AAParserAltCacheBasicTests, self).tearDown()
|
||||
|
||||
|
||||
@@ -314,18 +330,22 @@ 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_updates_features(self):
|
||||
'''test cache writing updates features'''
|
||||
|
||||
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
|
||||
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.compare_features_file(features_file)
|
||||
self.assert_path_exists(new_features_file)
|
||||
self.compare_features_file(new_features_file)
|
||||
|
||||
def test_cache_writing_updates_cache_file(self):
|
||||
'''test cache writing updates cache file'''
|
||||
@@ -494,13 +514,13 @@ class AAParserAltCacheTests(AAParserCachingTests):
|
||||
def setUp(self):
|
||||
super(AAParserAltCacheTests, self).setUp()
|
||||
|
||||
alt_cache_dir = tempfile.mkdtemp(prefix='aa-alt-cache', dir=self.tmp_dir)
|
||||
os.chmod(alt_cache_dir, 0o755)
|
||||
alt_cache_loc = tempfile.mkdtemp(prefix='aa-alt-cache', dir=self.tmp_dir)
|
||||
os.chmod(alt_cache_loc, 0o755)
|
||||
|
||||
self.orig_cache_dir = self.cache_dir
|
||||
self.cache_dir = alt_cache_dir
|
||||
self.cmd_prefix.extend(['--cache-loc', alt_cache_loc])
|
||||
self.cache_dir = self.get_cache_dir(create=True)
|
||||
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:
|
||||
|
7
parser/tst/simple_tests/bare_include_tests/bad_11.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/bad_11.sd
Normal file
@@ -0,0 +1,7 @@
|
||||
#
|
||||
#=DESCRIPTION includes testing - non-existent include should fail
|
||||
#=EXRESULT FAIL
|
||||
#
|
||||
/does/not/exist {
|
||||
#include "does-not-exist/does-not-exist"
|
||||
}
|
7
parser/tst/simple_tests/bare_include_tests/bad_12.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/bad_12.sd
Normal file
@@ -0,0 +1,7 @@
|
||||
#
|
||||
#=DESCRIPTION includes testing - mis-parsing include should fail
|
||||
#=EXRESULT FAIL
|
||||
#
|
||||
/does/not/exist {
|
||||
#include "/does-not-exist/does-not-exist"
|
||||
}
|
8
parser/tst/simple_tests/bare_include_tests/bad_13.sd
Normal file
8
parser/tst/simple_tests/bare_include_tests/bad_13.sd
Normal file
@@ -0,0 +1,8 @@
|
||||
#
|
||||
#=DESCRIPTION includes testing - non-existent include should fail
|
||||
#=EXRESULT FAIL
|
||||
#
|
||||
/does/not/exist {
|
||||
#include "does-not-exist/does-not-exist"
|
||||
#include <includes/base>
|
||||
}
|
8
parser/tst/simple_tests/bare_include_tests/bad_14.sd
Normal file
8
parser/tst/simple_tests/bare_include_tests/bad_14.sd
Normal file
@@ -0,0 +1,8 @@
|
||||
#
|
||||
#=DESCRIPTION includes testing - non-existent include should fail
|
||||
#=EXRESULT FAIL
|
||||
#
|
||||
/does/not/exist {
|
||||
#include <includes/base>
|
||||
#include "../does-not-exist/does-not-exist"
|
||||
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_11.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_11.sd
Normal file
@@ -0,0 +1,7 @@
|
||||
#
|
||||
#=DESCRIPTION includes testing - basic include of global and local include
|
||||
#=EXRESULT PASS
|
||||
#
|
||||
/does/not/exist {
|
||||
include "simple_tests/include_tests/includes_okay_helper.include"
|
||||
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_12.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_12.sd
Normal file
@@ -0,0 +1,7 @@
|
||||
#
|
||||
#=DESCRIPTION includes testing - basic include of global and local include
|
||||
#=EXRESULT PASS
|
||||
#
|
||||
/does/not/exist {
|
||||
include "../tst/simple_tests/include_tests/includes_okay_helper.include"
|
||||
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_13.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_13.sd
Normal file
@@ -0,0 +1,7 @@
|
||||
#
|
||||
#=DESCRIPTION includes testing - basic include of global and local include
|
||||
#=EXRESULT PASS
|
||||
#
|
||||
/does/not/exist {
|
||||
include "./simple_tests/include_tests/includes_okay_helper.include"
|
||||
}
|
8
parser/tst/simple_tests/bare_include_tests/ok_14.sd
Normal file
8
parser/tst/simple_tests/bare_include_tests/ok_14.sd
Normal file
@@ -0,0 +1,8 @@
|
||||
#
|
||||
#=DESCRIPTION includes testing - test some "odd" locations of includes
|
||||
#=EXRESULT PASS
|
||||
#
|
||||
/does/not/exist {
|
||||
/does/not/exist mr, include <includes/base> /bin/true Px,
|
||||
include "../tst/simple_tests/include_tests/includes_okay_helper.include" include <includes/base>
|
||||
}
|
9
parser/tst/simple_tests/bare_include_tests/ok_15.sd
Normal file
9
parser/tst/simple_tests/bare_include_tests/ok_15.sd
Normal file
@@ -0,0 +1,9 @@
|
||||
#
|
||||
#=DESCRIPTION includes testing - basic include of a directory
|
||||
#=EXRESULT PASS
|
||||
#
|
||||
/does/not/exist {
|
||||
include <includes/base>
|
||||
include "simple_tests/includes/"
|
||||
include <includes/base>
|
||||
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_16.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_16.sd
Normal file
@@ -0,0 +1,7 @@
|
||||
#
|
||||
#=DESCRIPTION includes testing - basic include of global and local include
|
||||
#=EXRESULT PASS
|
||||
#
|
||||
/does/not/exist {
|
||||
include simple_tests/include_tests/includes_okay_helper.include
|
||||
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_17.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_17.sd
Normal file
@@ -0,0 +1,7 @@
|
||||
#
|
||||
#=DESCRIPTION includes testing - basic include of global and local include
|
||||
#=EXRESULT PASS
|
||||
#
|
||||
/does/not/exist {
|
||||
include ../tst/simple_tests/include_tests/includes_okay_helper.include
|
||||
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_18.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_18.sd
Normal file
@@ -0,0 +1,7 @@
|
||||
#
|
||||
#=DESCRIPTION includes testing - basic include of global and local include
|
||||
#=EXRESULT PASS
|
||||
#
|
||||
/does/not/exist {
|
||||
include ./simple_tests/include_tests/includes_okay_helper.include
|
||||
}
|
8
parser/tst/simple_tests/bare_include_tests/ok_19.sd
Normal file
8
parser/tst/simple_tests/bare_include_tests/ok_19.sd
Normal file
@@ -0,0 +1,8 @@
|
||||
#
|
||||
#=DESCRIPTION includes testing - test some "odd" locations of includes
|
||||
#=EXRESULT PASS
|
||||
#
|
||||
/does/not/exist {
|
||||
/does/not/exist mr, include <includes/base> /bin/true Px,
|
||||
include ../tst/simple_tests/include_tests/includes_okay_helper.include include <includes/base>
|
||||
}
|
9
parser/tst/simple_tests/bare_include_tests/ok_20.sd
Normal file
9
parser/tst/simple_tests/bare_include_tests/ok_20.sd
Normal file
@@ -0,0 +1,9 @@
|
||||
#
|
||||
#=DESCRIPTION includes testing - basic include of a directory
|
||||
#=EXRESULT PASS
|
||||
#
|
||||
/does/not/exist {
|
||||
include <includes/base>
|
||||
include simple_tests/includes/
|
||||
include <includes/base>
|
||||
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_26.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_26.sd
Normal file
@@ -0,0 +1,7 @@
|
||||
#
|
||||
#=DESCRIPTION includes testing - basic include of global and local include
|
||||
#=EXRESULT PASS
|
||||
#
|
||||
/does/not/exist {
|
||||
include "simple_tests/include_tests/includes with space helper.include"
|
||||
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_27.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_27.sd
Normal file
@@ -0,0 +1,7 @@
|
||||
#
|
||||
#=DESCRIPTION includes testing - basic include of global and local include
|
||||
#=EXRESULT PASS
|
||||
#
|
||||
/does/not/exist {
|
||||
include "simple_tests/include_tests/includes with space helper.include" #comment
|
||||
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_28.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_28.sd
Normal file
@@ -0,0 +1,7 @@
|
||||
#
|
||||
#=DESCRIPTION includes testing - basic include of global and local include
|
||||
#=EXRESULT PASS
|
||||
#
|
||||
/does/not/exist {
|
||||
include <"include_tests/includes with space helper.include">
|
||||
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_29.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_29.sd
Normal file
@@ -0,0 +1,7 @@
|
||||
#
|
||||
#=DESCRIPTION includes testing - basic include of global and local include
|
||||
#=EXRESULT PASS
|
||||
#
|
||||
/does/not/exist {
|
||||
include <"include_tests/includes with space helper.include"> #comment
|
||||
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_30.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_30.sd
Normal file
@@ -0,0 +1,7 @@
|
||||
#
|
||||
#=DESCRIPTION includes testing - basic include of global and local include
|
||||
#=EXRESULT PASS
|
||||
#
|
||||
/does/not/exist {
|
||||
include <include_tests/includes with space helper.include>
|
||||
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_31.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_31.sd
Normal file
@@ -0,0 +1,7 @@
|
||||
#
|
||||
#=DESCRIPTION includes testing - basic include of global and local include
|
||||
#=EXRESULT PASS
|
||||
#
|
||||
/does/not/exist {
|
||||
include <include_tests/includes with space helper.include> #comment
|
||||
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_61.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_61.sd
Normal file
@@ -0,0 +1,7 @@
|
||||
#
|
||||
#=DESCRIPTION include if existss testing - basic include if exists of global and local include
|
||||
#=EXRESULT PASS
|
||||
#
|
||||
/does/not/exist {
|
||||
include if exists "simple_tests/include_tests/includes_okay_helper.include"
|
||||
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_62.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_62.sd
Normal file
@@ -0,0 +1,7 @@
|
||||
#
|
||||
#=DESCRIPTION include if existss testing - basic include if exists of global and local include
|
||||
#=EXRESULT PASS
|
||||
#
|
||||
/does/not/exist {
|
||||
include if exists "../tst/simple_tests/include_tests/includes_okay_helper.include"
|
||||
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_63.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_63.sd
Normal file
@@ -0,0 +1,7 @@
|
||||
#
|
||||
#=DESCRIPTION include if existss testing - basic include if exists of global and local include
|
||||
#=EXRESULT PASS
|
||||
#
|
||||
/does/not/exist {
|
||||
include if exists "./simple_tests/include_tests/includes_okay_helper.include"
|
||||
}
|
8
parser/tst/simple_tests/bare_include_tests/ok_64.sd
Normal file
8
parser/tst/simple_tests/bare_include_tests/ok_64.sd
Normal file
@@ -0,0 +1,8 @@
|
||||
#
|
||||
#=DESCRIPTION include if existss testing - test some "odd" locations of include if existss
|
||||
#=EXRESULT PASS
|
||||
#
|
||||
/does/not/exist {
|
||||
/does/not/exist mr, include if exists <includes/base> /bin/true Px,
|
||||
include if exists "../tst/simple_tests/include_tests/includes_okay_helper.include" include if exists <includes/base>
|
||||
}
|
9
parser/tst/simple_tests/bare_include_tests/ok_65.sd
Normal file
9
parser/tst/simple_tests/bare_include_tests/ok_65.sd
Normal file
@@ -0,0 +1,9 @@
|
||||
#
|
||||
#=DESCRIPTION include if existss testing - basic include if exists of a directory
|
||||
#=EXRESULT PASS
|
||||
#
|
||||
/does/not/exist {
|
||||
include if exists <includes/base>
|
||||
include if exists "simple_tests/includes/"
|
||||
include if exists <includes/base>
|
||||
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_66.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_66.sd
Normal file
@@ -0,0 +1,7 @@
|
||||
#
|
||||
#=DESCRIPTION include if existss testing - basic include if exists of global and local include
|
||||
#=EXRESULT PASS
|
||||
#
|
||||
/does/not/exist {
|
||||
include if exists simple_tests/include_tests/includes_okay_helper.include
|
||||
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_67.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_67.sd
Normal file
@@ -0,0 +1,7 @@
|
||||
#
|
||||
#=DESCRIPTION include if existss testing - basic include if exists of global and local include
|
||||
#=EXRESULT PASS
|
||||
#
|
||||
/does/not/exist {
|
||||
include if exists ../tst/simple_tests/include_tests/includes_okay_helper.include
|
||||
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_68.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_68.sd
Normal file
@@ -0,0 +1,7 @@
|
||||
#
|
||||
#=DESCRIPTION include if existss testing - basic include if exists of global and local include
|
||||
#=EXRESULT PASS
|
||||
#
|
||||
/does/not/exist {
|
||||
include if exists ./simple_tests/include_tests/includes_okay_helper.include
|
||||
}
|
8
parser/tst/simple_tests/bare_include_tests/ok_69.sd
Normal file
8
parser/tst/simple_tests/bare_include_tests/ok_69.sd
Normal file
@@ -0,0 +1,8 @@
|
||||
#
|
||||
#=DESCRIPTION include if existss testing - test some "odd" locations of include if existss
|
||||
#=EXRESULT PASS
|
||||
#
|
||||
/does/not/exist {
|
||||
/does/not/exist mr, include if exists <includes/base> /bin/true Px,
|
||||
include if exists ../tst/simple_tests/include_tests/includes_okay_helper.include include if exists <includes/base>
|
||||
}
|
9
parser/tst/simple_tests/bare_include_tests/ok_70.sd
Normal file
9
parser/tst/simple_tests/bare_include_tests/ok_70.sd
Normal file
@@ -0,0 +1,9 @@
|
||||
#
|
||||
#=DESCRIPTION include if existss testing - basic include if exists of a directory
|
||||
#=EXRESULT PASS
|
||||
#
|
||||
/does/not/exist {
|
||||
include if exists <includes/base>
|
||||
include if exists simple_tests/includes/
|
||||
include if exists <includes/base>
|
||||
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_76.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_76.sd
Normal file
@@ -0,0 +1,7 @@
|
||||
#
|
||||
#=DESCRIPTION include if existss testing - basic include if exists of global and local include
|
||||
#=EXRESULT PASS
|
||||
#
|
||||
/does/not/exist {
|
||||
include if exists "simple_tests/include_tests/includes with space helper.include"
|
||||
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_77.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_77.sd
Normal file
@@ -0,0 +1,7 @@
|
||||
#
|
||||
#=DESCRIPTION include if existss testing - basic include if exists of global and local include
|
||||
#=EXRESULT PASS
|
||||
#
|
||||
/does/not/exist {
|
||||
include if exists "simple_tests/include_tests/includes with space helper.include" #comment
|
||||
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_78.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_78.sd
Normal file
@@ -0,0 +1,7 @@
|
||||
#
|
||||
#=DESCRIPTION include if existss testing - basic include if exists of global and local include
|
||||
#=EXRESULT PASS
|
||||
#
|
||||
/does/not/exist {
|
||||
include if exists <"include_tests/includes with space helper.include">
|
||||
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_79.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_79.sd
Normal file
@@ -0,0 +1,7 @@
|
||||
#
|
||||
#=DESCRIPTION include if existss testing - basic include if exists of global and local include
|
||||
#=EXRESULT PASS
|
||||
#
|
||||
/does/not/exist {
|
||||
include if exists <"include_tests/includes with space helper.include"> #comment
|
||||
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_80.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_80.sd
Normal file
@@ -0,0 +1,7 @@
|
||||
#
|
||||
#=DESCRIPTION include if existss testing - basic include if exists of global and local include
|
||||
#=EXRESULT PASS
|
||||
#
|
||||
/does/not/exist {
|
||||
include if exists <include_tests/includes with space helper.include>
|
||||
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_81.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_81.sd
Normal file
@@ -0,0 +1,7 @@
|
||||
#
|
||||
#=DESCRIPTION include if existss testing - basic include if exists of global and local include
|
||||
#=EXRESULT PASS
|
||||
#
|
||||
/does/not/exist {
|
||||
include if exists <include_tests/includes with space helper.include> #comment
|
||||
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_82.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_82.sd
Normal file
@@ -0,0 +1,7 @@
|
||||
#
|
||||
#=DESCRIPTION include if exist testing - non-existent include should pass
|
||||
#=EXRESULT PASS
|
||||
#
|
||||
/does/not/exist {
|
||||
include if exists "does-not-exist/does-not-exist"
|
||||
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_83.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_83.sd
Normal file
@@ -0,0 +1,7 @@
|
||||
#
|
||||
#=DESCRIPTION include if exists testing - abs path include does not exist should pass
|
||||
#=EXRESULT PASS
|
||||
#
|
||||
/does/not/exist {
|
||||
include if exists "/does-not-exist/does-not-exist"
|
||||
}
|
8
parser/tst/simple_tests/bare_include_tests/ok_84.sd
Normal file
8
parser/tst/simple_tests/bare_include_tests/ok_84.sd
Normal file
@@ -0,0 +1,8 @@
|
||||
#
|
||||
#=DESCRIPTION include if exists testing - non-existent include should pass
|
||||
#=EXRESULT PASS
|
||||
#
|
||||
/does/not/exist {
|
||||
include <includes/base>
|
||||
include if exists "../does-not-exist/does-not-exist"
|
||||
}
|
8
parser/tst/simple_tests/bare_include_tests/ok_85.sd
Normal file
8
parser/tst/simple_tests/bare_include_tests/ok_85.sd
Normal file
@@ -0,0 +1,8 @@
|
||||
#
|
||||
#=DESCRIPTION include if exists testing - non-existent include should pass
|
||||
#=EXRESULT PASS
|
||||
#
|
||||
/does/not/exist {
|
||||
include <includes/base>
|
||||
include if exists "../does-not-exist/does-not-exist"
|
||||
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_86.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_86.sd
Normal file
@@ -0,0 +1,7 @@
|
||||
#
|
||||
#=DESCRIPTION include if exists testing - non-existent include should pass
|
||||
#=EXRESULT PASS
|
||||
#
|
||||
/does/not/exist {
|
||||
include if exists "does-not-exist/does-not-exist"
|
||||
}
|
7
parser/tst/simple_tests/bare_include_tests/ok_87.sd
Normal file
7
parser/tst/simple_tests/bare_include_tests/ok_87.sd
Normal file
@@ -0,0 +1,7 @@
|
||||
#
|
||||
#=DESCRIPTION include if exists testing - non-existent include should pass
|
||||
#=EXRESULT PASS
|
||||
#
|
||||
/does/not/exist {
|
||||
include if exists <does-not-exist/does-not-exist>
|
||||
}
|
8
parser/tst/simple_tests/bare_include_tests/ok_88.sd
Normal file
8
parser/tst/simple_tests/bare_include_tests/ok_88.sd
Normal file
@@ -0,0 +1,8 @@
|
||||
#
|
||||
#=DESCRIPTION include if exists testing - non-existent include should pass
|
||||
#=EXRESULT PASS
|
||||
#
|
||||
/does/not/exist {
|
||||
include if exists <does-not-exist/does-not-exist>
|
||||
include <includes/base>
|
||||
}
|
@@ -4,11 +4,11 @@
|
||||
# vim:syntax=apparmor
|
||||
#
|
||||
/usr/bin/foo {
|
||||
allow /bin/cat a,
|
||||
allow /bin/true ra,
|
||||
allow /bin/false ma,
|
||||
allow /{usr/,}bin/cat a,
|
||||
allow /{usr/,}bin/true ra,
|
||||
allow /{usr/,}bin/false ma,
|
||||
allow /lib/libc.so la,
|
||||
allow /bin/less ixa,
|
||||
allow /bin/more pxa,
|
||||
allow /{usr/,}bin/less ixa,
|
||||
allow /{usr/,}bin/more pxa,
|
||||
allow /a uxa,
|
||||
}
|
||||
|
@@ -2,6 +2,6 @@
|
||||
#=EXRESULT PASS
|
||||
# vim:syntax=apparmor
|
||||
|
||||
/bin/foo {
|
||||
/{usr/,}bin/foo {
|
||||
allow "/abc\ def" r,
|
||||
}
|
||||
|
@@ -2,6 +2,6 @@
|
||||
#=EXRESULT PASS
|
||||
# vim:syntax=apparmor
|
||||
|
||||
/bin/foo {
|
||||
/{usr/,}bin/foo {
|
||||
allow "/abc def" r,
|
||||
}
|
||||
|
@@ -4,15 +4,15 @@
|
||||
# vim:syntax=apparmor
|
||||
#
|
||||
/usr/bin/foo {
|
||||
allow /bin/a k,
|
||||
allow /bin/b rk,
|
||||
allow /bin/c wk,
|
||||
allow /bin/d ak,
|
||||
allow /bin/e lk,
|
||||
allow /bin/e mk,
|
||||
allow /bin/f pxk,
|
||||
allow /bin/g Pxk,
|
||||
allow /bin/h ixk,
|
||||
allow /bin/i uxk,
|
||||
allow /bin/j Uxk,
|
||||
allow /{usr/,}bin/a k,
|
||||
allow /{usr/,}bin/b rk,
|
||||
allow /{usr/,}bin/c wk,
|
||||
allow /{usr/,}bin/d ak,
|
||||
allow /{usr/,}bin/e lk,
|
||||
allow /{usr/,}bin/e mk,
|
||||
allow /{usr/,}bin/f pxk,
|
||||
allow /{usr/,}bin/g Pxk,
|
||||
allow /{usr/,}bin/h ixk,
|
||||
allow /{usr/,}bin/i uxk,
|
||||
allow /{usr/,}bin/j Uxk,
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user