mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-08-31 22:35:35 +00:00
Compare commits
109 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
99cb8cc7f1 | ||
|
7b47dee81e | ||
|
789309f419 | ||
|
e7488ebff1 | ||
|
498853ca6e | ||
|
e262991d18 | ||
|
90b8189547 | ||
|
34d1b5ddce | ||
|
9d09389290 | ||
|
b292de2ca0 | ||
|
e5daa5fa39 | ||
|
383bbd68d6 | ||
|
845507b8a1 | ||
|
6b2a8191a6 | ||
|
681fef917b | ||
|
b15f758490 | ||
|
c9e3e6e85a | ||
|
6920e3d717 | ||
|
ae595aea03 | ||
|
1251e0c143 | ||
|
b56fdec804 | ||
|
eacb977ebd | ||
|
29d287f94e | ||
|
9fd54008c4 | ||
|
0ffc0941a8 | ||
|
ed68e397aa | ||
|
c79607927d | ||
|
353ef34ca0 | ||
|
80a17a6106 | ||
|
44f2c6d2bc | ||
|
a7898cfe5b | ||
|
91b9b44f53 | ||
|
8fcfc27d56 | ||
|
791d40aa9d | ||
|
4ad98a8302 | ||
|
064541cb53 | ||
|
9618cc9a62 | ||
|
119522307f | ||
|
2a929f3f1c | ||
|
ec4de6e081 | ||
|
fde4f8a522 | ||
|
cad5d461ca | ||
|
922096a8be | ||
|
9d8340a8b3 | ||
|
1d8e388c93 | ||
|
28d5c335af | ||
|
8ea1054f50 | ||
|
36b699bcf6 | ||
|
0125d04924 | ||
|
ad169656bf | ||
|
0f7ccc49bb | ||
|
90e5294578 | ||
|
6d19a507ae | ||
|
fff8d65985 | ||
|
8e2595c634 | ||
|
711ca72c6b | ||
|
af8ccba6d2 | ||
|
fa5d235f28 | ||
|
bdb18c5ccf | ||
|
0cd0743b47 | ||
|
6e1e27a931 | ||
|
150350c42c | ||
|
61ee9623c5 | ||
|
458f696f8e | ||
|
331e54b36e | ||
|
85be9528ec | ||
|
5493e01408 | ||
|
da0daadf40 | ||
|
6d05fa4a6e | ||
|
f5df1bf45e | ||
|
a80c75e308 | ||
|
f5462aa931 | ||
|
91e73d54fe | ||
|
57cdc4257d | ||
|
4c04a05996 | ||
|
a492bcfc80 | ||
|
ec9292bd5e | ||
|
703cc22b52 | ||
|
4fd66468d8 | ||
|
b80aadd624 | ||
|
0dde5efc62 | ||
|
99b59f7169 | ||
|
061c76c5b1 | ||
|
dab2636a27 | ||
|
a41bff515f | ||
|
483f11d06c | ||
|
1140e54442 | ||
|
b54d1f2049 | ||
|
6e846245ab | ||
|
218cb42fbe | ||
|
df12e87fb5 | ||
|
5a2da347d4 | ||
|
cfbc1a2a79 | ||
|
51a0d5d863 | ||
|
3ab596ed83 | ||
|
d5824674d1 | ||
|
3ef80d788a | ||
|
d579fc51d4 | ||
|
8d68618f0b | ||
|
f6dcade84f | ||
|
0f4310d301 | ||
|
84ab95d263 | ||
|
eb2adf119b | ||
|
68041e0d2e | ||
|
4c0e6334b5 | ||
|
73cdd97596 | ||
|
dfe58983bb | ||
|
07b6148fd1 | ||
|
d04a03359c |
@@ -1,15 +1,7 @@
|
||||
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
|
||||
parser/generated_cap_names.h
|
||||
parser/tst_lib
|
||||
parser/tst_misc
|
||||
parser/tst_regex
|
||||
parser/tst_symtab
|
||||
@@ -20,37 +12,6 @@ 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
|
||||
@@ -58,14 +19,12 @@ parser/*.7.html
|
||||
parser/*.5.html
|
||||
parser/*.8.html
|
||||
parser/apparmor_parser
|
||||
parser/libapparmor_re/parse.cc
|
||||
parser/libapparmor_re/regexp.cc
|
||||
parser/techdoc.aux
|
||||
parser/techdoc.log
|
||||
parser/techdoc.pdf
|
||||
parser/techdoc.toc
|
||||
profiles/apparmor.d/local/*
|
||||
!profiles/apparmor.d/local/README
|
||||
profiles/apparmor.d/local/*.*
|
||||
libraries/libapparmor/Makefile
|
||||
libraries/libapparmor/Makefile.in
|
||||
libraries/libapparmor/aclocal.m4
|
||||
@@ -96,27 +55,17 @@ libraries/libapparmor/src/.deps
|
||||
libraries/libapparmor/src/.libs
|
||||
libraries/libapparmor/src/Makefile
|
||||
libraries/libapparmor/src/Makefile.in
|
||||
libraries/libapparmor/src/PMurHash.lo
|
||||
libraries/libapparmor/src/PMurHash.o
|
||||
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
|
||||
@@ -124,19 +73,7 @@ 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
|
||||
@@ -150,7 +87,6 @@ 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/
|
||||
@@ -160,18 +96,8 @@ 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/LibAppArmor.so
|
||||
libraries/libapparmor/swig/ruby/LibAppArmor_wrap.c
|
||||
libraries/libapparmor/swig/ruby/LibAppArmor_wrap.o
|
||||
libraries/libapparmor/swig/ruby/Makefile
|
||||
libraries/libapparmor/swig/ruby/Makefile.in
|
||||
libraries/libapparmor/swig/ruby/Makefile.new
|
||||
libraries/libapparmor/swig/ruby/Makefile.ruby
|
||||
libraries/libapparmor/swig/ruby/mkmf.log
|
||||
libraries/libapparmor/testsuite/.deps
|
||||
libraries/libapparmor/testsuite/.libs
|
||||
libraries/libapparmor/testsuite/Makefile
|
||||
@@ -187,7 +113,6 @@ 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
|
||||
@@ -195,15 +120,6 @@ utils/*.5
|
||||
utils/*.5.html
|
||||
utils/*.tmp
|
||||
utils/po/*.mo
|
||||
utils/apparmor/*.pyc
|
||||
utils/apparmor/rule/*.pyc
|
||||
utils/test/common_test.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
|
@@ -1,54 +0,0 @@
|
||||
---
|
||||
image: ubuntu:latest
|
||||
before_script:
|
||||
- export DEBIAN_FRONTEND=noninteractive && apt-get update -qq && apt-get install --no-install-recommends -y build-essential apache2-dev autoconf automake bison dejagnu flex libpam-dev libtool perl liblocale-gettext-perl pkg-config python-all-dev python3-all-dev pyflakes3 ruby-dev swig lsb-release python3-notify2 python3-psutil python3-setuptools zlib1g-dev
|
||||
- lsb_release -a
|
||||
- uname -a
|
||||
|
||||
# XXX - add a deploy stage to publish man pages, docs, and coverage
|
||||
# reports
|
||||
|
||||
stages:
|
||||
- build
|
||||
- test
|
||||
|
||||
build-all:
|
||||
stage: build
|
||||
artifacts:
|
||||
name: ${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA}
|
||||
expire_in: 30 days
|
||||
untracked: true
|
||||
paths:
|
||||
- libraries/libapparmor/
|
||||
- parser/
|
||||
- binutils/
|
||||
- utils/
|
||||
- changehat/mod_apparmor/
|
||||
- changehat/pam_apparmor/
|
||||
- profiles/
|
||||
script:
|
||||
- cd libraries/libapparmor && ./autogen.sh && PYTHON=/usr/bin/python3 ./configure --with-perl --with-python --prefix=/usr && make PYTHON=/usr/bin/python3 && cd ../.. || { cat config.log ; exit 1 ; }
|
||||
- make -C parser
|
||||
- make -C binutils
|
||||
- make -C utils
|
||||
- make -C changehat/mod_apparmor
|
||||
- make -C changehat/pam_apparmor
|
||||
- make -C profiles
|
||||
|
||||
test-all:
|
||||
stage: test
|
||||
script:
|
||||
- make -C libraries/libapparmor check PYTHON=/usr/bin/python3
|
||||
- make -C parser check
|
||||
- make -C binutils check
|
||||
- make -C utils check PYFLAKES=/usr/bin/pyflakes3 PYTHON_VERSIONS=/usr/bin/python3
|
||||
- make -C changehat/mod_apparmor check
|
||||
- make -C profiles check-parser
|
||||
|
||||
# Disabled due to aa-logprof dependency on /sbin/apparmor_parser existing
|
||||
# - make -C profiles check-profiles
|
||||
|
||||
# test-pam_apparmor:
|
||||
# - stage: test
|
||||
# - script:
|
||||
# - cd changehat/pam_apparmor && make check
|
64
Makefile
64
Makefile
@@ -8,29 +8,28 @@ all:
|
||||
COMMONDIR=common
|
||||
include ${COMMONDIR}/Make.rules
|
||||
|
||||
DIRS=libraries/libapparmor \
|
||||
binutils \
|
||||
parser \
|
||||
DIRS=parser \
|
||||
profiles \
|
||||
utils \
|
||||
libraries/libapparmor \
|
||||
changehat/mod_apparmor \
|
||||
changehat/pam_apparmor \
|
||||
profiles \
|
||||
tests
|
||||
|
||||
# with conversion to git, we don't export from the remote
|
||||
REPO_URL?=git@gitlab.com:apparmor/apparmor.git
|
||||
REPO_BRANCH?=apparmor-2.13
|
||||
#REPO_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/2.10
|
||||
# alternate possibilities to export from
|
||||
#REPO_URL=.
|
||||
#REPO_URL="bzr+ssh://bazaar.launchpad.net/~sbeattie/+junk/apparmor-dev/"
|
||||
|
||||
COVERITY_DIR=cov-int
|
||||
RELEASE_DIR=apparmor-${VERSION}
|
||||
__SETUP_DIR?=.
|
||||
|
||||
# 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}
|
||||
# apparmor version tag format 'vX.Y.ZZ'
|
||||
# apparmor branch name format 'apparmor-X.Y'
|
||||
TAG_VERSION="v$(subst ~,-,${VERSION})"
|
||||
TAG_VERSION=$(subst ~,-,${VERSION})
|
||||
|
||||
# Add exclusion entries arguments for tar here, of the form:
|
||||
# --exclude dir_to_exclude --exclude other_dir
|
||||
@@ -38,53 +37,38 @@ TAR_EXCLUSIONS=
|
||||
|
||||
.PHONY: tarball
|
||||
tarball: clean
|
||||
REPO_VERSION=`$(value REPO_VERSION_CMD)` && \
|
||||
$(MAKE) export_dir __EXPORT_DIR=${RELEASE_DIR} __REPO_VERSION=$${REPO_VERSION} && \
|
||||
$(MAKE) setup __SETUP_DIR=${RELEASE_DIR} && \
|
||||
REPO_VERSION=`$(value REPO_VERSION_CMD)` ; \
|
||||
make export_dir __EXPORT_DIR=${RELEASE_DIR} __REPO_VERSION=$${REPO_VERSION} ; \
|
||||
make setup __SETUP_DIR=${RELEASE_DIR} ; \
|
||||
tar ${TAR_EXCLUSIONS} -cvzf ${RELEASE_DIR}.tar.gz ${RELEASE_DIR}
|
||||
|
||||
.PHONY: snapshot
|
||||
snapshot: clean
|
||||
$(eval REPO_VERSION:=$(shell $(value REPO_VERSION_CMD)))
|
||||
$(eval SNAPSHOT_NAME=apparmor-$(VERSION)~$(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}
|
||||
REPO_VERSION=`$(value REPO_VERSION_CMD)` ; \
|
||||
SNAPSHOT_DIR=apparmor-${VERSION}~$${REPO_VERSION} ;\
|
||||
make export_dir __EXPORT_DIR=$${SNAPSHOT_DIR} __REPO_VERSION=$${REPO_VERSION} ; \
|
||||
make setup __SETUP_DIR=$${SNAPSHOT_DIR} ; \
|
||||
tar ${TAR_EXCLUSIONS} -cvzf $${SNAPSHOT_DIR}.tar.gz $${SNAPSHOT_DIR} ;
|
||||
|
||||
.PHONY: coverity
|
||||
coverity: snapshot
|
||||
cd $(SNAPSHOT_NAME)/libraries/libapparmor && ./configure --with-python
|
||||
$(foreach dir, $(filter-out utils profiles tests, $(DIRS)), \
|
||||
cov-build --dir $(COVERITY_DIR) -- $(MAKE) -C $(SNAPSHOT_NAME)/$(dir); \
|
||||
mv $(COVERITY_DIR)/build-log.txt $(COVERITY_DIR)/build-log-$(subst /,.,$(dir)).txt ;)
|
||||
$(foreach dir, libraries/libapparmor utils, \
|
||||
cov-build --dir $(COVERITY_DIR) --no-command --fs-capture-search $(SNAPSHOT_NAME)/$(dir); \
|
||||
mv $(COVERITY_DIR)/build-log.txt $(COVERITY_DIR)/build-log-python-$(subst /,.,$(dir)).txt ;)
|
||||
tar -cvzf $(SNAPSHOT_NAME)-$(COVERITY_DIR).tar.gz $(COVERITY_DIR)
|
||||
|
||||
.PHONY: export_dir
|
||||
export_dir:
|
||||
mkdir $(__EXPORT_DIR)
|
||||
/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
|
||||
/usr/bin/bzr export --per-file-timestamps -r $(__REPO_VERSION) $(__EXPORT_DIR) $(REPO_URL)
|
||||
echo "$(REPO_URL) $(__REPO_VERSION)" > $(__EXPORT_DIR)/common/.stamp_rev
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
-rm -rf ${RELEASE_DIR} ./apparmor-${VERSION}~* ${COVERITY_DIR}
|
||||
-rm -rf ${RELEASE_DIR} ./apparmor-${VERSION}~*
|
||||
for dir in $(DIRS); do \
|
||||
$(MAKE) -C $$dir clean; \
|
||||
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
|
||||
# libraries/libapparmor needs configure to have run before
|
||||
# building docs
|
||||
$(foreach dir, $(filter-out libraries/libapparmor tests, $(DIRS)), \
|
||||
$(MAKE) -C $(__SETUP_DIR)/$(dir) docs;)
|
||||
|
||||
.PHONY: tag
|
||||
tag:
|
||||
git tag -m 'AppArmor $(VERSION)' -s $(TAG_VERSION)
|
||||
bzr tag apparmor_${TAG_VERSION}
|
||||
|
||||
|
@@ -1,9 +1,3 @@
|
||||
# AppArmor
|
||||
|
||||
[](https://gitlab.com/apparmor/apparmor/commits/master)
|
||||
[](https://gitlab.com/apparmor/apparmor/pipelines)
|
||||
[](https://bestpractices.coreinfrastructure.org/projects/1699)
|
||||
|
||||
------------
|
||||
Introduction
|
||||
------------
|
||||
@@ -23,45 +17,9 @@ library, available under the LGPL license, which allows change_hat(2)
|
||||
and change_profile(2) to be used by non-GPL binaries).
|
||||
|
||||
For more information, you can read the techdoc.pdf (available after
|
||||
building the parser) and by visiting the https://apparmor.net/ web
|
||||
building the parser) and by visiting the http://apparmor.net/ web
|
||||
site.
|
||||
|
||||
----------------
|
||||
Getting in Touch
|
||||
----------------
|
||||
|
||||
Please send all complaints, feature requests, rants about the software,
|
||||
and questions to the
|
||||
[AppArmor mailing list](https://lists.ubuntu.com/mailman/listinfo/apparmor).
|
||||
|
||||
Bug reports can be filed against the AppArmor project on
|
||||
[launchpad](https://bugs.launchpad.net/apparmor) or reported to the mailing
|
||||
list directly for those who wish not to register for an account on
|
||||
launchpad. See the
|
||||
[wiki page](https://gitlab.com/apparmor/apparmor/wikis/home#reporting-bugs)
|
||||
for more information.
|
||||
|
||||
Security issues can be filed as security bugs on launchpad
|
||||
or directed to `security@apparmor.net`. Additional details can be found
|
||||
in the [wiki](https://gitlab.com/apparmor/apparmor/wikis/home#reporting-security-vulnerabilities).
|
||||
|
||||
|
||||
--------------
|
||||
Privacy Policy
|
||||
--------------
|
||||
|
||||
The AppArmor security project respects users privacy and data and does not collect data from or on its users beyond what is required for a given component to function.
|
||||
|
||||
The AppArmor kernel security module will log violations to the audit subsystem, and those will be logged/forwarded/recorded on the user's system(s) according to how the administrator has logging configured. Again this is not forwarded to or collected by the AppArmor project.
|
||||
|
||||
The AppArmor userspace tools do not collect information on the system user beyond the logs and information needed to interact with the user. This is not forwarded to, nor collected by the AppArmor project.
|
||||
|
||||
Users may submit information as part of an email, bug report or merge request, etc. and that will be recorded as part of the mailing list, bug/issue tracker, or code repository but only as part of a user initiated action.
|
||||
|
||||
The AppArmor project does not collect information from contributors beyond their interactions with the AppArmor project, code, and community. However contributors are subject to the terms and conditions and privacy policy of the individual platforms (currently GitLab and LaunchPad) should they choose to contribute through those platforms. And those platforms may collect data on the user that the AppArmor project does not.
|
||||
|
||||
Currently both GitLab an LaunchPad require a user account to submit patches or report bugs and issues. If a contributor does not wish to create an account for these platforms the mailing list is available. Membership in the list is not required. Content from non-list members will be sent to moderation, to ensure that it is on topic, so there may be a delay in choosing to interact in this way.
|
||||
|
||||
|
||||
-------------
|
||||
Source Layout
|
||||
@@ -69,8 +27,6 @@ Source Layout
|
||||
|
||||
AppArmor consists of several different parts:
|
||||
|
||||
```
|
||||
binutils/ source for basic utilities written in compiled languages
|
||||
changehat/ source for using changehat with Apache, PAM and Tomcat
|
||||
common/ common makefile rules
|
||||
desktop/ empty
|
||||
@@ -80,7 +36,6 @@ parser/ source for parser/loader and corresponding documentation
|
||||
profiles/ configuration files, reference profiles and abstractions
|
||||
tests/ regression and stress testsuites
|
||||
utils/ high-level utilities for working with AppArmor
|
||||
```
|
||||
|
||||
--------------------------------------
|
||||
Important note on AppArmor kernel code
|
||||
@@ -101,88 +56,55 @@ Building and Installing AppArmor Userspace
|
||||
------------------------------------------
|
||||
|
||||
To build and install AppArmor userspace on your system, build and install in
|
||||
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:
|
||||
the following order.
|
||||
|
||||
```
|
||||
$ export PYTHONPATH=$(realpath libraries/libapparmor/swig/python)
|
||||
$ export PYTHON=/usr/bin/python3
|
||||
$ export PYTHON_VERSION=3
|
||||
$ export PYTHON_VERSIONS=python3
|
||||
```
|
||||
|
||||
libapparmor:
|
||||
|
||||
```
|
||||
$ cd ./libraries/libapparmor
|
||||
$ sh ./autogen.sh
|
||||
$ sh ./configure --prefix=/usr --with-perl --with-python # see below
|
||||
$ make
|
||||
$ make check
|
||||
$ make install
|
||||
```
|
||||
|
||||
[an additional optional argument to libapparmor's configure is --with-ruby, to
|
||||
generate Ruby bindings to libapparmor.]
|
||||
|
||||
|
||||
Binary Utilities:
|
||||
|
||||
```
|
||||
$ cd binutils
|
||||
Utilities:
|
||||
$ cd utils
|
||||
$ make
|
||||
$ make check
|
||||
$ make install
|
||||
```
|
||||
|
||||
|
||||
parser:
|
||||
|
||||
```
|
||||
$ cd parser
|
||||
$ make # depends on libapparmor having been built first
|
||||
$ make check
|
||||
$ make install
|
||||
```
|
||||
|
||||
|
||||
Utilities:
|
||||
|
||||
```
|
||||
$ cd utils
|
||||
$ make
|
||||
$ make check PYFLAKES=/usr/bin/pyflakes3
|
||||
$ make install
|
||||
```
|
||||
|
||||
Apache mod_apparmor:
|
||||
|
||||
```
|
||||
$ cd changehat/mod_apparmor
|
||||
$ make # depends on libapparmor having been built first
|
||||
$ make install
|
||||
```
|
||||
|
||||
|
||||
PAM AppArmor:
|
||||
|
||||
```
|
||||
$ cd changehat/pam_apparmor
|
||||
$ make # depends on libapparmor having been built first
|
||||
$ make install
|
||||
```
|
||||
|
||||
|
||||
Profiles:
|
||||
|
||||
```
|
||||
$ cd profiles
|
||||
$ make
|
||||
$ make check # depends on the parser having been built first
|
||||
$ make install
|
||||
```
|
||||
|
||||
[Note that for the parser, binutils, and utils, if you only wish to build/use
|
||||
|
||||
[Note that for the parser and the utils, if you only with to build/use
|
||||
some of the locale languages, you can override the default by passing
|
||||
the LANGS arguments to make; e.g. make all install "LANGS=en_US fr".]
|
||||
|
||||
@@ -201,50 +123,38 @@ For details on structure and adding tests, see
|
||||
tests/regression/apparmor/README.
|
||||
|
||||
To run:
|
||||
|
||||
```
|
||||
$ cd tests/regression/apparmor (requires root)
|
||||
$ make
|
||||
$ sudo make tests
|
||||
$ sudo bash open.sh -r # runs and saves the last testcase from open.sh
|
||||
```
|
||||
|
||||
|
||||
Parser tests
|
||||
------------
|
||||
For details on structure and adding tests, see parser/tst/README.
|
||||
|
||||
To run:
|
||||
|
||||
```
|
||||
$ cd parser/tst
|
||||
$ make
|
||||
$ make tests
|
||||
```
|
||||
|
||||
|
||||
Libapparmor
|
||||
-----------
|
||||
For details on structure and adding tests, see libraries/libapparmor/README.
|
||||
|
||||
```
|
||||
$ cd libraries/libapparmor
|
||||
$ make check
|
||||
```
|
||||
|
||||
Utils
|
||||
-----
|
||||
Tests for the Python utilities exist in the test/ subdirectory.
|
||||
|
||||
```
|
||||
$ cd utils
|
||||
$ make check
|
||||
```
|
||||
|
||||
The aa-decode utility to be tested can be overridden by
|
||||
setting up environment variable APPARMOR_DECODE; e.g.:
|
||||
|
||||
```
|
||||
$ APPARMOR_DECODE=/usr/bin/aa-decode make check
|
||||
```
|
||||
|
||||
Profile checks
|
||||
--------------
|
||||
@@ -252,71 +162,32 @@ A basic consistency check to ensure that the parser and aa-logprof parse
|
||||
successfully the current set of shipped profiles. The system or other
|
||||
parser and logprof can be passed in by overriding the PARSER and LOGPROF
|
||||
variables.
|
||||
|
||||
```
|
||||
$ cd profiles
|
||||
$ make && make check
|
||||
```
|
||||
|
||||
Stress Tests
|
||||
------------
|
||||
To run AppArmor stress tests:
|
||||
|
||||
```
|
||||
$ make all
|
||||
```
|
||||
|
||||
Use these:
|
||||
|
||||
```
|
||||
$ ./change_hat
|
||||
$ ./child
|
||||
$ ./kill.sh
|
||||
$ ./open
|
||||
$ ./s.sh
|
||||
```
|
||||
|
||||
Or run all at once:
|
||||
|
||||
```
|
||||
$ ./stress.sh
|
||||
```
|
||||
|
||||
Please note that the above will stress the system so much it may end up
|
||||
invoking the OOM killer.
|
||||
|
||||
To run parser stress tests (requires /usr/bin/ruby):
|
||||
|
||||
```
|
||||
$ ./stress.sh
|
||||
```
|
||||
|
||||
(see stress.sh -h for options)
|
||||
|
||||
Coverity Support
|
||||
----------------
|
||||
Coverity scans are available to AppArmor developers at
|
||||
https://scan.coverity.com/projects/apparmor.
|
||||
|
||||
In order to submit a Coverity build for analysis, the cov-build binary
|
||||
must be discoverable from your PATH. See the "To Setup" section of
|
||||
https://scan.coverity.com/download?tab=cxx to obtain a pre-built copy of
|
||||
cov-build.
|
||||
|
||||
To generate a compressed tarball of an intermediate Coverity directory:
|
||||
|
||||
```
|
||||
$ make coverity
|
||||
```
|
||||
|
||||
The compressed tarball is written to
|
||||
apparmor-<SNAPSHOT_VERSION>-cov-int.tar.gz, where <SNAPSHOT_VERSION>
|
||||
is something like 2.10.90~3328, and must be uploaded to
|
||||
https://scan.coverity.com/projects/apparmor/builds/new for analysis. You must
|
||||
include the snapshot version in Coverity's project build submission form, in
|
||||
the "Project Version" field, so that it is quickly obvious to all AppArmor
|
||||
developers what snapshot of the AppArmor repository was used for the analysis.
|
||||
|
||||
-----------------------------------------------
|
||||
Building and Installing AppArmor Kernel Patches
|
||||
-----------------------------------------------
|
||||
@@ -332,8 +203,7 @@ The AppArmor userspace utilities are written with some assumptions about
|
||||
installed and available versions of other tools. This is a (possibly
|
||||
incomplete) list of known version dependencies:
|
||||
|
||||
The Python utilities require a minimum of Python 2.7 (deprecated) or Python 3.3.
|
||||
Python 3.x is recommended. Python 2.x support is deprecated since AppArmor 2.11.
|
||||
The Python utilities require a minimum of Python 2.7 or Python 3.3.
|
||||
|
||||
Some utilities (aa-exec, aa-notify and aa-decode) require Perl 5.10.1 or newer.
|
||||
|
@@ -1,161 +0,0 @@
|
||||
# ----------------------------------------------------------------------
|
||||
# Copyright (c) 2015
|
||||
# Canonical Ltd. (All rights reserved)
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of version 2 of the GNU General Public
|
||||
# License published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
# ----------------------------------------------------------------------
|
||||
NAME=aa-binutils
|
||||
all:
|
||||
COMMONDIR=../common/
|
||||
|
||||
include $(COMMONDIR)/Make.rules
|
||||
|
||||
DESTDIR=/
|
||||
BINDIR=${DESTDIR}/usr/bin
|
||||
LOCALEDIR=/usr/share/locale
|
||||
MANPAGES=aa-enabled.1 aa-exec.1
|
||||
|
||||
WARNINGS = -Wall
|
||||
EXTRA_WARNINGS = -Wsign-compare -Wmissing-field-initializers -Wformat-security -Wunused-parameter
|
||||
CPP_WARNINGS =
|
||||
ifndef CFLAGS
|
||||
CFLAGS = -g -O2 -pipe
|
||||
|
||||
ifdef DEBUG
|
||||
CFLAGS += -pg -D DEBUG
|
||||
endif
|
||||
ifdef COVERAGE
|
||||
CFLAGS = -g -pg -fprofile-arcs -ftest-coverage
|
||||
endif
|
||||
endif #CFLAGS
|
||||
|
||||
EXTRA_CFLAGS = ${CFLAGS} ${CPPFLAGS} ${EXTRA_CXXFLAGS} ${CPP_WARNINGS}
|
||||
|
||||
#INCLUDEDIR = /usr/src/linux/include
|
||||
INCLUDEDIR =
|
||||
|
||||
ifdef INCLUDEDIR
|
||||
CFLAGS += -I$(INCLUDEDIR)
|
||||
endif
|
||||
|
||||
# Internationalization support. Define a package and a LOCALEDIR
|
||||
EXTRA_CFLAGS+=-DPACKAGE=\"${NAME}\" -DLOCALEDIR=\"${LOCALEDIR}\"
|
||||
|
||||
SRCS = aa_enabled.c
|
||||
HDRS =
|
||||
TOOLS = aa-enabled aa-exec
|
||||
|
||||
AALIB = -Wl,-Bstatic -lapparmor -Wl,-Bdynamic -lpthread
|
||||
|
||||
ifdef WITH_LIBINTL
|
||||
AALIB += -lintl
|
||||
endif
|
||||
|
||||
ifdef USE_SYSTEM
|
||||
# Using the system libapparmor so Makefile dependencies can't be used
|
||||
LIBAPPARMOR_A =
|
||||
INCLUDE_APPARMOR =
|
||||
APPARMOR_H =
|
||||
LIBAPPARMOR_LDFLAGS =
|
||||
else
|
||||
LIBAPPARMOR_SRC = ../libraries/libapparmor/
|
||||
LOCAL_LIBAPPARMOR_INCLUDE = $(LIBAPPARMOR_SRC)/include
|
||||
LOCAL_LIBAPPARMOR_LDPATH = $(LIBAPPARMOR_SRC)/src/.libs
|
||||
|
||||
LIBAPPARMOR_A = $(LOCAL_LIBAPPARMOR_LDPATH)/libapparmor.a
|
||||
INCLUDE_APPARMOR = -I$(LOCAL_LIBAPPARMOR_INCLUDE)
|
||||
APPARMOR_H = $(LOCAL_LIBAPPARMOR_INCLUDE)/sys/apparmor.h
|
||||
LIBAPPARMOR_LDFLAGS = -L$(LOCAL_LIBAPPARMOR_LDPATH)
|
||||
endif
|
||||
EXTRA_CFLAGS += $(INCLUDE_APPARMOR)
|
||||
LDFLAGS += $(LIBAPPARMOR_LDFLAGS)
|
||||
|
||||
ifdef V
|
||||
VERBOSE = 1
|
||||
endif
|
||||
ifndef VERBOSE
|
||||
VERBOSE = 0
|
||||
endif
|
||||
ifeq ($(VERBOSE),1)
|
||||
BUILD_OUTPUT =
|
||||
Q =
|
||||
else
|
||||
BUILD_OUTPUT = > /dev/null 2>&1
|
||||
Q = @
|
||||
endif
|
||||
export Q VERBOSE BUILD_OUTPUT
|
||||
|
||||
po/%.pot: %.c
|
||||
$(MAKE) -C po $(@F) NAME=$* SOURCES=$*.c
|
||||
|
||||
# targets arranged this way so that people who don't want full docs can
|
||||
# pick specific targets they want.
|
||||
arch: $(TOOLS)
|
||||
|
||||
manpages: $(MANPAGES)
|
||||
|
||||
docs: manpages
|
||||
|
||||
indep: docs
|
||||
$(Q)$(MAKE) -C po all
|
||||
|
||||
all: arch indep
|
||||
|
||||
.PHONY: coverage
|
||||
coverage:
|
||||
$(MAKE) clean $(TOOLS) COVERAGE=1
|
||||
|
||||
ifndef USE_SYSTEM
|
||||
$(LIBAPPARMOR_A):
|
||||
@if [ ! -f $@ ]; then \
|
||||
echo "error: $@ is missing. Pick one of these possible solutions:" 1>&2; \
|
||||
echo " 1) Build against the in-tree libapparmor by building it first and then trying again. See the top-level README for help." 1>&2; \
|
||||
echo " 2) Build against the system libapparmor by adding USE_SYSTEM=1 to your make command." 1>&2;\
|
||||
exit 1; \
|
||||
fi
|
||||
endif
|
||||
|
||||
aa-enabled: aa_enabled.c $(LIBAPPARMOR_A)
|
||||
$(CC) $(LDFLAGS) $(EXTRA_CFLAGS) -o $@ $< $(LIBS) $(AALIB)
|
||||
|
||||
aa-exec: aa_exec.c $(LIBAPPARMOR_A)
|
||||
$(CC) $(LDFLAGS) $(EXTRA_CFLAGS) -o $@ $< $(LIBS) $(AALIB)
|
||||
|
||||
.SILENT: check
|
||||
.PHONY: check
|
||||
check: check_pod_files tests
|
||||
|
||||
.SILENT: tests
|
||||
tests: $(TOOLS) $(TESTS)
|
||||
echo "no tests atm"
|
||||
|
||||
.PHONY: install
|
||||
install: install-indep install-arch
|
||||
|
||||
.PHONY: install-arch
|
||||
install-arch: arch
|
||||
install -m 755 -d ${BINDIR}
|
||||
install -m 755 ${TOOLS} ${BINDIR}
|
||||
|
||||
.PHONY: install-indep
|
||||
install-indep: indep
|
||||
$(MAKE) -C po install NAME=${NAME} DESTDIR=${DESTDIR}
|
||||
$(MAKE) install_manpages DESTDIR=${DESTDIR}
|
||||
|
||||
ifndef VERBOSE
|
||||
.SILENT: clean
|
||||
endif
|
||||
.PHONY: clean
|
||||
clean: pod_clean
|
||||
rm -f core core.* *.o *.s *.a *~ *.gcda *.gcno
|
||||
rm -f gmon.out
|
||||
rm -f $(TOOLS) $(TESTS)
|
||||
$(MAKE) -s -C po clean
|
||||
|
@@ -1,94 +0,0 @@
|
||||
# This publication is intellectual property of Canonical Ltd. Its contents
|
||||
# can be duplicated, either in part or in whole, provided that a copyright
|
||||
# label is visibly located on each copy.
|
||||
#
|
||||
# All information found in this book has been compiled with utmost
|
||||
# attention to detail. However, this does not guarantee complete accuracy.
|
||||
# Neither Canonical Ltd, the authors, nor the translators shall be held
|
||||
# liable for possible errors or the consequences thereof.
|
||||
#
|
||||
# Many of the software and hardware descriptions cited in this book
|
||||
# are registered trademarks. All trade names are subject to copyright
|
||||
# restrictions and may be registered trade marks. Canonical Ltd
|
||||
# essentially adheres to the manufacturer's spelling.
|
||||
#
|
||||
# Names of products and trademarks appearing in this book (with or without
|
||||
# specific notation) are likewise subject to trademark and trade protection
|
||||
# laws and may thus fall under copyright restrictions.
|
||||
#
|
||||
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
aa-enabled - test whether AppArmor is enabled
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
B<aa-enabled> [options]
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
B<aa-enabled> is used to determine if AppArmor is enabled.
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
B<aa-enabled> accepts the following arguments:
|
||||
|
||||
=over 4
|
||||
|
||||
=item -h, --help
|
||||
|
||||
Display a brief usage guide.
|
||||
|
||||
=item -q, --quiet
|
||||
|
||||
Do not output anything to stdout. This option is intended to be used by
|
||||
scripts that simply want to use the exit code to determine if AppArmor is
|
||||
enabled.
|
||||
|
||||
=back
|
||||
|
||||
=head1 EXIT STATUS
|
||||
|
||||
Upon exiting, B<aa-enabled> will set its exit status to the following values:
|
||||
|
||||
=over 4
|
||||
|
||||
=item B<0>
|
||||
|
||||
if AppArmor is enabled.
|
||||
|
||||
=item B<1>
|
||||
|
||||
if AppArmor is not enabled/loaded.
|
||||
|
||||
=item B<2>
|
||||
|
||||
intentionally not used as an B<aa-enabled> exit status.
|
||||
|
||||
=item B<3>
|
||||
|
||||
if the AppArmor control files aren't available under /sys/kernel/security/.
|
||||
|
||||
=item B<4>
|
||||
|
||||
if B<aa-enabled> doesn't have enough privileges to read the apparmor control files.
|
||||
|
||||
=item B<64>
|
||||
|
||||
if any unexpected error or condition is encountered.
|
||||
|
||||
=back
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
If you find any bugs, please report them at
|
||||
L<https://bugs.launchpad.net/apparmor/+filebug>.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
apparmor(7), apparmor.d(5), aa_is_enabled(2), and L<https://wiki.apparmor.net>.
|
||||
|
||||
=cut
|
@@ -1,92 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Canonical Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of version 2 of the GNU General Public
|
||||
* License published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <locale.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <libintl.h>
|
||||
#define _(s) gettext(s)
|
||||
|
||||
#include <sys/apparmor.h>
|
||||
|
||||
void print_help(const char *command)
|
||||
{
|
||||
printf(_("%s: [options]\n"
|
||||
" options:\n"
|
||||
" -q | --quiet Don't print out any messages\n"
|
||||
" -h | --help Print help\n"),
|
||||
command);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
/* Exit statuses and meanings are documented in the aa-enabled.pod file */
|
||||
static void exit_with_error(int saved_errno, int quiet)
|
||||
{
|
||||
int err;
|
||||
|
||||
switch(saved_errno) {
|
||||
case ENOSYS:
|
||||
if (!quiet)
|
||||
printf(_("No - not available on this system.\n"));
|
||||
exit(1);
|
||||
case ECANCELED:
|
||||
if (!quiet)
|
||||
printf(_("No - disabled at boot.\n"));
|
||||
exit(1);
|
||||
case ENOENT:
|
||||
if (!quiet)
|
||||
printf(_("Maybe - policy interface not available.\n"));
|
||||
exit(3);
|
||||
case EPERM:
|
||||
case EACCES:
|
||||
if (!quiet)
|
||||
printf(_("Maybe - insufficient permissions to determine availability.\n"));
|
||||
exit(4);
|
||||
}
|
||||
|
||||
if (!quiet)
|
||||
printf(_("Error - %s\n"), strerror(saved_errno));
|
||||
exit(64);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int enabled;
|
||||
int quiet = 0;
|
||||
|
||||
setlocale(LC_MESSAGES, "");
|
||||
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||
textdomain(PACKAGE);
|
||||
|
||||
if (argc > 2) {
|
||||
printf(_("unknown or incompatible options\n"));
|
||||
print_help(argv[0]);
|
||||
} else if (argc == 2) {
|
||||
if (strcmp(argv[1], "--quiet") == 0 ||
|
||||
strcmp(argv[1], "-q") == 0) {
|
||||
quiet = 1;
|
||||
} else if (strcmp(argv[1], "--help") == 0 ||
|
||||
strcmp(argv[1], "-h") == 0) {
|
||||
print_help(argv[0]);
|
||||
} else {
|
||||
printf(_("unknown option '%s'\n"), argv[1]);
|
||||
print_help(argv[0]);
|
||||
}
|
||||
}
|
||||
|
||||
enabled = aa_is_enabled();
|
||||
if (!enabled)
|
||||
exit_with_error(errno, quiet);
|
||||
|
||||
if (!quiet)
|
||||
printf(_("Yes\n"));
|
||||
exit(0);
|
||||
}
|
@@ -1,218 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2015
|
||||
* Canonical, Ltd. (All rights reserved)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of version 2 of the GNU General Public
|
||||
* License published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, contact Novell, Inc. or Canonical
|
||||
* Ltd.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <getopt.h>
|
||||
#include <libintl.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/apparmor.h>
|
||||
#include <unistd.h>
|
||||
#define _(s) gettext(s)
|
||||
|
||||
static const char *opt_profile = NULL;
|
||||
static const char *opt_namespace = NULL;
|
||||
static bool opt_debug = false;
|
||||
static bool opt_immediate = false;
|
||||
static bool opt_verbose = false;
|
||||
|
||||
static void usage(const char *name, bool error)
|
||||
{
|
||||
FILE *stream = stdout;
|
||||
int status = EXIT_SUCCESS;
|
||||
|
||||
if (error) {
|
||||
stream = stderr;
|
||||
status = EXIT_FAILURE;
|
||||
}
|
||||
|
||||
fprintf(stream,
|
||||
_("USAGE: %s [OPTIONS] <prog> <args>\n"
|
||||
"\n"
|
||||
"Confine <prog> with the specified PROFILE.\n"
|
||||
"\n"
|
||||
"OPTIONS:\n"
|
||||
" -p PROFILE, --profile=PROFILE PROFILE to confine <prog> with\n"
|
||||
" -n NAMESPACE, --namespace=NAMESPACE NAMESPACE to confine <prog> in\n"
|
||||
" -d, --debug show messages with debugging information\n"
|
||||
" -i, --immediate change profile immediately instead of at exec\n"
|
||||
" -v, --verbose show messages with stats\n"
|
||||
" -h, --help display this help\n"
|
||||
"\n"), name);
|
||||
exit(status);
|
||||
}
|
||||
|
||||
#define error(fmt, args...) _error(_("aa-exec: ERROR: " fmt "\n"), ## args)
|
||||
static void _error(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
vfprintf(stderr, fmt, args);
|
||||
va_end(args);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
#define debug(fmt, args...) _debug(_("aa-exec: DEBUG: " fmt "\n"), ## args)
|
||||
static void _debug(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
if (!opt_debug)
|
||||
return;
|
||||
|
||||
va_start(args, fmt);
|
||||
vfprintf(stderr, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
#define verbose(fmt, args...) _verbose(_(fmt "\n"), ## args)
|
||||
static void _verbose(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
if (!opt_verbose)
|
||||
return;
|
||||
|
||||
va_start(args, fmt);
|
||||
vfprintf(stderr, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
static void verbose_print_argv(char **argv)
|
||||
{
|
||||
if (!opt_verbose)
|
||||
return;
|
||||
|
||||
fprintf(stderr, _("exec"));
|
||||
for (; *argv; argv++)
|
||||
fprintf(stderr, " %s", *argv);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
static char **parse_args(int argc, char **argv)
|
||||
{
|
||||
int opt;
|
||||
struct option long_opts[] = {
|
||||
{"debug", no_argument, 0, 'd'},
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"profile", required_argument, 0, 'p'},
|
||||
{"namespace", required_argument, 0, 'n'},
|
||||
{"immediate", no_argument, 0, 'i'},
|
||||
{"verbose", no_argument, 0, 'v'},
|
||||
};
|
||||
|
||||
while ((opt = getopt_long(argc, argv, "+dhp:n:iv", long_opts, NULL)) != -1) {
|
||||
switch (opt) {
|
||||
case 'd':
|
||||
opt_debug = true;
|
||||
break;
|
||||
case 'h':
|
||||
usage(argv[0], false);
|
||||
break;
|
||||
case 'p':
|
||||
opt_profile = optarg;
|
||||
break;
|
||||
case 'n':
|
||||
opt_namespace = optarg;
|
||||
break;
|
||||
case 'i':
|
||||
opt_immediate = true;
|
||||
break;
|
||||
case 'v':
|
||||
opt_verbose = true;
|
||||
break;
|
||||
default:
|
||||
usage(argv[0], true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (optind >= argc)
|
||||
usage(argv[0], true);
|
||||
|
||||
return argv + optind;
|
||||
}
|
||||
|
||||
static void build_name(char *name, size_t name_len,
|
||||
const char *namespace, const char *profile)
|
||||
{
|
||||
size_t required_len = 1; /* reserve 1 byte for NUL-terminator */
|
||||
|
||||
if (namespace)
|
||||
required_len += 1 + strlen(namespace) + 3; /* :<NAMESPACE>:// */
|
||||
|
||||
if (profile)
|
||||
required_len += strlen(profile);
|
||||
|
||||
if (required_len > name_len)
|
||||
error("name too long (%zu > %zu)", required_len, name_len);
|
||||
|
||||
name[0] = '\0';
|
||||
|
||||
if (namespace) {
|
||||
strcat(name, ":");
|
||||
strcat(name, namespace);
|
||||
strcat(name, "://");
|
||||
}
|
||||
|
||||
if (profile)
|
||||
strcat(name, profile);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char name[PATH_MAX];
|
||||
int rc = 0;
|
||||
|
||||
argv = parse_args(argc, argv);
|
||||
|
||||
if (opt_namespace || opt_profile)
|
||||
build_name(name, sizeof(name), opt_namespace, opt_profile);
|
||||
else
|
||||
goto exec;
|
||||
|
||||
if (opt_immediate) {
|
||||
verbose("aa_change_profile(\"%s\")", name);
|
||||
rc = aa_change_profile(name);
|
||||
debug("%d = aa_change_profile(\"%s\")", rc, name);
|
||||
} else {
|
||||
verbose("aa_change_onexec(\"%s\")", name);
|
||||
rc = aa_change_onexec(name);
|
||||
debug("%d = aa_change_onexec(\"%s\")", rc, name);
|
||||
}
|
||||
|
||||
if (rc) {
|
||||
if (errno == ENOENT || errno == EACCES) {
|
||||
error("%s '%s' does not exist\n",
|
||||
opt_profile ? "profile" : "namespace", name);
|
||||
} else if (errno == EINVAL) {
|
||||
error("AppArmor interface not available");
|
||||
} else {
|
||||
error("%m");
|
||||
}
|
||||
}
|
||||
|
||||
exec:
|
||||
verbose_print_argv(argv);
|
||||
execvp(argv[0], argv);
|
||||
error("Failed to execute \"%s\": %m", argv[0]);
|
||||
}
|
@@ -1,19 +0,0 @@
|
||||
# ----------------------------------------------------------------------
|
||||
# Copyright (C) 2015 Canonical Ltd.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of version 2 of the GNU General Public
|
||||
# License published by the Free Software Foundation.
|
||||
# ----------------------------------------------------------------------
|
||||
all:
|
||||
|
||||
# As translations get added, they will automatically be included, unless
|
||||
# the lang is explicitly added to DISABLED_LANGS; e.g. DISABLED_LANGS=en es
|
||||
|
||||
DISABLED_LANGS=
|
||||
|
||||
COMMONDIR=../../common
|
||||
include $(COMMONDIR)/Make-po.rules
|
||||
|
||||
XGETTEXT_ARGS+=--language=C --keyword=_ $(shell if [ -f ${NAME}.pot ] ; then echo -n -j ; fi)
|
||||
|
@@ -1,66 +0,0 @@
|
||||
# Copyright (C) 2015 Canonical Ltd
|
||||
# This file is distributed under the same license as the AppArmor package.
|
||||
# John Johansen <john.johansen@canonical.com>, 2015.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: apparmor@lists.ubuntu.com\n"
|
||||
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=CHARSET\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: ../aa_enabled.c:26
|
||||
#, c-format
|
||||
msgid ""
|
||||
"%s: [options]\n"
|
||||
" options:\n"
|
||||
" -q | --quiet Don't print out any messages\n"
|
||||
" -h | --help Print help\n"
|
||||
msgstr ""
|
||||
|
||||
#: ../aa_enabled.c:45
|
||||
#, c-format
|
||||
msgid "unknown or incompatible options\n"
|
||||
msgstr ""
|
||||
|
||||
#: ../aa_enabled.c:55
|
||||
#, c-format
|
||||
msgid "unknown option '%s'\n"
|
||||
msgstr ""
|
||||
|
||||
#: ../aa_enabled.c:64
|
||||
#, c-format
|
||||
msgid "Yes\n"
|
||||
msgstr ""
|
||||
|
||||
#: ../aa_enabled.c:71
|
||||
#, c-format
|
||||
msgid "No - not available on this system.\n"
|
||||
msgstr ""
|
||||
|
||||
#: ../aa_enabled.c:74
|
||||
#, c-format
|
||||
msgid "No - disabled at boot.\n"
|
||||
msgstr ""
|
||||
|
||||
#: ../aa_enabled.c:77
|
||||
#, c-format
|
||||
msgid "Maybe - policy interface not available.\n"
|
||||
msgstr ""
|
||||
|
||||
#: ../aa_enabled.c:81
|
||||
#, c-format
|
||||
msgid "Maybe - insufficient permissions to determine availability.\n"
|
||||
msgstr ""
|
||||
|
||||
#: ../aa_enabled.c:84
|
||||
#, c-format
|
||||
msgid "Error - '%s'\n"
|
||||
msgstr ""
|
@@ -1,67 +0,0 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR Canonical Ltd
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: apparmor@lists.ubuntu.com\n"
|
||||
"POT-Creation-Date: 2020-10-14 03:36-0700\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=CHARSET\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: ../aa_enabled.c:21
|
||||
#, c-format
|
||||
msgid ""
|
||||
"%s: [options]\n"
|
||||
" options:\n"
|
||||
" -q | --quiet Don't print out any messages\n"
|
||||
" -h | --help Print help\n"
|
||||
msgstr ""
|
||||
|
||||
#: ../aa_enabled.c:38
|
||||
#, c-format
|
||||
msgid "No - not available on this system.\n"
|
||||
msgstr ""
|
||||
|
||||
#: ../aa_enabled.c:42
|
||||
#, c-format
|
||||
msgid "No - disabled at boot.\n"
|
||||
msgstr ""
|
||||
|
||||
#: ../aa_enabled.c:46
|
||||
#, c-format
|
||||
msgid "Maybe - policy interface not available.\n"
|
||||
msgstr ""
|
||||
|
||||
#: ../aa_enabled.c:51
|
||||
#, c-format
|
||||
msgid "Maybe - insufficient permissions to determine availability.\n"
|
||||
msgstr ""
|
||||
|
||||
#: ../aa_enabled.c:56
|
||||
#, c-format
|
||||
msgid "Error - %s\n"
|
||||
msgstr ""
|
||||
|
||||
#: ../aa_enabled.c:70
|
||||
#, c-format
|
||||
msgid "unknown or incompatible options\n"
|
||||
msgstr ""
|
||||
|
||||
#: ../aa_enabled.c:80
|
||||
#, c-format
|
||||
msgid "unknown option '%s'\n"
|
||||
msgstr ""
|
||||
|
||||
#: ../aa_enabled.c:90
|
||||
#, c-format
|
||||
msgid "Yes\n"
|
||||
msgstr ""
|
@@ -1,52 +0,0 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR Canonical Ltd
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: apparmor@lists.ubuntu.com\n"
|
||||
"POT-Creation-Date: 2020-10-14 03:37-0700\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=CHARSET\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: ../aa_exec.c:48
|
||||
#, c-format
|
||||
msgid ""
|
||||
"USAGE: %s [OPTIONS] <prog> <args>\n"
|
||||
"\n"
|
||||
"Confine <prog> with the specified PROFILE.\n"
|
||||
"\n"
|
||||
"OPTIONS:\n"
|
||||
" -p PROFILE, --profile=PROFILE\t\tPROFILE to confine <prog> with\n"
|
||||
" -n NAMESPACE, --namespace=NAMESPACE\tNAMESPACE to confine <prog> in\n"
|
||||
" -d, --debug\t\t\t\tshow messages with debugging information\n"
|
||||
" -i, --immediate\t\t\tchange profile immediately instead of at exec\n"
|
||||
" -v, --verbose\t\t\t\tshow messages with stats\n"
|
||||
" -h, --help\t\t\t\tdisplay this help\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
|
||||
#: ../aa_exec.c:63
|
||||
msgid "aa-exec: ERROR: "
|
||||
msgstr ""
|
||||
|
||||
#: ../aa_exec.c:74
|
||||
msgid "aa-exec: DEBUG: "
|
||||
msgstr ""
|
||||
|
||||
#: ../aa_exec.c:87
|
||||
msgid "\n"
|
||||
msgstr ""
|
||||
|
||||
#: ../aa_exec.c:105
|
||||
#, c-format
|
||||
msgid "exec"
|
||||
msgstr ""
|
@@ -1,73 +0,0 @@
|
||||
# German translation for apparmor
|
||||
# Copyright (c) 2016 Rosetta Contributors and Canonical Ltd 2016
|
||||
# This file is distributed under the same license as the apparmor package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2016.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: apparmor\n"
|
||||
"Report-Msgid-Bugs-To: AppArmor list <apparmor@lists.ubuntu.com>\n"
|
||||
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
|
||||
"PO-Revision-Date: 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: 2019-04-18 05:33+0000\n"
|
||||
"X-Generator: Launchpad (build 18928)\n"
|
||||
"Language: de\n"
|
||||
|
||||
#: ../aa_enabled.c:26
|
||||
#, c-format
|
||||
msgid ""
|
||||
"%s: [options]\n"
|
||||
" options:\n"
|
||||
" -q | --quiet Don't print out any messages\n"
|
||||
" -h | --help Print help\n"
|
||||
msgstr ""
|
||||
"%s: [Optionen]\n"
|
||||
" Optionen:\n"
|
||||
" -q | --quiet Keine Nachrichten anzeigen\n"
|
||||
" -h | --help Hilfetext anzeigen\n"
|
||||
|
||||
#: ../aa_enabled.c:45
|
||||
#, c-format
|
||||
msgid "unknown or incompatible options\n"
|
||||
msgstr "unbekannte oder nicht kompatible Optionen\n"
|
||||
|
||||
#: ../aa_enabled.c:55
|
||||
#, c-format
|
||||
msgid "unknown option '%s'\n"
|
||||
msgstr "unbekannte Option »%s«\n"
|
||||
|
||||
#: ../aa_enabled.c:64
|
||||
#, c-format
|
||||
msgid "Yes\n"
|
||||
msgstr "Ja\n"
|
||||
|
||||
#: ../aa_enabled.c:71
|
||||
#, c-format
|
||||
msgid "No - not available on this system.\n"
|
||||
msgstr "Nein – auf diesem System nicht verfügbar.\n"
|
||||
|
||||
#: ../aa_enabled.c:74
|
||||
#, c-format
|
||||
msgid "No - disabled at boot.\n"
|
||||
msgstr "Nein – beim Start deaktiviert.\n"
|
||||
|
||||
#: ../aa_enabled.c:77
|
||||
#, c-format
|
||||
msgid "Maybe - policy interface not available.\n"
|
||||
msgstr "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"
|
@@ -1,72 +0,0 @@
|
||||
# English (United Kingdom) translation for apparmor
|
||||
# Copyright (c) 2016 Rosetta Contributors and Canonical Ltd 2016
|
||||
# This file is distributed under the same license as the apparmor package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2016.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: apparmor\n"
|
||||
"Report-Msgid-Bugs-To: AppArmor list <apparmor@lists.ubuntu.com>\n"
|
||||
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
|
||||
"PO-Revision-Date: 2016-02-18 06:22+0000\n"
|
||||
"Last-Translator: Andi Chandler <Unknown>\n"
|
||||
"Language-Team: English (United Kingdom) <en_GB@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2019-04-18 05:33+0000\n"
|
||||
"X-Generator: Launchpad (build 18928)\n"
|
||||
"Language: en_GB\n"
|
||||
|
||||
#: ../aa_enabled.c:26
|
||||
#, c-format
|
||||
msgid ""
|
||||
"%s: [options]\n"
|
||||
" options:\n"
|
||||
" -q | --quiet Don't print out any messages\n"
|
||||
" -h | --help Print help\n"
|
||||
msgstr ""
|
||||
"%s: [options]\n"
|
||||
" options:\n"
|
||||
" -q | --quiet Don't print out any messages\n"
|
||||
" -h | --help Print help\n"
|
||||
|
||||
#: ../aa_enabled.c:45
|
||||
#, c-format
|
||||
msgid "unknown or incompatible options\n"
|
||||
msgstr "unknown or incompatible options\n"
|
||||
|
||||
#: ../aa_enabled.c:55
|
||||
#, c-format
|
||||
msgid "unknown option '%s'\n"
|
||||
msgstr "unknown option '%s'\n"
|
||||
|
||||
#: ../aa_enabled.c:64
|
||||
#, c-format
|
||||
msgid "Yes\n"
|
||||
msgstr "Yes\n"
|
||||
|
||||
#: ../aa_enabled.c:71
|
||||
#, c-format
|
||||
msgid "No - not available on this system.\n"
|
||||
msgstr "No - not available on this system.\n"
|
||||
|
||||
#: ../aa_enabled.c:74
|
||||
#, c-format
|
||||
msgid "No - disabled at boot.\n"
|
||||
msgstr "No - disabled at boot.\n"
|
||||
|
||||
#: ../aa_enabled.c:77
|
||||
#, c-format
|
||||
msgid "Maybe - policy interface not available.\n"
|
||||
msgstr "Maybe - policy interface not available.\n"
|
||||
|
||||
#: ../aa_enabled.c:81
|
||||
#, c-format
|
||||
msgid "Maybe - insufficient permissions to determine availability.\n"
|
||||
msgstr "Maybe - insufficient permissions to determine availability.\n"
|
||||
|
||||
#: ../aa_enabled.c:84
|
||||
#, c-format
|
||||
msgid "Error - '%s'\n"
|
||||
msgstr "Error - '%s'\n"
|
@@ -1,71 +0,0 @@
|
||||
# Spanish translation for apparmor
|
||||
# Copyright (c) 2019 Rosetta Contributors and Canonical Ltd 2019
|
||||
# This file is distributed under the same license as the apparmor package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2019.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: apparmor\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
|
||||
"PO-Revision-Date: 2019-06-09 14:01+0000\n"
|
||||
"Last-Translator: Adolfo Jayme <fitoschido@gmail.com>\n"
|
||||
"Language-Team: Spanish <es@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: 2019-06-10 04:32+0000\n"
|
||||
"X-Generator: Launchpad (build 18978)\n"
|
||||
|
||||
#: ../aa_enabled.c:26
|
||||
#, c-format
|
||||
msgid ""
|
||||
"%s: [options]\n"
|
||||
" options:\n"
|
||||
" -q | --quiet Don't print out any messages\n"
|
||||
" -h | --help Print help\n"
|
||||
msgstr ""
|
||||
"%s: [opciones]\n"
|
||||
" opciones:\n"
|
||||
" -q | --quiet No emitir ningún mensaje\n"
|
||||
" -h | --help Mostrar la ayuda\n"
|
||||
|
||||
#: ../aa_enabled.c:45
|
||||
#, c-format
|
||||
msgid "unknown or incompatible options\n"
|
||||
msgstr "opciones desconocidas o incompatibles\n"
|
||||
|
||||
#: ../aa_enabled.c:55
|
||||
#, c-format
|
||||
msgid "unknown option '%s'\n"
|
||||
msgstr "se desconoce la opción «%s»\n"
|
||||
|
||||
#: ../aa_enabled.c:64
|
||||
#, c-format
|
||||
msgid "Yes\n"
|
||||
msgstr "Sí\n"
|
||||
|
||||
#: ../aa_enabled.c:71
|
||||
#, c-format
|
||||
msgid "No - not available on this system.\n"
|
||||
msgstr "No; no disponible en este sistema.\n"
|
||||
|
||||
#: ../aa_enabled.c:74
|
||||
#, c-format
|
||||
msgid "No - disabled at boot.\n"
|
||||
msgstr "No; desactivado durante el arranque.\n"
|
||||
|
||||
#: ../aa_enabled.c:77
|
||||
#, c-format
|
||||
msgid "Maybe - policy interface not available.\n"
|
||||
msgstr "Quizá; interfaz de directiva no disponible.\n"
|
||||
|
||||
#: ../aa_enabled.c:81
|
||||
#, c-format
|
||||
msgid "Maybe - insufficient permissions to determine availability.\n"
|
||||
msgstr "Quizá; permisos insuficientes para determinar disponibilidad.\n"
|
||||
|
||||
#: ../aa_enabled.c:84
|
||||
#, c-format
|
||||
msgid "Error - '%s'\n"
|
||||
msgstr "Error: «%s»\n"
|
@@ -1,72 +0,0 @@
|
||||
# Indonesian translation for apparmor
|
||||
# Copyright (c) 2016 Rosetta Contributors and Canonical Ltd 2016
|
||||
# This file is distributed under the same license as the apparmor package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2016.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: apparmor\n"
|
||||
"Report-Msgid-Bugs-To: AppArmor list <apparmor@lists.ubuntu.com>\n"
|
||||
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
|
||||
"PO-Revision-Date: 2016-01-20 08:59+0000\n"
|
||||
"Last-Translator: Ari Setyo Wibowo <mr.a.contact@gmail.com>\n"
|
||||
"Language-Team: Indonesian <id@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2019-04-18 05:33+0000\n"
|
||||
"X-Generator: Launchpad (build 18928)\n"
|
||||
"Language: id\n"
|
||||
|
||||
#: ../aa_enabled.c:26
|
||||
#, c-format
|
||||
msgid ""
|
||||
"%s: [options]\n"
|
||||
" options:\n"
|
||||
" -q | --quiet Don't print out any messages\n"
|
||||
" -h | --help Print help\n"
|
||||
msgstr ""
|
||||
"%s: [options]\n"
|
||||
" pilihan:\n"
|
||||
" -q | --quiet Jangan tampilkan pesan apapun\n"
|
||||
" -h | --help Tampilkan bantuan\n"
|
||||
|
||||
#: ../aa_enabled.c:45
|
||||
#, c-format
|
||||
msgid "unknown or incompatible options\n"
|
||||
msgstr "pilihan yang tidak dikenali atau tidak kompatibel\n"
|
||||
|
||||
#: ../aa_enabled.c:55
|
||||
#, c-format
|
||||
msgid "unknown option '%s'\n"
|
||||
msgstr "pilihan tidak dikenali '%s'\n"
|
||||
|
||||
#: ../aa_enabled.c:64
|
||||
#, c-format
|
||||
msgid "Yes\n"
|
||||
msgstr "Ya\n"
|
||||
|
||||
#: ../aa_enabled.c:71
|
||||
#, c-format
|
||||
msgid "No - not available on this system.\n"
|
||||
msgstr "Tidak - tidak tersedia di sistem ini.\n"
|
||||
|
||||
#: ../aa_enabled.c:74
|
||||
#, c-format
|
||||
msgid "No - disabled at boot.\n"
|
||||
msgstr "Tidak - nonaktifkan saat boot.\n"
|
||||
|
||||
#: ../aa_enabled.c:77
|
||||
#, c-format
|
||||
msgid "Maybe - policy interface not available.\n"
|
||||
msgstr "Mungkin - kebijakan antarmuka tidak tersedia.\n"
|
||||
|
||||
#: ../aa_enabled.c:81
|
||||
#, c-format
|
||||
msgid "Maybe - insufficient permissions to determine availability.\n"
|
||||
msgstr "Mungkin - izin tidak memadai untuk menentukan ketersediaan.\n"
|
||||
|
||||
#: ../aa_enabled.c:84
|
||||
#, c-format
|
||||
msgid "Error - '%s'\n"
|
||||
msgstr "Kesalahan - '%s'\n"
|
@@ -1,72 +0,0 @@
|
||||
# Portuguese translation for apparmor
|
||||
# Copyright (c) 2016 Rosetta Contributors and Canonical Ltd 2016
|
||||
# This file is distributed under the same license as the apparmor package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2016.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: apparmor\n"
|
||||
"Report-Msgid-Bugs-To: AppArmor list <apparmor@lists.ubuntu.com>\n"
|
||||
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
|
||||
"PO-Revision-Date: 2016-03-03 08:34+0000\n"
|
||||
"Last-Translator: Ivo Xavier <ivofernandes12@gmail.com>\n"
|
||||
"Language-Team: Portuguese <pt@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2019-04-18 05:33+0000\n"
|
||||
"X-Generator: Launchpad (build 18928)\n"
|
||||
"Language: pt\n"
|
||||
|
||||
#: ../aa_enabled.c:26
|
||||
#, c-format
|
||||
msgid ""
|
||||
"%s: [options]\n"
|
||||
" options:\n"
|
||||
" -q | --quiet Don't print out any messages\n"
|
||||
" -h | --help Print help\n"
|
||||
msgstr ""
|
||||
"%s: [opções]\n"
|
||||
" opções:\n"
|
||||
" -q | --silencioso Não mostrar mensagens\n"
|
||||
" -h | --ajuda Mostar ajuda\n"
|
||||
|
||||
#: ../aa_enabled.c:45
|
||||
#, c-format
|
||||
msgid "unknown or incompatible options\n"
|
||||
msgstr "opções desconhecidas ou incompatíveis\n"
|
||||
|
||||
#: ../aa_enabled.c:55
|
||||
#, c-format
|
||||
msgid "unknown option '%s'\n"
|
||||
msgstr "opção desconhecida '%s'\n"
|
||||
|
||||
#: ../aa_enabled.c:64
|
||||
#, c-format
|
||||
msgid "Yes\n"
|
||||
msgstr "Sim\n"
|
||||
|
||||
#: ../aa_enabled.c:71
|
||||
#, c-format
|
||||
msgid "No - not available on this system.\n"
|
||||
msgstr "Não - não disponível neste sistema.\n"
|
||||
|
||||
#: ../aa_enabled.c:74
|
||||
#, c-format
|
||||
msgid "No - disabled at boot.\n"
|
||||
msgstr "Não - desligado ao iniciar.\n"
|
||||
|
||||
#: ../aa_enabled.c:77
|
||||
#, c-format
|
||||
msgid "Maybe - policy interface not available.\n"
|
||||
msgstr "Talvez - política de interface não disponível.\n"
|
||||
|
||||
#: ../aa_enabled.c:81
|
||||
#, c-format
|
||||
msgid "Maybe - insufficient permissions to determine availability.\n"
|
||||
msgstr "Talvez - permissões insuficientes para determinar disponibilidade.\n"
|
||||
|
||||
#: ../aa_enabled.c:84
|
||||
#, c-format
|
||||
msgid "Error - '%s'\n"
|
||||
msgstr "Erro - '%s'\n"
|
@@ -1,72 +0,0 @@
|
||||
# Russian translation for apparmor
|
||||
# Copyright (c) 2016 Rosetta Contributors and Canonical Ltd 2016
|
||||
# This file is distributed under the same license as the apparmor package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2016.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: apparmor\n"
|
||||
"Report-Msgid-Bugs-To: AppArmor list <apparmor@lists.ubuntu.com>\n"
|
||||
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
|
||||
"PO-Revision-Date: 2016-03-29 14:46+0000\n"
|
||||
"Last-Translator: Eugene Roskin <Unknown>\n"
|
||||
"Language-Team: Russian <ru@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2019-04-18 05:33+0000\n"
|
||||
"X-Generator: Launchpad (build 18928)\n"
|
||||
"Language: ru\n"
|
||||
|
||||
#: ../aa_enabled.c:26
|
||||
#, c-format
|
||||
msgid ""
|
||||
"%s: [options]\n"
|
||||
" options:\n"
|
||||
" -q | --quiet Don't print out any messages\n"
|
||||
" -h | --help Print help\n"
|
||||
msgstr ""
|
||||
"%s: [параметры]\n"
|
||||
" параметры:\n"
|
||||
" -q | --quiet не выводить никакие сообщения\n"
|
||||
" -h | --help вывести справку\n"
|
||||
|
||||
#: ../aa_enabled.c:45
|
||||
#, c-format
|
||||
msgid "unknown or incompatible options\n"
|
||||
msgstr "неизвестные или несовместимые параметры\n"
|
||||
|
||||
#: ../aa_enabled.c:55
|
||||
#, c-format
|
||||
msgid "unknown option '%s'\n"
|
||||
msgstr "неизвестный параметр '%s'\n"
|
||||
|
||||
#: ../aa_enabled.c:64
|
||||
#, c-format
|
||||
msgid "Yes\n"
|
||||
msgstr "Да\n"
|
||||
|
||||
#: ../aa_enabled.c:71
|
||||
#, c-format
|
||||
msgid "No - not available on this system.\n"
|
||||
msgstr "Нет - недоступно на этой системе.\n"
|
||||
|
||||
#: ../aa_enabled.c:74
|
||||
#, c-format
|
||||
msgid "No - disabled at boot.\n"
|
||||
msgstr "Нет - выключено при загрузке.\n"
|
||||
|
||||
#: ../aa_enabled.c:77
|
||||
#, c-format
|
||||
msgid "Maybe - policy interface not available.\n"
|
||||
msgstr "Возможно - интерфейс политики недоступен.\n"
|
||||
|
||||
#: ../aa_enabled.c:81
|
||||
#, c-format
|
||||
msgid "Maybe - insufficient permissions to determine availability.\n"
|
||||
msgstr "Возможно - недостаточно разрешений для определения доступности.\n"
|
||||
|
||||
#: ../aa_enabled.c:84
|
||||
#, c-format
|
||||
msgid "Error - '%s'\n"
|
||||
msgstr "Ошибка - '%s'\n"
|
@@ -1,72 +0,0 @@
|
||||
# Swedish translation for apparmor
|
||||
# Copyright (c) 2018 Rosetta Contributors and Canonical Ltd 2018
|
||||
# This file is distributed under the same license as the apparmor package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2018.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: apparmor\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
|
||||
"PO-Revision-Date: 2018-09-08 03:51+0000\n"
|
||||
"Last-Translator: Jonatan Nyberg <Unknown>\n"
|
||||
"Language-Team: Swedish <sv@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: 2019-04-18 05:33+0000\n"
|
||||
"X-Generator: Launchpad (build 18928)\n"
|
||||
|
||||
#: ../aa_enabled.c:26
|
||||
#, c-format
|
||||
msgid ""
|
||||
"%s: [options]\n"
|
||||
" options:\n"
|
||||
" -q | --quiet Don't print out any messages\n"
|
||||
" -h | --help Print help\n"
|
||||
msgstr ""
|
||||
"%s: [options]\n"
|
||||
" flaggor:\n"
|
||||
" -q | --quiet Skriv inte ut några meddelanden\n"
|
||||
" -h | --help Skriv ut hjälp\n"
|
||||
|
||||
#: ../aa_enabled.c:45
|
||||
#, c-format
|
||||
msgid "unknown or incompatible options\n"
|
||||
msgstr "okända eller inkompatibla flaggor\n"
|
||||
|
||||
#: ../aa_enabled.c:55
|
||||
#, c-format
|
||||
msgid "unknown option '%s'\n"
|
||||
msgstr "okänd flagga '%s'\n"
|
||||
|
||||
#: ../aa_enabled.c:64
|
||||
#, c-format
|
||||
msgid "Yes\n"
|
||||
msgstr "Ja\n"
|
||||
|
||||
#: ../aa_enabled.c:71
|
||||
#, c-format
|
||||
msgid "No - not available on this system.\n"
|
||||
msgstr "Nej - inte tillgänglig på detta system.\n"
|
||||
|
||||
#: ../aa_enabled.c:74
|
||||
#, c-format
|
||||
msgid "No - disabled at boot.\n"
|
||||
msgstr "Nej - inaktiverad vid uppstart.\n"
|
||||
|
||||
#: ../aa_enabled.c:77
|
||||
#, c-format
|
||||
msgid "Maybe - policy interface not available.\n"
|
||||
msgstr "Kanske - policy gränssnitt inte tillgängliga.\n"
|
||||
|
||||
#: ../aa_enabled.c:81
|
||||
#, c-format
|
||||
msgid "Maybe - insufficient permissions to determine availability.\n"
|
||||
msgstr ""
|
||||
"Kanske - otillräckliga behörigheter för att bestämma tillgängligheten.\n"
|
||||
|
||||
#: ../aa_enabled.c:84
|
||||
#, c-format
|
||||
msgid "Error - '%s'\n"
|
||||
msgstr "Fel - '%s'\n"
|
@@ -1,72 +0,0 @@
|
||||
# Turkish translation for apparmor
|
||||
# Copyright (c) 2018 Rosetta Contributors and Canonical Ltd 2018
|
||||
# This file is distributed under the same license as the apparmor package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2018.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: apparmor\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
|
||||
"PO-Revision-Date: 2018-05-19 23:10+0000\n"
|
||||
"Last-Translator: Kudret EMRE <kudretemre@hotmail.com>\n"
|
||||
"Language-Team: Turkish <tr@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: 2019-04-18 05:33+0000\n"
|
||||
"X-Generator: Launchpad (build 18928)\n"
|
||||
|
||||
#: ../aa_enabled.c:26
|
||||
#, c-format
|
||||
msgid ""
|
||||
"%s: [options]\n"
|
||||
" options:\n"
|
||||
" -q | --quiet Don't print out any messages\n"
|
||||
" -h | --help Print help\n"
|
||||
msgstr ""
|
||||
"%s: [seçenekler]\n"
|
||||
" seçenekler:\n"
|
||||
" -q | --quiet Hiçbir mesajı gösterme\n"
|
||||
" -h | --help Yardımı görüntüler\n"
|
||||
|
||||
#: ../aa_enabled.c:45
|
||||
#, c-format
|
||||
msgid "unknown or incompatible options\n"
|
||||
msgstr "bilinmeyen veya uyumsuz seçenekler\n"
|
||||
|
||||
#: ../aa_enabled.c:55
|
||||
#, c-format
|
||||
msgid "unknown option '%s'\n"
|
||||
msgstr "bilinmeyen seçenek '%s'\n"
|
||||
|
||||
#: ../aa_enabled.c:64
|
||||
#, c-format
|
||||
msgid "Yes\n"
|
||||
msgstr "Evet\n"
|
||||
|
||||
#: ../aa_enabled.c:71
|
||||
#, c-format
|
||||
msgid "No - not available on this system.\n"
|
||||
msgstr "Hayır - Bu sistemde kullanılabilir değil.\n"
|
||||
|
||||
#: ../aa_enabled.c:74
|
||||
#, c-format
|
||||
msgid "No - disabled at boot.\n"
|
||||
msgstr "Hayır - önyüklemede devredışı bırakıldı.\n"
|
||||
|
||||
#: ../aa_enabled.c:77
|
||||
#, c-format
|
||||
msgid "Maybe - policy interface not available.\n"
|
||||
msgstr "Belki - policy arayüzü kullanılabilir değil.\n"
|
||||
|
||||
#: ../aa_enabled.c:81
|
||||
#, c-format
|
||||
msgid "Maybe - insufficient permissions to determine availability.\n"
|
||||
msgstr ""
|
||||
"Belki - kullanılabilir olup olmadığını denetlemek için yetersiz yetki.\n"
|
||||
|
||||
#: ../aa_enabled.c:84
|
||||
#, c-format
|
||||
msgid "Error - '%s'\n"
|
||||
msgstr "Hata - '%s'\n"
|
@@ -1,6 +1,5 @@
|
||||
# ----------------------------------------------------------------------
|
||||
# Copyright (c) 2004, 2005 NOVELL (All rights reserved)
|
||||
# Copyright (c) 2016 Canonical, Ltd.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of version 2 of the GNU General Public
|
||||
@@ -74,10 +73,7 @@ endif
|
||||
.SILENT: libapparmor_check
|
||||
libapparmor_check: ; $(ERROR_MESSAGE)
|
||||
|
||||
all: libapparmor_check $(TARGET) docs
|
||||
|
||||
.PHONY: docs
|
||||
docs: ${MANPAGES} ${HTMLMANPAGES}
|
||||
all: libapparmor_check $(TARGET) ${MANPAGES} ${HTMLMANPAGES}
|
||||
|
||||
%.so: %.c
|
||||
${APXS} ${LIBAPPARMOR_FLAGS} -c $< ${LDLIBS}
|
||||
@@ -87,7 +83,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
|
||||
|
@@ -140,6 +140,6 @@ them at L<https://bugs.launchpad.net/apparmor/+filebug>.
|
||||
=head1 SEE ALSO
|
||||
|
||||
apparmor(7), subdomain.conf(5), apparmor_parser(8), aa_change_hat(2) and
|
||||
L<https://wiki.apparmor.net>.
|
||||
L<http://wiki.apparmor.net>.
|
||||
|
||||
=cut
|
||||
|
@@ -1,6 +1,5 @@
|
||||
# ----------------------------------------------------------------------
|
||||
# Copyright (c) 1999, 2004, 2005 NOVELL (All rights reserved)
|
||||
# Copyright (c) 2016 Canonical, Ltd.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of version 2 of the GNU General Public
|
||||
@@ -55,7 +54,7 @@ libapparmor by adding USE_SYSTEM=1 to your make command.${nl}\
|
||||
AA_LDLIBS = -lapparmor
|
||||
endif
|
||||
EXTRA_CFLAGS=$(CFLAGS) $(CPPFLAGS) -fPIC -shared -Wall $(LIBAPPARMOR_INCLUDE)
|
||||
LINK_FLAGS=-Xlinker -x $(AA_LINK_FLAGS) $(LDFLAGS)
|
||||
LINK_FLAGS=-Xlinker -x $(AA_LINK_FLAGS)
|
||||
LIBS=-lpam $(AA_LDLIBS)
|
||||
OBJECTS=${NAME}.o get_options.o
|
||||
|
||||
@@ -63,11 +62,7 @@ OBJECTS=${NAME}.o get_options.o
|
||||
.SILENT: libapparmor_check
|
||||
libapparmor_check: ; $(ERROR_MESSAGE)
|
||||
|
||||
all: libapparmor_check $(NAME).so docs
|
||||
|
||||
.PHONY: docs
|
||||
# docs: we should have some
|
||||
docs:
|
||||
all: libapparmor_check $(NAME).so
|
||||
|
||||
$(NAME).so: ${OBJECTS}
|
||||
$(CC) $(EXTRA_CFLAGS) $(LINK_FLAGS) -o $@ ${OBJECTS} $(LIBS)
|
||||
@@ -82,7 +77,7 @@ SECDIR ?= ${DESTDIR}/lib/security
|
||||
.PHONY: install
|
||||
install: $(NAME).so
|
||||
install -m 755 -d $(SECDIR)
|
||||
install -m 755 $(NAME).so $(SECDIR)/
|
||||
install -m 555 $(NAME).so $(SECDIR)/
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
|
@@ -1,7 +1,7 @@
|
||||
# ------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (c) 1999-2008 NOVELL (All rights reserved)
|
||||
# Copyright 2009-2015 Canonical Ltd.
|
||||
# Copyright 2009-2010 Canonical Ltd.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of version 2 of the GNU General Public
|
||||
@@ -21,7 +21,7 @@
|
||||
# exist
|
||||
LOCALEDIR=/usr/share/locale
|
||||
|
||||
XGETTEXT_ARGS=--copyright-holder="Canonical Ltd" --msgid-bugs-address=apparmor@lists.ubuntu.com -d ${NAME}
|
||||
XGETTEXT_ARGS=--copyright-holder="NOVELL, Inc." --msgid-bugs-address=apparmor@lists.ubuntu.com -d ${NAME}
|
||||
|
||||
# When making the .pot file, it's expected that the parent Makefile will
|
||||
# pass in the list of sources in the SOURCES variable
|
||||
|
@@ -42,9 +42,10 @@ endif
|
||||
|
||||
define nl
|
||||
|
||||
|
||||
endef
|
||||
|
||||
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
|
||||
REPO_VERSION_CMD=([ -x /usr/bin/bzr ] && /usr/bin/bzr version-info . 2> /dev/null || awk '{ print "revno: "$2 }' common/.stamp_rev) | awk '/^revno:/ { print $2 }'
|
||||
|
||||
ifndef PYTHON_VERSIONS
|
||||
PYTHON_VERSIONS = $(call map, pathsearch, python2 python3)
|
||||
@@ -65,7 +66,7 @@ version:
|
||||
.PHONY: repo_version
|
||||
.SILENT: repo_version
|
||||
repo_version:
|
||||
echo $(shell $(value REPO_VERSION_CMD))
|
||||
$(value REPO_VERSION_CMD)
|
||||
|
||||
.PHONY: pod_clean
|
||||
ifndef VERBOSE
|
||||
@@ -74,6 +75,40 @@ endif
|
||||
pod_clean:
|
||||
-rm -f ${MANPAGES} *.[0-9].gz ${HTMLMANPAGES} pod2htm*.tmp
|
||||
|
||||
# =====================
|
||||
# generate list of capabilities based on
|
||||
# /usr/include/linux/capabilities.h for use in multiple locations in
|
||||
# the source tree
|
||||
# =====================
|
||||
|
||||
# emits defined capabilities in a simple list, e.g. "CAP_NAME CAP_NAME2"
|
||||
CAPABILITIES=$(shell echo "\#include <linux/capability.h>" | cpp -dM | LC_ALL=C sed -n -e '/CAP_EMPTY_SET/d' -e 's/^\#define[ \t]\+CAP_\([A-Z0-9_]\+\)[ \t]\+\([0-9xa-f]\+\)\(.*\)$$/CAP_\1/p' | LC_ALL=C sort)
|
||||
|
||||
.PHONY: list_capabilities
|
||||
list_capabilities: /usr/include/linux/capability.h
|
||||
@echo "$(CAPABILITIES)"
|
||||
|
||||
# =====================
|
||||
# generate list of network protocols based on
|
||||
# sys/socket.h for use in multiple locations in
|
||||
# the source tree
|
||||
# =====================
|
||||
|
||||
# These are the families that it doesn't make sense for apparmor
|
||||
# to mediate. We use PF_ here since that is what is required in
|
||||
# bits/socket.h, but we will rewrite these as AF_.
|
||||
|
||||
FILTER_FAMILIES=PF_UNIX
|
||||
|
||||
__FILTER=$(shell echo $(strip $(FILTER_FAMILIES)) | sed -e 's/ /\\\|/g')
|
||||
|
||||
# emits the AF names in a "AF_NAME NUMBER," pattern
|
||||
AF_NAMES=$(shell echo "\#include <sys/socket.h>" | cpp -dM | LC_ALL=C sed -n -e '/$(__FILTER)/d' -e 's/PF_LOCAL/PF_UNIX/' -e 's/^\#define[ \t]\+PF_\([A-Z0-9_]\+\)[ \t]\+\([0-9]\+\).*$$/AF_\1 \2,/p' | sort -n -k2)
|
||||
|
||||
.PHONY: list_af_names
|
||||
list_af_names:
|
||||
@echo "$(AF_NAMES)"
|
||||
|
||||
# =====================
|
||||
# manpages
|
||||
# =====================
|
||||
|
@@ -1 +1 @@
|
||||
2.13.11
|
||||
2.10.2
|
||||
|
@@ -1,19 +0,0 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
# =====================
|
||||
# generate list of network protocols based on
|
||||
# sys/socket.h for use in multiple locations in
|
||||
# the source tree
|
||||
# =====================
|
||||
|
||||
# It doesn't make sence for AppArmor to mediate PF_UNIX, filter it out. Search
|
||||
# for "PF_" constants since that is what is required in bits/socket.h, but
|
||||
# rewrite as "AF_".
|
||||
|
||||
echo "#include <sys/socket.h>" | \
|
||||
cpp -dM | \
|
||||
LC_ALL=C sed -n \
|
||||
-e '/PF_UNIX/d' \
|
||||
-e 's/PF_LOCAL/PF_UNIX/' \
|
||||
-e 's/^#define[ \t]\+PF_\([A-Z0-9_]\+\)[ \t]\+\([0-9]\+\).*$/AF_\1 \2,/p' | \
|
||||
sort -n -k2
|
@@ -1,14 +0,0 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
# =====================
|
||||
# generate list of capabilities based on
|
||||
# /usr/include/linux/capabilities.h for use in multiple locations in
|
||||
# the source tree
|
||||
# =====================
|
||||
|
||||
echo "#include <linux/capability.h>" | \
|
||||
cpp -dM | \
|
||||
LC_ALL=C sed -n \
|
||||
-e '/CAP_EMPTY_SET/d' \
|
||||
-e 's/^\#define[ \t]\+CAP_\([A-Z0-9_]\+\)[ \t]\+\([0-9xa-f]\+\)\(.*\)$/CAP_\1/p' | \
|
||||
LC_ALL=C sort
|
@@ -138,7 +138,7 @@ my $ratelimit_saved = sysctl_read($ratelimit_sysctl);
|
||||
END { sysctl_write($ratelimit_sysctl, $ratelimit_saved); }
|
||||
sysctl_write($ratelimit_sysctl, 0);
|
||||
|
||||
UI_Info(gettext("\nBefore you begin, you may wish to check if a\nprofile already exists for the application you\nwish to confine. See the following wiki page for\nmore information:\nhttps://gitlab.com/apparmor/apparmor/wikis/Profiles"));
|
||||
UI_Info(gettext("\nBefore you begin, you may wish to check if a\nprofile already exists for the application you\nwish to confine. See the following wiki page for\nmore information:\nhttp://wiki.apparmor.net/index.php/Profiles"));
|
||||
|
||||
UI_Important(gettext("Please start the application to be profiled in \nanother window and exercise its functionality now.\n\nOnce completed, select the \"Scan\" button below in \norder to scan the system logs for AppArmor events. \n\nFor each AppArmor event, you will be given the \nopportunity to choose whether the access should be \nallowed or denied."));
|
||||
|
||||
@@ -195,7 +195,7 @@ for my $p (sort keys %helpers) {
|
||||
}
|
||||
|
||||
UI_Info(gettext("Reloaded AppArmor profiles in enforce mode."));
|
||||
UI_Info(gettext("\nPlease consider contributing your new profile! See\nthe following wiki page for more information:\nhttps://gitlab.com/apparmor/apparmor/wikis/Profiles\n"));
|
||||
UI_Info(gettext("\nPlease consider contributing your new profile! See\nthe following wiki page for more information:\nhttp://wiki.apparmor.net/index.php/Profiles\n"));
|
||||
UI_Info(sprintf(gettext('Finished generating profile for %s.'), $fqdbin));
|
||||
exit 0;
|
||||
|
||||
|
@@ -1,36 +0,0 @@
|
||||
# ----------------------------------------------------------------------
|
||||
# Copyright (c) 2016 Canonical Ltd.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of version 2 of the GNU General Public
|
||||
# License published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
# ----------------------------------------------------------------------
|
||||
NAME = documentation
|
||||
all:
|
||||
COMMONDIR=../common/
|
||||
|
||||
include $(COMMONDIR)/Make.rules
|
||||
|
||||
all: docs
|
||||
|
||||
SOURCES:= $(wildcard *.odt)
|
||||
DOCS:=$(SOURCES:.odt=.pdf)
|
||||
|
||||
.PHONY: docs
|
||||
docs: $(DOCS)
|
||||
|
||||
%.pdf: %.odt
|
||||
unoconv -v -f pdf --output "$@" "$<"
|
||||
|
||||
.PHONY: clean
|
||||
ifndef VERBOSE
|
||||
.SILENT: clean
|
||||
endif
|
||||
clean:
|
||||
rm -f *.pdf
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 50 KiB |
@@ -1,118 +0,0 @@
|
||||
From 24b6ac149a57c2d3d5a9920e64d914e8ff00d346 Mon Sep 17 00:00:00 2001
|
||||
From: Vegard Nossum <vegard.nossum@oracle.com>
|
||||
Date: Thu, 7 Jul 2016 13:41:11 -0700
|
||||
Subject: [PATCH 01/27] apparmor: fix oops, validate buffer size in
|
||||
apparmor_setprocattr()
|
||||
|
||||
When proc_pid_attr_write() was changed to use memdup_user apparmor's
|
||||
(interface violating) assumption that the setprocattr buffer was always
|
||||
a single page was violated.
|
||||
|
||||
The size test is not strictly speaking needed as proc_pid_attr_write()
|
||||
will reject anything larger, but for the sake of robustness we can keep
|
||||
it in.
|
||||
|
||||
SMACK and SELinux look safe to me, but somebody else should probably
|
||||
have a look just in case.
|
||||
|
||||
Based on original patch from Vegard Nossum <vegard.nossum@oracle.com>
|
||||
modified for the case that apparmor provides null termination.
|
||||
|
||||
Fixes: bb646cdb12e75d82258c2f2e7746d5952d3e321a
|
||||
Reported-by: Vegard Nossum <vegard.nossum@oracle.com>
|
||||
Cc: Al Viro <viro@zeniv.linux.org.uk>
|
||||
Cc: John Johansen <john.johansen@canonical.com>
|
||||
Cc: Paul Moore <paul@paul-moore.com>
|
||||
Cc: Stephen Smalley <sds@tycho.nsa.gov>
|
||||
Cc: Eric Paris <eparis@parisplace.org>
|
||||
Cc: Casey Schaufler <casey@schaufler-ca.com>
|
||||
Cc: stable@kernel.org
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
Reviewed-by: Tyler Hicks <tyhicks@canonical.com>
|
||||
Signed-off-by: James Morris <james.l.morris@oracle.com>
|
||||
---
|
||||
security/apparmor/lsm.c | 36 +++++++++++++++++++-----------------
|
||||
1 file changed, 19 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
|
||||
index dec607c..5ee8201 100644
|
||||
--- a/security/apparmor/lsm.c
|
||||
+++ b/security/apparmor/lsm.c
|
||||
@@ -523,34 +523,34 @@ static int apparmor_setprocattr(struct task_struct *task, char *name,
|
||||
{
|
||||
struct common_audit_data sa;
|
||||
struct apparmor_audit_data aad = {0,};
|
||||
- char *command, *args = value;
|
||||
+ char *command, *largs = NULL, *args = value;
|
||||
size_t arg_size;
|
||||
int error;
|
||||
|
||||
if (size == 0)
|
||||
return -EINVAL;
|
||||
- /* args points to a PAGE_SIZE buffer, AppArmor requires that
|
||||
- * the buffer must be null terminated or have size <= PAGE_SIZE -1
|
||||
- * so that AppArmor can null terminate them
|
||||
- */
|
||||
- if (args[size - 1] != '\0') {
|
||||
- if (size == PAGE_SIZE)
|
||||
- return -EINVAL;
|
||||
- args[size] = '\0';
|
||||
- }
|
||||
-
|
||||
/* task can only write its own attributes */
|
||||
if (current != task)
|
||||
return -EACCES;
|
||||
|
||||
- args = value;
|
||||
+ /* AppArmor requires that the buffer must be null terminated atm */
|
||||
+ if (args[size - 1] != '\0') {
|
||||
+ /* null terminate */
|
||||
+ largs = args = kmalloc(size + 1, GFP_KERNEL);
|
||||
+ if (!args)
|
||||
+ return -ENOMEM;
|
||||
+ memcpy(args, value, size);
|
||||
+ args[size] = '\0';
|
||||
+ }
|
||||
+
|
||||
+ error = -EINVAL;
|
||||
args = strim(args);
|
||||
command = strsep(&args, " ");
|
||||
if (!args)
|
||||
- return -EINVAL;
|
||||
+ goto out;
|
||||
args = skip_spaces(args);
|
||||
if (!*args)
|
||||
- return -EINVAL;
|
||||
+ goto out;
|
||||
|
||||
arg_size = size - (args - (char *) value);
|
||||
if (strcmp(name, "current") == 0) {
|
||||
@@ -576,10 +576,12 @@ static int apparmor_setprocattr(struct task_struct *task, char *name,
|
||||
goto fail;
|
||||
} else
|
||||
/* only support the "current" and "exec" process attributes */
|
||||
- return -EINVAL;
|
||||
+ goto fail;
|
||||
|
||||
if (!error)
|
||||
error = size;
|
||||
+out:
|
||||
+ kfree(largs);
|
||||
return error;
|
||||
|
||||
fail:
|
||||
@@ -588,9 +590,9 @@ fail:
|
||||
aad.profile = aa_current_profile();
|
||||
aad.op = OP_SETPROCATTR;
|
||||
aad.info = name;
|
||||
- aad.error = -EINVAL;
|
||||
+ aad.error = error = -EINVAL;
|
||||
aa_audit_msg(AUDIT_APPARMOR_DENIED, &sa, NULL);
|
||||
- return -EINVAL;
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
static int apparmor_task_setrlimit(struct task_struct *task,
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,33 +0,0 @@
|
||||
From 444bc4f95ec283cd0fb9777f4890bd9bc307809d Mon Sep 17 00:00:00 2001
|
||||
From: John Johansen <john.johansen@canonical.com>
|
||||
Date: Mon, 11 Apr 2016 16:55:10 -0700
|
||||
Subject: [PATCH 02/27] apparmor: fix refcount bug in profile replacement
|
||||
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
Acked-by: Seth Arnold <seth.arnold@canonical.com>
|
||||
---
|
||||
security/apparmor/policy.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
|
||||
index 705c287..222052f 100644
|
||||
--- a/security/apparmor/policy.c
|
||||
+++ b/security/apparmor/policy.c
|
||||
@@ -1189,12 +1189,12 @@ ssize_t aa_replace_profiles(void *udata, size_t size, bool noreplace)
|
||||
aa_get_profile(newest);
|
||||
aa_put_profile(parent);
|
||||
rcu_assign_pointer(ent->new->parent, newest);
|
||||
- } else
|
||||
- aa_put_profile(newest);
|
||||
+ }
|
||||
/* aafs interface uses replacedby */
|
||||
rcu_assign_pointer(ent->new->replacedby->profile,
|
||||
aa_get_profile(ent->new));
|
||||
__list_add_profile(&parent->base.profiles, ent->new);
|
||||
+ aa_put_profile(newest);
|
||||
} else {
|
||||
/* aafs interface uses replacedby */
|
||||
rcu_assign_pointer(ent->new->replacedby->profile,
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,38 +0,0 @@
|
||||
From 1224a06778b89dcbf0ca85bd961c2fcdd8765a69 Mon Sep 17 00:00:00 2001
|
||||
From: John Johansen <john.johansen@canonical.com>
|
||||
Date: Mon, 11 Apr 2016 16:57:19 -0700
|
||||
Subject: [PATCH 03/27] apparmor: fix replacement bug that adds new child to
|
||||
old parent
|
||||
|
||||
When set atomic replacement is used and the parent is updated before the
|
||||
child, and the child did not exist in the old parent so there is no
|
||||
direct replacement then the new child is incorrectly added to the old
|
||||
parent. This results in the new parent not having the child(ren) that
|
||||
it should and the old parent when being destroyed asserting the
|
||||
following error.
|
||||
|
||||
AppArmor: policy_destroy: internal error, policy '<profile/name>' still
|
||||
contains profiles
|
||||
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
Acked-by: Seth Arnold <seth.arnold@canonical.com>
|
||||
---
|
||||
security/apparmor/policy.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
|
||||
index 222052f..c92a9f6 100644
|
||||
--- a/security/apparmor/policy.c
|
||||
+++ b/security/apparmor/policy.c
|
||||
@@ -1193,7 +1193,7 @@ ssize_t aa_replace_profiles(void *udata, size_t size, bool noreplace)
|
||||
/* aafs interface uses replacedby */
|
||||
rcu_assign_pointer(ent->new->replacedby->profile,
|
||||
aa_get_profile(ent->new));
|
||||
- __list_add_profile(&parent->base.profiles, ent->new);
|
||||
+ __list_add_profile(&newest->base.profiles, ent->new);
|
||||
aa_put_profile(newest);
|
||||
} else {
|
||||
/* aafs interface uses replacedby */
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,87 +0,0 @@
|
||||
From 15d921647676fdc2c3ee1cf9aa8f578b1012ecff Mon Sep 17 00:00:00 2001
|
||||
From: John Johansen <john.johansen@canonical.com>
|
||||
Date: Sun, 8 Jun 2014 11:20:54 -0700
|
||||
Subject: [PATCH 04/27] apparmor: fix uninitialized lsm_audit member
|
||||
|
||||
BugLink: http://bugs.launchpad.net/bugs/1268727
|
||||
|
||||
The task field in the lsm_audit struct needs to be initialized if
|
||||
a change_hat fails, otherwise the following oops will occur
|
||||
|
||||
BUG: unable to handle kernel paging request at 0000002fbead7d08
|
||||
IP: [<ffffffff8171153e>] _raw_spin_lock+0xe/0x50
|
||||
PGD 1e3f35067 PUD 0
|
||||
Oops: 0002 [#1] SMP
|
||||
Modules linked in: pppox crc_ccitt p8023 p8022 psnap llc ax25 btrfs raid6_pq xor xfs libcrc32c dm_multipath scsi_dh kvm_amd dcdbas kvm microcode amd64_edac_mod joydev edac_core psmouse edac_mce_amd serio_raw k10temp sp5100_tco i2c_piix4 ipmi_si ipmi_msghandler acpi_power_meter mac_hid lp parport hid_generic usbhid hid pata_acpi mpt2sas ahci raid_class pata_atiixp bnx2 libahci scsi_transport_sas [last unloaded: tipc]
|
||||
CPU: 2 PID: 699 Comm: changehat_twice Tainted: GF O 3.13.0-7-generic #25-Ubuntu
|
||||
Hardware name: Dell Inc. PowerEdge R415/08WNM9, BIOS 1.8.6 12/06/2011
|
||||
task: ffff8802135c6000 ti: ffff880212986000 task.ti: ffff880212986000
|
||||
RIP: 0010:[<ffffffff8171153e>] [<ffffffff8171153e>] _raw_spin_lock+0xe/0x50
|
||||
RSP: 0018:ffff880212987b68 EFLAGS: 00010006
|
||||
RAX: 0000000000020000 RBX: 0000002fbead7500 RCX: 0000000000000000
|
||||
RDX: 0000000000000292 RSI: ffff880212987ba8 RDI: 0000002fbead7d08
|
||||
RBP: ffff880212987b68 R08: 0000000000000246 R09: ffff880216e572a0
|
||||
R10: ffffffff815fd677 R11: ffffea0008469580 R12: ffffffff8130966f
|
||||
R13: ffff880212987ba8 R14: 0000002fbead7d08 R15: ffff8800d8c6b830
|
||||
FS: 00002b5e6c84e7c0(0000) GS:ffff880216e40000(0000) knlGS:0000000055731700
|
||||
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
|
||||
CR2: 0000002fbead7d08 CR3: 000000021270f000 CR4: 00000000000006e0
|
||||
Stack:
|
||||
ffff880212987b98 ffffffff81075f17 ffffffff8130966f 0000000000000009
|
||||
0000000000000000 0000000000000000 ffff880212987bd0 ffffffff81075f7c
|
||||
0000000000000292 ffff880212987c08 ffff8800d8c6b800 0000000000000026
|
||||
Call Trace:
|
||||
[<ffffffff81075f17>] __lock_task_sighand+0x47/0x80
|
||||
[<ffffffff8130966f>] ? apparmor_cred_prepare+0x2f/0x50
|
||||
[<ffffffff81075f7c>] do_send_sig_info+0x2c/0x80
|
||||
[<ffffffff81075fee>] send_sig_info+0x1e/0x30
|
||||
[<ffffffff8130242d>] aa_audit+0x13d/0x190
|
||||
[<ffffffff8130c1dc>] aa_audit_file+0xbc/0x130
|
||||
[<ffffffff8130966f>] ? apparmor_cred_prepare+0x2f/0x50
|
||||
[<ffffffff81304cc2>] aa_change_hat+0x202/0x530
|
||||
[<ffffffff81308fc6>] aa_setprocattr_changehat+0x116/0x1d0
|
||||
[<ffffffff8130a11d>] apparmor_setprocattr+0x25d/0x300
|
||||
[<ffffffff812cee56>] security_setprocattr+0x16/0x20
|
||||
[<ffffffff8121fc87>] proc_pid_attr_write+0x107/0x130
|
||||
[<ffffffff811b7604>] vfs_write+0xb4/0x1f0
|
||||
[<ffffffff811b8039>] SyS_write+0x49/0xa0
|
||||
[<ffffffff8171a1bf>] tracesys+0xe1/0xe6
|
||||
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
Acked-by: Seth Arnold <seth.arnold@canonical.com>
|
||||
---
|
||||
security/apparmor/audit.c | 3 ++-
|
||||
security/apparmor/file.c | 3 ++-
|
||||
2 files changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/security/apparmor/audit.c b/security/apparmor/audit.c
|
||||
index 89c7865..3a7f1da 100644
|
||||
--- a/security/apparmor/audit.c
|
||||
+++ b/security/apparmor/audit.c
|
||||
@@ -200,7 +200,8 @@ int aa_audit(int type, struct aa_profile *profile, gfp_t gfp,
|
||||
|
||||
if (sa->aad->type == AUDIT_APPARMOR_KILL)
|
||||
(void)send_sig_info(SIGKILL, NULL,
|
||||
- sa->u.tsk ? sa->u.tsk : current);
|
||||
+ sa->type == LSM_AUDIT_DATA_TASK && sa->u.tsk ?
|
||||
+ sa->u.tsk : current);
|
||||
|
||||
if (sa->aad->type == AUDIT_APPARMOR_ALLOWED)
|
||||
return complain_error(sa->aad->error);
|
||||
diff --git a/security/apparmor/file.c b/security/apparmor/file.c
|
||||
index 913f377..43d6ae7 100644
|
||||
--- a/security/apparmor/file.c
|
||||
+++ b/security/apparmor/file.c
|
||||
@@ -110,7 +110,8 @@ int aa_audit_file(struct aa_profile *profile, struct file_perms *perms,
|
||||
int type = AUDIT_APPARMOR_AUTO;
|
||||
struct common_audit_data sa;
|
||||
struct apparmor_audit_data aad = {0,};
|
||||
- sa.type = LSM_AUDIT_DATA_NONE;
|
||||
+ sa.type = LSM_AUDIT_DATA_TASK;
|
||||
+ sa.u.tsk = NULL;
|
||||
sa.aad = &aad;
|
||||
aad.op = op,
|
||||
aad.fs.request = request;
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,32 +0,0 @@
|
||||
From c1216728b7d644443eef31e4bd9d01b4a0a51d61 Mon Sep 17 00:00:00 2001
|
||||
From: John Johansen <john.johansen@canonical.com>
|
||||
Date: Fri, 25 Jul 2014 04:02:03 -0700
|
||||
Subject: [PATCH 05/27] apparmor: exec should not be returning ENOENT when it
|
||||
denies
|
||||
|
||||
The current behavior is confusing as it causes exec failures to report
|
||||
the executable is missing instead of identifying that apparmor
|
||||
caused the failure.
|
||||
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
Acked-by: Seth Arnold <seth.arnold@canonical.com>
|
||||
---
|
||||
security/apparmor/domain.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
|
||||
index dc0027b..67a7418 100644
|
||||
--- a/security/apparmor/domain.c
|
||||
+++ b/security/apparmor/domain.c
|
||||
@@ -433,7 +433,7 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
|
||||
new_profile = aa_get_newest_profile(ns->unconfined);
|
||||
info = "ux fallback";
|
||||
} else {
|
||||
- error = -ENOENT;
|
||||
+ error = -EACCES;
|
||||
info = "profile not found";
|
||||
/* remove MAY_EXEC to audit as failure */
|
||||
perms.allow &= ~MAY_EXEC;
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,28 +0,0 @@
|
||||
From 2d3389de6c8ab6b3ad2cef4ea460c8fce2a226b9 Mon Sep 17 00:00:00 2001
|
||||
From: John Johansen <john.johansen@canonical.com>
|
||||
Date: Fri, 25 Jul 2014 04:01:56 -0700
|
||||
Subject: [PATCH 06/27] apparmor: fix update the mtime of the profile file on
|
||||
replacement
|
||||
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
Acked-by: Seth Arnold <seth.arnold@canonical.com>
|
||||
---
|
||||
security/apparmor/apparmorfs.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
|
||||
index ad4fa49..45a6199 100644
|
||||
--- a/security/apparmor/apparmorfs.c
|
||||
+++ b/security/apparmor/apparmorfs.c
|
||||
@@ -379,6 +379,8 @@ void __aa_fs_profile_migrate_dents(struct aa_profile *old,
|
||||
|
||||
for (i = 0; i < AAFS_PROF_SIZEOF; i++) {
|
||||
new->dents[i] = old->dents[i];
|
||||
+ if (new->dents[i])
|
||||
+ new->dents[i]->d_inode->i_mtime = CURRENT_TIME;
|
||||
old->dents[i] = NULL;
|
||||
}
|
||||
}
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,36 +0,0 @@
|
||||
From 9caa96e30a1b2bb191a29af872285c8d0b078c10 Mon Sep 17 00:00:00 2001
|
||||
From: John Johansen <john.johansen@canonical.com>
|
||||
Date: Fri, 25 Jul 2014 04:02:08 -0700
|
||||
Subject: [PATCH 07/27] apparmor: fix disconnected bind mnts reconnection
|
||||
|
||||
Bind mounts can fail to be properly reconnected when PATH_CONNECT is
|
||||
specified. Ensure that when PATH_CONNECT is specified the path has
|
||||
a root.
|
||||
|
||||
BugLink: http://bugs.launchpad.net/bugs/1319984
|
||||
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
Acked-by: Seth Arnold <seth.arnold@canonical.com>
|
||||
---
|
||||
security/apparmor/path.c | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/security/apparmor/path.c b/security/apparmor/path.c
|
||||
index 71e0e3a..bb2f2c6 100644
|
||||
--- a/security/apparmor/path.c
|
||||
+++ b/security/apparmor/path.c
|
||||
@@ -141,7 +141,10 @@ static int d_namespace_path(struct path *path, char *buf, int buflen,
|
||||
error = -EACCES;
|
||||
if (*res == '/')
|
||||
*name = res + 1;
|
||||
- }
|
||||
+ } else if (*res != '/')
|
||||
+ /* CONNECT_PATH with missing root */
|
||||
+ error = prepend(name, *name - buf, "/", 1);
|
||||
+
|
||||
}
|
||||
|
||||
out:
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,114 +0,0 @@
|
||||
From 11702a732e149380e05e2ab8ae1b743ac89f892f Mon Sep 17 00:00:00 2001
|
||||
From: John Johansen <john.johansen@canonical.com>
|
||||
Date: Fri, 25 Jul 2014 04:02:10 -0700
|
||||
Subject: [PATCH 08/27] apparmor: internal paths should be treated as
|
||||
disconnected
|
||||
|
||||
Internal mounts are not mounted anywhere and as such should be treated
|
||||
as disconnected paths.
|
||||
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
Acked-by: Seth Arnold <seth.arnold@canonical.com>
|
||||
---
|
||||
security/apparmor/path.c | 64 +++++++++++++++++++++++++++---------------------
|
||||
1 file changed, 36 insertions(+), 28 deletions(-)
|
||||
|
||||
diff --git a/security/apparmor/path.c b/security/apparmor/path.c
|
||||
index bb2f2c6..596f799 100644
|
||||
--- a/security/apparmor/path.c
|
||||
+++ b/security/apparmor/path.c
|
||||
@@ -25,7 +25,6 @@
|
||||
#include "include/path.h"
|
||||
#include "include/policy.h"
|
||||
|
||||
-
|
||||
/* modified from dcache.c */
|
||||
static int prepend(char **buffer, int buflen, const char *str, int namelen)
|
||||
{
|
||||
@@ -39,6 +38,38 @@ static int prepend(char **buffer, int buflen, const char *str, int namelen)
|
||||
|
||||
#define CHROOT_NSCONNECT (PATH_CHROOT_REL | PATH_CHROOT_NSCONNECT)
|
||||
|
||||
+/* If the path is not connected to the expected root,
|
||||
+ * check if it is a sysctl and handle specially else remove any
|
||||
+ * leading / that __d_path may have returned.
|
||||
+ * Unless
|
||||
+ * specifically directed to connect the path,
|
||||
+ * OR
|
||||
+ * if in a chroot and doing chroot relative paths and the path
|
||||
+ * resolves to the namespace root (would be connected outside
|
||||
+ * of chroot) and specifically directed to connect paths to
|
||||
+ * namespace root.
|
||||
+ */
|
||||
+static int disconnect(const struct path *path, char *buf, char **name,
|
||||
+ int flags)
|
||||
+{
|
||||
+ int error = 0;
|
||||
+
|
||||
+ if (!(flags & PATH_CONNECT_PATH) &&
|
||||
+ !(((flags & CHROOT_NSCONNECT) == CHROOT_NSCONNECT) &&
|
||||
+ our_mnt(path->mnt))) {
|
||||
+ /* disconnected path, don't return pathname starting
|
||||
+ * with '/'
|
||||
+ */
|
||||
+ error = -EACCES;
|
||||
+ if (**name == '/')
|
||||
+ *name = *name + 1;
|
||||
+ } else if (**name != '/')
|
||||
+ /* CONNECT_PATH with missing root */
|
||||
+ error = prepend(name, *name - buf, "/", 1);
|
||||
+
|
||||
+ return error;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* d_namespace_path - lookup a name associated with a given path
|
||||
* @path: path to lookup (NOT NULL)
|
||||
@@ -74,7 +105,8 @@ static int d_namespace_path(struct path *path, char *buf, int buflen,
|
||||
* control instead of hard coded /proc
|
||||
*/
|
||||
return prepend(name, *name - buf, "/proc", 5);
|
||||
- }
|
||||
+ } else
|
||||
+ return disconnect(path, buf, name, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -120,32 +152,8 @@ static int d_namespace_path(struct path *path, char *buf, int buflen,
|
||||
goto out;
|
||||
}
|
||||
|
||||
- /* If the path is not connected to the expected root,
|
||||
- * check if it is a sysctl and handle specially else remove any
|
||||
- * leading / that __d_path may have returned.
|
||||
- * Unless
|
||||
- * specifically directed to connect the path,
|
||||
- * OR
|
||||
- * if in a chroot and doing chroot relative paths and the path
|
||||
- * resolves to the namespace root (would be connected outside
|
||||
- * of chroot) and specifically directed to connect paths to
|
||||
- * namespace root.
|
||||
- */
|
||||
- if (!connected) {
|
||||
- if (!(flags & PATH_CONNECT_PATH) &&
|
||||
- !(((flags & CHROOT_NSCONNECT) == CHROOT_NSCONNECT) &&
|
||||
- our_mnt(path->mnt))) {
|
||||
- /* disconnected path, don't return pathname starting
|
||||
- * with '/'
|
||||
- */
|
||||
- error = -EACCES;
|
||||
- if (*res == '/')
|
||||
- *name = res + 1;
|
||||
- } else if (*res != '/')
|
||||
- /* CONNECT_PATH with missing root */
|
||||
- error = prepend(name, *name - buf, "/", 1);
|
||||
-
|
||||
- }
|
||||
+ if (!connected)
|
||||
+ error = disconnect(path, buf, name, flags);
|
||||
|
||||
out:
|
||||
return error;
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,29 +0,0 @@
|
||||
From c70811d9e6234c96d0ef405cd8ad78b70efb8637 Mon Sep 17 00:00:00 2001
|
||||
From: John Johansen <john.johansen@canonical.com>
|
||||
Date: Sat, 16 Apr 2016 13:59:02 -0700
|
||||
Subject: [PATCH 09/27] apparmor: fix put() parent ref after updating the
|
||||
active ref
|
||||
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
Acked-by: Seth Arnold <seth.arnold@canonical.com>
|
||||
---
|
||||
security/apparmor/policy.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
|
||||
index c92a9f6..455c9f8 100644
|
||||
--- a/security/apparmor/policy.c
|
||||
+++ b/security/apparmor/policy.c
|
||||
@@ -1187,8 +1187,8 @@ ssize_t aa_replace_profiles(void *udata, size_t size, bool noreplace)
|
||||
/* parent replaced in this atomic set? */
|
||||
if (newest != parent) {
|
||||
aa_get_profile(newest);
|
||||
- aa_put_profile(parent);
|
||||
rcu_assign_pointer(ent->new->parent, newest);
|
||||
+ aa_put_profile(parent);
|
||||
}
|
||||
/* aafs interface uses replacedby */
|
||||
rcu_assign_pointer(ent->new->replacedby->profile,
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,87 +0,0 @@
|
||||
From f671b902943f83f0fbc8c8b7bf8bbfb817d124f1 Mon Sep 17 00:00:00 2001
|
||||
From: John Johansen <john.johansen@canonical.com>
|
||||
Date: Sat, 16 Apr 2016 14:16:50 -0700
|
||||
Subject: [PATCH 10/27] apparmor: fix log failures for all profiles in a set
|
||||
|
||||
currently only the profile that is causing the failure is logged. This
|
||||
makes it more confusing than necessary about which profiles loaded
|
||||
and which didn't. So make sure to log success and failure messages for
|
||||
all profiles in the set being loaded.
|
||||
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
Acked-by: Seth Arnold <seth.arnold@canonical.com>
|
||||
---
|
||||
security/apparmor/policy.c | 29 +++++++++++++++++++----------
|
||||
1 file changed, 19 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
|
||||
index 455c9f8..db31bc5 100644
|
||||
--- a/security/apparmor/policy.c
|
||||
+++ b/security/apparmor/policy.c
|
||||
@@ -1067,7 +1067,7 @@ static int __lookup_replace(struct aa_namespace *ns, const char *hname,
|
||||
*/
|
||||
ssize_t aa_replace_profiles(void *udata, size_t size, bool noreplace)
|
||||
{
|
||||
- const char *ns_name, *name = NULL, *info = NULL;
|
||||
+ const char *ns_name, *info = NULL;
|
||||
struct aa_namespace *ns = NULL;
|
||||
struct aa_load_ent *ent, *tmp;
|
||||
int op = OP_PROF_REPL;
|
||||
@@ -1082,18 +1082,15 @@ ssize_t aa_replace_profiles(void *udata, size_t size, bool noreplace)
|
||||
/* released below */
|
||||
ns = aa_prepare_namespace(ns_name);
|
||||
if (!ns) {
|
||||
- info = "failed to prepare namespace";
|
||||
- error = -ENOMEM;
|
||||
- name = ns_name;
|
||||
- goto fail;
|
||||
+ error = audit_policy(op, GFP_KERNEL, ns_name,
|
||||
+ "failed to prepare namespace", -ENOMEM);
|
||||
+ goto free;
|
||||
}
|
||||
|
||||
mutex_lock(&ns->lock);
|
||||
/* setup parent and ns info */
|
||||
list_for_each_entry(ent, &lh, list) {
|
||||
struct aa_policy *policy;
|
||||
-
|
||||
- name = ent->new->base.hname;
|
||||
error = __lookup_replace(ns, ent->new->base.hname, noreplace,
|
||||
&ent->old, &info);
|
||||
if (error)
|
||||
@@ -1121,7 +1118,6 @@ ssize_t aa_replace_profiles(void *udata, size_t size, bool noreplace)
|
||||
if (!p) {
|
||||
error = -ENOENT;
|
||||
info = "parent does not exist";
|
||||
- name = ent->new->base.hname;
|
||||
goto fail_lock;
|
||||
}
|
||||
rcu_assign_pointer(ent->new->parent, aa_get_profile(p));
|
||||
@@ -1214,9 +1210,22 @@ out:
|
||||
|
||||
fail_lock:
|
||||
mutex_unlock(&ns->lock);
|
||||
-fail:
|
||||
- error = audit_policy(op, GFP_KERNEL, name, info, error);
|
||||
|
||||
+ /* audit cause of failure */
|
||||
+ op = (!ent->old) ? OP_PROF_LOAD : OP_PROF_REPL;
|
||||
+ audit_policy(op, GFP_KERNEL, ent->new->base.hname, info, error);
|
||||
+ /* audit status that rest of profiles in the atomic set failed too */
|
||||
+ info = "valid profile in failed atomic policy load";
|
||||
+ list_for_each_entry(tmp, &lh, list) {
|
||||
+ if (tmp == ent) {
|
||||
+ info = "unchecked profile in failed atomic policy load";
|
||||
+ /* skip entry that caused failure */
|
||||
+ continue;
|
||||
+ }
|
||||
+ op = (!ent->old) ? OP_PROF_LOAD : OP_PROF_REPL;
|
||||
+ audit_policy(op, GFP_KERNEL, tmp->new->base.hname, info, error);
|
||||
+ }
|
||||
+free:
|
||||
list_for_each_entry_safe(ent, tmp, &lh, list) {
|
||||
list_del_init(&ent->list);
|
||||
aa_load_ent_free(ent);
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,33 +0,0 @@
|
||||
From bc3c7d342bf53afdfdf46bc92dac5c624c89fb91 Mon Sep 17 00:00:00 2001
|
||||
From: John Johansen <john.johansen@canonical.com>
|
||||
Date: Sat, 16 Apr 2016 14:19:38 -0700
|
||||
Subject: [PATCH 11/27] apparmor: fix audit full profile hname on successful
|
||||
load
|
||||
|
||||
Currently logging of a successful profile load only logs the basename
|
||||
of the profile. This can result in confusion when a child profile has
|
||||
the same name as the another profile in the set. Logging the hname
|
||||
will ensure there is no confusion.
|
||||
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
Acked-by: Seth Arnold <seth.arnold@canonical.com>
|
||||
---
|
||||
security/apparmor/policy.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
|
||||
index db31bc5..ca402d0 100644
|
||||
--- a/security/apparmor/policy.c
|
||||
+++ b/security/apparmor/policy.c
|
||||
@@ -1159,7 +1159,7 @@ ssize_t aa_replace_profiles(void *udata, size_t size, bool noreplace)
|
||||
list_del_init(&ent->list);
|
||||
op = (!ent->old && !ent->rename) ? OP_PROF_LOAD : OP_PROF_REPL;
|
||||
|
||||
- audit_policy(op, GFP_ATOMIC, ent->new->base.name, NULL, error);
|
||||
+ audit_policy(op, GFP_ATOMIC, ent->new->base.hname, NULL, error);
|
||||
|
||||
if (ent->old) {
|
||||
__replace_profile(ent->old, ent->new, 1);
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,112 +0,0 @@
|
||||
From 848da0479e5b9da3dc2ae4c64e0cca77a0abf02a Mon Sep 17 00:00:00 2001
|
||||
From: John Johansen <john.johansen@canonical.com>
|
||||
Date: Wed, 20 Apr 2016 14:18:18 -0700
|
||||
Subject: [PATCH 12/27] apparmor: ensure the target profile name is always
|
||||
audited
|
||||
|
||||
The target profile name was not being correctly audited in a few
|
||||
cases because the target variable was not being set and gotos
|
||||
passed the code to set it at apply:
|
||||
|
||||
Since it is always based on new_profile just drop the target var
|
||||
and conditionally report based on new_profile.
|
||||
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
Acked-by: Seth Arnold <seth.arnold@canonical.com>
|
||||
---
|
||||
security/apparmor/domain.c | 20 +++++++++-----------
|
||||
1 file changed, 9 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
|
||||
index 67a7418..fc3036b 100644
|
||||
--- a/security/apparmor/domain.c
|
||||
+++ b/security/apparmor/domain.c
|
||||
@@ -346,7 +346,7 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
|
||||
file_inode(bprm->file)->i_uid,
|
||||
file_inode(bprm->file)->i_mode
|
||||
};
|
||||
- const char *name = NULL, *target = NULL, *info = NULL;
|
||||
+ const char *name = NULL, *info = NULL;
|
||||
int error = 0;
|
||||
|
||||
if (bprm->cred_prepared)
|
||||
@@ -399,6 +399,7 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
|
||||
if (cxt->onexec) {
|
||||
struct file_perms cp;
|
||||
info = "change_profile onexec";
|
||||
+ new_profile = aa_get_newest_profile(cxt->onexec);
|
||||
if (!(perms.allow & AA_MAY_ONEXEC))
|
||||
goto audit;
|
||||
|
||||
@@ -413,7 +414,6 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
|
||||
|
||||
if (!(cp.allow & AA_MAY_ONEXEC))
|
||||
goto audit;
|
||||
- new_profile = aa_get_newest_profile(cxt->onexec);
|
||||
goto apply;
|
||||
}
|
||||
|
||||
@@ -445,10 +445,8 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
|
||||
if (!new_profile) {
|
||||
error = -ENOMEM;
|
||||
info = "could not create null profile";
|
||||
- } else {
|
||||
+ } else
|
||||
error = -EACCES;
|
||||
- target = new_profile->base.hname;
|
||||
- }
|
||||
perms.xindex |= AA_X_UNSAFE;
|
||||
} else
|
||||
/* fail exec */
|
||||
@@ -459,7 +457,6 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
|
||||
* fail the exec.
|
||||
*/
|
||||
if (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS) {
|
||||
- aa_put_profile(new_profile);
|
||||
error = -EPERM;
|
||||
goto cleanup;
|
||||
}
|
||||
@@ -474,10 +471,8 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
|
||||
|
||||
if (bprm->unsafe & (LSM_UNSAFE_PTRACE | LSM_UNSAFE_PTRACE_CAP)) {
|
||||
error = may_change_ptraced_domain(new_profile);
|
||||
- if (error) {
|
||||
- aa_put_profile(new_profile);
|
||||
+ if (error)
|
||||
goto audit;
|
||||
- }
|
||||
}
|
||||
|
||||
/* Determine if secure exec is needed.
|
||||
@@ -498,7 +493,6 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
|
||||
bprm->unsafe |= AA_SECURE_X_NEEDED;
|
||||
}
|
||||
apply:
|
||||
- target = new_profile->base.hname;
|
||||
/* when transitioning profiles clear unsafe personality bits */
|
||||
bprm->per_clear |= PER_CLEAR_ON_SETID;
|
||||
|
||||
@@ -506,15 +500,19 @@ x_clear:
|
||||
aa_put_profile(cxt->profile);
|
||||
/* transfer new profile reference will be released when cxt is freed */
|
||||
cxt->profile = new_profile;
|
||||
+ new_profile = NULL;
|
||||
|
||||
/* clear out all temporary/transitional state from the context */
|
||||
aa_clear_task_cxt_trans(cxt);
|
||||
|
||||
audit:
|
||||
error = aa_audit_file(profile, &perms, GFP_KERNEL, OP_EXEC, MAY_EXEC,
|
||||
- name, target, cond.uid, info, error);
|
||||
+ name,
|
||||
+ new_profile ? new_profile->base.hname : NULL,
|
||||
+ cond.uid, info, error);
|
||||
|
||||
cleanup:
|
||||
+ aa_put_profile(new_profile);
|
||||
aa_put_profile(profile);
|
||||
kfree(buffer);
|
||||
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,27 +0,0 @@
|
||||
From 706473f3ead5cdffe5ad159adfbc090e0fda81d6 Mon Sep 17 00:00:00 2001
|
||||
From: John Johansen <john.johansen@canonical.com>
|
||||
Date: Thu, 17 Mar 2016 12:02:54 -0700
|
||||
Subject: [PATCH 13/27] apparmor: check that xindex is in trans_table bounds
|
||||
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
Acked-by: Seth Arnold <seth.arnold@canonical.com>
|
||||
---
|
||||
security/apparmor/policy_unpack.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
|
||||
index a689f10..c841b12 100644
|
||||
--- a/security/apparmor/policy_unpack.c
|
||||
+++ b/security/apparmor/policy_unpack.c
|
||||
@@ -676,7 +676,7 @@ static bool verify_xindex(int xindex, int table_size)
|
||||
int index, xtype;
|
||||
xtype = xindex & AA_X_TYPE_MASK;
|
||||
index = xindex & AA_X_INDEX_MASK;
|
||||
- if (xtype == AA_X_TABLE && index > table_size)
|
||||
+ if (xtype == AA_X_TABLE && index >= table_size)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,27 +0,0 @@
|
||||
From 05a64c434466029b298ee1e78a988cd6a7f80c0e Mon Sep 17 00:00:00 2001
|
||||
From: John Johansen <john.johansen@canonical.com>
|
||||
Date: Wed, 18 Nov 2015 11:41:05 -0800
|
||||
Subject: [PATCH 14/27] apparmor: fix ref count leak when profile sha1 hash is
|
||||
read
|
||||
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
Acked-by: Seth Arnold <seth.arnold@canonical.com>
|
||||
---
|
||||
security/apparmor/apparmorfs.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
|
||||
index 45a6199..0d8dd71 100644
|
||||
--- a/security/apparmor/apparmorfs.c
|
||||
+++ b/security/apparmor/apparmorfs.c
|
||||
@@ -331,6 +331,7 @@ static int aa_fs_seq_hash_show(struct seq_file *seq, void *v)
|
||||
seq_printf(seq, "%.2x", profile->hash[i]);
|
||||
seq_puts(seq, "\n");
|
||||
}
|
||||
+ aa_put_profile(profile);
|
||||
|
||||
return 0;
|
||||
}
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,37 +0,0 @@
|
||||
From 6b0b8b91f454bd021e27abe0e611a6764e4806c1 Mon Sep 17 00:00:00 2001
|
||||
From: John Johansen <john.johansen@canonical.com>
|
||||
Date: Wed, 16 Dec 2015 18:09:10 -0800
|
||||
Subject: [PATCH 15/27] apparmor: fix refcount race when finding a child
|
||||
profile
|
||||
|
||||
When finding a child profile via an rcu critical section, the profile
|
||||
may be put and scheduled for deletion after the child is found but
|
||||
before its refcount is incremented.
|
||||
|
||||
Protect against this by repeating the lookup if the profiles refcount
|
||||
is 0 and is one its way to deletion.
|
||||
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
Acked-by: Seth Arnold <seth.arnold@canonical.com>
|
||||
---
|
||||
security/apparmor/policy.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
|
||||
index ca402d0..7807125 100644
|
||||
--- a/security/apparmor/policy.c
|
||||
+++ b/security/apparmor/policy.c
|
||||
@@ -766,7 +766,9 @@ struct aa_profile *aa_find_child(struct aa_profile *parent, const char *name)
|
||||
struct aa_profile *profile;
|
||||
|
||||
rcu_read_lock();
|
||||
- profile = aa_get_profile(__find_child(&parent->base.profiles, name));
|
||||
+ do {
|
||||
+ profile = __find_child(&parent->base.profiles, name);
|
||||
+ } while (profile && !aa_get_profile_not0(profile));
|
||||
rcu_read_unlock();
|
||||
|
||||
/* refcount released by caller */
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,59 +0,0 @@
|
||||
From 84acc6aa6976e62756e14d3a00c5634724cbaa59 Mon Sep 17 00:00:00 2001
|
||||
From: Geliang Tang <geliangtang@163.com>
|
||||
Date: Mon, 16 Nov 2015 21:46:33 +0800
|
||||
Subject: [PATCH 16/27] apparmor: use list_next_entry instead of
|
||||
list_entry_next
|
||||
|
||||
list_next_entry has been defined in list.h, so I replace list_entry_next
|
||||
with it.
|
||||
|
||||
Signed-off-by: Geliang Tang <geliangtang@163.com>
|
||||
Acked-by: Serge Hallyn <serge.hallyn@canonical.com>
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
---
|
||||
security/apparmor/apparmorfs.c | 8 +++-----
|
||||
1 file changed, 3 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
|
||||
index 0d8dd71..729e595 100644
|
||||
--- a/security/apparmor/apparmorfs.c
|
||||
+++ b/security/apparmor/apparmorfs.c
|
||||
@@ -553,8 +553,6 @@ fail2:
|
||||
}
|
||||
|
||||
|
||||
-#define list_entry_next(pos, member) \
|
||||
- list_entry(pos->member.next, typeof(*pos), member)
|
||||
#define list_entry_is_head(pos, head, member) (&pos->member == (head))
|
||||
|
||||
/**
|
||||
@@ -585,7 +583,7 @@ static struct aa_namespace *__next_namespace(struct aa_namespace *root,
|
||||
parent = ns->parent;
|
||||
while (ns != root) {
|
||||
mutex_unlock(&ns->lock);
|
||||
- next = list_entry_next(ns, base.list);
|
||||
+ next = list_next_entry(ns, base.list);
|
||||
if (!list_entry_is_head(next, &parent->sub_ns, base.list)) {
|
||||
mutex_lock(&next->lock);
|
||||
return next;
|
||||
@@ -639,7 +637,7 @@ static struct aa_profile *__next_profile(struct aa_profile *p)
|
||||
parent = rcu_dereference_protected(p->parent,
|
||||
mutex_is_locked(&p->ns->lock));
|
||||
while (parent) {
|
||||
- p = list_entry_next(p, base.list);
|
||||
+ p = list_next_entry(p, base.list);
|
||||
if (!list_entry_is_head(p, &parent->base.profiles, base.list))
|
||||
return p;
|
||||
p = parent;
|
||||
@@ -648,7 +646,7 @@ static struct aa_profile *__next_profile(struct aa_profile *p)
|
||||
}
|
||||
|
||||
/* is next another profile in the namespace */
|
||||
- p = list_entry_next(p, base.list);
|
||||
+ p = list_next_entry(p, base.list);
|
||||
if (!list_entry_is_head(p, &ns->base.profiles, base.list))
|
||||
return p;
|
||||
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,50 +0,0 @@
|
||||
From a3896605318b86d8cf288c122e03604e349d5dd7 Mon Sep 17 00:00:00 2001
|
||||
From: Jeff Mahoney <jeffm@suse.com>
|
||||
Date: Fri, 6 Nov 2015 15:17:30 -0500
|
||||
Subject: [PATCH 17/27] apparmor: allow SYS_CAP_RESOURCE to be sufficient to
|
||||
prlimit another task
|
||||
|
||||
While using AppArmor, SYS_CAP_RESOURCE is insufficient to call prlimit
|
||||
on another task. The only other example of a AppArmor mediating access to
|
||||
another, already running, task (ignoring fork+exec) is ptrace.
|
||||
|
||||
The AppArmor model for ptrace is that one of the following must be true:
|
||||
1) The tracer is unconfined
|
||||
2) The tracer is in complain mode
|
||||
3) The tracer and tracee are confined by the same profile
|
||||
4) The tracer is confined but has SYS_CAP_PTRACE
|
||||
|
||||
1), 2, and 3) are already true for setrlimit.
|
||||
|
||||
We can match the ptrace model just by allowing CAP_SYS_RESOURCE.
|
||||
|
||||
We still test the values of the rlimit since it can always be overridden
|
||||
using a value that means unlimited for a particular resource.
|
||||
|
||||
Signed-off-by: Jeff Mahoney <jeffm@suse.com>
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
---
|
||||
security/apparmor/resource.c | 6 ++++--
|
||||
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/security/apparmor/resource.c b/security/apparmor/resource.c
|
||||
index 748bf0c..67a6072 100644
|
||||
--- a/security/apparmor/resource.c
|
||||
+++ b/security/apparmor/resource.c
|
||||
@@ -101,9 +101,11 @@ int aa_task_setrlimit(struct aa_profile *profile, struct task_struct *task,
|
||||
/* TODO: extend resource control to handle other (non current)
|
||||
* profiles. AppArmor rules currently have the implicit assumption
|
||||
* that the task is setting the resource of a task confined with
|
||||
- * the same profile.
|
||||
+ * the same profile or that the task setting the resource of another
|
||||
+ * task has CAP_SYS_RESOURCE.
|
||||
*/
|
||||
- if (profile != task_profile ||
|
||||
+ if ((profile != task_profile &&
|
||||
+ aa_capable(profile, CAP_SYS_RESOURCE, 1)) ||
|
||||
(profile->rlimits.mask & (1 << resource) &&
|
||||
new_rlim->rlim_max > profile->rlimits.limits[resource].rlim_max))
|
||||
error = -EACCES;
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,40 +0,0 @@
|
||||
From 6fdcc3cfecd4d89457036627d59ebe5154d094c5 Mon Sep 17 00:00:00 2001
|
||||
From: John Johansen <john.johansen@canonical.com>
|
||||
Date: Thu, 2 Jun 2016 02:37:02 -0700
|
||||
Subject: [PATCH 18/27] apparmor: add missing id bounds check on dfa
|
||||
verification
|
||||
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
---
|
||||
security/apparmor/include/match.h | 1 +
|
||||
security/apparmor/match.c | 2 ++
|
||||
2 files changed, 3 insertions(+)
|
||||
|
||||
diff --git a/security/apparmor/include/match.h b/security/apparmor/include/match.h
|
||||
index 001c43a..a1c04fe 100644
|
||||
--- a/security/apparmor/include/match.h
|
||||
+++ b/security/apparmor/include/match.h
|
||||
@@ -62,6 +62,7 @@ struct table_set_header {
|
||||
#define YYTD_ID_ACCEPT2 6
|
||||
#define YYTD_ID_NXT 7
|
||||
#define YYTD_ID_TSIZE 8
|
||||
+#define YYTD_ID_MAX 8
|
||||
|
||||
#define YYTD_DATA8 1
|
||||
#define YYTD_DATA16 2
|
||||
diff --git a/security/apparmor/match.c b/security/apparmor/match.c
|
||||
index 727eb42..f9f57c6 100644
|
||||
--- a/security/apparmor/match.c
|
||||
+++ b/security/apparmor/match.c
|
||||
@@ -47,6 +47,8 @@ static struct table_header *unpack_table(char *blob, size_t bsize)
|
||||
* it every time we use td_id as an index
|
||||
*/
|
||||
th.td_id = be16_to_cpu(*(u16 *) (blob)) - 1;
|
||||
+ if (th.td_id > YYTD_ID_MAX)
|
||||
+ goto out;
|
||||
th.td_flags = be16_to_cpu(*(u16 *) (blob + 2));
|
||||
th.td_lolen = be32_to_cpu(*(u32 *) (blob + 8));
|
||||
blob += sizeof(struct table_header);
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,38 +0,0 @@
|
||||
From 95d203cfb59627a86483a279ba82f1aa75297e07 Mon Sep 17 00:00:00 2001
|
||||
From: John Johansen <john.johansen@canonical.com>
|
||||
Date: Wed, 15 Jun 2016 09:57:55 +0300
|
||||
Subject: [PATCH 19/27] apparmor: don't check for vmalloc_addr if kvzalloc()
|
||||
failed
|
||||
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
---
|
||||
security/apparmor/match.c | 10 +++++-----
|
||||
1 file changed, 5 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/security/apparmor/match.c b/security/apparmor/match.c
|
||||
index f9f57c6..32b72eb 100644
|
||||
--- a/security/apparmor/match.c
|
||||
+++ b/security/apparmor/match.c
|
||||
@@ -75,14 +75,14 @@ static struct table_header *unpack_table(char *blob, size_t bsize)
|
||||
u32, be32_to_cpu);
|
||||
else
|
||||
goto fail;
|
||||
+ /* if table was vmalloced make sure the page tables are synced
|
||||
+ * before it is used, as it goes live to all cpus.
|
||||
+ */
|
||||
+ if (is_vmalloc_addr(table))
|
||||
+ vm_unmap_aliases();
|
||||
}
|
||||
|
||||
out:
|
||||
- /* if table was vmalloced make sure the page tables are synced
|
||||
- * before it is used, as it goes live to all cpus.
|
||||
- */
|
||||
- if (is_vmalloc_addr(table))
|
||||
- vm_unmap_aliases();
|
||||
return table;
|
||||
fail:
|
||||
kvfree(table);
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,33 +0,0 @@
|
||||
From e925f976c7a9c85455f67c360671254bac2d9a91 Mon Sep 17 00:00:00 2001
|
||||
From: John Johansen <john.johansen@canonical.com>
|
||||
Date: Wed, 15 Jun 2016 10:00:55 +0300
|
||||
Subject: [PATCH 20/27] apparmor: fix oops in profile_unpack() when policy_db
|
||||
is not present
|
||||
|
||||
BugLink: http://bugs.launchpad.net/bugs/1592547
|
||||
|
||||
If unpack_dfa() returns NULL due to the dfa not being present,
|
||||
profile_unpack() is not checking if the dfa is not present (NULL).
|
||||
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
---
|
||||
security/apparmor/policy_unpack.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
|
||||
index c841b12..dac2121 100644
|
||||
--- a/security/apparmor/policy_unpack.c
|
||||
+++ b/security/apparmor/policy_unpack.c
|
||||
@@ -583,6 +583,9 @@ static struct aa_profile *unpack_profile(struct aa_ext *e)
|
||||
error = PTR_ERR(profile->policy.dfa);
|
||||
profile->policy.dfa = NULL;
|
||||
goto fail;
|
||||
+ } else if (!profile->policy.dfa) {
|
||||
+ error = -EPROTO;
|
||||
+ goto fail;
|
||||
}
|
||||
if (!unpack_u32(e, &profile->policy.start[0], "start"))
|
||||
/* default start state */
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,162 +0,0 @@
|
||||
From 45774028820fe2ffbbc94667165f04749821d529 Mon Sep 17 00:00:00 2001
|
||||
From: John Johansen <john.johansen@canonical.com>
|
||||
Date: Wed, 22 Jun 2016 18:01:08 -0700
|
||||
Subject: [PATCH 21/27] apparmor: fix module parameters can be changed after
|
||||
policy is locked
|
||||
|
||||
the policy_lock parameter is a one way switch that prevents policy
|
||||
from being further modified. Unfortunately some of the module parameters
|
||||
can effectively modify policy by turning off enforcement.
|
||||
|
||||
split policy_admin_capable into a view check and a full admin check,
|
||||
and update the admin check to test the policy_lock parameter.
|
||||
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
---
|
||||
security/apparmor/include/policy.h | 2 ++
|
||||
security/apparmor/lsm.c | 22 ++++++++++------------
|
||||
security/apparmor/policy.c | 18 +++++++++++++++++-
|
||||
3 files changed, 29 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h
|
||||
index c28b0f2..52275f0 100644
|
||||
--- a/security/apparmor/include/policy.h
|
||||
+++ b/security/apparmor/include/policy.h
|
||||
@@ -403,6 +403,8 @@ static inline int AUDIT_MODE(struct aa_profile *profile)
|
||||
return profile->audit;
|
||||
}
|
||||
|
||||
+bool policy_view_capable(void);
|
||||
+bool policy_admin_capable(void);
|
||||
bool aa_may_manage_policy(int op);
|
||||
|
||||
#endif /* __AA_POLICY_H */
|
||||
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
|
||||
index 5ee8201..bd40b12 100644
|
||||
--- a/security/apparmor/lsm.c
|
||||
+++ b/security/apparmor/lsm.c
|
||||
@@ -751,51 +751,49 @@ __setup("apparmor=", apparmor_enabled_setup);
|
||||
/* set global flag turning off the ability to load policy */
|
||||
static int param_set_aalockpolicy(const char *val, const struct kernel_param *kp)
|
||||
{
|
||||
- if (!capable(CAP_MAC_ADMIN))
|
||||
+ if (!policy_admin_capable())
|
||||
return -EPERM;
|
||||
- if (aa_g_lock_policy)
|
||||
- return -EACCES;
|
||||
return param_set_bool(val, kp);
|
||||
}
|
||||
|
||||
static int param_get_aalockpolicy(char *buffer, const struct kernel_param *kp)
|
||||
{
|
||||
- if (!capable(CAP_MAC_ADMIN))
|
||||
+ if (!policy_view_capable())
|
||||
return -EPERM;
|
||||
return param_get_bool(buffer, kp);
|
||||
}
|
||||
|
||||
static int param_set_aabool(const char *val, const struct kernel_param *kp)
|
||||
{
|
||||
- if (!capable(CAP_MAC_ADMIN))
|
||||
+ if (!policy_admin_capable())
|
||||
return -EPERM;
|
||||
return param_set_bool(val, kp);
|
||||
}
|
||||
|
||||
static int param_get_aabool(char *buffer, const struct kernel_param *kp)
|
||||
{
|
||||
- if (!capable(CAP_MAC_ADMIN))
|
||||
+ if (!policy_view_capable())
|
||||
return -EPERM;
|
||||
return param_get_bool(buffer, kp);
|
||||
}
|
||||
|
||||
static int param_set_aauint(const char *val, const struct kernel_param *kp)
|
||||
{
|
||||
- if (!capable(CAP_MAC_ADMIN))
|
||||
+ if (!policy_admin_capable())
|
||||
return -EPERM;
|
||||
return param_set_uint(val, kp);
|
||||
}
|
||||
|
||||
static int param_get_aauint(char *buffer, const struct kernel_param *kp)
|
||||
{
|
||||
- if (!capable(CAP_MAC_ADMIN))
|
||||
+ if (!policy_view_capable())
|
||||
return -EPERM;
|
||||
return param_get_uint(buffer, kp);
|
||||
}
|
||||
|
||||
static int param_get_audit(char *buffer, struct kernel_param *kp)
|
||||
{
|
||||
- if (!capable(CAP_MAC_ADMIN))
|
||||
+ if (!policy_view_capable())
|
||||
return -EPERM;
|
||||
|
||||
if (!apparmor_enabled)
|
||||
@@ -807,7 +805,7 @@ static int param_get_audit(char *buffer, struct kernel_param *kp)
|
||||
static int param_set_audit(const char *val, struct kernel_param *kp)
|
||||
{
|
||||
int i;
|
||||
- if (!capable(CAP_MAC_ADMIN))
|
||||
+ if (!policy_admin_capable())
|
||||
return -EPERM;
|
||||
|
||||
if (!apparmor_enabled)
|
||||
@@ -828,7 +826,7 @@ static int param_set_audit(const char *val, struct kernel_param *kp)
|
||||
|
||||
static int param_get_mode(char *buffer, struct kernel_param *kp)
|
||||
{
|
||||
- if (!capable(CAP_MAC_ADMIN))
|
||||
+ if (!policy_admin_capable())
|
||||
return -EPERM;
|
||||
|
||||
if (!apparmor_enabled)
|
||||
@@ -840,7 +838,7 @@ static int param_get_mode(char *buffer, struct kernel_param *kp)
|
||||
static int param_set_mode(const char *val, struct kernel_param *kp)
|
||||
{
|
||||
int i;
|
||||
- if (!capable(CAP_MAC_ADMIN))
|
||||
+ if (!policy_admin_capable())
|
||||
return -EPERM;
|
||||
|
||||
if (!apparmor_enabled)
|
||||
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
|
||||
index 7807125..179e68d 100644
|
||||
--- a/security/apparmor/policy.c
|
||||
+++ b/security/apparmor/policy.c
|
||||
@@ -918,6 +918,22 @@ static int audit_policy(int op, gfp_t gfp, const char *name, const char *info,
|
||||
&sa, NULL);
|
||||
}
|
||||
|
||||
+bool policy_view_capable(void)
|
||||
+{
|
||||
+ struct user_namespace *user_ns = current_user_ns();
|
||||
+ bool response = false;
|
||||
+
|
||||
+ if (ns_capable(user_ns, CAP_MAC_ADMIN))
|
||||
+ response = true;
|
||||
+
|
||||
+ return response;
|
||||
+}
|
||||
+
|
||||
+bool policy_admin_capable(void)
|
||||
+{
|
||||
+ return policy_view_capable() && !aa_g_lock_policy;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* aa_may_manage_policy - can the current task manage policy
|
||||
* @op: the policy manipulation operation being done
|
||||
@@ -932,7 +948,7 @@ bool aa_may_manage_policy(int op)
|
||||
return 0;
|
||||
}
|
||||
|
||||
- if (!capable(CAP_MAC_ADMIN)) {
|
||||
+ if (!policy_admin_capable()) {
|
||||
audit_policy(op, GFP_KERNEL, NULL, "not policy admin", -EACCES);
|
||||
return 0;
|
||||
}
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,31 +0,0 @@
|
||||
From 7fcfc22cd04261ac35a579c99bcc804db7eb3e83 Mon Sep 17 00:00:00 2001
|
||||
From: Heinrich Schuchardt <xypron.glpk@gmx.de>
|
||||
Date: Fri, 10 Jun 2016 23:34:26 +0200
|
||||
Subject: [PATCH 22/27] apparmor: do not expose kernel stack
|
||||
|
||||
Do not copy uninitalized fields th.td_hilen, th.td_data.
|
||||
|
||||
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
---
|
||||
security/apparmor/match.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/security/apparmor/match.c b/security/apparmor/match.c
|
||||
index 32b72eb..3f900fc 100644
|
||||
--- a/security/apparmor/match.c
|
||||
+++ b/security/apparmor/match.c
|
||||
@@ -63,7 +63,9 @@ static struct table_header *unpack_table(char *blob, size_t bsize)
|
||||
|
||||
table = kvzalloc(tsize);
|
||||
if (table) {
|
||||
- *table = th;
|
||||
+ table->td_id = th.td_id;
|
||||
+ table->td_flags = th.td_flags;
|
||||
+ table->td_lolen = th.td_lolen;
|
||||
if (th.td_flags == YYTD_DATA8)
|
||||
UNPACK_ARRAY(table->td_data, blob, th.td_lolen,
|
||||
u8, byte_to_byte);
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,27 +0,0 @@
|
||||
From 1b98560066c26fecb0a61aeb9249e141af2e63f9 Mon Sep 17 00:00:00 2001
|
||||
From: John Johansen <john.johansen@canonical.com>
|
||||
Date: Sat, 9 Jul 2016 23:46:33 -0700
|
||||
Subject: [PATCH 23/27] apparmor: fix arg_size computation for when setprocattr
|
||||
is null terminated
|
||||
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
---
|
||||
security/apparmor/lsm.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
|
||||
index bd40b12..1bf6c53 100644
|
||||
--- a/security/apparmor/lsm.c
|
||||
+++ b/security/apparmor/lsm.c
|
||||
@@ -552,7 +552,7 @@ static int apparmor_setprocattr(struct task_struct *task, char *name,
|
||||
if (!*args)
|
||||
goto out;
|
||||
|
||||
- arg_size = size - (args - (char *) value);
|
||||
+ arg_size = size - (args - (largs ? largs : (char *) value));
|
||||
if (strcmp(name, "current") == 0) {
|
||||
if (strcmp(command, "changehat") == 0) {
|
||||
error = aa_setprocattr_changehat(args, arg_size,
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,603 +0,0 @@
|
||||
From 8d7c032e7798fa1c46449728874b64fff882368b Mon Sep 17 00:00:00 2001
|
||||
From: John Johansen <john.johansen@canonical.com>
|
||||
Date: Mon, 4 Oct 2010 15:03:36 -0700
|
||||
Subject: [PATCH 24/27] UBUNTU: SAUCE: AppArmor: basic networking rules
|
||||
|
||||
Base support for network mediation.
|
||||
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
---
|
||||
security/apparmor/.gitignore | 1 +
|
||||
security/apparmor/Makefile | 42 +++++++++-
|
||||
security/apparmor/apparmorfs.c | 1 +
|
||||
security/apparmor/include/audit.h | 4 +
|
||||
security/apparmor/include/net.h | 44 ++++++++++
|
||||
security/apparmor/include/policy.h | 3 +
|
||||
security/apparmor/lsm.c | 112 +++++++++++++++++++++++++
|
||||
security/apparmor/net.c | 162 +++++++++++++++++++++++++++++++++++++
|
||||
security/apparmor/policy.c | 1 +
|
||||
security/apparmor/policy_unpack.c | 46 +++++++++++
|
||||
10 files changed, 414 insertions(+), 2 deletions(-)
|
||||
create mode 100644 security/apparmor/include/net.h
|
||||
create mode 100644 security/apparmor/net.c
|
||||
|
||||
diff --git a/security/apparmor/.gitignore b/security/apparmor/.gitignore
|
||||
index 9cdec70..d5b291e 100644
|
||||
--- a/security/apparmor/.gitignore
|
||||
+++ b/security/apparmor/.gitignore
|
||||
@@ -1,5 +1,6 @@
|
||||
#
|
||||
# Generated include files
|
||||
#
|
||||
+net_names.h
|
||||
capability_names.h
|
||||
rlim_names.h
|
||||
diff --git a/security/apparmor/Makefile b/security/apparmor/Makefile
|
||||
index d693df8..5dbb72f 100644
|
||||
--- a/security/apparmor/Makefile
|
||||
+++ b/security/apparmor/Makefile
|
||||
@@ -4,10 +4,10 @@ obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o
|
||||
|
||||
apparmor-y := apparmorfs.o audit.o capability.o context.o ipc.o lib.o match.o \
|
||||
path.o domain.o policy.o policy_unpack.o procattr.o lsm.o \
|
||||
- resource.o sid.o file.o
|
||||
+ resource.o sid.o file.o net.o
|
||||
apparmor-$(CONFIG_SECURITY_APPARMOR_HASH) += crypto.o
|
||||
|
||||
-clean-files := capability_names.h rlim_names.h
|
||||
+clean-files := capability_names.h rlim_names.h net_names.h
|
||||
|
||||
|
||||
# Build a lower case string table of capability names
|
||||
@@ -25,6 +25,38 @@ cmd_make-caps = echo "static const char *const capability_names[] = {" > $@ ;\
|
||||
-e 's/^\#define[ \t]+CAP_([A-Z0-9_]+)[ \t]+([0-9]+)/\L\1/p' | \
|
||||
tr '\n' ' ' | sed -e 's/ $$/"\n/' >> $@
|
||||
|
||||
+# Build a lower case string table of address family names
|
||||
+# Transform lines from
|
||||
+# define AF_LOCAL 1 /* POSIX name for AF_UNIX */
|
||||
+# #define AF_INET 2 /* Internet IP Protocol */
|
||||
+# to
|
||||
+# [1] = "local",
|
||||
+# [2] = "inet",
|
||||
+#
|
||||
+# and build the securityfs entries for the mapping.
|
||||
+# Transforms lines from
|
||||
+# #define AF_INET 2 /* Internet IP Protocol */
|
||||
+# to
|
||||
+# #define AA_FS_AF_MASK "local inet"
|
||||
+quiet_cmd_make-af = GEN $@
|
||||
+cmd_make-af = echo "static const char *address_family_names[] = {" > $@ ;\
|
||||
+ sed $< >>$@ -r -n -e "/AF_MAX/d" -e "/AF_LOCAL/d" -e \
|
||||
+ 's/^\#define[ \t]+AF_([A-Z0-9_]+)[ \t]+([0-9]+)(.*)/[\2] = "\L\1",/p';\
|
||||
+ echo "};" >> $@ ;\
|
||||
+ echo -n '\#define AA_FS_AF_MASK "' >> $@ ;\
|
||||
+ sed -r -n 's/^\#define[ \t]+AF_([A-Z0-9_]+)[ \t]+([0-9]+)(.*)/\L\1/p'\
|
||||
+ $< | tr '\n' ' ' | sed -e 's/ $$/"\n/' >> $@
|
||||
+
|
||||
+# Build a lower case string table of sock type names
|
||||
+# Transform lines from
|
||||
+# SOCK_STREAM = 1,
|
||||
+# to
|
||||
+# [1] = "stream",
|
||||
+quiet_cmd_make-sock = GEN $@
|
||||
+cmd_make-sock = echo "static const char *sock_type_names[] = {" >> $@ ;\
|
||||
+ sed $^ >>$@ -r -n \
|
||||
+ -e 's/^\tSOCK_([A-Z0-9_]+)[\t]+=[ \t]+([0-9]+)(.*)/[\2] = "\L\1",/p';\
|
||||
+ echo "};" >> $@
|
||||
|
||||
# Build a lower case string table of rlimit names.
|
||||
# Transforms lines from
|
||||
@@ -61,6 +93,7 @@ cmd_make-rlim = echo "static const char *const rlim_names[RLIM_NLIMITS] = {" \
|
||||
tr '\n' ' ' | sed -e 's/ $$/"\n/' >> $@
|
||||
|
||||
$(obj)/capability.o : $(obj)/capability_names.h
|
||||
+$(obj)/net.o : $(obj)/net_names.h
|
||||
$(obj)/resource.o : $(obj)/rlim_names.h
|
||||
$(obj)/capability_names.h : $(srctree)/include/uapi/linux/capability.h \
|
||||
$(src)/Makefile
|
||||
@@ -68,3 +101,8 @@ $(obj)/capability_names.h : $(srctree)/include/uapi/linux/capability.h \
|
||||
$(obj)/rlim_names.h : $(srctree)/include/uapi/asm-generic/resource.h \
|
||||
$(src)/Makefile
|
||||
$(call cmd,make-rlim)
|
||||
+$(obj)/net_names.h : $(srctree)/include/linux/socket.h \
|
||||
+ $(srctree)/include/linux/net.h \
|
||||
+ $(src)/Makefile
|
||||
+ $(call cmd,make-af)
|
||||
+ $(call cmd,make-sock)
|
||||
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
|
||||
index 729e595..181d961 100644
|
||||
--- a/security/apparmor/apparmorfs.c
|
||||
+++ b/security/apparmor/apparmorfs.c
|
||||
@@ -807,6 +807,7 @@ static struct aa_fs_entry aa_fs_entry_features[] = {
|
||||
AA_FS_DIR("policy", aa_fs_entry_policy),
|
||||
AA_FS_DIR("domain", aa_fs_entry_domain),
|
||||
AA_FS_DIR("file", aa_fs_entry_file),
|
||||
+ AA_FS_DIR("network", aa_fs_entry_network),
|
||||
AA_FS_FILE_U64("capability", VFS_CAP_FLAGS_MASK),
|
||||
AA_FS_DIR("rlimit", aa_fs_entry_rlimit),
|
||||
AA_FS_DIR("caps", aa_fs_entry_caps),
|
||||
diff --git a/security/apparmor/include/audit.h b/security/apparmor/include/audit.h
|
||||
index ba3dfd1..5d3c419 100644
|
||||
--- a/security/apparmor/include/audit.h
|
||||
+++ b/security/apparmor/include/audit.h
|
||||
@@ -125,6 +125,10 @@ struct apparmor_audit_data {
|
||||
u32 denied;
|
||||
kuid_t ouid;
|
||||
} fs;
|
||||
+ struct {
|
||||
+ int type, protocol;
|
||||
+ struct sock *sk;
|
||||
+ } net;
|
||||
};
|
||||
};
|
||||
|
||||
diff --git a/security/apparmor/include/net.h b/security/apparmor/include/net.h
|
||||
new file mode 100644
|
||||
index 0000000..cb8a121
|
||||
--- /dev/null
|
||||
+++ b/security/apparmor/include/net.h
|
||||
@@ -0,0 +1,44 @@
|
||||
+/*
|
||||
+ * AppArmor security module
|
||||
+ *
|
||||
+ * This file contains AppArmor network mediation definitions.
|
||||
+ *
|
||||
+ * Copyright (C) 1998-2008 Novell/SUSE
|
||||
+ * Copyright 2009-2012 Canonical Ltd.
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU General Public License as
|
||||
+ * published by the Free Software Foundation, version 2 of the
|
||||
+ * License.
|
||||
+ */
|
||||
+
|
||||
+#ifndef __AA_NET_H
|
||||
+#define __AA_NET_H
|
||||
+
|
||||
+#include <net/sock.h>
|
||||
+
|
||||
+#include "apparmorfs.h"
|
||||
+
|
||||
+/* struct aa_net - network confinement data
|
||||
+ * @allowed: basic network families permissions
|
||||
+ * @audit_network: which network permissions to force audit
|
||||
+ * @quiet_network: which network permissions to quiet rejects
|
||||
+ */
|
||||
+struct aa_net {
|
||||
+ u16 allow[AF_MAX];
|
||||
+ u16 audit[AF_MAX];
|
||||
+ u16 quiet[AF_MAX];
|
||||
+};
|
||||
+
|
||||
+extern struct aa_fs_entry aa_fs_entry_network[];
|
||||
+
|
||||
+extern int aa_net_perm(int op, struct aa_profile *profile, u16 family,
|
||||
+ int type, int protocol, struct sock *sk);
|
||||
+extern int aa_revalidate_sk(int op, struct sock *sk);
|
||||
+
|
||||
+static inline void aa_free_net_rules(struct aa_net *new)
|
||||
+{
|
||||
+ /* NOP */
|
||||
+}
|
||||
+
|
||||
+#endif /* __AA_NET_H */
|
||||
diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h
|
||||
index 52275f0..4fc4dac 100644
|
||||
--- a/security/apparmor/include/policy.h
|
||||
+++ b/security/apparmor/include/policy.h
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "capability.h"
|
||||
#include "domain.h"
|
||||
#include "file.h"
|
||||
+#include "net.h"
|
||||
#include "resource.h"
|
||||
|
||||
extern const char *const aa_profile_mode_names[];
|
||||
@@ -176,6 +177,7 @@ struct aa_replacedby {
|
||||
* @policy: general match rules governing policy
|
||||
* @file: The set of rules governing basic file access and domain transitions
|
||||
* @caps: capabilities for the profile
|
||||
+ * @net: network controls for the profile
|
||||
* @rlimits: rlimits for the profile
|
||||
*
|
||||
* @dents: dentries for the profiles file entries in apparmorfs
|
||||
@@ -217,6 +219,7 @@ struct aa_profile {
|
||||
struct aa_policydb policy;
|
||||
struct aa_file_rules file;
|
||||
struct aa_caps caps;
|
||||
+ struct aa_net net;
|
||||
struct aa_rlimit rlimits;
|
||||
|
||||
unsigned char *hash;
|
||||
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
|
||||
index 1bf6c53..284ddda 100644
|
||||
--- a/security/apparmor/lsm.c
|
||||
+++ b/security/apparmor/lsm.c
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "include/context.h"
|
||||
#include "include/file.h"
|
||||
#include "include/ipc.h"
|
||||
+#include "include/net.h"
|
||||
#include "include/path.h"
|
||||
#include "include/policy.h"
|
||||
#include "include/procattr.h"
|
||||
@@ -607,6 +608,104 @@ static int apparmor_task_setrlimit(struct task_struct *task,
|
||||
return error;
|
||||
}
|
||||
|
||||
+static int apparmor_socket_create(int family, int type, int protocol, int kern)
|
||||
+{
|
||||
+ struct aa_profile *profile;
|
||||
+ int error = 0;
|
||||
+
|
||||
+ if (kern)
|
||||
+ return 0;
|
||||
+
|
||||
+ profile = __aa_current_profile();
|
||||
+ if (!unconfined(profile))
|
||||
+ error = aa_net_perm(OP_CREATE, profile, family, type, protocol,
|
||||
+ NULL);
|
||||
+ return error;
|
||||
+}
|
||||
+
|
||||
+static int apparmor_socket_bind(struct socket *sock,
|
||||
+ struct sockaddr *address, int addrlen)
|
||||
+{
|
||||
+ struct sock *sk = sock->sk;
|
||||
+
|
||||
+ return aa_revalidate_sk(OP_BIND, sk);
|
||||
+}
|
||||
+
|
||||
+static int apparmor_socket_connect(struct socket *sock,
|
||||
+ struct sockaddr *address, int addrlen)
|
||||
+{
|
||||
+ struct sock *sk = sock->sk;
|
||||
+
|
||||
+ return aa_revalidate_sk(OP_CONNECT, sk);
|
||||
+}
|
||||
+
|
||||
+static int apparmor_socket_listen(struct socket *sock, int backlog)
|
||||
+{
|
||||
+ struct sock *sk = sock->sk;
|
||||
+
|
||||
+ return aa_revalidate_sk(OP_LISTEN, sk);
|
||||
+}
|
||||
+
|
||||
+static int apparmor_socket_accept(struct socket *sock, struct socket *newsock)
|
||||
+{
|
||||
+ struct sock *sk = sock->sk;
|
||||
+
|
||||
+ return aa_revalidate_sk(OP_ACCEPT, sk);
|
||||
+}
|
||||
+
|
||||
+static int apparmor_socket_sendmsg(struct socket *sock,
|
||||
+ struct msghdr *msg, int size)
|
||||
+{
|
||||
+ struct sock *sk = sock->sk;
|
||||
+
|
||||
+ return aa_revalidate_sk(OP_SENDMSG, sk);
|
||||
+}
|
||||
+
|
||||
+static int apparmor_socket_recvmsg(struct socket *sock,
|
||||
+ struct msghdr *msg, int size, int flags)
|
||||
+{
|
||||
+ struct sock *sk = sock->sk;
|
||||
+
|
||||
+ return aa_revalidate_sk(OP_RECVMSG, sk);
|
||||
+}
|
||||
+
|
||||
+static int apparmor_socket_getsockname(struct socket *sock)
|
||||
+{
|
||||
+ struct sock *sk = sock->sk;
|
||||
+
|
||||
+ return aa_revalidate_sk(OP_GETSOCKNAME, sk);
|
||||
+}
|
||||
+
|
||||
+static int apparmor_socket_getpeername(struct socket *sock)
|
||||
+{
|
||||
+ struct sock *sk = sock->sk;
|
||||
+
|
||||
+ return aa_revalidate_sk(OP_GETPEERNAME, sk);
|
||||
+}
|
||||
+
|
||||
+static int apparmor_socket_getsockopt(struct socket *sock, int level,
|
||||
+ int optname)
|
||||
+{
|
||||
+ struct sock *sk = sock->sk;
|
||||
+
|
||||
+ return aa_revalidate_sk(OP_GETSOCKOPT, sk);
|
||||
+}
|
||||
+
|
||||
+static int apparmor_socket_setsockopt(struct socket *sock, int level,
|
||||
+ int optname)
|
||||
+{
|
||||
+ struct sock *sk = sock->sk;
|
||||
+
|
||||
+ return aa_revalidate_sk(OP_SETSOCKOPT, sk);
|
||||
+}
|
||||
+
|
||||
+static int apparmor_socket_shutdown(struct socket *sock, int how)
|
||||
+{
|
||||
+ struct sock *sk = sock->sk;
|
||||
+
|
||||
+ return aa_revalidate_sk(OP_SOCK_SHUTDOWN, sk);
|
||||
+}
|
||||
+
|
||||
static struct security_hook_list apparmor_hooks[] = {
|
||||
LSM_HOOK_INIT(ptrace_access_check, apparmor_ptrace_access_check),
|
||||
LSM_HOOK_INIT(ptrace_traceme, apparmor_ptrace_traceme),
|
||||
@@ -636,6 +735,19 @@ static struct security_hook_list apparmor_hooks[] = {
|
||||
LSM_HOOK_INIT(getprocattr, apparmor_getprocattr),
|
||||
LSM_HOOK_INIT(setprocattr, apparmor_setprocattr),
|
||||
|
||||
+ LSM_HOOK_INIT(socket_create, apparmor_socket_create),
|
||||
+ LSM_HOOK_INIT(socket_bind, apparmor_socket_bind),
|
||||
+ LSM_HOOK_INIT(socket_connect, apparmor_socket_connect),
|
||||
+ LSM_HOOK_INIT(socket_listen, apparmor_socket_listen),
|
||||
+ LSM_HOOK_INIT(socket_accept, apparmor_socket_accept),
|
||||
+ LSM_HOOK_INIT(socket_sendmsg, apparmor_socket_sendmsg),
|
||||
+ LSM_HOOK_INIT(socket_recvmsg, apparmor_socket_recvmsg),
|
||||
+ LSM_HOOK_INIT(socket_getsockname, apparmor_socket_getsockname),
|
||||
+ LSM_HOOK_INIT(socket_getpeername, apparmor_socket_getpeername),
|
||||
+ LSM_HOOK_INIT(socket_getsockopt, apparmor_socket_getsockopt),
|
||||
+ LSM_HOOK_INIT(socket_setsockopt, apparmor_socket_setsockopt),
|
||||
+ LSM_HOOK_INIT(socket_shutdown, apparmor_socket_shutdown),
|
||||
+
|
||||
LSM_HOOK_INIT(cred_alloc_blank, apparmor_cred_alloc_blank),
|
||||
LSM_HOOK_INIT(cred_free, apparmor_cred_free),
|
||||
LSM_HOOK_INIT(cred_prepare, apparmor_cred_prepare),
|
||||
diff --git a/security/apparmor/net.c b/security/apparmor/net.c
|
||||
new file mode 100644
|
||||
index 0000000..003dd18
|
||||
--- /dev/null
|
||||
+++ b/security/apparmor/net.c
|
||||
@@ -0,0 +1,162 @@
|
||||
+/*
|
||||
+ * AppArmor security module
|
||||
+ *
|
||||
+ * This file contains AppArmor network mediation
|
||||
+ *
|
||||
+ * Copyright (C) 1998-2008 Novell/SUSE
|
||||
+ * Copyright 2009-2012 Canonical Ltd.
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU General Public License as
|
||||
+ * published by the Free Software Foundation, version 2 of the
|
||||
+ * License.
|
||||
+ */
|
||||
+
|
||||
+#include "include/apparmor.h"
|
||||
+#include "include/audit.h"
|
||||
+#include "include/context.h"
|
||||
+#include "include/net.h"
|
||||
+#include "include/policy.h"
|
||||
+
|
||||
+#include "net_names.h"
|
||||
+
|
||||
+struct aa_fs_entry aa_fs_entry_network[] = {
|
||||
+ AA_FS_FILE_STRING("af_mask", AA_FS_AF_MASK),
|
||||
+ { }
|
||||
+};
|
||||
+
|
||||
+/* audit callback for net specific fields */
|
||||
+static void audit_cb(struct audit_buffer *ab, void *va)
|
||||
+{
|
||||
+ struct common_audit_data *sa = va;
|
||||
+
|
||||
+ audit_log_format(ab, " family=");
|
||||
+ if (address_family_names[sa->u.net->family]) {
|
||||
+ audit_log_string(ab, address_family_names[sa->u.net->family]);
|
||||
+ } else {
|
||||
+ audit_log_format(ab, "\"unknown(%d)\"", sa->u.net->family);
|
||||
+ }
|
||||
+ audit_log_format(ab, " sock_type=");
|
||||
+ if (sock_type_names[sa->aad->net.type]) {
|
||||
+ audit_log_string(ab, sock_type_names[sa->aad->net.type]);
|
||||
+ } else {
|
||||
+ audit_log_format(ab, "\"unknown(%d)\"", sa->aad->net.type);
|
||||
+ }
|
||||
+ audit_log_format(ab, " protocol=%d", sa->aad->net.protocol);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * audit_net - audit network access
|
||||
+ * @profile: profile being enforced (NOT NULL)
|
||||
+ * @op: operation being checked
|
||||
+ * @family: network family
|
||||
+ * @type: network type
|
||||
+ * @protocol: network protocol
|
||||
+ * @sk: socket auditing is being applied to
|
||||
+ * @error: error code for failure else 0
|
||||
+ *
|
||||
+ * Returns: %0 or sa->error else other errorcode on failure
|
||||
+ */
|
||||
+static int audit_net(struct aa_profile *profile, int op, u16 family, int type,
|
||||
+ int protocol, struct sock *sk, int error)
|
||||
+{
|
||||
+ int audit_type = AUDIT_APPARMOR_AUTO;
|
||||
+ struct common_audit_data sa;
|
||||
+ struct apparmor_audit_data aad = { };
|
||||
+ struct lsm_network_audit net = { };
|
||||
+ if (sk) {
|
||||
+ sa.type = LSM_AUDIT_DATA_NET;
|
||||
+ } else {
|
||||
+ sa.type = LSM_AUDIT_DATA_NONE;
|
||||
+ }
|
||||
+ /* todo fill in socket addr info */
|
||||
+ sa.aad = &aad;
|
||||
+ sa.u.net = &net;
|
||||
+ sa.aad->op = op,
|
||||
+ sa.u.net->family = family;
|
||||
+ sa.u.net->sk = sk;
|
||||
+ sa.aad->net.type = type;
|
||||
+ sa.aad->net.protocol = protocol;
|
||||
+ sa.aad->error = error;
|
||||
+
|
||||
+ if (likely(!sa.aad->error)) {
|
||||
+ u16 audit_mask = profile->net.audit[sa.u.net->family];
|
||||
+ if (likely((AUDIT_MODE(profile) != AUDIT_ALL) &&
|
||||
+ !(1 << sa.aad->net.type & audit_mask)))
|
||||
+ return 0;
|
||||
+ audit_type = AUDIT_APPARMOR_AUDIT;
|
||||
+ } else {
|
||||
+ u16 quiet_mask = profile->net.quiet[sa.u.net->family];
|
||||
+ u16 kill_mask = 0;
|
||||
+ u16 denied = (1 << sa.aad->net.type) & ~quiet_mask;
|
||||
+
|
||||
+ if (denied & kill_mask)
|
||||
+ audit_type = AUDIT_APPARMOR_KILL;
|
||||
+
|
||||
+ if ((denied & quiet_mask) &&
|
||||
+ AUDIT_MODE(profile) != AUDIT_NOQUIET &&
|
||||
+ AUDIT_MODE(profile) != AUDIT_ALL)
|
||||
+ return COMPLAIN_MODE(profile) ? 0 : sa.aad->error;
|
||||
+ }
|
||||
+
|
||||
+ return aa_audit(audit_type, profile, GFP_KERNEL, &sa, audit_cb);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * aa_net_perm - very course network access check
|
||||
+ * @op: operation being checked
|
||||
+ * @profile: profile being enforced (NOT NULL)
|
||||
+ * @family: network family
|
||||
+ * @type: network type
|
||||
+ * @protocol: network protocol
|
||||
+ *
|
||||
+ * Returns: %0 else error if permission denied
|
||||
+ */
|
||||
+int aa_net_perm(int op, struct aa_profile *profile, u16 family, int type,
|
||||
+ int protocol, struct sock *sk)
|
||||
+{
|
||||
+ u16 family_mask;
|
||||
+ int error;
|
||||
+
|
||||
+ if ((family < 0) || (family >= AF_MAX))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if ((type < 0) || (type >= SOCK_MAX))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ /* unix domain and netlink sockets are handled by ipc */
|
||||
+ if (family == AF_UNIX || family == AF_NETLINK)
|
||||
+ return 0;
|
||||
+
|
||||
+ family_mask = profile->net.allow[family];
|
||||
+
|
||||
+ error = (family_mask & (1 << type)) ? 0 : -EACCES;
|
||||
+
|
||||
+ return audit_net(profile, op, family, type, protocol, sk, error);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * aa_revalidate_sk - Revalidate access to a sock
|
||||
+ * @op: operation being checked
|
||||
+ * @sk: sock being revalidated (NOT NULL)
|
||||
+ *
|
||||
+ * Returns: %0 else error if permission denied
|
||||
+ */
|
||||
+int aa_revalidate_sk(int op, struct sock *sk)
|
||||
+{
|
||||
+ struct aa_profile *profile;
|
||||
+ int error = 0;
|
||||
+
|
||||
+ /* aa_revalidate_sk should not be called from interrupt context
|
||||
+ * don't mediate these calls as they are not task related
|
||||
+ */
|
||||
+ if (in_interrupt())
|
||||
+ return 0;
|
||||
+
|
||||
+ profile = __aa_current_profile();
|
||||
+ if (!unconfined(profile))
|
||||
+ error = aa_net_perm(op, profile, sk->sk_family, sk->sk_type,
|
||||
+ sk->sk_protocol, sk);
|
||||
+
|
||||
+ return error;
|
||||
+}
|
||||
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
|
||||
index 179e68d..f1a8541 100644
|
||||
--- a/security/apparmor/policy.c
|
||||
+++ b/security/apparmor/policy.c
|
||||
@@ -603,6 +603,7 @@ void aa_free_profile(struct aa_profile *profile)
|
||||
|
||||
aa_free_file_rules(&profile->file);
|
||||
aa_free_cap_rules(&profile->caps);
|
||||
+ aa_free_net_rules(&profile->net);
|
||||
aa_free_rlimit_rules(&profile->rlimits);
|
||||
|
||||
kzfree(profile->dirname);
|
||||
diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
|
||||
index dac2121..0107bc4 100644
|
||||
--- a/security/apparmor/policy_unpack.c
|
||||
+++ b/security/apparmor/policy_unpack.c
|
||||
@@ -193,6 +193,19 @@ fail:
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static bool unpack_u16(struct aa_ext *e, u16 *data, const char *name)
|
||||
+{
|
||||
+ if (unpack_nameX(e, AA_U16, name)) {
|
||||
+ if (!inbounds(e, sizeof(u16)))
|
||||
+ return 0;
|
||||
+ if (data)
|
||||
+ *data = le16_to_cpu(get_unaligned((u16 *) e->pos));
|
||||
+ e->pos += sizeof(u16);
|
||||
+ return 1;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static bool unpack_u32(struct aa_ext *e, u32 *data, const char *name)
|
||||
{
|
||||
if (unpack_nameX(e, AA_U32, name)) {
|
||||
@@ -476,6 +489,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e)
|
||||
{
|
||||
struct aa_profile *profile = NULL;
|
||||
const char *name = NULL;
|
||||
+ size_t size = 0;
|
||||
int i, error = -EPROTO;
|
||||
kernel_cap_t tmpcap;
|
||||
u32 tmp;
|
||||
@@ -576,6 +590,38 @@ static struct aa_profile *unpack_profile(struct aa_ext *e)
|
||||
if (!unpack_rlimits(e, profile))
|
||||
goto fail;
|
||||
|
||||
+ size = unpack_array(e, "net_allowed_af");
|
||||
+ if (size) {
|
||||
+
|
||||
+ for (i = 0; i < size; i++) {
|
||||
+ /* discard extraneous rules that this kernel will
|
||||
+ * never request
|
||||
+ */
|
||||
+ if (i >= AF_MAX) {
|
||||
+ u16 tmp;
|
||||
+ if (!unpack_u16(e, &tmp, NULL) ||
|
||||
+ !unpack_u16(e, &tmp, NULL) ||
|
||||
+ !unpack_u16(e, &tmp, NULL))
|
||||
+ goto fail;
|
||||
+ continue;
|
||||
+ }
|
||||
+ if (!unpack_u16(e, &profile->net.allow[i], NULL))
|
||||
+ goto fail;
|
||||
+ if (!unpack_u16(e, &profile->net.audit[i], NULL))
|
||||
+ goto fail;
|
||||
+ if (!unpack_u16(e, &profile->net.quiet[i], NULL))
|
||||
+ goto fail;
|
||||
+ }
|
||||
+ if (!unpack_nameX(e, AA_ARRAYEND, NULL))
|
||||
+ goto fail;
|
||||
+ }
|
||||
+ /*
|
||||
+ * allow unix domain and netlink sockets they are handled
|
||||
+ * by IPC
|
||||
+ */
|
||||
+ profile->net.allow[AF_UNIX] = 0xffff;
|
||||
+ profile->net.allow[AF_NETLINK] = 0xffff;
|
||||
+
|
||||
if (unpack_nameX(e, AA_STRUCT, "policydb")) {
|
||||
/* generic policy dfa - optional and may be NULL */
|
||||
profile->policy.dfa = unpack_dfa(e);
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,38 +0,0 @@
|
||||
From aa45ba104003404efb59e6f7178045ade756035d Mon Sep 17 00:00:00 2001
|
||||
From: John Johansen <john.johansen@canonical.com>
|
||||
Date: Fri, 29 Jun 2012 17:34:00 -0700
|
||||
Subject: [PATCH 25/27] apparmor: Fix quieting of audit messages for network
|
||||
mediation
|
||||
|
||||
If a profile specified a quieting of network denials for a given rule by
|
||||
either the quiet or deny rule qualifiers, the resultant quiet mask for
|
||||
denied requests was applied incorrectly, resulting in two potential bugs.
|
||||
1. The misapplied quiet mask would prevent denials from being correctly
|
||||
tested against the kill mask/mode. Thus network access requests that
|
||||
should have resulted in the application being killed did not.
|
||||
|
||||
2. The actual quieting of the denied network request was not being applied.
|
||||
This would result in network rejections always being logged even when
|
||||
they had been specifically marked as quieted.
|
||||
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
---
|
||||
security/apparmor/net.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/security/apparmor/net.c b/security/apparmor/net.c
|
||||
index 003dd18..6e6e5c9 100644
|
||||
--- a/security/apparmor/net.c
|
||||
+++ b/security/apparmor/net.c
|
||||
@@ -88,7 +88,7 @@ static int audit_net(struct aa_profile *profile, int op, u16 family, int type,
|
||||
} else {
|
||||
u16 quiet_mask = profile->net.quiet[sa.u.net->family];
|
||||
u16 kill_mask = 0;
|
||||
- u16 denied = (1 << sa.aad->net.type) & ~quiet_mask;
|
||||
+ u16 denied = (1 << sa.aad->net.type);
|
||||
|
||||
if (denied & kill_mask)
|
||||
audit_type = AUDIT_APPARMOR_KILL;
|
||||
--
|
||||
2.7.4
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,180 +0,0 @@
|
||||
From 1eff686074a6af0cf47fc24c45ebb001c570a98b Mon Sep 17 00:00:00 2001
|
||||
From: kbuild test robot <fengguang.wu@intel.com>
|
||||
Date: Fri, 29 Jul 2016 12:44:43 +0800
|
||||
Subject: [PATCH 27/27] UBUNTU: SAUCE: AppArmor: fix boolreturn.cocci warnings
|
||||
|
||||
security/apparmor/policy_unpack.c:143:9-10: WARNING: return of 0/1 in function 'unpack_X' with return type bool
|
||||
security/apparmor/policy_unpack.c:189:9-10: WARNING: return of 0/1 in function 'unpack_nameX' with return type bool
|
||||
security/apparmor/policy_unpack.c:475:8-9: WARNING: return of 0/1 in function 'unpack_rlimits' with return type bool
|
||||
security/apparmor/policy_unpack.c:440:8-9: WARNING: return of 0/1 in function 'unpack_trans_table' with return type bool
|
||||
security/apparmor/policy_unpack.c:200:10-11: WARNING: return of 0/1 in function 'unpack_u16' with return type bool
|
||||
security/apparmor/policy_unpack.c:213:10-11: WARNING: return of 0/1 in function 'unpack_u32' with return type bool
|
||||
security/apparmor/policy_unpack.c:226:10-11: WARNING: return of 0/1 in function 'unpack_u64' with return type bool
|
||||
security/apparmor/policy_unpack.c:325:10-11: WARNING: return of 0/1 in function 'verify_accept' with return type bool
|
||||
security/apparmor/policy_unpack.c:739:10-11: WARNING: return of 0/1 in function 'verify_dfa_xindex' with return type bool
|
||||
security/apparmor/policy_unpack.c:729:9-10: WARNING: return of 0/1 in function 'verify_xindex' with return type bool
|
||||
|
||||
Return statements in functions returning bool should use
|
||||
true/false instead of 1/0.
|
||||
Generated by: scripts/coccinelle/misc/boolreturn.cocci
|
||||
Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
---
|
||||
security/apparmor/policy_unpack.c | 52 +++++++++++++++++++--------------------
|
||||
1 file changed, 26 insertions(+), 26 deletions(-)
|
||||
|
||||
diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
|
||||
index 0107bc4..af14626 100644
|
||||
--- a/security/apparmor/policy_unpack.c
|
||||
+++ b/security/apparmor/policy_unpack.c
|
||||
@@ -140,11 +140,11 @@ static size_t unpack_u16_chunk(struct aa_ext *e, char **chunk)
|
||||
static bool unpack_X(struct aa_ext *e, enum aa_code code)
|
||||
{
|
||||
if (!inbounds(e, 1))
|
||||
- return 0;
|
||||
+ return false;
|
||||
if (*(u8 *) e->pos != code)
|
||||
- return 0;
|
||||
+ return false;
|
||||
e->pos++;
|
||||
- return 1;
|
||||
+ return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -186,50 +186,50 @@ static bool unpack_nameX(struct aa_ext *e, enum aa_code code, const char *name)
|
||||
|
||||
/* now check if type code matches */
|
||||
if (unpack_X(e, code))
|
||||
- return 1;
|
||||
+ return true;
|
||||
|
||||
fail:
|
||||
e->pos = pos;
|
||||
- return 0;
|
||||
+ return false;
|
||||
}
|
||||
|
||||
static bool unpack_u16(struct aa_ext *e, u16 *data, const char *name)
|
||||
{
|
||||
if (unpack_nameX(e, AA_U16, name)) {
|
||||
if (!inbounds(e, sizeof(u16)))
|
||||
- return 0;
|
||||
+ return false;
|
||||
if (data)
|
||||
*data = le16_to_cpu(get_unaligned((u16 *) e->pos));
|
||||
e->pos += sizeof(u16);
|
||||
- return 1;
|
||||
+ return true;
|
||||
}
|
||||
- return 0;
|
||||
+ return false;
|
||||
}
|
||||
|
||||
static bool unpack_u32(struct aa_ext *e, u32 *data, const char *name)
|
||||
{
|
||||
if (unpack_nameX(e, AA_U32, name)) {
|
||||
if (!inbounds(e, sizeof(u32)))
|
||||
- return 0;
|
||||
+ return false;
|
||||
if (data)
|
||||
*data = le32_to_cpu(get_unaligned((u32 *) e->pos));
|
||||
e->pos += sizeof(u32);
|
||||
- return 1;
|
||||
+ return true;
|
||||
}
|
||||
- return 0;
|
||||
+ return false;
|
||||
}
|
||||
|
||||
static bool unpack_u64(struct aa_ext *e, u64 *data, const char *name)
|
||||
{
|
||||
if (unpack_nameX(e, AA_U64, name)) {
|
||||
if (!inbounds(e, sizeof(u64)))
|
||||
- return 0;
|
||||
+ return false;
|
||||
if (data)
|
||||
*data = le64_to_cpu(get_unaligned((u64 *) e->pos));
|
||||
e->pos += sizeof(u64);
|
||||
- return 1;
|
||||
+ return true;
|
||||
}
|
||||
- return 0;
|
||||
+ return false;
|
||||
}
|
||||
|
||||
static size_t unpack_array(struct aa_ext *e, const char *name)
|
||||
@@ -322,12 +322,12 @@ static bool verify_accept(struct aa_dfa *dfa, int flags)
|
||||
int mode = ACCEPT_TABLE(dfa)[i];
|
||||
|
||||
if (mode & ~DFA_VALID_PERM_MASK)
|
||||
- return 0;
|
||||
+ return false;
|
||||
|
||||
if (ACCEPT_TABLE2(dfa)[i] & ~DFA_VALID_PERM2_MASK)
|
||||
- return 0;
|
||||
+ return false;
|
||||
}
|
||||
- return 1;
|
||||
+ return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -437,12 +437,12 @@ static bool unpack_trans_table(struct aa_ext *e, struct aa_profile *profile)
|
||||
if (!unpack_nameX(e, AA_STRUCTEND, NULL))
|
||||
goto fail;
|
||||
}
|
||||
- return 1;
|
||||
+ return true;
|
||||
|
||||
fail:
|
||||
aa_free_domain_entries(&profile->file.trans);
|
||||
e->pos = pos;
|
||||
- return 0;
|
||||
+ return false;
|
||||
}
|
||||
|
||||
static bool unpack_rlimits(struct aa_ext *e, struct aa_profile *profile)
|
||||
@@ -472,11 +472,11 @@ static bool unpack_rlimits(struct aa_ext *e, struct aa_profile *profile)
|
||||
if (!unpack_nameX(e, AA_STRUCTEND, NULL))
|
||||
goto fail;
|
||||
}
|
||||
- return 1;
|
||||
+ return true;
|
||||
|
||||
fail:
|
||||
e->pos = pos;
|
||||
- return 0;
|
||||
+ return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -726,8 +726,8 @@ static bool verify_xindex(int xindex, int table_size)
|
||||
xtype = xindex & AA_X_TYPE_MASK;
|
||||
index = xindex & AA_X_INDEX_MASK;
|
||||
if (xtype == AA_X_TABLE && index >= table_size)
|
||||
- return 0;
|
||||
- return 1;
|
||||
+ return false;
|
||||
+ return true;
|
||||
}
|
||||
|
||||
/* verify dfa xindexes are in range of transition tables */
|
||||
@@ -736,11 +736,11 @@ static bool verify_dfa_xindex(struct aa_dfa *dfa, int table_size)
|
||||
int i;
|
||||
for (i = 0; i < dfa->tables[YYTD_ID_ACCEPT]->td_lolen; i++) {
|
||||
if (!verify_xindex(dfa_user_xindex(dfa, i), table_size))
|
||||
- return 0;
|
||||
+ return false;
|
||||
if (!verify_xindex(dfa_other_xindex(dfa, i), table_size))
|
||||
- return 0;
|
||||
+ return false;
|
||||
}
|
||||
- return 1;
|
||||
+ return true;
|
||||
}
|
||||
|
||||
/**
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,118 +0,0 @@
|
||||
From 24b6ac149a57c2d3d5a9920e64d914e8ff00d346 Mon Sep 17 00:00:00 2001
|
||||
From: Vegard Nossum <vegard.nossum@oracle.com>
|
||||
Date: Thu, 7 Jul 2016 13:41:11 -0700
|
||||
Subject: [PATCH 01/27] apparmor: fix oops, validate buffer size in
|
||||
apparmor_setprocattr()
|
||||
|
||||
When proc_pid_attr_write() was changed to use memdup_user apparmor's
|
||||
(interface violating) assumption that the setprocattr buffer was always
|
||||
a single page was violated.
|
||||
|
||||
The size test is not strictly speaking needed as proc_pid_attr_write()
|
||||
will reject anything larger, but for the sake of robustness we can keep
|
||||
it in.
|
||||
|
||||
SMACK and SELinux look safe to me, but somebody else should probably
|
||||
have a look just in case.
|
||||
|
||||
Based on original patch from Vegard Nossum <vegard.nossum@oracle.com>
|
||||
modified for the case that apparmor provides null termination.
|
||||
|
||||
Fixes: bb646cdb12e75d82258c2f2e7746d5952d3e321a
|
||||
Reported-by: Vegard Nossum <vegard.nossum@oracle.com>
|
||||
Cc: Al Viro <viro@zeniv.linux.org.uk>
|
||||
Cc: John Johansen <john.johansen@canonical.com>
|
||||
Cc: Paul Moore <paul@paul-moore.com>
|
||||
Cc: Stephen Smalley <sds@tycho.nsa.gov>
|
||||
Cc: Eric Paris <eparis@parisplace.org>
|
||||
Cc: Casey Schaufler <casey@schaufler-ca.com>
|
||||
Cc: stable@kernel.org
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
Reviewed-by: Tyler Hicks <tyhicks@canonical.com>
|
||||
Signed-off-by: James Morris <james.l.morris@oracle.com>
|
||||
---
|
||||
security/apparmor/lsm.c | 36 +++++++++++++++++++-----------------
|
||||
1 file changed, 19 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
|
||||
index dec607c..5ee8201 100644
|
||||
--- a/security/apparmor/lsm.c
|
||||
+++ b/security/apparmor/lsm.c
|
||||
@@ -523,34 +523,34 @@ static int apparmor_setprocattr(struct task_struct *task, char *name,
|
||||
{
|
||||
struct common_audit_data sa;
|
||||
struct apparmor_audit_data aad = {0,};
|
||||
- char *command, *args = value;
|
||||
+ char *command, *largs = NULL, *args = value;
|
||||
size_t arg_size;
|
||||
int error;
|
||||
|
||||
if (size == 0)
|
||||
return -EINVAL;
|
||||
- /* args points to a PAGE_SIZE buffer, AppArmor requires that
|
||||
- * the buffer must be null terminated or have size <= PAGE_SIZE -1
|
||||
- * so that AppArmor can null terminate them
|
||||
- */
|
||||
- if (args[size - 1] != '\0') {
|
||||
- if (size == PAGE_SIZE)
|
||||
- return -EINVAL;
|
||||
- args[size] = '\0';
|
||||
- }
|
||||
-
|
||||
/* task can only write its own attributes */
|
||||
if (current != task)
|
||||
return -EACCES;
|
||||
|
||||
- args = value;
|
||||
+ /* AppArmor requires that the buffer must be null terminated atm */
|
||||
+ if (args[size - 1] != '\0') {
|
||||
+ /* null terminate */
|
||||
+ largs = args = kmalloc(size + 1, GFP_KERNEL);
|
||||
+ if (!args)
|
||||
+ return -ENOMEM;
|
||||
+ memcpy(args, value, size);
|
||||
+ args[size] = '\0';
|
||||
+ }
|
||||
+
|
||||
+ error = -EINVAL;
|
||||
args = strim(args);
|
||||
command = strsep(&args, " ");
|
||||
if (!args)
|
||||
- return -EINVAL;
|
||||
+ goto out;
|
||||
args = skip_spaces(args);
|
||||
if (!*args)
|
||||
- return -EINVAL;
|
||||
+ goto out;
|
||||
|
||||
arg_size = size - (args - (char *) value);
|
||||
if (strcmp(name, "current") == 0) {
|
||||
@@ -576,10 +576,12 @@ static int apparmor_setprocattr(struct task_struct *task, char *name,
|
||||
goto fail;
|
||||
} else
|
||||
/* only support the "current" and "exec" process attributes */
|
||||
- return -EINVAL;
|
||||
+ goto fail;
|
||||
|
||||
if (!error)
|
||||
error = size;
|
||||
+out:
|
||||
+ kfree(largs);
|
||||
return error;
|
||||
|
||||
fail:
|
||||
@@ -588,9 +590,9 @@ fail:
|
||||
aad.profile = aa_current_profile();
|
||||
aad.op = OP_SETPROCATTR;
|
||||
aad.info = name;
|
||||
- aad.error = -EINVAL;
|
||||
+ aad.error = error = -EINVAL;
|
||||
aa_audit_msg(AUDIT_APPARMOR_DENIED, &sa, NULL);
|
||||
- return -EINVAL;
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
static int apparmor_task_setrlimit(struct task_struct *task,
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,33 +0,0 @@
|
||||
From 444bc4f95ec283cd0fb9777f4890bd9bc307809d Mon Sep 17 00:00:00 2001
|
||||
From: John Johansen <john.johansen@canonical.com>
|
||||
Date: Mon, 11 Apr 2016 16:55:10 -0700
|
||||
Subject: [PATCH 02/27] apparmor: fix refcount bug in profile replacement
|
||||
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
Acked-by: Seth Arnold <seth.arnold@canonical.com>
|
||||
---
|
||||
security/apparmor/policy.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
|
||||
index 705c287..222052f 100644
|
||||
--- a/security/apparmor/policy.c
|
||||
+++ b/security/apparmor/policy.c
|
||||
@@ -1189,12 +1189,12 @@ ssize_t aa_replace_profiles(void *udata, size_t size, bool noreplace)
|
||||
aa_get_profile(newest);
|
||||
aa_put_profile(parent);
|
||||
rcu_assign_pointer(ent->new->parent, newest);
|
||||
- } else
|
||||
- aa_put_profile(newest);
|
||||
+ }
|
||||
/* aafs interface uses replacedby */
|
||||
rcu_assign_pointer(ent->new->replacedby->profile,
|
||||
aa_get_profile(ent->new));
|
||||
__list_add_profile(&parent->base.profiles, ent->new);
|
||||
+ aa_put_profile(newest);
|
||||
} else {
|
||||
/* aafs interface uses replacedby */
|
||||
rcu_assign_pointer(ent->new->replacedby->profile,
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,38 +0,0 @@
|
||||
From 1224a06778b89dcbf0ca85bd961c2fcdd8765a69 Mon Sep 17 00:00:00 2001
|
||||
From: John Johansen <john.johansen@canonical.com>
|
||||
Date: Mon, 11 Apr 2016 16:57:19 -0700
|
||||
Subject: [PATCH 03/27] apparmor: fix replacement bug that adds new child to
|
||||
old parent
|
||||
|
||||
When set atomic replacement is used and the parent is updated before the
|
||||
child, and the child did not exist in the old parent so there is no
|
||||
direct replacement then the new child is incorrectly added to the old
|
||||
parent. This results in the new parent not having the child(ren) that
|
||||
it should and the old parent when being destroyed asserting the
|
||||
following error.
|
||||
|
||||
AppArmor: policy_destroy: internal error, policy '<profile/name>' still
|
||||
contains profiles
|
||||
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
Acked-by: Seth Arnold <seth.arnold@canonical.com>
|
||||
---
|
||||
security/apparmor/policy.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
|
||||
index 222052f..c92a9f6 100644
|
||||
--- a/security/apparmor/policy.c
|
||||
+++ b/security/apparmor/policy.c
|
||||
@@ -1193,7 +1193,7 @@ ssize_t aa_replace_profiles(void *udata, size_t size, bool noreplace)
|
||||
/* aafs interface uses replacedby */
|
||||
rcu_assign_pointer(ent->new->replacedby->profile,
|
||||
aa_get_profile(ent->new));
|
||||
- __list_add_profile(&parent->base.profiles, ent->new);
|
||||
+ __list_add_profile(&newest->base.profiles, ent->new);
|
||||
aa_put_profile(newest);
|
||||
} else {
|
||||
/* aafs interface uses replacedby */
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,87 +0,0 @@
|
||||
From 15d921647676fdc2c3ee1cf9aa8f578b1012ecff Mon Sep 17 00:00:00 2001
|
||||
From: John Johansen <john.johansen@canonical.com>
|
||||
Date: Sun, 8 Jun 2014 11:20:54 -0700
|
||||
Subject: [PATCH 04/27] apparmor: fix uninitialized lsm_audit member
|
||||
|
||||
BugLink: http://bugs.launchpad.net/bugs/1268727
|
||||
|
||||
The task field in the lsm_audit struct needs to be initialized if
|
||||
a change_hat fails, otherwise the following oops will occur
|
||||
|
||||
BUG: unable to handle kernel paging request at 0000002fbead7d08
|
||||
IP: [<ffffffff8171153e>] _raw_spin_lock+0xe/0x50
|
||||
PGD 1e3f35067 PUD 0
|
||||
Oops: 0002 [#1] SMP
|
||||
Modules linked in: pppox crc_ccitt p8023 p8022 psnap llc ax25 btrfs raid6_pq xor xfs libcrc32c dm_multipath scsi_dh kvm_amd dcdbas kvm microcode amd64_edac_mod joydev edac_core psmouse edac_mce_amd serio_raw k10temp sp5100_tco i2c_piix4 ipmi_si ipmi_msghandler acpi_power_meter mac_hid lp parport hid_generic usbhid hid pata_acpi mpt2sas ahci raid_class pata_atiixp bnx2 libahci scsi_transport_sas [last unloaded: tipc]
|
||||
CPU: 2 PID: 699 Comm: changehat_twice Tainted: GF O 3.13.0-7-generic #25-Ubuntu
|
||||
Hardware name: Dell Inc. PowerEdge R415/08WNM9, BIOS 1.8.6 12/06/2011
|
||||
task: ffff8802135c6000 ti: ffff880212986000 task.ti: ffff880212986000
|
||||
RIP: 0010:[<ffffffff8171153e>] [<ffffffff8171153e>] _raw_spin_lock+0xe/0x50
|
||||
RSP: 0018:ffff880212987b68 EFLAGS: 00010006
|
||||
RAX: 0000000000020000 RBX: 0000002fbead7500 RCX: 0000000000000000
|
||||
RDX: 0000000000000292 RSI: ffff880212987ba8 RDI: 0000002fbead7d08
|
||||
RBP: ffff880212987b68 R08: 0000000000000246 R09: ffff880216e572a0
|
||||
R10: ffffffff815fd677 R11: ffffea0008469580 R12: ffffffff8130966f
|
||||
R13: ffff880212987ba8 R14: 0000002fbead7d08 R15: ffff8800d8c6b830
|
||||
FS: 00002b5e6c84e7c0(0000) GS:ffff880216e40000(0000) knlGS:0000000055731700
|
||||
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
|
||||
CR2: 0000002fbead7d08 CR3: 000000021270f000 CR4: 00000000000006e0
|
||||
Stack:
|
||||
ffff880212987b98 ffffffff81075f17 ffffffff8130966f 0000000000000009
|
||||
0000000000000000 0000000000000000 ffff880212987bd0 ffffffff81075f7c
|
||||
0000000000000292 ffff880212987c08 ffff8800d8c6b800 0000000000000026
|
||||
Call Trace:
|
||||
[<ffffffff81075f17>] __lock_task_sighand+0x47/0x80
|
||||
[<ffffffff8130966f>] ? apparmor_cred_prepare+0x2f/0x50
|
||||
[<ffffffff81075f7c>] do_send_sig_info+0x2c/0x80
|
||||
[<ffffffff81075fee>] send_sig_info+0x1e/0x30
|
||||
[<ffffffff8130242d>] aa_audit+0x13d/0x190
|
||||
[<ffffffff8130c1dc>] aa_audit_file+0xbc/0x130
|
||||
[<ffffffff8130966f>] ? apparmor_cred_prepare+0x2f/0x50
|
||||
[<ffffffff81304cc2>] aa_change_hat+0x202/0x530
|
||||
[<ffffffff81308fc6>] aa_setprocattr_changehat+0x116/0x1d0
|
||||
[<ffffffff8130a11d>] apparmor_setprocattr+0x25d/0x300
|
||||
[<ffffffff812cee56>] security_setprocattr+0x16/0x20
|
||||
[<ffffffff8121fc87>] proc_pid_attr_write+0x107/0x130
|
||||
[<ffffffff811b7604>] vfs_write+0xb4/0x1f0
|
||||
[<ffffffff811b8039>] SyS_write+0x49/0xa0
|
||||
[<ffffffff8171a1bf>] tracesys+0xe1/0xe6
|
||||
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
Acked-by: Seth Arnold <seth.arnold@canonical.com>
|
||||
---
|
||||
security/apparmor/audit.c | 3 ++-
|
||||
security/apparmor/file.c | 3 ++-
|
||||
2 files changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/security/apparmor/audit.c b/security/apparmor/audit.c
|
||||
index 89c7865..3a7f1da 100644
|
||||
--- a/security/apparmor/audit.c
|
||||
+++ b/security/apparmor/audit.c
|
||||
@@ -200,7 +200,8 @@ int aa_audit(int type, struct aa_profile *profile, gfp_t gfp,
|
||||
|
||||
if (sa->aad->type == AUDIT_APPARMOR_KILL)
|
||||
(void)send_sig_info(SIGKILL, NULL,
|
||||
- sa->u.tsk ? sa->u.tsk : current);
|
||||
+ sa->type == LSM_AUDIT_DATA_TASK && sa->u.tsk ?
|
||||
+ sa->u.tsk : current);
|
||||
|
||||
if (sa->aad->type == AUDIT_APPARMOR_ALLOWED)
|
||||
return complain_error(sa->aad->error);
|
||||
diff --git a/security/apparmor/file.c b/security/apparmor/file.c
|
||||
index 913f377..43d6ae7 100644
|
||||
--- a/security/apparmor/file.c
|
||||
+++ b/security/apparmor/file.c
|
||||
@@ -110,7 +110,8 @@ int aa_audit_file(struct aa_profile *profile, struct file_perms *perms,
|
||||
int type = AUDIT_APPARMOR_AUTO;
|
||||
struct common_audit_data sa;
|
||||
struct apparmor_audit_data aad = {0,};
|
||||
- sa.type = LSM_AUDIT_DATA_NONE;
|
||||
+ sa.type = LSM_AUDIT_DATA_TASK;
|
||||
+ sa.u.tsk = NULL;
|
||||
sa.aad = &aad;
|
||||
aad.op = op,
|
||||
aad.fs.request = request;
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,32 +0,0 @@
|
||||
From c1216728b7d644443eef31e4bd9d01b4a0a51d61 Mon Sep 17 00:00:00 2001
|
||||
From: John Johansen <john.johansen@canonical.com>
|
||||
Date: Fri, 25 Jul 2014 04:02:03 -0700
|
||||
Subject: [PATCH 05/27] apparmor: exec should not be returning ENOENT when it
|
||||
denies
|
||||
|
||||
The current behavior is confusing as it causes exec failures to report
|
||||
the executable is missing instead of identifying that apparmor
|
||||
caused the failure.
|
||||
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
Acked-by: Seth Arnold <seth.arnold@canonical.com>
|
||||
---
|
||||
security/apparmor/domain.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
|
||||
index dc0027b..67a7418 100644
|
||||
--- a/security/apparmor/domain.c
|
||||
+++ b/security/apparmor/domain.c
|
||||
@@ -433,7 +433,7 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
|
||||
new_profile = aa_get_newest_profile(ns->unconfined);
|
||||
info = "ux fallback";
|
||||
} else {
|
||||
- error = -ENOENT;
|
||||
+ error = -EACCES;
|
||||
info = "profile not found";
|
||||
/* remove MAY_EXEC to audit as failure */
|
||||
perms.allow &= ~MAY_EXEC;
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,28 +0,0 @@
|
||||
From 2d3389de6c8ab6b3ad2cef4ea460c8fce2a226b9 Mon Sep 17 00:00:00 2001
|
||||
From: John Johansen <john.johansen@canonical.com>
|
||||
Date: Fri, 25 Jul 2014 04:01:56 -0700
|
||||
Subject: [PATCH 06/27] apparmor: fix update the mtime of the profile file on
|
||||
replacement
|
||||
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
Acked-by: Seth Arnold <seth.arnold@canonical.com>
|
||||
---
|
||||
security/apparmor/apparmorfs.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
|
||||
index ad4fa49..45a6199 100644
|
||||
--- a/security/apparmor/apparmorfs.c
|
||||
+++ b/security/apparmor/apparmorfs.c
|
||||
@@ -379,6 +379,8 @@ void __aa_fs_profile_migrate_dents(struct aa_profile *old,
|
||||
|
||||
for (i = 0; i < AAFS_PROF_SIZEOF; i++) {
|
||||
new->dents[i] = old->dents[i];
|
||||
+ if (new->dents[i])
|
||||
+ new->dents[i]->d_inode->i_mtime = CURRENT_TIME;
|
||||
old->dents[i] = NULL;
|
||||
}
|
||||
}
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,36 +0,0 @@
|
||||
From 9caa96e30a1b2bb191a29af872285c8d0b078c10 Mon Sep 17 00:00:00 2001
|
||||
From: John Johansen <john.johansen@canonical.com>
|
||||
Date: Fri, 25 Jul 2014 04:02:08 -0700
|
||||
Subject: [PATCH 07/27] apparmor: fix disconnected bind mnts reconnection
|
||||
|
||||
Bind mounts can fail to be properly reconnected when PATH_CONNECT is
|
||||
specified. Ensure that when PATH_CONNECT is specified the path has
|
||||
a root.
|
||||
|
||||
BugLink: http://bugs.launchpad.net/bugs/1319984
|
||||
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
Acked-by: Seth Arnold <seth.arnold@canonical.com>
|
||||
---
|
||||
security/apparmor/path.c | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/security/apparmor/path.c b/security/apparmor/path.c
|
||||
index 71e0e3a..bb2f2c6 100644
|
||||
--- a/security/apparmor/path.c
|
||||
+++ b/security/apparmor/path.c
|
||||
@@ -141,7 +141,10 @@ static int d_namespace_path(struct path *path, char *buf, int buflen,
|
||||
error = -EACCES;
|
||||
if (*res == '/')
|
||||
*name = res + 1;
|
||||
- }
|
||||
+ } else if (*res != '/')
|
||||
+ /* CONNECT_PATH with missing root */
|
||||
+ error = prepend(name, *name - buf, "/", 1);
|
||||
+
|
||||
}
|
||||
|
||||
out:
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,114 +0,0 @@
|
||||
From 11702a732e149380e05e2ab8ae1b743ac89f892f Mon Sep 17 00:00:00 2001
|
||||
From: John Johansen <john.johansen@canonical.com>
|
||||
Date: Fri, 25 Jul 2014 04:02:10 -0700
|
||||
Subject: [PATCH 08/27] apparmor: internal paths should be treated as
|
||||
disconnected
|
||||
|
||||
Internal mounts are not mounted anywhere and as such should be treated
|
||||
as disconnected paths.
|
||||
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
Acked-by: Seth Arnold <seth.arnold@canonical.com>
|
||||
---
|
||||
security/apparmor/path.c | 64 +++++++++++++++++++++++++++---------------------
|
||||
1 file changed, 36 insertions(+), 28 deletions(-)
|
||||
|
||||
diff --git a/security/apparmor/path.c b/security/apparmor/path.c
|
||||
index bb2f2c6..596f799 100644
|
||||
--- a/security/apparmor/path.c
|
||||
+++ b/security/apparmor/path.c
|
||||
@@ -25,7 +25,6 @@
|
||||
#include "include/path.h"
|
||||
#include "include/policy.h"
|
||||
|
||||
-
|
||||
/* modified from dcache.c */
|
||||
static int prepend(char **buffer, int buflen, const char *str, int namelen)
|
||||
{
|
||||
@@ -39,6 +38,38 @@ static int prepend(char **buffer, int buflen, const char *str, int namelen)
|
||||
|
||||
#define CHROOT_NSCONNECT (PATH_CHROOT_REL | PATH_CHROOT_NSCONNECT)
|
||||
|
||||
+/* If the path is not connected to the expected root,
|
||||
+ * check if it is a sysctl and handle specially else remove any
|
||||
+ * leading / that __d_path may have returned.
|
||||
+ * Unless
|
||||
+ * specifically directed to connect the path,
|
||||
+ * OR
|
||||
+ * if in a chroot and doing chroot relative paths and the path
|
||||
+ * resolves to the namespace root (would be connected outside
|
||||
+ * of chroot) and specifically directed to connect paths to
|
||||
+ * namespace root.
|
||||
+ */
|
||||
+static int disconnect(const struct path *path, char *buf, char **name,
|
||||
+ int flags)
|
||||
+{
|
||||
+ int error = 0;
|
||||
+
|
||||
+ if (!(flags & PATH_CONNECT_PATH) &&
|
||||
+ !(((flags & CHROOT_NSCONNECT) == CHROOT_NSCONNECT) &&
|
||||
+ our_mnt(path->mnt))) {
|
||||
+ /* disconnected path, don't return pathname starting
|
||||
+ * with '/'
|
||||
+ */
|
||||
+ error = -EACCES;
|
||||
+ if (**name == '/')
|
||||
+ *name = *name + 1;
|
||||
+ } else if (**name != '/')
|
||||
+ /* CONNECT_PATH with missing root */
|
||||
+ error = prepend(name, *name - buf, "/", 1);
|
||||
+
|
||||
+ return error;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* d_namespace_path - lookup a name associated with a given path
|
||||
* @path: path to lookup (NOT NULL)
|
||||
@@ -74,7 +105,8 @@ static int d_namespace_path(struct path *path, char *buf, int buflen,
|
||||
* control instead of hard coded /proc
|
||||
*/
|
||||
return prepend(name, *name - buf, "/proc", 5);
|
||||
- }
|
||||
+ } else
|
||||
+ return disconnect(path, buf, name, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -120,32 +152,8 @@ static int d_namespace_path(struct path *path, char *buf, int buflen,
|
||||
goto out;
|
||||
}
|
||||
|
||||
- /* If the path is not connected to the expected root,
|
||||
- * check if it is a sysctl and handle specially else remove any
|
||||
- * leading / that __d_path may have returned.
|
||||
- * Unless
|
||||
- * specifically directed to connect the path,
|
||||
- * OR
|
||||
- * if in a chroot and doing chroot relative paths and the path
|
||||
- * resolves to the namespace root (would be connected outside
|
||||
- * of chroot) and specifically directed to connect paths to
|
||||
- * namespace root.
|
||||
- */
|
||||
- if (!connected) {
|
||||
- if (!(flags & PATH_CONNECT_PATH) &&
|
||||
- !(((flags & CHROOT_NSCONNECT) == CHROOT_NSCONNECT) &&
|
||||
- our_mnt(path->mnt))) {
|
||||
- /* disconnected path, don't return pathname starting
|
||||
- * with '/'
|
||||
- */
|
||||
- error = -EACCES;
|
||||
- if (*res == '/')
|
||||
- *name = res + 1;
|
||||
- } else if (*res != '/')
|
||||
- /* CONNECT_PATH with missing root */
|
||||
- error = prepend(name, *name - buf, "/", 1);
|
||||
-
|
||||
- }
|
||||
+ if (!connected)
|
||||
+ error = disconnect(path, buf, name, flags);
|
||||
|
||||
out:
|
||||
return error;
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,29 +0,0 @@
|
||||
From c70811d9e6234c96d0ef405cd8ad78b70efb8637 Mon Sep 17 00:00:00 2001
|
||||
From: John Johansen <john.johansen@canonical.com>
|
||||
Date: Sat, 16 Apr 2016 13:59:02 -0700
|
||||
Subject: [PATCH 09/27] apparmor: fix put() parent ref after updating the
|
||||
active ref
|
||||
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
Acked-by: Seth Arnold <seth.arnold@canonical.com>
|
||||
---
|
||||
security/apparmor/policy.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
|
||||
index c92a9f6..455c9f8 100644
|
||||
--- a/security/apparmor/policy.c
|
||||
+++ b/security/apparmor/policy.c
|
||||
@@ -1187,8 +1187,8 @@ ssize_t aa_replace_profiles(void *udata, size_t size, bool noreplace)
|
||||
/* parent replaced in this atomic set? */
|
||||
if (newest != parent) {
|
||||
aa_get_profile(newest);
|
||||
- aa_put_profile(parent);
|
||||
rcu_assign_pointer(ent->new->parent, newest);
|
||||
+ aa_put_profile(parent);
|
||||
}
|
||||
/* aafs interface uses replacedby */
|
||||
rcu_assign_pointer(ent->new->replacedby->profile,
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,87 +0,0 @@
|
||||
From f671b902943f83f0fbc8c8b7bf8bbfb817d124f1 Mon Sep 17 00:00:00 2001
|
||||
From: John Johansen <john.johansen@canonical.com>
|
||||
Date: Sat, 16 Apr 2016 14:16:50 -0700
|
||||
Subject: [PATCH 10/27] apparmor: fix log failures for all profiles in a set
|
||||
|
||||
currently only the profile that is causing the failure is logged. This
|
||||
makes it more confusing than necessary about which profiles loaded
|
||||
and which didn't. So make sure to log success and failure messages for
|
||||
all profiles in the set being loaded.
|
||||
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
Acked-by: Seth Arnold <seth.arnold@canonical.com>
|
||||
---
|
||||
security/apparmor/policy.c | 29 +++++++++++++++++++----------
|
||||
1 file changed, 19 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
|
||||
index 455c9f8..db31bc5 100644
|
||||
--- a/security/apparmor/policy.c
|
||||
+++ b/security/apparmor/policy.c
|
||||
@@ -1067,7 +1067,7 @@ static int __lookup_replace(struct aa_namespace *ns, const char *hname,
|
||||
*/
|
||||
ssize_t aa_replace_profiles(void *udata, size_t size, bool noreplace)
|
||||
{
|
||||
- const char *ns_name, *name = NULL, *info = NULL;
|
||||
+ const char *ns_name, *info = NULL;
|
||||
struct aa_namespace *ns = NULL;
|
||||
struct aa_load_ent *ent, *tmp;
|
||||
int op = OP_PROF_REPL;
|
||||
@@ -1082,18 +1082,15 @@ ssize_t aa_replace_profiles(void *udata, size_t size, bool noreplace)
|
||||
/* released below */
|
||||
ns = aa_prepare_namespace(ns_name);
|
||||
if (!ns) {
|
||||
- info = "failed to prepare namespace";
|
||||
- error = -ENOMEM;
|
||||
- name = ns_name;
|
||||
- goto fail;
|
||||
+ error = audit_policy(op, GFP_KERNEL, ns_name,
|
||||
+ "failed to prepare namespace", -ENOMEM);
|
||||
+ goto free;
|
||||
}
|
||||
|
||||
mutex_lock(&ns->lock);
|
||||
/* setup parent and ns info */
|
||||
list_for_each_entry(ent, &lh, list) {
|
||||
struct aa_policy *policy;
|
||||
-
|
||||
- name = ent->new->base.hname;
|
||||
error = __lookup_replace(ns, ent->new->base.hname, noreplace,
|
||||
&ent->old, &info);
|
||||
if (error)
|
||||
@@ -1121,7 +1118,6 @@ ssize_t aa_replace_profiles(void *udata, size_t size, bool noreplace)
|
||||
if (!p) {
|
||||
error = -ENOENT;
|
||||
info = "parent does not exist";
|
||||
- name = ent->new->base.hname;
|
||||
goto fail_lock;
|
||||
}
|
||||
rcu_assign_pointer(ent->new->parent, aa_get_profile(p));
|
||||
@@ -1214,9 +1210,22 @@ out:
|
||||
|
||||
fail_lock:
|
||||
mutex_unlock(&ns->lock);
|
||||
-fail:
|
||||
- error = audit_policy(op, GFP_KERNEL, name, info, error);
|
||||
|
||||
+ /* audit cause of failure */
|
||||
+ op = (!ent->old) ? OP_PROF_LOAD : OP_PROF_REPL;
|
||||
+ audit_policy(op, GFP_KERNEL, ent->new->base.hname, info, error);
|
||||
+ /* audit status that rest of profiles in the atomic set failed too */
|
||||
+ info = "valid profile in failed atomic policy load";
|
||||
+ list_for_each_entry(tmp, &lh, list) {
|
||||
+ if (tmp == ent) {
|
||||
+ info = "unchecked profile in failed atomic policy load";
|
||||
+ /* skip entry that caused failure */
|
||||
+ continue;
|
||||
+ }
|
||||
+ op = (!ent->old) ? OP_PROF_LOAD : OP_PROF_REPL;
|
||||
+ audit_policy(op, GFP_KERNEL, tmp->new->base.hname, info, error);
|
||||
+ }
|
||||
+free:
|
||||
list_for_each_entry_safe(ent, tmp, &lh, list) {
|
||||
list_del_init(&ent->list);
|
||||
aa_load_ent_free(ent);
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,33 +0,0 @@
|
||||
From bc3c7d342bf53afdfdf46bc92dac5c624c89fb91 Mon Sep 17 00:00:00 2001
|
||||
From: John Johansen <john.johansen@canonical.com>
|
||||
Date: Sat, 16 Apr 2016 14:19:38 -0700
|
||||
Subject: [PATCH 11/27] apparmor: fix audit full profile hname on successful
|
||||
load
|
||||
|
||||
Currently logging of a successful profile load only logs the basename
|
||||
of the profile. This can result in confusion when a child profile has
|
||||
the same name as the another profile in the set. Logging the hname
|
||||
will ensure there is no confusion.
|
||||
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
Acked-by: Seth Arnold <seth.arnold@canonical.com>
|
||||
---
|
||||
security/apparmor/policy.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
|
||||
index db31bc5..ca402d0 100644
|
||||
--- a/security/apparmor/policy.c
|
||||
+++ b/security/apparmor/policy.c
|
||||
@@ -1159,7 +1159,7 @@ ssize_t aa_replace_profiles(void *udata, size_t size, bool noreplace)
|
||||
list_del_init(&ent->list);
|
||||
op = (!ent->old && !ent->rename) ? OP_PROF_LOAD : OP_PROF_REPL;
|
||||
|
||||
- audit_policy(op, GFP_ATOMIC, ent->new->base.name, NULL, error);
|
||||
+ audit_policy(op, GFP_ATOMIC, ent->new->base.hname, NULL, error);
|
||||
|
||||
if (ent->old) {
|
||||
__replace_profile(ent->old, ent->new, 1);
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,112 +0,0 @@
|
||||
From 848da0479e5b9da3dc2ae4c64e0cca77a0abf02a Mon Sep 17 00:00:00 2001
|
||||
From: John Johansen <john.johansen@canonical.com>
|
||||
Date: Wed, 20 Apr 2016 14:18:18 -0700
|
||||
Subject: [PATCH 12/27] apparmor: ensure the target profile name is always
|
||||
audited
|
||||
|
||||
The target profile name was not being correctly audited in a few
|
||||
cases because the target variable was not being set and gotos
|
||||
passed the code to set it at apply:
|
||||
|
||||
Since it is always based on new_profile just drop the target var
|
||||
and conditionally report based on new_profile.
|
||||
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
Acked-by: Seth Arnold <seth.arnold@canonical.com>
|
||||
---
|
||||
security/apparmor/domain.c | 20 +++++++++-----------
|
||||
1 file changed, 9 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
|
||||
index 67a7418..fc3036b 100644
|
||||
--- a/security/apparmor/domain.c
|
||||
+++ b/security/apparmor/domain.c
|
||||
@@ -346,7 +346,7 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
|
||||
file_inode(bprm->file)->i_uid,
|
||||
file_inode(bprm->file)->i_mode
|
||||
};
|
||||
- const char *name = NULL, *target = NULL, *info = NULL;
|
||||
+ const char *name = NULL, *info = NULL;
|
||||
int error = 0;
|
||||
|
||||
if (bprm->cred_prepared)
|
||||
@@ -399,6 +399,7 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
|
||||
if (cxt->onexec) {
|
||||
struct file_perms cp;
|
||||
info = "change_profile onexec";
|
||||
+ new_profile = aa_get_newest_profile(cxt->onexec);
|
||||
if (!(perms.allow & AA_MAY_ONEXEC))
|
||||
goto audit;
|
||||
|
||||
@@ -413,7 +414,6 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
|
||||
|
||||
if (!(cp.allow & AA_MAY_ONEXEC))
|
||||
goto audit;
|
||||
- new_profile = aa_get_newest_profile(cxt->onexec);
|
||||
goto apply;
|
||||
}
|
||||
|
||||
@@ -445,10 +445,8 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
|
||||
if (!new_profile) {
|
||||
error = -ENOMEM;
|
||||
info = "could not create null profile";
|
||||
- } else {
|
||||
+ } else
|
||||
error = -EACCES;
|
||||
- target = new_profile->base.hname;
|
||||
- }
|
||||
perms.xindex |= AA_X_UNSAFE;
|
||||
} else
|
||||
/* fail exec */
|
||||
@@ -459,7 +457,6 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
|
||||
* fail the exec.
|
||||
*/
|
||||
if (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS) {
|
||||
- aa_put_profile(new_profile);
|
||||
error = -EPERM;
|
||||
goto cleanup;
|
||||
}
|
||||
@@ -474,10 +471,8 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
|
||||
|
||||
if (bprm->unsafe & (LSM_UNSAFE_PTRACE | LSM_UNSAFE_PTRACE_CAP)) {
|
||||
error = may_change_ptraced_domain(new_profile);
|
||||
- if (error) {
|
||||
- aa_put_profile(new_profile);
|
||||
+ if (error)
|
||||
goto audit;
|
||||
- }
|
||||
}
|
||||
|
||||
/* Determine if secure exec is needed.
|
||||
@@ -498,7 +493,6 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
|
||||
bprm->unsafe |= AA_SECURE_X_NEEDED;
|
||||
}
|
||||
apply:
|
||||
- target = new_profile->base.hname;
|
||||
/* when transitioning profiles clear unsafe personality bits */
|
||||
bprm->per_clear |= PER_CLEAR_ON_SETID;
|
||||
|
||||
@@ -506,15 +500,19 @@ x_clear:
|
||||
aa_put_profile(cxt->profile);
|
||||
/* transfer new profile reference will be released when cxt is freed */
|
||||
cxt->profile = new_profile;
|
||||
+ new_profile = NULL;
|
||||
|
||||
/* clear out all temporary/transitional state from the context */
|
||||
aa_clear_task_cxt_trans(cxt);
|
||||
|
||||
audit:
|
||||
error = aa_audit_file(profile, &perms, GFP_KERNEL, OP_EXEC, MAY_EXEC,
|
||||
- name, target, cond.uid, info, error);
|
||||
+ name,
|
||||
+ new_profile ? new_profile->base.hname : NULL,
|
||||
+ cond.uid, info, error);
|
||||
|
||||
cleanup:
|
||||
+ aa_put_profile(new_profile);
|
||||
aa_put_profile(profile);
|
||||
kfree(buffer);
|
||||
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,27 +0,0 @@
|
||||
From 706473f3ead5cdffe5ad159adfbc090e0fda81d6 Mon Sep 17 00:00:00 2001
|
||||
From: John Johansen <john.johansen@canonical.com>
|
||||
Date: Thu, 17 Mar 2016 12:02:54 -0700
|
||||
Subject: [PATCH 13/27] apparmor: check that xindex is in trans_table bounds
|
||||
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
Acked-by: Seth Arnold <seth.arnold@canonical.com>
|
||||
---
|
||||
security/apparmor/policy_unpack.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
|
||||
index a689f10..c841b12 100644
|
||||
--- a/security/apparmor/policy_unpack.c
|
||||
+++ b/security/apparmor/policy_unpack.c
|
||||
@@ -676,7 +676,7 @@ static bool verify_xindex(int xindex, int table_size)
|
||||
int index, xtype;
|
||||
xtype = xindex & AA_X_TYPE_MASK;
|
||||
index = xindex & AA_X_INDEX_MASK;
|
||||
- if (xtype == AA_X_TABLE && index > table_size)
|
||||
+ if (xtype == AA_X_TABLE && index >= table_size)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,27 +0,0 @@
|
||||
From 05a64c434466029b298ee1e78a988cd6a7f80c0e Mon Sep 17 00:00:00 2001
|
||||
From: John Johansen <john.johansen@canonical.com>
|
||||
Date: Wed, 18 Nov 2015 11:41:05 -0800
|
||||
Subject: [PATCH 14/27] apparmor: fix ref count leak when profile sha1 hash is
|
||||
read
|
||||
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
Acked-by: Seth Arnold <seth.arnold@canonical.com>
|
||||
---
|
||||
security/apparmor/apparmorfs.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
|
||||
index 45a6199..0d8dd71 100644
|
||||
--- a/security/apparmor/apparmorfs.c
|
||||
+++ b/security/apparmor/apparmorfs.c
|
||||
@@ -331,6 +331,7 @@ static int aa_fs_seq_hash_show(struct seq_file *seq, void *v)
|
||||
seq_printf(seq, "%.2x", profile->hash[i]);
|
||||
seq_puts(seq, "\n");
|
||||
}
|
||||
+ aa_put_profile(profile);
|
||||
|
||||
return 0;
|
||||
}
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,37 +0,0 @@
|
||||
From 6b0b8b91f454bd021e27abe0e611a6764e4806c1 Mon Sep 17 00:00:00 2001
|
||||
From: John Johansen <john.johansen@canonical.com>
|
||||
Date: Wed, 16 Dec 2015 18:09:10 -0800
|
||||
Subject: [PATCH 15/27] apparmor: fix refcount race when finding a child
|
||||
profile
|
||||
|
||||
When finding a child profile via an rcu critical section, the profile
|
||||
may be put and scheduled for deletion after the child is found but
|
||||
before its refcount is incremented.
|
||||
|
||||
Protect against this by repeating the lookup if the profiles refcount
|
||||
is 0 and is one its way to deletion.
|
||||
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
Acked-by: Seth Arnold <seth.arnold@canonical.com>
|
||||
---
|
||||
security/apparmor/policy.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
|
||||
index ca402d0..7807125 100644
|
||||
--- a/security/apparmor/policy.c
|
||||
+++ b/security/apparmor/policy.c
|
||||
@@ -766,7 +766,9 @@ struct aa_profile *aa_find_child(struct aa_profile *parent, const char *name)
|
||||
struct aa_profile *profile;
|
||||
|
||||
rcu_read_lock();
|
||||
- profile = aa_get_profile(__find_child(&parent->base.profiles, name));
|
||||
+ do {
|
||||
+ profile = __find_child(&parent->base.profiles, name);
|
||||
+ } while (profile && !aa_get_profile_not0(profile));
|
||||
rcu_read_unlock();
|
||||
|
||||
/* refcount released by caller */
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,59 +0,0 @@
|
||||
From 84acc6aa6976e62756e14d3a00c5634724cbaa59 Mon Sep 17 00:00:00 2001
|
||||
From: Geliang Tang <geliangtang@163.com>
|
||||
Date: Mon, 16 Nov 2015 21:46:33 +0800
|
||||
Subject: [PATCH 16/27] apparmor: use list_next_entry instead of
|
||||
list_entry_next
|
||||
|
||||
list_next_entry has been defined in list.h, so I replace list_entry_next
|
||||
with it.
|
||||
|
||||
Signed-off-by: Geliang Tang <geliangtang@163.com>
|
||||
Acked-by: Serge Hallyn <serge.hallyn@canonical.com>
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
---
|
||||
security/apparmor/apparmorfs.c | 8 +++-----
|
||||
1 file changed, 3 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
|
||||
index 0d8dd71..729e595 100644
|
||||
--- a/security/apparmor/apparmorfs.c
|
||||
+++ b/security/apparmor/apparmorfs.c
|
||||
@@ -553,8 +553,6 @@ fail2:
|
||||
}
|
||||
|
||||
|
||||
-#define list_entry_next(pos, member) \
|
||||
- list_entry(pos->member.next, typeof(*pos), member)
|
||||
#define list_entry_is_head(pos, head, member) (&pos->member == (head))
|
||||
|
||||
/**
|
||||
@@ -585,7 +583,7 @@ static struct aa_namespace *__next_namespace(struct aa_namespace *root,
|
||||
parent = ns->parent;
|
||||
while (ns != root) {
|
||||
mutex_unlock(&ns->lock);
|
||||
- next = list_entry_next(ns, base.list);
|
||||
+ next = list_next_entry(ns, base.list);
|
||||
if (!list_entry_is_head(next, &parent->sub_ns, base.list)) {
|
||||
mutex_lock(&next->lock);
|
||||
return next;
|
||||
@@ -639,7 +637,7 @@ static struct aa_profile *__next_profile(struct aa_profile *p)
|
||||
parent = rcu_dereference_protected(p->parent,
|
||||
mutex_is_locked(&p->ns->lock));
|
||||
while (parent) {
|
||||
- p = list_entry_next(p, base.list);
|
||||
+ p = list_next_entry(p, base.list);
|
||||
if (!list_entry_is_head(p, &parent->base.profiles, base.list))
|
||||
return p;
|
||||
p = parent;
|
||||
@@ -648,7 +646,7 @@ static struct aa_profile *__next_profile(struct aa_profile *p)
|
||||
}
|
||||
|
||||
/* is next another profile in the namespace */
|
||||
- p = list_entry_next(p, base.list);
|
||||
+ p = list_next_entry(p, base.list);
|
||||
if (!list_entry_is_head(p, &ns->base.profiles, base.list))
|
||||
return p;
|
||||
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,50 +0,0 @@
|
||||
From a3896605318b86d8cf288c122e03604e349d5dd7 Mon Sep 17 00:00:00 2001
|
||||
From: Jeff Mahoney <jeffm@suse.com>
|
||||
Date: Fri, 6 Nov 2015 15:17:30 -0500
|
||||
Subject: [PATCH 17/27] apparmor: allow SYS_CAP_RESOURCE to be sufficient to
|
||||
prlimit another task
|
||||
|
||||
While using AppArmor, SYS_CAP_RESOURCE is insufficient to call prlimit
|
||||
on another task. The only other example of a AppArmor mediating access to
|
||||
another, already running, task (ignoring fork+exec) is ptrace.
|
||||
|
||||
The AppArmor model for ptrace is that one of the following must be true:
|
||||
1) The tracer is unconfined
|
||||
2) The tracer is in complain mode
|
||||
3) The tracer and tracee are confined by the same profile
|
||||
4) The tracer is confined but has SYS_CAP_PTRACE
|
||||
|
||||
1), 2, and 3) are already true for setrlimit.
|
||||
|
||||
We can match the ptrace model just by allowing CAP_SYS_RESOURCE.
|
||||
|
||||
We still test the values of the rlimit since it can always be overridden
|
||||
using a value that means unlimited for a particular resource.
|
||||
|
||||
Signed-off-by: Jeff Mahoney <jeffm@suse.com>
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
---
|
||||
security/apparmor/resource.c | 6 ++++--
|
||||
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/security/apparmor/resource.c b/security/apparmor/resource.c
|
||||
index 748bf0c..67a6072 100644
|
||||
--- a/security/apparmor/resource.c
|
||||
+++ b/security/apparmor/resource.c
|
||||
@@ -101,9 +101,11 @@ int aa_task_setrlimit(struct aa_profile *profile, struct task_struct *task,
|
||||
/* TODO: extend resource control to handle other (non current)
|
||||
* profiles. AppArmor rules currently have the implicit assumption
|
||||
* that the task is setting the resource of a task confined with
|
||||
- * the same profile.
|
||||
+ * the same profile or that the task setting the resource of another
|
||||
+ * task has CAP_SYS_RESOURCE.
|
||||
*/
|
||||
- if (profile != task_profile ||
|
||||
+ if ((profile != task_profile &&
|
||||
+ aa_capable(profile, CAP_SYS_RESOURCE, 1)) ||
|
||||
(profile->rlimits.mask & (1 << resource) &&
|
||||
new_rlim->rlim_max > profile->rlimits.limits[resource].rlim_max))
|
||||
error = -EACCES;
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,40 +0,0 @@
|
||||
From 6fdcc3cfecd4d89457036627d59ebe5154d094c5 Mon Sep 17 00:00:00 2001
|
||||
From: John Johansen <john.johansen@canonical.com>
|
||||
Date: Thu, 2 Jun 2016 02:37:02 -0700
|
||||
Subject: [PATCH 18/27] apparmor: add missing id bounds check on dfa
|
||||
verification
|
||||
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
---
|
||||
security/apparmor/include/match.h | 1 +
|
||||
security/apparmor/match.c | 2 ++
|
||||
2 files changed, 3 insertions(+)
|
||||
|
||||
diff --git a/security/apparmor/include/match.h b/security/apparmor/include/match.h
|
||||
index 001c43a..a1c04fe 100644
|
||||
--- a/security/apparmor/include/match.h
|
||||
+++ b/security/apparmor/include/match.h
|
||||
@@ -62,6 +62,7 @@ struct table_set_header {
|
||||
#define YYTD_ID_ACCEPT2 6
|
||||
#define YYTD_ID_NXT 7
|
||||
#define YYTD_ID_TSIZE 8
|
||||
+#define YYTD_ID_MAX 8
|
||||
|
||||
#define YYTD_DATA8 1
|
||||
#define YYTD_DATA16 2
|
||||
diff --git a/security/apparmor/match.c b/security/apparmor/match.c
|
||||
index 727eb42..f9f57c6 100644
|
||||
--- a/security/apparmor/match.c
|
||||
+++ b/security/apparmor/match.c
|
||||
@@ -47,6 +47,8 @@ static struct table_header *unpack_table(char *blob, size_t bsize)
|
||||
* it every time we use td_id as an index
|
||||
*/
|
||||
th.td_id = be16_to_cpu(*(u16 *) (blob)) - 1;
|
||||
+ if (th.td_id > YYTD_ID_MAX)
|
||||
+ goto out;
|
||||
th.td_flags = be16_to_cpu(*(u16 *) (blob + 2));
|
||||
th.td_lolen = be32_to_cpu(*(u32 *) (blob + 8));
|
||||
blob += sizeof(struct table_header);
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,38 +0,0 @@
|
||||
From 95d203cfb59627a86483a279ba82f1aa75297e07 Mon Sep 17 00:00:00 2001
|
||||
From: John Johansen <john.johansen@canonical.com>
|
||||
Date: Wed, 15 Jun 2016 09:57:55 +0300
|
||||
Subject: [PATCH 19/27] apparmor: don't check for vmalloc_addr if kvzalloc()
|
||||
failed
|
||||
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
---
|
||||
security/apparmor/match.c | 10 +++++-----
|
||||
1 file changed, 5 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/security/apparmor/match.c b/security/apparmor/match.c
|
||||
index f9f57c6..32b72eb 100644
|
||||
--- a/security/apparmor/match.c
|
||||
+++ b/security/apparmor/match.c
|
||||
@@ -75,14 +75,14 @@ static struct table_header *unpack_table(char *blob, size_t bsize)
|
||||
u32, be32_to_cpu);
|
||||
else
|
||||
goto fail;
|
||||
+ /* if table was vmalloced make sure the page tables are synced
|
||||
+ * before it is used, as it goes live to all cpus.
|
||||
+ */
|
||||
+ if (is_vmalloc_addr(table))
|
||||
+ vm_unmap_aliases();
|
||||
}
|
||||
|
||||
out:
|
||||
- /* if table was vmalloced make sure the page tables are synced
|
||||
- * before it is used, as it goes live to all cpus.
|
||||
- */
|
||||
- if (is_vmalloc_addr(table))
|
||||
- vm_unmap_aliases();
|
||||
return table;
|
||||
fail:
|
||||
kvfree(table);
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,33 +0,0 @@
|
||||
From e925f976c7a9c85455f67c360671254bac2d9a91 Mon Sep 17 00:00:00 2001
|
||||
From: John Johansen <john.johansen@canonical.com>
|
||||
Date: Wed, 15 Jun 2016 10:00:55 +0300
|
||||
Subject: [PATCH 20/27] apparmor: fix oops in profile_unpack() when policy_db
|
||||
is not present
|
||||
|
||||
BugLink: http://bugs.launchpad.net/bugs/1592547
|
||||
|
||||
If unpack_dfa() returns NULL due to the dfa not being present,
|
||||
profile_unpack() is not checking if the dfa is not present (NULL).
|
||||
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
---
|
||||
security/apparmor/policy_unpack.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
|
||||
index c841b12..dac2121 100644
|
||||
--- a/security/apparmor/policy_unpack.c
|
||||
+++ b/security/apparmor/policy_unpack.c
|
||||
@@ -583,6 +583,9 @@ static struct aa_profile *unpack_profile(struct aa_ext *e)
|
||||
error = PTR_ERR(profile->policy.dfa);
|
||||
profile->policy.dfa = NULL;
|
||||
goto fail;
|
||||
+ } else if (!profile->policy.dfa) {
|
||||
+ error = -EPROTO;
|
||||
+ goto fail;
|
||||
}
|
||||
if (!unpack_u32(e, &profile->policy.start[0], "start"))
|
||||
/* default start state */
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,162 +0,0 @@
|
||||
From 45774028820fe2ffbbc94667165f04749821d529 Mon Sep 17 00:00:00 2001
|
||||
From: John Johansen <john.johansen@canonical.com>
|
||||
Date: Wed, 22 Jun 2016 18:01:08 -0700
|
||||
Subject: [PATCH 21/27] apparmor: fix module parameters can be changed after
|
||||
policy is locked
|
||||
|
||||
the policy_lock parameter is a one way switch that prevents policy
|
||||
from being further modified. Unfortunately some of the module parameters
|
||||
can effectively modify policy by turning off enforcement.
|
||||
|
||||
split policy_admin_capable into a view check and a full admin check,
|
||||
and update the admin check to test the policy_lock parameter.
|
||||
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
---
|
||||
security/apparmor/include/policy.h | 2 ++
|
||||
security/apparmor/lsm.c | 22 ++++++++++------------
|
||||
security/apparmor/policy.c | 18 +++++++++++++++++-
|
||||
3 files changed, 29 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h
|
||||
index c28b0f2..52275f0 100644
|
||||
--- a/security/apparmor/include/policy.h
|
||||
+++ b/security/apparmor/include/policy.h
|
||||
@@ -403,6 +403,8 @@ static inline int AUDIT_MODE(struct aa_profile *profile)
|
||||
return profile->audit;
|
||||
}
|
||||
|
||||
+bool policy_view_capable(void);
|
||||
+bool policy_admin_capable(void);
|
||||
bool aa_may_manage_policy(int op);
|
||||
|
||||
#endif /* __AA_POLICY_H */
|
||||
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
|
||||
index 5ee8201..bd40b12 100644
|
||||
--- a/security/apparmor/lsm.c
|
||||
+++ b/security/apparmor/lsm.c
|
||||
@@ -751,51 +751,49 @@ __setup("apparmor=", apparmor_enabled_setup);
|
||||
/* set global flag turning off the ability to load policy */
|
||||
static int param_set_aalockpolicy(const char *val, const struct kernel_param *kp)
|
||||
{
|
||||
- if (!capable(CAP_MAC_ADMIN))
|
||||
+ if (!policy_admin_capable())
|
||||
return -EPERM;
|
||||
- if (aa_g_lock_policy)
|
||||
- return -EACCES;
|
||||
return param_set_bool(val, kp);
|
||||
}
|
||||
|
||||
static int param_get_aalockpolicy(char *buffer, const struct kernel_param *kp)
|
||||
{
|
||||
- if (!capable(CAP_MAC_ADMIN))
|
||||
+ if (!policy_view_capable())
|
||||
return -EPERM;
|
||||
return param_get_bool(buffer, kp);
|
||||
}
|
||||
|
||||
static int param_set_aabool(const char *val, const struct kernel_param *kp)
|
||||
{
|
||||
- if (!capable(CAP_MAC_ADMIN))
|
||||
+ if (!policy_admin_capable())
|
||||
return -EPERM;
|
||||
return param_set_bool(val, kp);
|
||||
}
|
||||
|
||||
static int param_get_aabool(char *buffer, const struct kernel_param *kp)
|
||||
{
|
||||
- if (!capable(CAP_MAC_ADMIN))
|
||||
+ if (!policy_view_capable())
|
||||
return -EPERM;
|
||||
return param_get_bool(buffer, kp);
|
||||
}
|
||||
|
||||
static int param_set_aauint(const char *val, const struct kernel_param *kp)
|
||||
{
|
||||
- if (!capable(CAP_MAC_ADMIN))
|
||||
+ if (!policy_admin_capable())
|
||||
return -EPERM;
|
||||
return param_set_uint(val, kp);
|
||||
}
|
||||
|
||||
static int param_get_aauint(char *buffer, const struct kernel_param *kp)
|
||||
{
|
||||
- if (!capable(CAP_MAC_ADMIN))
|
||||
+ if (!policy_view_capable())
|
||||
return -EPERM;
|
||||
return param_get_uint(buffer, kp);
|
||||
}
|
||||
|
||||
static int param_get_audit(char *buffer, struct kernel_param *kp)
|
||||
{
|
||||
- if (!capable(CAP_MAC_ADMIN))
|
||||
+ if (!policy_view_capable())
|
||||
return -EPERM;
|
||||
|
||||
if (!apparmor_enabled)
|
||||
@@ -807,7 +805,7 @@ static int param_get_audit(char *buffer, struct kernel_param *kp)
|
||||
static int param_set_audit(const char *val, struct kernel_param *kp)
|
||||
{
|
||||
int i;
|
||||
- if (!capable(CAP_MAC_ADMIN))
|
||||
+ if (!policy_admin_capable())
|
||||
return -EPERM;
|
||||
|
||||
if (!apparmor_enabled)
|
||||
@@ -828,7 +826,7 @@ static int param_set_audit(const char *val, struct kernel_param *kp)
|
||||
|
||||
static int param_get_mode(char *buffer, struct kernel_param *kp)
|
||||
{
|
||||
- if (!capable(CAP_MAC_ADMIN))
|
||||
+ if (!policy_admin_capable())
|
||||
return -EPERM;
|
||||
|
||||
if (!apparmor_enabled)
|
||||
@@ -840,7 +838,7 @@ static int param_get_mode(char *buffer, struct kernel_param *kp)
|
||||
static int param_set_mode(const char *val, struct kernel_param *kp)
|
||||
{
|
||||
int i;
|
||||
- if (!capable(CAP_MAC_ADMIN))
|
||||
+ if (!policy_admin_capable())
|
||||
return -EPERM;
|
||||
|
||||
if (!apparmor_enabled)
|
||||
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
|
||||
index 7807125..179e68d 100644
|
||||
--- a/security/apparmor/policy.c
|
||||
+++ b/security/apparmor/policy.c
|
||||
@@ -918,6 +918,22 @@ static int audit_policy(int op, gfp_t gfp, const char *name, const char *info,
|
||||
&sa, NULL);
|
||||
}
|
||||
|
||||
+bool policy_view_capable(void)
|
||||
+{
|
||||
+ struct user_namespace *user_ns = current_user_ns();
|
||||
+ bool response = false;
|
||||
+
|
||||
+ if (ns_capable(user_ns, CAP_MAC_ADMIN))
|
||||
+ response = true;
|
||||
+
|
||||
+ return response;
|
||||
+}
|
||||
+
|
||||
+bool policy_admin_capable(void)
|
||||
+{
|
||||
+ return policy_view_capable() && !aa_g_lock_policy;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* aa_may_manage_policy - can the current task manage policy
|
||||
* @op: the policy manipulation operation being done
|
||||
@@ -932,7 +948,7 @@ bool aa_may_manage_policy(int op)
|
||||
return 0;
|
||||
}
|
||||
|
||||
- if (!capable(CAP_MAC_ADMIN)) {
|
||||
+ if (!policy_admin_capable()) {
|
||||
audit_policy(op, GFP_KERNEL, NULL, "not policy admin", -EACCES);
|
||||
return 0;
|
||||
}
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,31 +0,0 @@
|
||||
From 7fcfc22cd04261ac35a579c99bcc804db7eb3e83 Mon Sep 17 00:00:00 2001
|
||||
From: Heinrich Schuchardt <xypron.glpk@gmx.de>
|
||||
Date: Fri, 10 Jun 2016 23:34:26 +0200
|
||||
Subject: [PATCH 22/27] apparmor: do not expose kernel stack
|
||||
|
||||
Do not copy uninitalized fields th.td_hilen, th.td_data.
|
||||
|
||||
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
---
|
||||
security/apparmor/match.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/security/apparmor/match.c b/security/apparmor/match.c
|
||||
index 32b72eb..3f900fc 100644
|
||||
--- a/security/apparmor/match.c
|
||||
+++ b/security/apparmor/match.c
|
||||
@@ -63,7 +63,9 @@ static struct table_header *unpack_table(char *blob, size_t bsize)
|
||||
|
||||
table = kvzalloc(tsize);
|
||||
if (table) {
|
||||
- *table = th;
|
||||
+ table->td_id = th.td_id;
|
||||
+ table->td_flags = th.td_flags;
|
||||
+ table->td_lolen = th.td_lolen;
|
||||
if (th.td_flags == YYTD_DATA8)
|
||||
UNPACK_ARRAY(table->td_data, blob, th.td_lolen,
|
||||
u8, byte_to_byte);
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,27 +0,0 @@
|
||||
From 1b98560066c26fecb0a61aeb9249e141af2e63f9 Mon Sep 17 00:00:00 2001
|
||||
From: John Johansen <john.johansen@canonical.com>
|
||||
Date: Sat, 9 Jul 2016 23:46:33 -0700
|
||||
Subject: [PATCH 23/27] apparmor: fix arg_size computation for when setprocattr
|
||||
is null terminated
|
||||
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
---
|
||||
security/apparmor/lsm.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
|
||||
index bd40b12..1bf6c53 100644
|
||||
--- a/security/apparmor/lsm.c
|
||||
+++ b/security/apparmor/lsm.c
|
||||
@@ -552,7 +552,7 @@ static int apparmor_setprocattr(struct task_struct *task, char *name,
|
||||
if (!*args)
|
||||
goto out;
|
||||
|
||||
- arg_size = size - (args - (char *) value);
|
||||
+ arg_size = size - (args - (largs ? largs : (char *) value));
|
||||
if (strcmp(name, "current") == 0) {
|
||||
if (strcmp(command, "changehat") == 0) {
|
||||
error = aa_setprocattr_changehat(args, arg_size,
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,603 +0,0 @@
|
||||
From 8d7c032e7798fa1c46449728874b64fff882368b Mon Sep 17 00:00:00 2001
|
||||
From: John Johansen <john.johansen@canonical.com>
|
||||
Date: Mon, 4 Oct 2010 15:03:36 -0700
|
||||
Subject: [PATCH 24/27] UBUNTU: SAUCE: AppArmor: basic networking rules
|
||||
|
||||
Base support for network mediation.
|
||||
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
---
|
||||
security/apparmor/.gitignore | 1 +
|
||||
security/apparmor/Makefile | 42 +++++++++-
|
||||
security/apparmor/apparmorfs.c | 1 +
|
||||
security/apparmor/include/audit.h | 4 +
|
||||
security/apparmor/include/net.h | 44 ++++++++++
|
||||
security/apparmor/include/policy.h | 3 +
|
||||
security/apparmor/lsm.c | 112 +++++++++++++++++++++++++
|
||||
security/apparmor/net.c | 162 +++++++++++++++++++++++++++++++++++++
|
||||
security/apparmor/policy.c | 1 +
|
||||
security/apparmor/policy_unpack.c | 46 +++++++++++
|
||||
10 files changed, 414 insertions(+), 2 deletions(-)
|
||||
create mode 100644 security/apparmor/include/net.h
|
||||
create mode 100644 security/apparmor/net.c
|
||||
|
||||
diff --git a/security/apparmor/.gitignore b/security/apparmor/.gitignore
|
||||
index 9cdec70..d5b291e 100644
|
||||
--- a/security/apparmor/.gitignore
|
||||
+++ b/security/apparmor/.gitignore
|
||||
@@ -1,5 +1,6 @@
|
||||
#
|
||||
# Generated include files
|
||||
#
|
||||
+net_names.h
|
||||
capability_names.h
|
||||
rlim_names.h
|
||||
diff --git a/security/apparmor/Makefile b/security/apparmor/Makefile
|
||||
index d693df8..5dbb72f 100644
|
||||
--- a/security/apparmor/Makefile
|
||||
+++ b/security/apparmor/Makefile
|
||||
@@ -4,10 +4,10 @@ obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o
|
||||
|
||||
apparmor-y := apparmorfs.o audit.o capability.o context.o ipc.o lib.o match.o \
|
||||
path.o domain.o policy.o policy_unpack.o procattr.o lsm.o \
|
||||
- resource.o sid.o file.o
|
||||
+ resource.o sid.o file.o net.o
|
||||
apparmor-$(CONFIG_SECURITY_APPARMOR_HASH) += crypto.o
|
||||
|
||||
-clean-files := capability_names.h rlim_names.h
|
||||
+clean-files := capability_names.h rlim_names.h net_names.h
|
||||
|
||||
|
||||
# Build a lower case string table of capability names
|
||||
@@ -25,6 +25,38 @@ cmd_make-caps = echo "static const char *const capability_names[] = {" > $@ ;\
|
||||
-e 's/^\#define[ \t]+CAP_([A-Z0-9_]+)[ \t]+([0-9]+)/\L\1/p' | \
|
||||
tr '\n' ' ' | sed -e 's/ $$/"\n/' >> $@
|
||||
|
||||
+# Build a lower case string table of address family names
|
||||
+# Transform lines from
|
||||
+# define AF_LOCAL 1 /* POSIX name for AF_UNIX */
|
||||
+# #define AF_INET 2 /* Internet IP Protocol */
|
||||
+# to
|
||||
+# [1] = "local",
|
||||
+# [2] = "inet",
|
||||
+#
|
||||
+# and build the securityfs entries for the mapping.
|
||||
+# Transforms lines from
|
||||
+# #define AF_INET 2 /* Internet IP Protocol */
|
||||
+# to
|
||||
+# #define AA_FS_AF_MASK "local inet"
|
||||
+quiet_cmd_make-af = GEN $@
|
||||
+cmd_make-af = echo "static const char *address_family_names[] = {" > $@ ;\
|
||||
+ sed $< >>$@ -r -n -e "/AF_MAX/d" -e "/AF_LOCAL/d" -e \
|
||||
+ 's/^\#define[ \t]+AF_([A-Z0-9_]+)[ \t]+([0-9]+)(.*)/[\2] = "\L\1",/p';\
|
||||
+ echo "};" >> $@ ;\
|
||||
+ echo -n '\#define AA_FS_AF_MASK "' >> $@ ;\
|
||||
+ sed -r -n 's/^\#define[ \t]+AF_([A-Z0-9_]+)[ \t]+([0-9]+)(.*)/\L\1/p'\
|
||||
+ $< | tr '\n' ' ' | sed -e 's/ $$/"\n/' >> $@
|
||||
+
|
||||
+# Build a lower case string table of sock type names
|
||||
+# Transform lines from
|
||||
+# SOCK_STREAM = 1,
|
||||
+# to
|
||||
+# [1] = "stream",
|
||||
+quiet_cmd_make-sock = GEN $@
|
||||
+cmd_make-sock = echo "static const char *sock_type_names[] = {" >> $@ ;\
|
||||
+ sed $^ >>$@ -r -n \
|
||||
+ -e 's/^\tSOCK_([A-Z0-9_]+)[\t]+=[ \t]+([0-9]+)(.*)/[\2] = "\L\1",/p';\
|
||||
+ echo "};" >> $@
|
||||
|
||||
# Build a lower case string table of rlimit names.
|
||||
# Transforms lines from
|
||||
@@ -61,6 +93,7 @@ cmd_make-rlim = echo "static const char *const rlim_names[RLIM_NLIMITS] = {" \
|
||||
tr '\n' ' ' | sed -e 's/ $$/"\n/' >> $@
|
||||
|
||||
$(obj)/capability.o : $(obj)/capability_names.h
|
||||
+$(obj)/net.o : $(obj)/net_names.h
|
||||
$(obj)/resource.o : $(obj)/rlim_names.h
|
||||
$(obj)/capability_names.h : $(srctree)/include/uapi/linux/capability.h \
|
||||
$(src)/Makefile
|
||||
@@ -68,3 +101,8 @@ $(obj)/capability_names.h : $(srctree)/include/uapi/linux/capability.h \
|
||||
$(obj)/rlim_names.h : $(srctree)/include/uapi/asm-generic/resource.h \
|
||||
$(src)/Makefile
|
||||
$(call cmd,make-rlim)
|
||||
+$(obj)/net_names.h : $(srctree)/include/linux/socket.h \
|
||||
+ $(srctree)/include/linux/net.h \
|
||||
+ $(src)/Makefile
|
||||
+ $(call cmd,make-af)
|
||||
+ $(call cmd,make-sock)
|
||||
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
|
||||
index 729e595..181d961 100644
|
||||
--- a/security/apparmor/apparmorfs.c
|
||||
+++ b/security/apparmor/apparmorfs.c
|
||||
@@ -807,6 +807,7 @@ static struct aa_fs_entry aa_fs_entry_features[] = {
|
||||
AA_FS_DIR("policy", aa_fs_entry_policy),
|
||||
AA_FS_DIR("domain", aa_fs_entry_domain),
|
||||
AA_FS_DIR("file", aa_fs_entry_file),
|
||||
+ AA_FS_DIR("network", aa_fs_entry_network),
|
||||
AA_FS_FILE_U64("capability", VFS_CAP_FLAGS_MASK),
|
||||
AA_FS_DIR("rlimit", aa_fs_entry_rlimit),
|
||||
AA_FS_DIR("caps", aa_fs_entry_caps),
|
||||
diff --git a/security/apparmor/include/audit.h b/security/apparmor/include/audit.h
|
||||
index ba3dfd1..5d3c419 100644
|
||||
--- a/security/apparmor/include/audit.h
|
||||
+++ b/security/apparmor/include/audit.h
|
||||
@@ -125,6 +125,10 @@ struct apparmor_audit_data {
|
||||
u32 denied;
|
||||
kuid_t ouid;
|
||||
} fs;
|
||||
+ struct {
|
||||
+ int type, protocol;
|
||||
+ struct sock *sk;
|
||||
+ } net;
|
||||
};
|
||||
};
|
||||
|
||||
diff --git a/security/apparmor/include/net.h b/security/apparmor/include/net.h
|
||||
new file mode 100644
|
||||
index 0000000..cb8a121
|
||||
--- /dev/null
|
||||
+++ b/security/apparmor/include/net.h
|
||||
@@ -0,0 +1,44 @@
|
||||
+/*
|
||||
+ * AppArmor security module
|
||||
+ *
|
||||
+ * This file contains AppArmor network mediation definitions.
|
||||
+ *
|
||||
+ * Copyright (C) 1998-2008 Novell/SUSE
|
||||
+ * Copyright 2009-2012 Canonical Ltd.
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU General Public License as
|
||||
+ * published by the Free Software Foundation, version 2 of the
|
||||
+ * License.
|
||||
+ */
|
||||
+
|
||||
+#ifndef __AA_NET_H
|
||||
+#define __AA_NET_H
|
||||
+
|
||||
+#include <net/sock.h>
|
||||
+
|
||||
+#include "apparmorfs.h"
|
||||
+
|
||||
+/* struct aa_net - network confinement data
|
||||
+ * @allowed: basic network families permissions
|
||||
+ * @audit_network: which network permissions to force audit
|
||||
+ * @quiet_network: which network permissions to quiet rejects
|
||||
+ */
|
||||
+struct aa_net {
|
||||
+ u16 allow[AF_MAX];
|
||||
+ u16 audit[AF_MAX];
|
||||
+ u16 quiet[AF_MAX];
|
||||
+};
|
||||
+
|
||||
+extern struct aa_fs_entry aa_fs_entry_network[];
|
||||
+
|
||||
+extern int aa_net_perm(int op, struct aa_profile *profile, u16 family,
|
||||
+ int type, int protocol, struct sock *sk);
|
||||
+extern int aa_revalidate_sk(int op, struct sock *sk);
|
||||
+
|
||||
+static inline void aa_free_net_rules(struct aa_net *new)
|
||||
+{
|
||||
+ /* NOP */
|
||||
+}
|
||||
+
|
||||
+#endif /* __AA_NET_H */
|
||||
diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h
|
||||
index 52275f0..4fc4dac 100644
|
||||
--- a/security/apparmor/include/policy.h
|
||||
+++ b/security/apparmor/include/policy.h
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "capability.h"
|
||||
#include "domain.h"
|
||||
#include "file.h"
|
||||
+#include "net.h"
|
||||
#include "resource.h"
|
||||
|
||||
extern const char *const aa_profile_mode_names[];
|
||||
@@ -176,6 +177,7 @@ struct aa_replacedby {
|
||||
* @policy: general match rules governing policy
|
||||
* @file: The set of rules governing basic file access and domain transitions
|
||||
* @caps: capabilities for the profile
|
||||
+ * @net: network controls for the profile
|
||||
* @rlimits: rlimits for the profile
|
||||
*
|
||||
* @dents: dentries for the profiles file entries in apparmorfs
|
||||
@@ -217,6 +219,7 @@ struct aa_profile {
|
||||
struct aa_policydb policy;
|
||||
struct aa_file_rules file;
|
||||
struct aa_caps caps;
|
||||
+ struct aa_net net;
|
||||
struct aa_rlimit rlimits;
|
||||
|
||||
unsigned char *hash;
|
||||
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
|
||||
index 1bf6c53..284ddda 100644
|
||||
--- a/security/apparmor/lsm.c
|
||||
+++ b/security/apparmor/lsm.c
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "include/context.h"
|
||||
#include "include/file.h"
|
||||
#include "include/ipc.h"
|
||||
+#include "include/net.h"
|
||||
#include "include/path.h"
|
||||
#include "include/policy.h"
|
||||
#include "include/procattr.h"
|
||||
@@ -607,6 +608,104 @@ static int apparmor_task_setrlimit(struct task_struct *task,
|
||||
return error;
|
||||
}
|
||||
|
||||
+static int apparmor_socket_create(int family, int type, int protocol, int kern)
|
||||
+{
|
||||
+ struct aa_profile *profile;
|
||||
+ int error = 0;
|
||||
+
|
||||
+ if (kern)
|
||||
+ return 0;
|
||||
+
|
||||
+ profile = __aa_current_profile();
|
||||
+ if (!unconfined(profile))
|
||||
+ error = aa_net_perm(OP_CREATE, profile, family, type, protocol,
|
||||
+ NULL);
|
||||
+ return error;
|
||||
+}
|
||||
+
|
||||
+static int apparmor_socket_bind(struct socket *sock,
|
||||
+ struct sockaddr *address, int addrlen)
|
||||
+{
|
||||
+ struct sock *sk = sock->sk;
|
||||
+
|
||||
+ return aa_revalidate_sk(OP_BIND, sk);
|
||||
+}
|
||||
+
|
||||
+static int apparmor_socket_connect(struct socket *sock,
|
||||
+ struct sockaddr *address, int addrlen)
|
||||
+{
|
||||
+ struct sock *sk = sock->sk;
|
||||
+
|
||||
+ return aa_revalidate_sk(OP_CONNECT, sk);
|
||||
+}
|
||||
+
|
||||
+static int apparmor_socket_listen(struct socket *sock, int backlog)
|
||||
+{
|
||||
+ struct sock *sk = sock->sk;
|
||||
+
|
||||
+ return aa_revalidate_sk(OP_LISTEN, sk);
|
||||
+}
|
||||
+
|
||||
+static int apparmor_socket_accept(struct socket *sock, struct socket *newsock)
|
||||
+{
|
||||
+ struct sock *sk = sock->sk;
|
||||
+
|
||||
+ return aa_revalidate_sk(OP_ACCEPT, sk);
|
||||
+}
|
||||
+
|
||||
+static int apparmor_socket_sendmsg(struct socket *sock,
|
||||
+ struct msghdr *msg, int size)
|
||||
+{
|
||||
+ struct sock *sk = sock->sk;
|
||||
+
|
||||
+ return aa_revalidate_sk(OP_SENDMSG, sk);
|
||||
+}
|
||||
+
|
||||
+static int apparmor_socket_recvmsg(struct socket *sock,
|
||||
+ struct msghdr *msg, int size, int flags)
|
||||
+{
|
||||
+ struct sock *sk = sock->sk;
|
||||
+
|
||||
+ return aa_revalidate_sk(OP_RECVMSG, sk);
|
||||
+}
|
||||
+
|
||||
+static int apparmor_socket_getsockname(struct socket *sock)
|
||||
+{
|
||||
+ struct sock *sk = sock->sk;
|
||||
+
|
||||
+ return aa_revalidate_sk(OP_GETSOCKNAME, sk);
|
||||
+}
|
||||
+
|
||||
+static int apparmor_socket_getpeername(struct socket *sock)
|
||||
+{
|
||||
+ struct sock *sk = sock->sk;
|
||||
+
|
||||
+ return aa_revalidate_sk(OP_GETPEERNAME, sk);
|
||||
+}
|
||||
+
|
||||
+static int apparmor_socket_getsockopt(struct socket *sock, int level,
|
||||
+ int optname)
|
||||
+{
|
||||
+ struct sock *sk = sock->sk;
|
||||
+
|
||||
+ return aa_revalidate_sk(OP_GETSOCKOPT, sk);
|
||||
+}
|
||||
+
|
||||
+static int apparmor_socket_setsockopt(struct socket *sock, int level,
|
||||
+ int optname)
|
||||
+{
|
||||
+ struct sock *sk = sock->sk;
|
||||
+
|
||||
+ return aa_revalidate_sk(OP_SETSOCKOPT, sk);
|
||||
+}
|
||||
+
|
||||
+static int apparmor_socket_shutdown(struct socket *sock, int how)
|
||||
+{
|
||||
+ struct sock *sk = sock->sk;
|
||||
+
|
||||
+ return aa_revalidate_sk(OP_SOCK_SHUTDOWN, sk);
|
||||
+}
|
||||
+
|
||||
static struct security_hook_list apparmor_hooks[] = {
|
||||
LSM_HOOK_INIT(ptrace_access_check, apparmor_ptrace_access_check),
|
||||
LSM_HOOK_INIT(ptrace_traceme, apparmor_ptrace_traceme),
|
||||
@@ -636,6 +735,19 @@ static struct security_hook_list apparmor_hooks[] = {
|
||||
LSM_HOOK_INIT(getprocattr, apparmor_getprocattr),
|
||||
LSM_HOOK_INIT(setprocattr, apparmor_setprocattr),
|
||||
|
||||
+ LSM_HOOK_INIT(socket_create, apparmor_socket_create),
|
||||
+ LSM_HOOK_INIT(socket_bind, apparmor_socket_bind),
|
||||
+ LSM_HOOK_INIT(socket_connect, apparmor_socket_connect),
|
||||
+ LSM_HOOK_INIT(socket_listen, apparmor_socket_listen),
|
||||
+ LSM_HOOK_INIT(socket_accept, apparmor_socket_accept),
|
||||
+ LSM_HOOK_INIT(socket_sendmsg, apparmor_socket_sendmsg),
|
||||
+ LSM_HOOK_INIT(socket_recvmsg, apparmor_socket_recvmsg),
|
||||
+ LSM_HOOK_INIT(socket_getsockname, apparmor_socket_getsockname),
|
||||
+ LSM_HOOK_INIT(socket_getpeername, apparmor_socket_getpeername),
|
||||
+ LSM_HOOK_INIT(socket_getsockopt, apparmor_socket_getsockopt),
|
||||
+ LSM_HOOK_INIT(socket_setsockopt, apparmor_socket_setsockopt),
|
||||
+ LSM_HOOK_INIT(socket_shutdown, apparmor_socket_shutdown),
|
||||
+
|
||||
LSM_HOOK_INIT(cred_alloc_blank, apparmor_cred_alloc_blank),
|
||||
LSM_HOOK_INIT(cred_free, apparmor_cred_free),
|
||||
LSM_HOOK_INIT(cred_prepare, apparmor_cred_prepare),
|
||||
diff --git a/security/apparmor/net.c b/security/apparmor/net.c
|
||||
new file mode 100644
|
||||
index 0000000..003dd18
|
||||
--- /dev/null
|
||||
+++ b/security/apparmor/net.c
|
||||
@@ -0,0 +1,162 @@
|
||||
+/*
|
||||
+ * AppArmor security module
|
||||
+ *
|
||||
+ * This file contains AppArmor network mediation
|
||||
+ *
|
||||
+ * Copyright (C) 1998-2008 Novell/SUSE
|
||||
+ * Copyright 2009-2012 Canonical Ltd.
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU General Public License as
|
||||
+ * published by the Free Software Foundation, version 2 of the
|
||||
+ * License.
|
||||
+ */
|
||||
+
|
||||
+#include "include/apparmor.h"
|
||||
+#include "include/audit.h"
|
||||
+#include "include/context.h"
|
||||
+#include "include/net.h"
|
||||
+#include "include/policy.h"
|
||||
+
|
||||
+#include "net_names.h"
|
||||
+
|
||||
+struct aa_fs_entry aa_fs_entry_network[] = {
|
||||
+ AA_FS_FILE_STRING("af_mask", AA_FS_AF_MASK),
|
||||
+ { }
|
||||
+};
|
||||
+
|
||||
+/* audit callback for net specific fields */
|
||||
+static void audit_cb(struct audit_buffer *ab, void *va)
|
||||
+{
|
||||
+ struct common_audit_data *sa = va;
|
||||
+
|
||||
+ audit_log_format(ab, " family=");
|
||||
+ if (address_family_names[sa->u.net->family]) {
|
||||
+ audit_log_string(ab, address_family_names[sa->u.net->family]);
|
||||
+ } else {
|
||||
+ audit_log_format(ab, "\"unknown(%d)\"", sa->u.net->family);
|
||||
+ }
|
||||
+ audit_log_format(ab, " sock_type=");
|
||||
+ if (sock_type_names[sa->aad->net.type]) {
|
||||
+ audit_log_string(ab, sock_type_names[sa->aad->net.type]);
|
||||
+ } else {
|
||||
+ audit_log_format(ab, "\"unknown(%d)\"", sa->aad->net.type);
|
||||
+ }
|
||||
+ audit_log_format(ab, " protocol=%d", sa->aad->net.protocol);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * audit_net - audit network access
|
||||
+ * @profile: profile being enforced (NOT NULL)
|
||||
+ * @op: operation being checked
|
||||
+ * @family: network family
|
||||
+ * @type: network type
|
||||
+ * @protocol: network protocol
|
||||
+ * @sk: socket auditing is being applied to
|
||||
+ * @error: error code for failure else 0
|
||||
+ *
|
||||
+ * Returns: %0 or sa->error else other errorcode on failure
|
||||
+ */
|
||||
+static int audit_net(struct aa_profile *profile, int op, u16 family, int type,
|
||||
+ int protocol, struct sock *sk, int error)
|
||||
+{
|
||||
+ int audit_type = AUDIT_APPARMOR_AUTO;
|
||||
+ struct common_audit_data sa;
|
||||
+ struct apparmor_audit_data aad = { };
|
||||
+ struct lsm_network_audit net = { };
|
||||
+ if (sk) {
|
||||
+ sa.type = LSM_AUDIT_DATA_NET;
|
||||
+ } else {
|
||||
+ sa.type = LSM_AUDIT_DATA_NONE;
|
||||
+ }
|
||||
+ /* todo fill in socket addr info */
|
||||
+ sa.aad = &aad;
|
||||
+ sa.u.net = &net;
|
||||
+ sa.aad->op = op,
|
||||
+ sa.u.net->family = family;
|
||||
+ sa.u.net->sk = sk;
|
||||
+ sa.aad->net.type = type;
|
||||
+ sa.aad->net.protocol = protocol;
|
||||
+ sa.aad->error = error;
|
||||
+
|
||||
+ if (likely(!sa.aad->error)) {
|
||||
+ u16 audit_mask = profile->net.audit[sa.u.net->family];
|
||||
+ if (likely((AUDIT_MODE(profile) != AUDIT_ALL) &&
|
||||
+ !(1 << sa.aad->net.type & audit_mask)))
|
||||
+ return 0;
|
||||
+ audit_type = AUDIT_APPARMOR_AUDIT;
|
||||
+ } else {
|
||||
+ u16 quiet_mask = profile->net.quiet[sa.u.net->family];
|
||||
+ u16 kill_mask = 0;
|
||||
+ u16 denied = (1 << sa.aad->net.type) & ~quiet_mask;
|
||||
+
|
||||
+ if (denied & kill_mask)
|
||||
+ audit_type = AUDIT_APPARMOR_KILL;
|
||||
+
|
||||
+ if ((denied & quiet_mask) &&
|
||||
+ AUDIT_MODE(profile) != AUDIT_NOQUIET &&
|
||||
+ AUDIT_MODE(profile) != AUDIT_ALL)
|
||||
+ return COMPLAIN_MODE(profile) ? 0 : sa.aad->error;
|
||||
+ }
|
||||
+
|
||||
+ return aa_audit(audit_type, profile, GFP_KERNEL, &sa, audit_cb);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * aa_net_perm - very course network access check
|
||||
+ * @op: operation being checked
|
||||
+ * @profile: profile being enforced (NOT NULL)
|
||||
+ * @family: network family
|
||||
+ * @type: network type
|
||||
+ * @protocol: network protocol
|
||||
+ *
|
||||
+ * Returns: %0 else error if permission denied
|
||||
+ */
|
||||
+int aa_net_perm(int op, struct aa_profile *profile, u16 family, int type,
|
||||
+ int protocol, struct sock *sk)
|
||||
+{
|
||||
+ u16 family_mask;
|
||||
+ int error;
|
||||
+
|
||||
+ if ((family < 0) || (family >= AF_MAX))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if ((type < 0) || (type >= SOCK_MAX))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ /* unix domain and netlink sockets are handled by ipc */
|
||||
+ if (family == AF_UNIX || family == AF_NETLINK)
|
||||
+ return 0;
|
||||
+
|
||||
+ family_mask = profile->net.allow[family];
|
||||
+
|
||||
+ error = (family_mask & (1 << type)) ? 0 : -EACCES;
|
||||
+
|
||||
+ return audit_net(profile, op, family, type, protocol, sk, error);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * aa_revalidate_sk - Revalidate access to a sock
|
||||
+ * @op: operation being checked
|
||||
+ * @sk: sock being revalidated (NOT NULL)
|
||||
+ *
|
||||
+ * Returns: %0 else error if permission denied
|
||||
+ */
|
||||
+int aa_revalidate_sk(int op, struct sock *sk)
|
||||
+{
|
||||
+ struct aa_profile *profile;
|
||||
+ int error = 0;
|
||||
+
|
||||
+ /* aa_revalidate_sk should not be called from interrupt context
|
||||
+ * don't mediate these calls as they are not task related
|
||||
+ */
|
||||
+ if (in_interrupt())
|
||||
+ return 0;
|
||||
+
|
||||
+ profile = __aa_current_profile();
|
||||
+ if (!unconfined(profile))
|
||||
+ error = aa_net_perm(op, profile, sk->sk_family, sk->sk_type,
|
||||
+ sk->sk_protocol, sk);
|
||||
+
|
||||
+ return error;
|
||||
+}
|
||||
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
|
||||
index 179e68d..f1a8541 100644
|
||||
--- a/security/apparmor/policy.c
|
||||
+++ b/security/apparmor/policy.c
|
||||
@@ -603,6 +603,7 @@ void aa_free_profile(struct aa_profile *profile)
|
||||
|
||||
aa_free_file_rules(&profile->file);
|
||||
aa_free_cap_rules(&profile->caps);
|
||||
+ aa_free_net_rules(&profile->net);
|
||||
aa_free_rlimit_rules(&profile->rlimits);
|
||||
|
||||
kzfree(profile->dirname);
|
||||
diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
|
||||
index dac2121..0107bc4 100644
|
||||
--- a/security/apparmor/policy_unpack.c
|
||||
+++ b/security/apparmor/policy_unpack.c
|
||||
@@ -193,6 +193,19 @@ fail:
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static bool unpack_u16(struct aa_ext *e, u16 *data, const char *name)
|
||||
+{
|
||||
+ if (unpack_nameX(e, AA_U16, name)) {
|
||||
+ if (!inbounds(e, sizeof(u16)))
|
||||
+ return 0;
|
||||
+ if (data)
|
||||
+ *data = le16_to_cpu(get_unaligned((u16 *) e->pos));
|
||||
+ e->pos += sizeof(u16);
|
||||
+ return 1;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static bool unpack_u32(struct aa_ext *e, u32 *data, const char *name)
|
||||
{
|
||||
if (unpack_nameX(e, AA_U32, name)) {
|
||||
@@ -476,6 +489,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e)
|
||||
{
|
||||
struct aa_profile *profile = NULL;
|
||||
const char *name = NULL;
|
||||
+ size_t size = 0;
|
||||
int i, error = -EPROTO;
|
||||
kernel_cap_t tmpcap;
|
||||
u32 tmp;
|
||||
@@ -576,6 +590,38 @@ static struct aa_profile *unpack_profile(struct aa_ext *e)
|
||||
if (!unpack_rlimits(e, profile))
|
||||
goto fail;
|
||||
|
||||
+ size = unpack_array(e, "net_allowed_af");
|
||||
+ if (size) {
|
||||
+
|
||||
+ for (i = 0; i < size; i++) {
|
||||
+ /* discard extraneous rules that this kernel will
|
||||
+ * never request
|
||||
+ */
|
||||
+ if (i >= AF_MAX) {
|
||||
+ u16 tmp;
|
||||
+ if (!unpack_u16(e, &tmp, NULL) ||
|
||||
+ !unpack_u16(e, &tmp, NULL) ||
|
||||
+ !unpack_u16(e, &tmp, NULL))
|
||||
+ goto fail;
|
||||
+ continue;
|
||||
+ }
|
||||
+ if (!unpack_u16(e, &profile->net.allow[i], NULL))
|
||||
+ goto fail;
|
||||
+ if (!unpack_u16(e, &profile->net.audit[i], NULL))
|
||||
+ goto fail;
|
||||
+ if (!unpack_u16(e, &profile->net.quiet[i], NULL))
|
||||
+ goto fail;
|
||||
+ }
|
||||
+ if (!unpack_nameX(e, AA_ARRAYEND, NULL))
|
||||
+ goto fail;
|
||||
+ }
|
||||
+ /*
|
||||
+ * allow unix domain and netlink sockets they are handled
|
||||
+ * by IPC
|
||||
+ */
|
||||
+ profile->net.allow[AF_UNIX] = 0xffff;
|
||||
+ profile->net.allow[AF_NETLINK] = 0xffff;
|
||||
+
|
||||
if (unpack_nameX(e, AA_STRUCT, "policydb")) {
|
||||
/* generic policy dfa - optional and may be NULL */
|
||||
profile->policy.dfa = unpack_dfa(e);
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,38 +0,0 @@
|
||||
From aa45ba104003404efb59e6f7178045ade756035d Mon Sep 17 00:00:00 2001
|
||||
From: John Johansen <john.johansen@canonical.com>
|
||||
Date: Fri, 29 Jun 2012 17:34:00 -0700
|
||||
Subject: [PATCH 25/27] apparmor: Fix quieting of audit messages for network
|
||||
mediation
|
||||
|
||||
If a profile specified a quieting of network denials for a given rule by
|
||||
either the quiet or deny rule qualifiers, the resultant quiet mask for
|
||||
denied requests was applied incorrectly, resulting in two potential bugs.
|
||||
1. The misapplied quiet mask would prevent denials from being correctly
|
||||
tested against the kill mask/mode. Thus network access requests that
|
||||
should have resulted in the application being killed did not.
|
||||
|
||||
2. The actual quieting of the denied network request was not being applied.
|
||||
This would result in network rejections always being logged even when
|
||||
they had been specifically marked as quieted.
|
||||
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
---
|
||||
security/apparmor/net.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/security/apparmor/net.c b/security/apparmor/net.c
|
||||
index 003dd18..6e6e5c9 100644
|
||||
--- a/security/apparmor/net.c
|
||||
+++ b/security/apparmor/net.c
|
||||
@@ -88,7 +88,7 @@ static int audit_net(struct aa_profile *profile, int op, u16 family, int type,
|
||||
} else {
|
||||
u16 quiet_mask = profile->net.quiet[sa.u.net->family];
|
||||
u16 kill_mask = 0;
|
||||
- u16 denied = (1 << sa.aad->net.type) & ~quiet_mask;
|
||||
+ u16 denied = (1 << sa.aad->net.type);
|
||||
|
||||
if (denied & kill_mask)
|
||||
audit_type = AUDIT_APPARMOR_KILL;
|
||||
--
|
||||
2.7.4
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,180 +0,0 @@
|
||||
From 1eff686074a6af0cf47fc24c45ebb001c570a98b Mon Sep 17 00:00:00 2001
|
||||
From: kbuild test robot <fengguang.wu@intel.com>
|
||||
Date: Fri, 29 Jul 2016 12:44:43 +0800
|
||||
Subject: [PATCH 27/27] UBUNTU: SAUCE: AppArmor: fix boolreturn.cocci warnings
|
||||
|
||||
security/apparmor/policy_unpack.c:143:9-10: WARNING: return of 0/1 in function 'unpack_X' with return type bool
|
||||
security/apparmor/policy_unpack.c:189:9-10: WARNING: return of 0/1 in function 'unpack_nameX' with return type bool
|
||||
security/apparmor/policy_unpack.c:475:8-9: WARNING: return of 0/1 in function 'unpack_rlimits' with return type bool
|
||||
security/apparmor/policy_unpack.c:440:8-9: WARNING: return of 0/1 in function 'unpack_trans_table' with return type bool
|
||||
security/apparmor/policy_unpack.c:200:10-11: WARNING: return of 0/1 in function 'unpack_u16' with return type bool
|
||||
security/apparmor/policy_unpack.c:213:10-11: WARNING: return of 0/1 in function 'unpack_u32' with return type bool
|
||||
security/apparmor/policy_unpack.c:226:10-11: WARNING: return of 0/1 in function 'unpack_u64' with return type bool
|
||||
security/apparmor/policy_unpack.c:325:10-11: WARNING: return of 0/1 in function 'verify_accept' with return type bool
|
||||
security/apparmor/policy_unpack.c:739:10-11: WARNING: return of 0/1 in function 'verify_dfa_xindex' with return type bool
|
||||
security/apparmor/policy_unpack.c:729:9-10: WARNING: return of 0/1 in function 'verify_xindex' with return type bool
|
||||
|
||||
Return statements in functions returning bool should use
|
||||
true/false instead of 1/0.
|
||||
Generated by: scripts/coccinelle/misc/boolreturn.cocci
|
||||
Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
---
|
||||
security/apparmor/policy_unpack.c | 52 +++++++++++++++++++--------------------
|
||||
1 file changed, 26 insertions(+), 26 deletions(-)
|
||||
|
||||
diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
|
||||
index 0107bc4..af14626 100644
|
||||
--- a/security/apparmor/policy_unpack.c
|
||||
+++ b/security/apparmor/policy_unpack.c
|
||||
@@ -140,11 +140,11 @@ static size_t unpack_u16_chunk(struct aa_ext *e, char **chunk)
|
||||
static bool unpack_X(struct aa_ext *e, enum aa_code code)
|
||||
{
|
||||
if (!inbounds(e, 1))
|
||||
- return 0;
|
||||
+ return false;
|
||||
if (*(u8 *) e->pos != code)
|
||||
- return 0;
|
||||
+ return false;
|
||||
e->pos++;
|
||||
- return 1;
|
||||
+ return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -186,50 +186,50 @@ static bool unpack_nameX(struct aa_ext *e, enum aa_code code, const char *name)
|
||||
|
||||
/* now check if type code matches */
|
||||
if (unpack_X(e, code))
|
||||
- return 1;
|
||||
+ return true;
|
||||
|
||||
fail:
|
||||
e->pos = pos;
|
||||
- return 0;
|
||||
+ return false;
|
||||
}
|
||||
|
||||
static bool unpack_u16(struct aa_ext *e, u16 *data, const char *name)
|
||||
{
|
||||
if (unpack_nameX(e, AA_U16, name)) {
|
||||
if (!inbounds(e, sizeof(u16)))
|
||||
- return 0;
|
||||
+ return false;
|
||||
if (data)
|
||||
*data = le16_to_cpu(get_unaligned((u16 *) e->pos));
|
||||
e->pos += sizeof(u16);
|
||||
- return 1;
|
||||
+ return true;
|
||||
}
|
||||
- return 0;
|
||||
+ return false;
|
||||
}
|
||||
|
||||
static bool unpack_u32(struct aa_ext *e, u32 *data, const char *name)
|
||||
{
|
||||
if (unpack_nameX(e, AA_U32, name)) {
|
||||
if (!inbounds(e, sizeof(u32)))
|
||||
- return 0;
|
||||
+ return false;
|
||||
if (data)
|
||||
*data = le32_to_cpu(get_unaligned((u32 *) e->pos));
|
||||
e->pos += sizeof(u32);
|
||||
- return 1;
|
||||
+ return true;
|
||||
}
|
||||
- return 0;
|
||||
+ return false;
|
||||
}
|
||||
|
||||
static bool unpack_u64(struct aa_ext *e, u64 *data, const char *name)
|
||||
{
|
||||
if (unpack_nameX(e, AA_U64, name)) {
|
||||
if (!inbounds(e, sizeof(u64)))
|
||||
- return 0;
|
||||
+ return false;
|
||||
if (data)
|
||||
*data = le64_to_cpu(get_unaligned((u64 *) e->pos));
|
||||
e->pos += sizeof(u64);
|
||||
- return 1;
|
||||
+ return true;
|
||||
}
|
||||
- return 0;
|
||||
+ return false;
|
||||
}
|
||||
|
||||
static size_t unpack_array(struct aa_ext *e, const char *name)
|
||||
@@ -322,12 +322,12 @@ static bool verify_accept(struct aa_dfa *dfa, int flags)
|
||||
int mode = ACCEPT_TABLE(dfa)[i];
|
||||
|
||||
if (mode & ~DFA_VALID_PERM_MASK)
|
||||
- return 0;
|
||||
+ return false;
|
||||
|
||||
if (ACCEPT_TABLE2(dfa)[i] & ~DFA_VALID_PERM2_MASK)
|
||||
- return 0;
|
||||
+ return false;
|
||||
}
|
||||
- return 1;
|
||||
+ return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -437,12 +437,12 @@ static bool unpack_trans_table(struct aa_ext *e, struct aa_profile *profile)
|
||||
if (!unpack_nameX(e, AA_STRUCTEND, NULL))
|
||||
goto fail;
|
||||
}
|
||||
- return 1;
|
||||
+ return true;
|
||||
|
||||
fail:
|
||||
aa_free_domain_entries(&profile->file.trans);
|
||||
e->pos = pos;
|
||||
- return 0;
|
||||
+ return false;
|
||||
}
|
||||
|
||||
static bool unpack_rlimits(struct aa_ext *e, struct aa_profile *profile)
|
||||
@@ -472,11 +472,11 @@ static bool unpack_rlimits(struct aa_ext *e, struct aa_profile *profile)
|
||||
if (!unpack_nameX(e, AA_STRUCTEND, NULL))
|
||||
goto fail;
|
||||
}
|
||||
- return 1;
|
||||
+ return true;
|
||||
|
||||
fail:
|
||||
e->pos = pos;
|
||||
- return 0;
|
||||
+ return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -726,8 +726,8 @@ static bool verify_xindex(int xindex, int table_size)
|
||||
xtype = xindex & AA_X_TYPE_MASK;
|
||||
index = xindex & AA_X_INDEX_MASK;
|
||||
if (xtype == AA_X_TABLE && index >= table_size)
|
||||
- return 0;
|
||||
- return 1;
|
||||
+ return false;
|
||||
+ return true;
|
||||
}
|
||||
|
||||
/* verify dfa xindexes are in range of transition tables */
|
||||
@@ -736,11 +736,11 @@ static bool verify_dfa_xindex(struct aa_dfa *dfa, int table_size)
|
||||
int i;
|
||||
for (i = 0; i < dfa->tables[YYTD_ID_ACCEPT]->td_lolen; i++) {
|
||||
if (!verify_xindex(dfa_user_xindex(dfa, i), table_size))
|
||||
- return 0;
|
||||
+ return false;
|
||||
if (!verify_xindex(dfa_other_xindex(dfa, i), table_size))
|
||||
- return 0;
|
||||
+ return false;
|
||||
}
|
||||
- return 1;
|
||||
+ return true;
|
||||
}
|
||||
|
||||
/**
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,118 +0,0 @@
|
||||
From 24b6ac149a57c2d3d5a9920e64d914e8ff00d346 Mon Sep 17 00:00:00 2001
|
||||
From: Vegard Nossum <vegard.nossum@oracle.com>
|
||||
Date: Thu, 7 Jul 2016 13:41:11 -0700
|
||||
Subject: [PATCH 01/27] apparmor: fix oops, validate buffer size in
|
||||
apparmor_setprocattr()
|
||||
|
||||
When proc_pid_attr_write() was changed to use memdup_user apparmor's
|
||||
(interface violating) assumption that the setprocattr buffer was always
|
||||
a single page was violated.
|
||||
|
||||
The size test is not strictly speaking needed as proc_pid_attr_write()
|
||||
will reject anything larger, but for the sake of robustness we can keep
|
||||
it in.
|
||||
|
||||
SMACK and SELinux look safe to me, but somebody else should probably
|
||||
have a look just in case.
|
||||
|
||||
Based on original patch from Vegard Nossum <vegard.nossum@oracle.com>
|
||||
modified for the case that apparmor provides null termination.
|
||||
|
||||
Fixes: bb646cdb12e75d82258c2f2e7746d5952d3e321a
|
||||
Reported-by: Vegard Nossum <vegard.nossum@oracle.com>
|
||||
Cc: Al Viro <viro@zeniv.linux.org.uk>
|
||||
Cc: John Johansen <john.johansen@canonical.com>
|
||||
Cc: Paul Moore <paul@paul-moore.com>
|
||||
Cc: Stephen Smalley <sds@tycho.nsa.gov>
|
||||
Cc: Eric Paris <eparis@parisplace.org>
|
||||
Cc: Casey Schaufler <casey@schaufler-ca.com>
|
||||
Cc: stable@kernel.org
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
Reviewed-by: Tyler Hicks <tyhicks@canonical.com>
|
||||
Signed-off-by: James Morris <james.l.morris@oracle.com>
|
||||
---
|
||||
security/apparmor/lsm.c | 36 +++++++++++++++++++-----------------
|
||||
1 file changed, 19 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
|
||||
index dec607c..5ee8201 100644
|
||||
--- a/security/apparmor/lsm.c
|
||||
+++ b/security/apparmor/lsm.c
|
||||
@@ -523,34 +523,34 @@ static int apparmor_setprocattr(struct task_struct *task, char *name,
|
||||
{
|
||||
struct common_audit_data sa;
|
||||
struct apparmor_audit_data aad = {0,};
|
||||
- char *command, *args = value;
|
||||
+ char *command, *largs = NULL, *args = value;
|
||||
size_t arg_size;
|
||||
int error;
|
||||
|
||||
if (size == 0)
|
||||
return -EINVAL;
|
||||
- /* args points to a PAGE_SIZE buffer, AppArmor requires that
|
||||
- * the buffer must be null terminated or have size <= PAGE_SIZE -1
|
||||
- * so that AppArmor can null terminate them
|
||||
- */
|
||||
- if (args[size - 1] != '\0') {
|
||||
- if (size == PAGE_SIZE)
|
||||
- return -EINVAL;
|
||||
- args[size] = '\0';
|
||||
- }
|
||||
-
|
||||
/* task can only write its own attributes */
|
||||
if (current != task)
|
||||
return -EACCES;
|
||||
|
||||
- args = value;
|
||||
+ /* AppArmor requires that the buffer must be null terminated atm */
|
||||
+ if (args[size - 1] != '\0') {
|
||||
+ /* null terminate */
|
||||
+ largs = args = kmalloc(size + 1, GFP_KERNEL);
|
||||
+ if (!args)
|
||||
+ return -ENOMEM;
|
||||
+ memcpy(args, value, size);
|
||||
+ args[size] = '\0';
|
||||
+ }
|
||||
+
|
||||
+ error = -EINVAL;
|
||||
args = strim(args);
|
||||
command = strsep(&args, " ");
|
||||
if (!args)
|
||||
- return -EINVAL;
|
||||
+ goto out;
|
||||
args = skip_spaces(args);
|
||||
if (!*args)
|
||||
- return -EINVAL;
|
||||
+ goto out;
|
||||
|
||||
arg_size = size - (args - (char *) value);
|
||||
if (strcmp(name, "current") == 0) {
|
||||
@@ -576,10 +576,12 @@ static int apparmor_setprocattr(struct task_struct *task, char *name,
|
||||
goto fail;
|
||||
} else
|
||||
/* only support the "current" and "exec" process attributes */
|
||||
- return -EINVAL;
|
||||
+ goto fail;
|
||||
|
||||
if (!error)
|
||||
error = size;
|
||||
+out:
|
||||
+ kfree(largs);
|
||||
return error;
|
||||
|
||||
fail:
|
||||
@@ -588,9 +590,9 @@ fail:
|
||||
aad.profile = aa_current_profile();
|
||||
aad.op = OP_SETPROCATTR;
|
||||
aad.info = name;
|
||||
- aad.error = -EINVAL;
|
||||
+ aad.error = error = -EINVAL;
|
||||
aa_audit_msg(AUDIT_APPARMOR_DENIED, &sa, NULL);
|
||||
- return -EINVAL;
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
static int apparmor_task_setrlimit(struct task_struct *task,
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,33 +0,0 @@
|
||||
From 444bc4f95ec283cd0fb9777f4890bd9bc307809d Mon Sep 17 00:00:00 2001
|
||||
From: John Johansen <john.johansen@canonical.com>
|
||||
Date: Mon, 11 Apr 2016 16:55:10 -0700
|
||||
Subject: [PATCH 02/27] apparmor: fix refcount bug in profile replacement
|
||||
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
Acked-by: Seth Arnold <seth.arnold@canonical.com>
|
||||
---
|
||||
security/apparmor/policy.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
|
||||
index 705c287..222052f 100644
|
||||
--- a/security/apparmor/policy.c
|
||||
+++ b/security/apparmor/policy.c
|
||||
@@ -1189,12 +1189,12 @@ ssize_t aa_replace_profiles(void *udata, size_t size, bool noreplace)
|
||||
aa_get_profile(newest);
|
||||
aa_put_profile(parent);
|
||||
rcu_assign_pointer(ent->new->parent, newest);
|
||||
- } else
|
||||
- aa_put_profile(newest);
|
||||
+ }
|
||||
/* aafs interface uses replacedby */
|
||||
rcu_assign_pointer(ent->new->replacedby->profile,
|
||||
aa_get_profile(ent->new));
|
||||
__list_add_profile(&parent->base.profiles, ent->new);
|
||||
+ aa_put_profile(newest);
|
||||
} else {
|
||||
/* aafs interface uses replacedby */
|
||||
rcu_assign_pointer(ent->new->replacedby->profile,
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,38 +0,0 @@
|
||||
From 1224a06778b89dcbf0ca85bd961c2fcdd8765a69 Mon Sep 17 00:00:00 2001
|
||||
From: John Johansen <john.johansen@canonical.com>
|
||||
Date: Mon, 11 Apr 2016 16:57:19 -0700
|
||||
Subject: [PATCH 03/27] apparmor: fix replacement bug that adds new child to
|
||||
old parent
|
||||
|
||||
When set atomic replacement is used and the parent is updated before the
|
||||
child, and the child did not exist in the old parent so there is no
|
||||
direct replacement then the new child is incorrectly added to the old
|
||||
parent. This results in the new parent not having the child(ren) that
|
||||
it should and the old parent when being destroyed asserting the
|
||||
following error.
|
||||
|
||||
AppArmor: policy_destroy: internal error, policy '<profile/name>' still
|
||||
contains profiles
|
||||
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
Acked-by: Seth Arnold <seth.arnold@canonical.com>
|
||||
---
|
||||
security/apparmor/policy.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
|
||||
index 222052f..c92a9f6 100644
|
||||
--- a/security/apparmor/policy.c
|
||||
+++ b/security/apparmor/policy.c
|
||||
@@ -1193,7 +1193,7 @@ ssize_t aa_replace_profiles(void *udata, size_t size, bool noreplace)
|
||||
/* aafs interface uses replacedby */
|
||||
rcu_assign_pointer(ent->new->replacedby->profile,
|
||||
aa_get_profile(ent->new));
|
||||
- __list_add_profile(&parent->base.profiles, ent->new);
|
||||
+ __list_add_profile(&newest->base.profiles, ent->new);
|
||||
aa_put_profile(newest);
|
||||
} else {
|
||||
/* aafs interface uses replacedby */
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,87 +0,0 @@
|
||||
From 15d921647676fdc2c3ee1cf9aa8f578b1012ecff Mon Sep 17 00:00:00 2001
|
||||
From: John Johansen <john.johansen@canonical.com>
|
||||
Date: Sun, 8 Jun 2014 11:20:54 -0700
|
||||
Subject: [PATCH 04/27] apparmor: fix uninitialized lsm_audit member
|
||||
|
||||
BugLink: http://bugs.launchpad.net/bugs/1268727
|
||||
|
||||
The task field in the lsm_audit struct needs to be initialized if
|
||||
a change_hat fails, otherwise the following oops will occur
|
||||
|
||||
BUG: unable to handle kernel paging request at 0000002fbead7d08
|
||||
IP: [<ffffffff8171153e>] _raw_spin_lock+0xe/0x50
|
||||
PGD 1e3f35067 PUD 0
|
||||
Oops: 0002 [#1] SMP
|
||||
Modules linked in: pppox crc_ccitt p8023 p8022 psnap llc ax25 btrfs raid6_pq xor xfs libcrc32c dm_multipath scsi_dh kvm_amd dcdbas kvm microcode amd64_edac_mod joydev edac_core psmouse edac_mce_amd serio_raw k10temp sp5100_tco i2c_piix4 ipmi_si ipmi_msghandler acpi_power_meter mac_hid lp parport hid_generic usbhid hid pata_acpi mpt2sas ahci raid_class pata_atiixp bnx2 libahci scsi_transport_sas [last unloaded: tipc]
|
||||
CPU: 2 PID: 699 Comm: changehat_twice Tainted: GF O 3.13.0-7-generic #25-Ubuntu
|
||||
Hardware name: Dell Inc. PowerEdge R415/08WNM9, BIOS 1.8.6 12/06/2011
|
||||
task: ffff8802135c6000 ti: ffff880212986000 task.ti: ffff880212986000
|
||||
RIP: 0010:[<ffffffff8171153e>] [<ffffffff8171153e>] _raw_spin_lock+0xe/0x50
|
||||
RSP: 0018:ffff880212987b68 EFLAGS: 00010006
|
||||
RAX: 0000000000020000 RBX: 0000002fbead7500 RCX: 0000000000000000
|
||||
RDX: 0000000000000292 RSI: ffff880212987ba8 RDI: 0000002fbead7d08
|
||||
RBP: ffff880212987b68 R08: 0000000000000246 R09: ffff880216e572a0
|
||||
R10: ffffffff815fd677 R11: ffffea0008469580 R12: ffffffff8130966f
|
||||
R13: ffff880212987ba8 R14: 0000002fbead7d08 R15: ffff8800d8c6b830
|
||||
FS: 00002b5e6c84e7c0(0000) GS:ffff880216e40000(0000) knlGS:0000000055731700
|
||||
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
|
||||
CR2: 0000002fbead7d08 CR3: 000000021270f000 CR4: 00000000000006e0
|
||||
Stack:
|
||||
ffff880212987b98 ffffffff81075f17 ffffffff8130966f 0000000000000009
|
||||
0000000000000000 0000000000000000 ffff880212987bd0 ffffffff81075f7c
|
||||
0000000000000292 ffff880212987c08 ffff8800d8c6b800 0000000000000026
|
||||
Call Trace:
|
||||
[<ffffffff81075f17>] __lock_task_sighand+0x47/0x80
|
||||
[<ffffffff8130966f>] ? apparmor_cred_prepare+0x2f/0x50
|
||||
[<ffffffff81075f7c>] do_send_sig_info+0x2c/0x80
|
||||
[<ffffffff81075fee>] send_sig_info+0x1e/0x30
|
||||
[<ffffffff8130242d>] aa_audit+0x13d/0x190
|
||||
[<ffffffff8130c1dc>] aa_audit_file+0xbc/0x130
|
||||
[<ffffffff8130966f>] ? apparmor_cred_prepare+0x2f/0x50
|
||||
[<ffffffff81304cc2>] aa_change_hat+0x202/0x530
|
||||
[<ffffffff81308fc6>] aa_setprocattr_changehat+0x116/0x1d0
|
||||
[<ffffffff8130a11d>] apparmor_setprocattr+0x25d/0x300
|
||||
[<ffffffff812cee56>] security_setprocattr+0x16/0x20
|
||||
[<ffffffff8121fc87>] proc_pid_attr_write+0x107/0x130
|
||||
[<ffffffff811b7604>] vfs_write+0xb4/0x1f0
|
||||
[<ffffffff811b8039>] SyS_write+0x49/0xa0
|
||||
[<ffffffff8171a1bf>] tracesys+0xe1/0xe6
|
||||
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
Acked-by: Seth Arnold <seth.arnold@canonical.com>
|
||||
---
|
||||
security/apparmor/audit.c | 3 ++-
|
||||
security/apparmor/file.c | 3 ++-
|
||||
2 files changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/security/apparmor/audit.c b/security/apparmor/audit.c
|
||||
index 89c7865..3a7f1da 100644
|
||||
--- a/security/apparmor/audit.c
|
||||
+++ b/security/apparmor/audit.c
|
||||
@@ -200,7 +200,8 @@ int aa_audit(int type, struct aa_profile *profile, gfp_t gfp,
|
||||
|
||||
if (sa->aad->type == AUDIT_APPARMOR_KILL)
|
||||
(void)send_sig_info(SIGKILL, NULL,
|
||||
- sa->u.tsk ? sa->u.tsk : current);
|
||||
+ sa->type == LSM_AUDIT_DATA_TASK && sa->u.tsk ?
|
||||
+ sa->u.tsk : current);
|
||||
|
||||
if (sa->aad->type == AUDIT_APPARMOR_ALLOWED)
|
||||
return complain_error(sa->aad->error);
|
||||
diff --git a/security/apparmor/file.c b/security/apparmor/file.c
|
||||
index 913f377..43d6ae7 100644
|
||||
--- a/security/apparmor/file.c
|
||||
+++ b/security/apparmor/file.c
|
||||
@@ -110,7 +110,8 @@ int aa_audit_file(struct aa_profile *profile, struct file_perms *perms,
|
||||
int type = AUDIT_APPARMOR_AUTO;
|
||||
struct common_audit_data sa;
|
||||
struct apparmor_audit_data aad = {0,};
|
||||
- sa.type = LSM_AUDIT_DATA_NONE;
|
||||
+ sa.type = LSM_AUDIT_DATA_TASK;
|
||||
+ sa.u.tsk = NULL;
|
||||
sa.aad = &aad;
|
||||
aad.op = op,
|
||||
aad.fs.request = request;
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,32 +0,0 @@
|
||||
From c1216728b7d644443eef31e4bd9d01b4a0a51d61 Mon Sep 17 00:00:00 2001
|
||||
From: John Johansen <john.johansen@canonical.com>
|
||||
Date: Fri, 25 Jul 2014 04:02:03 -0700
|
||||
Subject: [PATCH 05/27] apparmor: exec should not be returning ENOENT when it
|
||||
denies
|
||||
|
||||
The current behavior is confusing as it causes exec failures to report
|
||||
the executable is missing instead of identifying that apparmor
|
||||
caused the failure.
|
||||
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
Acked-by: Seth Arnold <seth.arnold@canonical.com>
|
||||
---
|
||||
security/apparmor/domain.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
|
||||
index dc0027b..67a7418 100644
|
||||
--- a/security/apparmor/domain.c
|
||||
+++ b/security/apparmor/domain.c
|
||||
@@ -433,7 +433,7 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
|
||||
new_profile = aa_get_newest_profile(ns->unconfined);
|
||||
info = "ux fallback";
|
||||
} else {
|
||||
- error = -ENOENT;
|
||||
+ error = -EACCES;
|
||||
info = "profile not found";
|
||||
/* remove MAY_EXEC to audit as failure */
|
||||
perms.allow &= ~MAY_EXEC;
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,28 +0,0 @@
|
||||
From 2d3389de6c8ab6b3ad2cef4ea460c8fce2a226b9 Mon Sep 17 00:00:00 2001
|
||||
From: John Johansen <john.johansen@canonical.com>
|
||||
Date: Fri, 25 Jul 2014 04:01:56 -0700
|
||||
Subject: [PATCH 06/27] apparmor: fix update the mtime of the profile file on
|
||||
replacement
|
||||
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
Acked-by: Seth Arnold <seth.arnold@canonical.com>
|
||||
---
|
||||
security/apparmor/apparmorfs.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
|
||||
index ad4fa49..45a6199 100644
|
||||
--- a/security/apparmor/apparmorfs.c
|
||||
+++ b/security/apparmor/apparmorfs.c
|
||||
@@ -379,6 +379,8 @@ void __aa_fs_profile_migrate_dents(struct aa_profile *old,
|
||||
|
||||
for (i = 0; i < AAFS_PROF_SIZEOF; i++) {
|
||||
new->dents[i] = old->dents[i];
|
||||
+ if (new->dents[i])
|
||||
+ new->dents[i]->d_inode->i_mtime = CURRENT_TIME;
|
||||
old->dents[i] = NULL;
|
||||
}
|
||||
}
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,36 +0,0 @@
|
||||
From 9caa96e30a1b2bb191a29af872285c8d0b078c10 Mon Sep 17 00:00:00 2001
|
||||
From: John Johansen <john.johansen@canonical.com>
|
||||
Date: Fri, 25 Jul 2014 04:02:08 -0700
|
||||
Subject: [PATCH 07/27] apparmor: fix disconnected bind mnts reconnection
|
||||
|
||||
Bind mounts can fail to be properly reconnected when PATH_CONNECT is
|
||||
specified. Ensure that when PATH_CONNECT is specified the path has
|
||||
a root.
|
||||
|
||||
BugLink: http://bugs.launchpad.net/bugs/1319984
|
||||
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
Acked-by: Seth Arnold <seth.arnold@canonical.com>
|
||||
---
|
||||
security/apparmor/path.c | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/security/apparmor/path.c b/security/apparmor/path.c
|
||||
index 71e0e3a..bb2f2c6 100644
|
||||
--- a/security/apparmor/path.c
|
||||
+++ b/security/apparmor/path.c
|
||||
@@ -141,7 +141,10 @@ static int d_namespace_path(struct path *path, char *buf, int buflen,
|
||||
error = -EACCES;
|
||||
if (*res == '/')
|
||||
*name = res + 1;
|
||||
- }
|
||||
+ } else if (*res != '/')
|
||||
+ /* CONNECT_PATH with missing root */
|
||||
+ error = prepend(name, *name - buf, "/", 1);
|
||||
+
|
||||
}
|
||||
|
||||
out:
|
||||
--
|
||||
2.7.4
|
||||
|
@@ -1,114 +0,0 @@
|
||||
From 11702a732e149380e05e2ab8ae1b743ac89f892f Mon Sep 17 00:00:00 2001
|
||||
From: John Johansen <john.johansen@canonical.com>
|
||||
Date: Fri, 25 Jul 2014 04:02:10 -0700
|
||||
Subject: [PATCH 08/27] apparmor: internal paths should be treated as
|
||||
disconnected
|
||||
|
||||
Internal mounts are not mounted anywhere and as such should be treated
|
||||
as disconnected paths.
|
||||
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
Acked-by: Seth Arnold <seth.arnold@canonical.com>
|
||||
---
|
||||
security/apparmor/path.c | 64 +++++++++++++++++++++++++++---------------------
|
||||
1 file changed, 36 insertions(+), 28 deletions(-)
|
||||
|
||||
diff --git a/security/apparmor/path.c b/security/apparmor/path.c
|
||||
index bb2f2c6..596f799 100644
|
||||
--- a/security/apparmor/path.c
|
||||
+++ b/security/apparmor/path.c
|
||||
@@ -25,7 +25,6 @@
|
||||
#include "include/path.h"
|
||||
#include "include/policy.h"
|
||||
|
||||
-
|
||||
/* modified from dcache.c */
|
||||
static int prepend(char **buffer, int buflen, const char *str, int namelen)
|
||||
{
|
||||
@@ -39,6 +38,38 @@ static int prepend(char **buffer, int buflen, const char *str, int namelen)
|
||||
|
||||
#define CHROOT_NSCONNECT (PATH_CHROOT_REL | PATH_CHROOT_NSCONNECT)
|
||||
|
||||
+/* If the path is not connected to the expected root,
|
||||
+ * check if it is a sysctl and handle specially else remove any
|
||||
+ * leading / that __d_path may have returned.
|
||||
+ * Unless
|
||||
+ * specifically directed to connect the path,
|
||||
+ * OR
|
||||
+ * if in a chroot and doing chroot relative paths and the path
|
||||
+ * resolves to the namespace root (would be connected outside
|
||||
+ * of chroot) and specifically directed to connect paths to
|
||||
+ * namespace root.
|
||||
+ */
|
||||
+static int disconnect(const struct path *path, char *buf, char **name,
|
||||
+ int flags)
|
||||
+{
|
||||
+ int error = 0;
|
||||
+
|
||||
+ if (!(flags & PATH_CONNECT_PATH) &&
|
||||
+ !(((flags & CHROOT_NSCONNECT) == CHROOT_NSCONNECT) &&
|
||||
+ our_mnt(path->mnt))) {
|
||||
+ /* disconnected path, don't return pathname starting
|
||||
+ * with '/'
|
||||
+ */
|
||||
+ error = -EACCES;
|
||||
+ if (**name == '/')
|
||||
+ *name = *name + 1;
|
||||
+ } else if (**name != '/')
|
||||
+ /* CONNECT_PATH with missing root */
|
||||
+ error = prepend(name, *name - buf, "/", 1);
|
||||
+
|
||||
+ return error;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* d_namespace_path - lookup a name associated with a given path
|
||||
* @path: path to lookup (NOT NULL)
|
||||
@@ -74,7 +105,8 @@ static int d_namespace_path(struct path *path, char *buf, int buflen,
|
||||
* control instead of hard coded /proc
|
||||
*/
|
||||
return prepend(name, *name - buf, "/proc", 5);
|
||||
- }
|
||||
+ } else
|
||||
+ return disconnect(path, buf, name, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -120,32 +152,8 @@ static int d_namespace_path(struct path *path, char *buf, int buflen,
|
||||
goto out;
|
||||
}
|
||||
|
||||
- /* If the path is not connected to the expected root,
|
||||
- * check if it is a sysctl and handle specially else remove any
|
||||
- * leading / that __d_path may have returned.
|
||||
- * Unless
|
||||
- * specifically directed to connect the path,
|
||||
- * OR
|
||||
- * if in a chroot and doing chroot relative paths and the path
|
||||
- * resolves to the namespace root (would be connected outside
|
||||
- * of chroot) and specifically directed to connect paths to
|
||||
- * namespace root.
|
||||
- */
|
||||
- if (!connected) {
|
||||
- if (!(flags & PATH_CONNECT_PATH) &&
|
||||
- !(((flags & CHROOT_NSCONNECT) == CHROOT_NSCONNECT) &&
|
||||
- our_mnt(path->mnt))) {
|
||||
- /* disconnected path, don't return pathname starting
|
||||
- * with '/'
|
||||
- */
|
||||
- error = -EACCES;
|
||||
- if (*res == '/')
|
||||
- *name = res + 1;
|
||||
- } else if (*res != '/')
|
||||
- /* CONNECT_PATH with missing root */
|
||||
- error = prepend(name, *name - buf, "/", 1);
|
||||
-
|
||||
- }
|
||||
+ if (!connected)
|
||||
+ error = disconnect(path, buf, name, flags);
|
||||
|
||||
out:
|
||||
return error;
|
||||
--
|
||||
2.7.4
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user