debian/0000775000000000000000000000000012317446506007200 5ustar debian/aa-update-browser.80000664000000000000000000000262012315045675012613 0ustar .IX Title "AA-UPDATE-BROWSER 8" .TH AA-UPDATE-BROWSER 8 "2010-08-11" "Canonical Ltd" "AppArmor" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" aa-update-browser \- update browser profiles with browser abstractions .SH "SYNOPSIS" .IX Header "SYNOPSIS" \&\fBaa-update-browser\fR [option] .SH "DESCRIPTION" .IX Header "DESCRIPTION" \&\fBaa-update-browser\fR will list current browser abstractions in /etc/apparmor.d/abstractions/ubuntu-browsers.d as well as update browser profiles to use those abstractions. .SH "OPTIONS" .IX Header "OPTIONS" \&\fBaa-update-browser\fR accepts the following arguments: .IP "\-d" 4 .IX Item "-d" dry-run. Only show what would be done. .IP "\-u \s-1ABSTRACTIONS\s0" 4 .IX Item "-u ABSTRACTIONS" update the specified profile with the comma-separated list of \s-1ABSTRACTIONS\s0. Specifying '' will remove all \s-1ABSTRACTIONS\s0. .IP "\-l" 4 .IX Item "-l" show supported browser abstractions .IP "\-h" 4 .IX Item "-h" show help .SH "BUGS" .IX Header "BUGS" \&\fBaa-update-browser\fR will always add the plugins-common abstraction if the list of abstractions \s-1ABSTRACTIONS\s0 is not empty. .PP If you find any additional bugs, please report them to Launchpad at . .SH "SEE ALSO" .IX Header "SEE ALSO" \&\fIapparmor\fR\|(7) debian/debhelper/0000775000000000000000000000000012315045676011133 5ustar debian/debhelper/dh_apparmor0000664000000000000000000000645412315045675013362 0ustar #!/usr/bin/perl -w =head1 NAME dh_apparmor - reload AppArmor profile and create local include =cut use strict; use Debian::Debhelper::Dh_Lib; =head1 SYNOPSIS B [B<--manifest=>I] B<--profile-name=>I =head1 DESCRIPTION dh_apparmor is a debhelper program that will create/remove the /etc/apparmor.d/local/ include file in maintainer scripts. It also reloads the specified AppArmor profile in postinst using: =over 4 apparmor_parser -r -W -T /etc/apparmor.d/ =back By using '-W -T' we ensure that any abstraction updates are also pulled in. =head1 OPTIONS =over 4 =item B<--profile-name=> Specify the profile name. Eg: dh_apparmor --profile-name=bin.foo dh_apparmor --profile-name=bin.foo -p foo =back =over 4 =item B<--manifest=> Optionally specify a manifest file. When specified, a profile is generated by calling B with the specified manifest file and putting the resulting profile in debian/apparmor/. Eg, if there is a valid manifest in debian/manifest.json, then the following command will create debian/apparmor/bin.bar for the 'bar' package (you will need to clean this up via override_dh_clean or similar). dh_apparmor --manifest=manifest.json --profile-name=bin.bar -p bar Because not all build enviroments support the apparmor kernel interface, B is called with the --no-verify option. Use of this option requires that apparmor-easyprof is installed. =back =head1 NOTES When using modern dh packaging techniques, dh_apparmor can be added to the override_dh_install section of the rules file. Note that for packages that have multiple binary packages, you will want to pass '-p' to dh_apparmor, otherwise dh_apparmor will add AppArmor reload commands for all packages rather than just the one that ships the profile. In addition, you will have to install the profile itself in /etc/apparmor.d. Eg, in the above manifest file example if you are using dh_install you would add to debian/bar.install: =over 4 debian/apparmor/bin.bar etc/apparmor.d =back =cut init(options => { "profile-name=s" => \$dh{PROFILE_NAME}, "manifest-file=s" => \$dh{AA_MANIFEST}, }); my $aa_dir = "debian/apparmor"; foreach my $package (@{$dh{DOPACKAGES}}) { if (! $dh{PROFILE_NAME}) { error("Must specify --profile-name for $package"); } my $pname = $dh{PROFILE_NAME}; autoscript($package,"postinst","postinst-apparmor","s/#PROFILE#/$pname/"); autoscript($package,"postrm","postrm-apparmor","s/#PROFILE#/$pname/"); if ($dh{AA_MANIFEST}) { unless (-e "debian/$dh{AA_MANIFEST}") { error("Could not find debian/$dh{AA_MANIFEST}"); } unless (-x "/usr/bin/aa-easyprof") { error("Could not find aa-easyprof"); } if (! -d "$aa_dir") { mkdir("$aa_dir"); } my $profile_fn = "$aa_dir/$dh{PROFILE_NAME}"; if (-e "$profile_fn") { warning("Regenerating $profile_fn"); unlink("$profile_fn"); } my $tmpdir = tmpdir($package); my $tmp = "$tmpdir/$dh{PROFILE_NAME}.aa-easyprof.tmp"; complex_doit("aa-easyprof --no-verify --manifest=debian/$dh{AA_MANIFEST} > $tmp"); rename("$tmp", "$profile_fn"); } } =head1 SEE ALSO L L This program is a part of debhelper. =head1 AUTHOR Jamie Strandboge =cut debian/debhelper/postrm-apparmor0000664000000000000000000000044312315045675014221 0ustar if [ "$1" = "purge" ] && ! [ -e "/etc/apparmor.d/#PROFILE#" ] ; then rm -f "/etc/apparmor.d/disable/#PROFILE#" || true rm -f "/etc/apparmor.d/force-complain/#PROFILE#" || true rm -f "/etc/apparmor.d/local/#PROFILE#" || true rmdir /etc/apparmor.d/local 2>/dev/null || true fi debian/debhelper/postinst-apparmor0000664000000000000000000000141612315045675014561 0ustar if [ "$1" = "configure" ]; then APP_PROFILE="/etc/apparmor.d/#PROFILE#" if [ -f "$APP_PROFILE" ]; then # Add the local/ include LOCAL_APP_PROFILE="/etc/apparmor.d/local/#PROFILE#" test -e "$LOCAL_APP_PROFILE" || { tmp=`mktemp` cat < "$tmp" # Site-specific additions and overrides for #PROFILE#. # For more details, please see /etc/apparmor.d/local/README. EOM mkdir `dirname "$LOCAL_APP_PROFILE"` 2>/dev/null || true mv -f "$tmp" "$LOCAL_APP_PROFILE" chmod 644 "$LOCAL_APP_PROFILE" } # Reload the profile, including any abstraction updates if aa-status --enabled 2>/dev/null; then apparmor_parser -r -T -W "$APP_PROFILE" || true fi fi fi debian/compat0000664000000000000000000000000212315045675010376 0ustar 9 debian/clean0000664000000000000000000000247112315045675010211 0ustar libraries/libapparmor/config.guess libraries/libapparmor/config.sub libraries/libapparmor/ltmain.sh libraries/libapparmor/Makefile.in libraries/libapparmor/aclocal.m4 libraries/libapparmor/compile libraries/libapparmor/configure libraries/libapparmor/depcomp libraries/libapparmor/install-sh libraries/libapparmor/missing libraries/libapparmor/py-compile libraries/libapparmor/ylwrap libraries/libapparmor/doc/Makefile.in libraries/libapparmor/doc/*.2 libraries/libapparmor/src/Makefile.in libraries/libapparmor/src/af_protos.h libraries/libapparmor/src/grammar.c libraries/libapparmor/src/grammar.h libraries/libapparmor/src/scanner.c libraries/libapparmor/src/scanner.h libraries/libapparmor/swig/Makefile.in libraries/libapparmor/swig/perl/.build-stamp libraries/libapparmor/swig/perl/LibAppArmor.pm libraries/libapparmor/swig/perl/Makefile.in libraries/libapparmor/swig/perl/Makefile.perl libraries/libapparmor/swig/perl/Makefile.perl.old libraries/libapparmor/swig/perl/Makefile.perle libraries/libapparmor/swig/perl/libapparmor_wrap.c libraries/libapparmor/swig/python/Makefile.in libraries/libapparmor/swig/ruby/Makefile.in libraries/libapparmor/testsuite/Makefile.in libraries/libapparmor/testsuite/config/Makefile.in libraries/libapparmor/testsuite/lib/Makefile.in libraries/libapparmor/testsuite/libaalogparse.test/Makefile.in debian/apparmor.dirs0000664000000000000000000000041712315045675011706 0ustar /etc/apparmor.d/cache /etc/apparmor.d/local /etc/apparmor.d/disable /etc/apparmor.d/force-complain /etc/apparmor.d/tunables/home.d /etc/apparmor.d/tunables/multiarch.d /etc/apparmor.d/tunables/xdg-user-dirs.d /lib/apparmor/ /var/cache/apparmor /var/lib/apparmor/profiles debian/apparmor-profiles.dirs0000664000000000000000000000002612315045675013523 0ustar /etc/apparmor.d/local debian/libapache2-mod-apparmor.apache20000664000000000000000000000015312315045675015012 0ustar mod debian/tmp/usr/lib/apache2/modules/mod_apparmor.so mod debian/etc/apache2/mods-available/apparmor.load debian/libapache2-mod-apparmor.maintscript0000664000000000000000000000025012315045675016042 0ustar rm_conffile /etc/apparmor.d/usr.lib.apache2.mpm-prefork.apache2 2.8.0-0ubuntu21~ rm_conffile /etc/apparmor.d/local/usr.lib.apache2.mpm-prefork.apache2 2.8.0-0ubuntu21~ debian/profiles/0000775000000000000000000000000012315045676011024 5ustar debian/profiles/chromium-browser0000664000000000000000000000125612315045675014256 0ustar # This file is updated currently not managed by the package but in the future # will be overwritten on upgrades. # # For site-specific adjustments, please see: # /etc/apparmor.d/local/usr.bin.chromium-browser #include #include #include #include #include #include #include #include #include debian/apparmor-easyprof.install0000664000000000000000000000014112315045675014233 0ustar etc/apparmor/easyprof.conf usr/bin/aa-easyprof usr/share/apparmor/easyprof/ /usr/share/apparmor/ debian/apparmor-notify.manpages0000664000000000000000000000005212315045675014041 0ustar debian/tmp/usr/share/man/man8/aa-notify.8 debian/libapache2-mod-apparmor.manpages0000664000000000000000000000005512315045675015303 0ustar debian/tmp/usr/share/man/man8/mod_apparmor.8 debian/apparmor-easyprof.manpages0000664000000000000000000000005412315045675014363 0ustar debian/tmp/usr/share/man/man8/aa-easyprof.8 debian/libpam-apparmor.docs0000664000000000000000000000003612315045675013134 0ustar changehat/pam_apparmor/README debian/etc/0000775000000000000000000000000012315045674007752 5ustar debian/etc/apache2/0000775000000000000000000000000012315045674011255 5ustar debian/etc/apache2/mods-available/0000775000000000000000000000000012315045676014137 5ustar debian/etc/apache2/mods-available/apparmor.load0000664000000000000000000000010412315045675016613 0ustar LoadModule apparmor_module /usr/lib/apache2/modules/mod_apparmor.so debian/apparmor.prerm0000664000000000000000000000127412315045675012074 0ustar #!/bin/sh # prerm script for apparmor # # see: dh_installdeb(1) set -e # summary of how this script can be called: # * `remove' # * `upgrade' # * `failed-upgrade' # * `remove' `in-favour' # * `deconfigure' `in-favour' # `removing' # # for details, see http://www.debian.org/doc/debian-policy/ or # the debian-policy package # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# exit 0 debian/apparmor.postrm0000664000000000000000000000253712315045675012276 0ustar #!/bin/sh # postrm script for apparmor # # see: dh_installdeb(1) set -e # summary of how this script can be called: # * `remove' # * `purge' # * `upgrade' # * `failed-upgrade' # * `abort-install' # * `abort-install' # * `abort-upgrade' # * `disappear' # # for details, see http://www.debian.org/doc/debian-policy/ or # the debian-policy package case "$1" in purge) if [ -e /usr/share/debconf/confmodule ]; then . /usr/share/debconf/confmodule db_purge fi if [ -e "/etc/apparmor.d/tunables/home.d/ubuntu" ]; then rm -f /etc/apparmor.d/tunables/home.d/ubuntu fi if [ -e "/etc/apparmor.d/tunables/xdg-user-dirs.d/site.local" ]; then rm -f /etc/apparmor.d/tunables/xdg-user-dirs.d/site.local fi ;; abort-install|abort-upgrade|remove|upgrade|failed-upgrade|disappear) ;; *) echo "postrm called with unknown argument \`$1'" >&2 exit 1 ;; esac # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# exit 0 debian/vim-apparmor.yaml0000664000000000000000000000014612315045675012477 0ustar addon: apparmor description: "syntax highlighting for AppArmor files" files: - syntax/apparmor.vim debian/apparmor.preinst0000664000000000000000000000056212315045675012432 0ustar #!/bin/sh # preinst script for apparmor # # see: dh_installdeb(1) set -e case "$1" in install|upgrade|abort-upgrade) # Nothing to do ;; *) echo "preinst called with unknown argument \`$1'" >&2 exit 1 ;; esac # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# exit 0 debian/libapparmor-perl.install0000664000000000000000000000002012315045675014030 0ustar usr/lib/perl5/* debian/libapache2-mod-apparmor.preinst0000664000000000000000000000126612315045675015201 0ustar #!/bin/sh # preinst script for libapache2-mod-apparmor # # see: dh_installdeb(1) set -e APP_PROFILE="usr.sbin.apache2" APP_CONFFILE="/etc/apparmor.d/$APP_PROFILE" APP_DISABLE="/etc/apparmor.d/disable/$APP_PROFILE" if [ "$1" = "install" ] || [ "$1" = "upgrade" ]; then # Disable AppArmor profile on install or upgrade from earlier than when we # first shipped the profile if the user does not already have a profile # defined if dpkg --compare-versions "$2" lt 2.8.0-0ubuntu21 ; then if [ ! -e "$APP_CONFFILE" ]; then mkdir -p `dirname $APP_DISABLE` 2>/dev/null || true ln -sf $APP_CONFFILE $APP_DISABLE fi fi fi #DEBHELPER# exit 0 debian/source/0000775000000000000000000000000012315045676010501 5ustar debian/source/format0000664000000000000000000000001412315045675011706 0ustar 3.0 (quilt) debian/apparmor-notify.install0000664000000000000000000000017712315045675013724 0ustar debian/notify/notify.conf /etc/apparmor/ debian/notify/apparmor-notify.desktop /etc/xdg/autostart usr/sbin/aa-notify /usr/bin/ debian/libapache2-mod-apparmor.dirs0000664000000000000000000000003212315045675014444 0ustar /etc/apparmor.d/apache2.d debian/po/0000775000000000000000000000000012315045676007617 5ustar debian/po/zh_CN.po0000664000000000000000000000305712315045675011164 0ustar # Simplified Chinese translation of apparmor debconf. # Copyright (C) 2011 Free Software Foundation, Inc. # This file is distributed under the same license as the apparmor package. # Aron Xu , 2011. # msgid "" msgstr "" "Project-Id-Version: apparmor 2.6.1-3\n" "Report-Msgid-Bugs-To: apparmor@lists.ubuntu.com\n" "POT-Creation-Date: 2010-01-05 17:45-0600\n" "PO-Revision-Date: 2011-05-02 15:53+0800\n" "Last-Translator: Aron Xu \n" "Language-Team: Chinese (simplified) \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: string #. Description #: ../templates:1001 msgid "Additional home directory locations:" msgstr "附加主目录位置:" #. Type: string #. Description #: ../templates:1001 msgid "" "Please enter a space separated list of any additional locations for user " "home directories. These locations are in addition to those specified in /etc/" "apparmor.d/tunables/home and must end with a '/'." msgstr "" "请输入用户主目录位置,多个位置请使用空格分隔。这些位置将作为 " "/etc/apparmor.d/tunables/home 中已指定的目录的补充,每个目录必须以“/”结尾。" #. Type: string #. Description #: ../templates:1001 msgid "" "Example: if user's directories are stored in /srv/nfs/home and /mnt/homes, " "you should enter \"/srv/nfs/home/ /mnt/homes/\"." msgstr "" "例如:如果用户目录存放于 /srv/nfs/home 和 /mnt/homes,您应当输入" "“/srv/nfs/home/ /mnt/homes/”。" debian/po/es.po0000664000000000000000000000457212315045675010575 0ustar # apparmor po-debconf translation to Spanish # Copyright (C) 2011 Software in the Public Interest # This file is distributed under the same license as the apparmor package. # # Changes: # - Initial translation # Francisco Javier Cuadrado , 2011 # # Traductores, si no conocen el formato PO, merece la pena leer la # documentación de gettext, especialmente las secciones dedicadas a este # formato, por ejemplo ejecutando: # info -n '(gettext)PO Files' # info -n '(gettext)Header Entry' # # Equipo de traducción al español, por favor, lean antes de traducir # los siguientes documentos: # # - El proyecto de traducción de Debian al español # http://www.debian.org/intl/spanish/ # especialmente las notas de traducción en # http://www.debian.org/intl/spanish/notas # # - La guía de traducción de po's de debconf: # /usr/share/doc/po-debconf/README-trans # o http://www.debian.org/intl/l10n/po-debconf/README-trans # msgid "" msgstr "" "Project-Id-Version: apparmor 2.6.1-3\n" "Report-Msgid-Bugs-To: apparmor@lists.ubuntu.com\n" "POT-Creation-Date: 2010-01-05 17:45-0600\n" "PO-Revision-Date: 2011-05-06 13:45+0100\n" "Last-Translator: Francisco Javier Cuadrado \n" "Language-Team: Debian l10n Spanish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: string #. Description #: ../templates:1001 msgid "Additional home directory locations:" msgstr "Rutas adicionales de los directorios personales:" #. Type: string #. Description #: ../templates:1001 msgid "Please enter a space separated list of any additional locations for user home directories. These locations are in addition to those specified in /etc/apparmor.d/tunables/home and must end with a '/'." msgstr "Introduzca una lista separada por espacios con las rutas adicionales para los directorios personales. Estas rutas se suman a las indicadas en «/etc/apparmor.d/tunables/home» y deben terminar con una barra «/»." #. Type: string #. Description #: ../templates:1001 msgid "Example: if user's directories are stored in /srv/nfs/home and /mnt/homes, you should enter \"/srv/nfs/home/ /mnt/homes/\"." msgstr "Por ejemplo: si los directorios del usuario están ubicados en «/srv/nfs/home» y «/mnt/homes», debería introducir «/srv/nfs/home/ /mnt/homes/»." debian/po/pt.po0000664000000000000000000000321612315045675010603 0ustar # Portuguese apparmor debconf translation # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the apparmor package. # Pedro Ribeiro , 2011 # msgid "" msgstr "" "Project-Id-Version: apparmor 2.7.0~beta1+bzr1774-1\n" "Report-Msgid-Bugs-To: apparmor@lists.ubuntu.com\n" "POT-Creation-Date: 2010-01-05 17:45-0600\n" "PO-Revision-Date: 2011-12-06 00:05+0000\n" "Last-Translator: Pedro Ribeiro , 2011\n" "Language-Team: Portuguese \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: string #. Description #: ../templates:1001 msgid "Additional home directory locations:" msgstr "Localizações adicionais para o directório home:" #. Type: string #. Description #: ../templates:1001 msgid "" "Please enter a space separated list of any additional locations for user " "home directories. These locations are in addition to those specified in /etc/" "apparmor.d/tunables/home and must end with a '/'." msgstr "" "Indique por favor uma lista de localizações adicionais para os directórios " "home de utilizador, separadas por espaços. Estas localizações serão " "acrescentadas às indicadas em /etc/apparmor.d/tunables/home e têm que " "terminar com '/'." #. Type: string #. Description #: ../templates:1001 msgid "" "Example: if user's directories are stored in /srv/nfs/home and /mnt/homes, " "you should enter \"/srv/nfs/home/ /mnt/homes/\"." msgstr "" "Exemplo: se os directórios de utilizador estiverem em /srv/nfs/home e " "/mnt/homes, deve indicar \"/srv/nfs/home/ /mnt/homes/\"." debian/po/templates.pot0000664000000000000000000000223512315045675012342 0ustar # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: apparmor@lists.ubuntu.com\n" "POT-Creation-Date: 2010-01-05 17:45-0600\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" #. Type: string #. Description #: ../templates:1001 msgid "Additional home directory locations:" msgstr "" #. Type: string #. Description #: ../templates:1001 msgid "" "Please enter a space separated list of any additional locations for user " "home directories. These locations are in addition to those specified in /etc/" "apparmor.d/tunables/home and must end with a '/'." msgstr "" #. Type: string #. Description #: ../templates:1001 msgid "" "Example: if user's directories are stored in /srv/nfs/home and /mnt/homes, " "you should enter \"/srv/nfs/home/ /mnt/homes/\"." msgstr "" debian/po/ja.po0000664000000000000000000000323012315045675010546 0ustar # Copyright (C) 2010 Kees Cook # This file is distributed under the same license as the apparmor package. # Hideki Yamane , 2011. # msgid "" msgstr "" "Project-Id-Version: apparmor 2.6.1-3\n" "Report-Msgid-Bugs-To: apparmor@lists.ubuntu.com\n" "POT-Creation-Date: 2010-01-05 17:45-0600\n" "PO-Revision-Date: 2011-05-03 10:52+0900\n" "Last-Translator: Hideki Yamane \n" "Language-Team: Japanese \n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: string #. Description #: ../templates:1001 msgid "Additional home directory locations:" msgstr "追加のホームディレクトリの場所:" #. Type: string #. Description #: ../templates:1001 msgid "" "Please enter a space separated list of any additional locations for user " "home directories. These locations are in addition to those specified in /etc/" "apparmor.d/tunables/home and must end with a '/'." msgstr "" "空白で区切ったユーザのホームディレクトリの追加の場所一覧を入力してください。" "これらの場所は、/etc/apparmor.d/tunables/home で指定したものへの追加で、" "'/' で終わっている必要があります。" #. Type: string #. Description #: ../templates:1001 msgid "" "Example: if user's directories are stored in /srv/nfs/home and /mnt/homes, " "you should enter \"/srv/nfs/home/ /mnt/homes/\"." msgstr "" "例: ユーザのディレクトリが /srv/nfs/home と /mnt/homes に保存されている場合、" "「/srv/nfs/home/ /mnt/homes/」と入力する必要があります。" debian/po/cs.po0000664000000000000000000000320212315045675010560 0ustar # Czech PO debconf template translation of apparmor. # Copyright (C) 2010 Michal Simunek # This file is distributed under the same license as the apparmor package. # Michal Simunek , 2011. # msgid "" msgstr "" "Project-Id-Version: apparmor 2.6.1-3\n" "Report-Msgid-Bugs-To: apparmor@lists.ubuntu.com\n" "POT-Creation-Date: 2010-01-05 17:45-0600\n" "PO-Revision-Date: 2011-05-03 17:31+0200\n" "Last-Translator: Michal Simunek \n" "Language-Team: Czech \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: string #. Description #: ../templates:1001 msgid "Additional home directory locations:" msgstr "Další umístění domovských adresářů:" #. Type: string #. Description #: ../templates:1001 msgid "" "Please enter a space separated list of any additional locations for user " "home directories. These locations are in addition to those specified in /etc/" "apparmor.d/tunables/home and must end with a '/'." msgstr "" "Zadejte prosím mezerami oddělený seznam všech dalších umístění pro domovské " "adresáře uživatelů. Tato umístění rozšiřují ta, která jsou uvedena v /etc/" "apparmor.d/tunables/home a musí být zakončena '/'." #. Type: string #. Description #: ../templates:1001 msgid "" "Example: if user's directories are stored in /srv/nfs/home and /mnt/homes, " "you should enter \"/srv/nfs/home/ /mnt/homes/\"." msgstr "" "Nacházejí-li se například adresáře uživatelů v /srv/nfs/home a /mnt/homes, " "zadejte \"/srv/nfs/home/ /mnt/homes/\"." debian/po/da.po0000664000000000000000000000306312315045675010544 0ustar # Danish translation apparmor. # Copyright (C) 2011 apparmor & nedenstående oversættere. # This file is distributed under the same license as the apparmor package. # Joe Hansen , 2011. # msgid "" msgstr "" "Project-Id-Version: apparmor\n" "Report-Msgid-Bugs-To: apparmor@lists.ubuntu.com\n" "POT-Creation-Date: 2010-01-05 17:45-0600\n" "PO-Revision-Date: 2011-05-02 17:30+01:00\n" "Last-Translator: Joe Hansen \n" "Language-Team: Danish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: string #. Description #: ../templates:1001 msgid "Additional home directory locations:" msgstr "Yderligere placeringer af hjemmemapper:" #. Type: string #. Description #: ../templates:1001 msgid "" "Please enter a space separated list of any additional locations for user " "home directories. These locations are in addition to those specified in /etc/" "apparmor.d/tunables/home and must end with a '/'." msgstr "" "Indtast venligst en mellemrumsadskilt liste af alle yderligere placeringer for " "brugerhjemmemapper. Disse placeringer er udover de i /etc/apparmor.d/tunables/home " "angivne og skal afsluttes med et »/«." #. Type: string #. Description #: ../templates:1001 msgid "" "Example: if user's directories are stored in /srv/nfs/home and /mnt/homes, " "you should enter \"/srv/nfs/home/ /mnt/homes/\"." msgstr "" "Eksempel: Hvis brugerens mapper er gemt i /srv/nfs/home og /mnt/homes, " "skal du indtaste »/srv/nfs/home/ /mnt/homes/«." debian/po/ru.po0000664000000000000000000000366412315045675010615 0ustar # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the apparmor package. # # Yuri Kozlov , 2011. msgid "" msgstr "" "Project-Id-Version: apparmor 2.6.1-2\n" "Report-Msgid-Bugs-To: apparmor@lists.ubuntu.com\n" "POT-Creation-Date: 2010-01-05 17:45-0600\n" "PO-Revision-Date: 2011-05-01 10:19+0400\n" "Last-Translator: Yuri Kozlov \n" "Language-Team: Russian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Lokalize 1.0\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" #. Type: string #. Description #: ../templates:1001 msgid "Additional home directory locations:" msgstr "Дополнительные места расположения домашних каталогов:" #. Type: string #. Description #: ../templates:1001 msgid "" "Please enter a space separated list of any additional locations for user " "home directories. These locations are in addition to those specified in /etc/" "apparmor.d/tunables/home and must end with a '/'." msgstr "" "Введите через пробел дополнительные места расположения " "домашних каталогов пользователей. " "Эти места добавятся к указанным в /etc/apparmor.d/tunables/home " "и должны заканчиваться символом «/»." #. Type: string #. Description #: ../templates:1001 msgid "" "Example: if user's directories are stored in /srv/nfs/home and /mnt/homes, " "you should enter \"/srv/nfs/home/ /mnt/homes/\"." msgstr "" "Пример: если домашние каталоги пользователей находятся в /srv/nfs/home и " "/mnt/homes, " "то введите «/srv/nfs/home/ /mnt/homes/»." debian/po/POTFILES.in0000664000000000000000000000004412315045675011371 0ustar [type: gettext/rfc822deb] templates debian/po/nl.po0000664000000000000000000000316412315045675010573 0ustar # Dutch translation of apparmor debconf templates. # Copyright (C) 2011 THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the apparmor package. # Jeroen Schot , 2011. # msgid "" msgstr "" "Project-Id-Version: apparmor_2.6.1-3\n" "Report-Msgid-Bugs-To: apparmor@lists.ubuntu.com\n" "POT-Creation-Date: 2010-01-05 17:45-0600\n" "PO-Revision-Date: 2011-05-10 14:17+0200\n" "Last-Translator: Jeroen Schot \n" "Language-Team: Debian l10n Dutch \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: nl\n" #. Type: string #. Description #: ../templates:1001 msgid "Additional home directory locations:" msgstr "Extra locaties van thuismappen:" #. Type: string #. Description #: ../templates:1001 msgid "" "Please enter a space separated list of any additional locations for user " "home directories. These locations are in addition to those specified in /etc/" "apparmor.d/tunables/home and must end with a '/'." msgstr "" "Voer alstublieft een door spaties gescheiden lijst van extra " "thuismappen van gebruikers in. Deze locaties zijn een toevoeging op die in /etc/" "apparmor.d/tunables/home en moeten met een '/' eindigen." #. Type: string #. Description #: ../templates:1001 msgid "" "Example: if user's directories are stored in /srv/nfs/home and /mnt/homes, " "you should enter \"/srv/nfs/home/ /mnt/homes/\"." msgstr "" "Voorbeeld: Als de thuismappen van gebruikers zich in /srv/nfs/home " "en /mnt/homes bevinden dient u \"/srv/nfs/home/ /mnt/homes/\" in te voeren." debian/po/it.po0000664000000000000000000000313012315045675010567 0ustar # Italian translation of apparmor'S PO-DEBCONF FILE. # Copyright (C) 2011 THE apparmor'S COPYRIGHT HOLDER # This file is distributed under the same license as the apparmor package. # Dario Santamaria , 2011. # msgid "" msgstr "" "Project-Id-Version: 2.6.1-3\n" "Report-Msgid-Bugs-To: apparmor@lists.ubuntu.com\n" "POT-Creation-Date: 2010-01-05 17:45-0600\n" "PO-Revision-Date: 2011-05-04 00:01+0200\n" "Last-Translator: Dario Santamaria \n" "Language-Team: Italian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: string #. Description #: ../templates:1001 msgid "Additional home directory locations:" msgstr "Posizioni aggiuntive per directory home:" #. Type: string #. Description #: ../templates:1001 msgid "" "Please enter a space separated list of any additional locations for user " "home directories. These locations are in addition to those specified in /etc/" "apparmor.d/tunables/home and must end with a '/'." msgstr "" "Inserire un elenco separato da spazi di posizioni aggiuntive per le directory " "home utente. Questi percorsi vanno ad aggiungersi a quelli specificati in " "/etc/apparmor.d/tunables/home e devono terminare con una «/»." #. Type: string #. Description #: ../templates:1001 msgid "" "Example: if user's directories are stored in /srv/nfs/home and /mnt/homes, " "you should enter \"/srv/nfs/home/ /mnt/homes/\"." msgstr "" "Esempio: se le directory home utente si trovano in /srv/nfs/home e " "/mnt/homes, inserire \"/srv/nfs/home/ /mnt/homes/\"." debian/po/de.po0000664000000000000000000000316412315045675010552 0ustar # German translation of apparmor. # This file is distributed under the same license as the apparmor package. # Copyright (C) Chris Leick , 2011. # msgid "" msgstr "" "Project-Id-Version: apparmor 2.6.1-3\n" "Report-Msgid-Bugs-To: apparmor@lists.ubuntu.com\n" "POT-Creation-Date: 2010-01-05 17:45-0600\n" "PO-Revision-Date: 2011-05-02 23:05+0100\n" "Last-Translator: Chris Leick \n" "Language-Team: Debian German \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: string #. Description #: ../templates:1001 msgid "Additional home directory locations:" msgstr "Zusätzliche Speicherorte für Home-Verzeichnisse:" #. Type: string #. Description #: ../templates:1001 msgid "" "Please enter a space separated list of any additional locations for user " "home directories. These locations are in addition to those specified in /etc/" "apparmor.d/tunables/home and must end with a '/'." msgstr "" "Bitte geben Sie eine durch Leerzeichen getrennte Liste zusätzlicher " "Speicherorte für die Home-Verzeichnisse der Benutzer ein. Diese Speicherorte " "ergänzen die, die in /etc/apparmor.d/tunables/home angegeben sind und müssen " "mit einem »/« enden." #. Type: string #. Description #: ../templates:1001 msgid "" "Example: if user's directories are stored in /srv/nfs/home and /mnt/homes, " "you should enter \"/srv/nfs/home/ /mnt/homes/\"." msgstr "" "Beispiel: Falls die Verzeichnisse der Anwender in /srv/nfs/home und " "/mnt/homes gespeichert sind, sollten Sie »/srv/nfs/home/ /mnt/homes/« " "eingeben." debian/po/sv.po0000664000000000000000000000320412315045675010605 0ustar # Translation of apparmor debconf template to Swedish # Copyright (C) 2011 Martin Bagge # This file is distributed under the same license as the apparmor package. # # Martin Bagge , 2011 msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: apparmor@lists.ubuntu.com\n" "POT-Creation-Date: 2010-01-05 17:45-0600\n" "PO-Revision-Date: 2011-05-02 23:44+0100\n" "Last-Translator: Martin Bagge / brother \n" "Language-Team: Swedish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Poedit-Language: Swedish\n" "X-Poedit-Country: Sweden\n" #. Type: string #. Description #: ../templates:1001 msgid "Additional home directory locations:" msgstr "Ytterligare sökvägar till hemkataloger:" #. Type: string #. Description #: ../templates:1001 msgid "" "Please enter a space separated list of any additional locations for user " "home directories. These locations are in addition to those specified in /etc/" "apparmor.d/tunables/home and must end with a '/'." msgstr "" "Ange en ytterligare sökvägar till användares hemkataloger separera med " "mellanslag. Dessa sökvägar är utöver de som anges i /etc/apparmor.d/tunables/" "home och måste sluta på \"/\"." #. Type: string #. Description #: ../templates:1001 msgid "" "Example: if user's directories are stored in /srv/nfs/home and /mnt/homes, " "you should enter \"/srv/nfs/home/ /mnt/homes/\"." msgstr "" "Exempel: Om användares hemkataloger finns i /srv/nfs/home och /mnt/homes så " "ska du ange \"/srv/nfs/home/ /mnt/homes/\"." debian/po/fr.po0000664000000000000000000000337212315045675010572 0ustar # Translation of apparmor debconf templates to French # Copyright (C) 2011 Debian French l10n team # This file is distributed under the same license as the APPARMOR package. # Julien Patriarca , 2011. # msgid "" msgstr "" "Project-Id-Version: apparmor\n" "Report-Msgid-Bugs-To: apparmor@lists.ubuntu.com\n" "POT-Creation-Date: 2010-01-05 17:45-0600\n" "PO-Revision-Date: 2011-05-16 11:05+0100\n" "Last-Translator: Julien Patriarca \n" "Language-Team: FRENCH \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: string #. Description #: ../templates:1001 msgid "Additional home directory locations:" msgstr "Emplacement du répertoire personnel supplémentaire :" #. Type: string #. Description #: ../templates:1001 msgid "" "Please enter a space separated list of any additional locations for user " "home directories. These locations are in addition to those specified in /etc/" "apparmor.d/tunables/home and must end with a '/'." msgstr "" "Veuillez indiquer, séparés par des espaces, les emplacements des répertoires " "personnels (« home ») supplémentaires des utilisateurs. Ces répertoires " "seront ajoutés à ceux qui sont indiqués dans /etc/apparmor.d/tunables/home ; " "ils doivent se terminer par un « / »." #. Type: string #. Description #: ../templates:1001 msgid "" "Example: if user's directories are stored in /srv/nfs/home and /mnt/homes, " "you should enter \"/srv/nfs/home/ /mnt/homes/\"." msgstr "" "Exemple : si les répertoires des utilisateurs sont stockés dans /srv/nfs/" "home et /mnt/homes, vous devriez entrer « /srv/nfs/home/ /mnt/homes/ »." debian/watch0000664000000000000000000000015312315045675010230 0ustar version=3 http://launchpad.net/apparmor/+download/ http://launchpad.net/apparmor/.*/AppArmor-(.*)\.tar\.gz debian/apparmor.init0000664000000000000000000001076412315045675011716 0ustar #!/bin/sh # ---------------------------------------------------------------------- # Copyright (c) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 # NOVELL (All rights reserved) # Copyright (c) 2008, 2009 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. # # You should have received a copy of the GNU General Public License # along with this program; if not, contact Novell, Inc. # ---------------------------------------------------------------------- # Authors: # Steve Beattie # Kees Cook # # /etc/init.d/apparmor # ### BEGIN INIT INFO # Provides: apparmor # Required-Start: $remote_fs # Required-Stop: umountfs # Default-Start: S # Default-Stop: # Short-Description: AppArmor initialization # Description: AppArmor init script. This script loads all AppArmor profiles. ### END INIT INFO . /lib/apparmor/functions . /lib/lsb/init-functions usage() { echo "Usage: $0 {start|stop|restart|reload|force-reload|status|recache}" } test -x ${PARSER} || exit 0 # by debian policy # LSM is built-in, so it is either there or not enabled for this boot test -d /sys/module/apparmor || exit 0 securityfs() { # Need securityfs for any mode if [ ! -d "${AA_SFS}" ]; then if cut -d" " -f2,3 /proc/mounts | grep -q "^${SECURITYFS} securityfs"'$' ; then log_action_msg "AppArmor not available as kernel LSM." log_end_msg 1 exit 1 else log_action_begin_msg "Mounting securityfs on ${SECURITYFS}" if ! mount -t securityfs none "${SECURITYFS}"; then log_action_end_msg 1 log_end_msg 1 exit 1 fi fi fi if [ ! -w "$AA_SFS"/.load ]; then log_action_msg "Insufficient privileges to change profiles." log_end_msg 1 exit 1 fi } # Allow "recache" even when running on the liveCD if [ "$1" = "recache" ]; then log_daemon_msg "Recaching AppArmor profiles" recache_profiles rc=$? log_end_msg "$rc" exit $rc fi # do not perform start/stop/reload actions when running from liveCD test -d /rofs/etc/apparmor.d && exit 0 rc=255 case "$1" in start) if [ -x /bin/running-in-container ] && /bin/running-in-container; then log_daemon_msg "Not starting AppArmor in container" log_end_msg 0 exit 0 fi log_daemon_msg "Starting AppArmor profiles" securityfs load_configured_profiles rc=$? log_end_msg "$rc" ;; stop) log_daemon_msg "Clearing AppArmor profiles cache" clear_cache rc=$? log_end_msg "$rc" cat >&2 < "$aa_configured" || exit 1 aa_loaded=$(mktemp -t aa-XXXXXX) running_profile_names > "$aa_loaded" || exit 1 LC_COLLATE=C comm -2 -3 "$aa_loaded" "$aa_configured" | while read profile ; do unload_profile "$profile" done rm -f "$aa_configured" "$aa_loaded" log_end_msg "$rc" ;; status) securityfs if [ -x /usr/sbin/aa-status ]; then aa-status --verbose else cat "$AA_SFS"/profiles fi rc=$? ;; *) usage rc=1 ;; esac exit $rc debian/libapache2-mod-apparmor.install0000664000000000000000000000010612315045675015153 0ustar etc/apparmor.d/usr.sbin.apache2 etc/apparmor.d/local/usr.sbin.apache2 debian/lib/0000775000000000000000000000000012315045674007745 5ustar debian/lib/apparmor/0000775000000000000000000000000012315045676011570 5ustar debian/lib/apparmor/functions0000664000000000000000000000677212315045675013536 0ustar # /lib/apparmor/functions for Debian -*- shell-script -*- # ---------------------------------------------------------------------- # Copyright (c) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 # NOVELL (All rights reserved) # Copyright (c) 2008-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 # 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. # ---------------------------------------------------------------------- # Authors: # Kees Cook PROFILES="/etc/apparmor.d" PROFILES_CACHE="$PROFILES/cache" PROFILES_VAR="/var/lib/apparmor/profiles" PROFILES_CACHE_VAR="/var/cache/apparmor" PARSER="/sbin/apparmor_parser" SECURITYFS="/sys/kernel/security" export AA_SFS="$SECURITYFS/apparmor" # Suppress warnings when booting in quiet mode quiet_arg="" [ "${QUIET:-no}" = yes ] && quiet_arg="-q" [ "${quiet:-n}" = y ] && quiet_arg="-q" foreach_configured_profile() { for pdir in "$PROFILES" "$PROFILES_VAR" ; do if [ ! -d "$pdir" ]; then continue fi num=`find "$pdir" -type f ! -name '*.md5sums' | wc -l` if [ "$num" = "0" ]; then continue fi cache_args="--cache-loc=$PROFILES_CACHE" if [ "$pdir" = "$PROFILES_VAR" ] && [ -d "$PROFILES_CACHE_VAR" ]; then cache_args="--cache-loc=$PROFILES_CACHE_VAR" fi (ls -1 "$pdir" | egrep -v '(\.dpkg-(new|old|dist|bak)|~)$' | \ while read profile; do if [ -f "$pdir"/"$profile" ]; then echo "$pdir"/"$profile" fi done) | \ xargs -n1 -d"\n" -P$(getconf _NPROCESSORS_ONLN) "$PARSER" "$@" "$cache_args" -- done } load_configured_profiles() { clear_cache_if_outdated foreach_configured_profile $quiet_arg --write-cache --replace } load_configured_profiles_without_caching() { foreach_configured_profile $quiet_arg --replace } recache_profiles() { clear_cache foreach_configured_profile $quiet_arg --write-cache --skip-kernel-load } configured_profile_names() { foreach_configured_profile $quiet_arg -N 2>/dev/null | LC_COLLATE=C sort | grep -v '//' } running_profile_names() { # Output a sorted list of loaded profiles, skipping libvirt's # dynamically generated files cat "$AA_SFS"/profiles | sed -e "s/ (\(enforce\|complain\))$//" | egrep -v '^libvirt-[0-9a-f\-]+$' | LC_COLLATE=C sort | grep -v '//' } unload_profile() { echo -n "$1" > "$AA_SFS"/.remove } clear_cache() { find "$PROFILES_CACHE" -maxdepth 1 -type f -print0 | xargs -0 rm -f -- find "$PROFILES_CACHE_VAR" -maxdepth 1 -type f -print0 | xargs -0 rm -f -- } read_features_dir() { for f in `ls -AU "$1"` ; do if [ -f "$1/$f" ] ; then read -r KF < "$1/$f" || true echo -n "$f {$KF } " elif [ -d "$1/$f" ] ; then echo -n "$f {" KF=`read_features_dir "$1/$f"` || true echo -n "$KF} " fi done } clear_cache_if_outdated() { if [ -r "$PROFILES_CACHE"/.features ]; then if [ -d "$AA_SFS"/features ]; then KERN_FEATURES=`read_features_dir "$AA_SFS"/features` else read -r KERN_FEATURES < "$AA_SFS"/features fi CACHE_FEATURES=`tr '\n' ' ' < "$PROFILES_CACHE"/.features` if [ "$KERN_FEATURES" != "$CACHE_FEATURES" ]; then clear_cache fi fi } debian/python3-apparmor.install0000664000000000000000000000005112315045675014007 0ustar usr/lib/python3*/dist-packages/apparmor* debian/apparmor.config0000664000000000000000000000017412315045675012212 0ustar #!/bin/sh set -e # debconf . /usr/share/debconf/confmodule db_version 2.0 db_input medium apparmor/homedirs || true db_go debian/libapache2-mod-apparmor.postinst0000664000000000000000000000260112315045675015372 0ustar #!/bin/sh # postinst script for libapache2-mod-apparmor # # see: dh_installdeb(1) set -e # summary of how this script can be called: # * `configure' # * `abort-upgrade' # * `abort-remove' `in-favour' # # * `abort-remove' # * `abort-deconfigure' `in-favour' # `removing' # # for details, see http://www.debian.org/doc/debian-policy/ or # the debian-policy package case "$1" in configure) APP_PROFILE="/etc/apparmor.d/usr.sbin.apache2" if [ -f "$APP_PROFILE" ] && aa-status --enabled 2>/dev/null; then apparmor_parser -rTW "$APP_PROFILE" || true fi # 2.8.0-0ubuntu21 no longer ships usr.lib.apache2.mpm-prefork.apache2 if dpkg --compare-versions "$2" lt-nl "2.8.0-0ubuntu21" ; then rm -f /etc/apparmor.d/disable/usr.lib.apache2.mpm-prefork.apache2 fi ;; abort-upgrade|abort-remove|abort-deconfigure) ;; *) echo "postinst called with unknown argument \`$1'" >&2 exit 1 ;; esac # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# exit 0 debian/python-libapparmor.install0000664000000000000000000000005412315045675014416 0ustar usr/lib/python2*/dist-packages/LibAppArmor* debian/libapparmor-dev.manpages0000664000000000000000000000027512315045675014005 0ustar debian/tmp/usr/share/man/man2/aa_change_hat.2 debian/tmp/usr/share/man/man2/aa_change_profile.2 debian/tmp/usr/share/man/man2/aa_find_mountpoint.2 debian/tmp/usr/share/man/man2/aa_getcon.2 debian/dh-apparmor.install0000664000000000000000000000025112315045675013000 0ustar debian/debhelper/dh_apparmor usr/bin debian/debhelper/postinst-apparmor usr/share/debhelper/autoscripts debian/debhelper/postrm-apparmor usr/share/debhelper/autoscripts debian/apparmor.manpages0000664000000000000000000000054212315045675012537 0ustar debian/tmp/usr/share/man/man5/subdomain.conf.5 debian/tmp/usr/share/man/man5/apparmor.vim.5 debian/tmp/usr/share/man/man5/apparmor.d.5 debian/tmp/usr/share/man/man8/apparmor_parser.8 debian/tmp/usr/share/man/man7/apparmor.7 debian/tmp/usr/share/man/man8/aa-exec.8 debian/tmp/usr/share/man/man8/aa-status.8 debian/tmp/usr/share/man/man8/apparmor_status.8 debian/libapparmor1.symbols0000664000000000000000000000177612315045675013216 0ustar libapparmor.so.1 libapparmor1 #MINVER# APPARMOR_1.0@APPARMOR_1.0 2.6~devel APPARMOR_1.1@APPARMOR_1.1 2.6~devel APPARMOR_2.9@APPARMOR_2.9 2.8.94-0ubuntu1 IMMUNIX_1.0@IMMUNIX_1.0 2.6~devel aa_change_hat@APPARMOR_1.1 2.6~devel aa_change_hat_vargs@APPARMOR_1.1 2.6~devel aa_change_hatv@APPARMOR_1.1 2.6~devel aa_change_onexec@APPARMOR_1.1 2.6~devel aa_change_profile@APPARMOR_1.1 2.6~devel aa_find_mountpoint@APPARMOR_1.1 2.7.0~beta1+bzr1772 aa_getcon@APPARMOR_1.1 2.7.0~beta1+bzr1772 aa_getpeercon@APPARMOR_1.1 2.7.0~beta1+bzr1772 aa_getpeercon_raw@APPARMOR_1.1 2.7.0~beta1+bzr1772 aa_getprocattr@APPARMOR_1.1 2.7.0~beta1+bzr1772 aa_getprocattr_raw@APPARMOR_1.1 2.7.0~beta1+bzr1772 aa_gettaskcon@APPARMOR_1.1 2.7.0~beta1+bzr1772 aa_is_enabled@APPARMOR_1.1 2.7.0~beta1+bzr1772 aa_query_label@APPARMOR_1.1 2.8.94-0ubuntu1 aa_query_label@APPARMOR_2.9 2.8.94-0ubuntu1 change_hat@APPARMOR_1.0 2.6~devel change_hat@IMMUNIX_1.0 2.6~devel free_record@APPARMOR_1.0 2.6~devel parse_record@APPARMOR_1.0 2.6~devel debian/control0000664000000000000000000001611212317446026010601 0ustar Source: apparmor Section: admin Priority: extra Maintainer: Ubuntu Developers XSBC-Original-Maintainer: Kees Cook Build-Depends: debhelper (>= 8.1.2), flex, bison, bzip2, apache2-dev, dh-apache2, libpam-dev, autotools-dev, libtool, automake, autoconf, chrpath, texlive-latex-base, texlive-latex-recommended, swig, po-debconf, dejagnu, python-all-dev, python, python3-all-dev, python3, perl (>= 5.8.0), liblocale-gettext-perl, pkg-config Standards-Version: 3.9.4 Homepage: http://apparmor.net/ Vcs-Bzr: https://code.launchpad.net/~ubuntu-core-dev/apparmor/master Package: apparmor Architecture: any Pre-Depends: ${misc:Pre-Depends} Depends: ${shlibs:Depends}, ${misc:Depends}, ${python3:Depends}, libapparmor-perl, lsb-base, initramfs-tools [linux-any], debconf Breaks: libapache2-mod-apparmor (<< 2.5.1-0ubuntu3), apparmor-utils (<< 2.8.0-0ubuntu28), libvirt-bin (<< 1.2.2-0ubuntu9~), lightdm (<< 1.9.14-0ubuntu2~), lxc (<< 1.0.2-0ubuntu2~), apparmor-easyprof-ubuntu (<< 1.1.14) Replaces: apparmor-parser, libapache2-mod-apparmor (<< 2.5.1-0ubuntu3), apparmor-utils (<< 2.8.0-0ubuntu28) Suggests: apparmor-profiles, apparmor-docs, apparmor-utils Description: User-space parser utility for AppArmor This provides the system initialization scripts needed to use the AppArmor Mandatory Access Control system, including the AppArmor Parser which is required to convert AppArmor text profiles into machine-readable policies that are loaded into the kernel for use with the AppArmor Linux Security Module. Package: apparmor-utils Architecture: any Depends: apparmor (>= 2.6.1-4ubuntu1), libapparmor-perl, python3-apparmor, ${shlibs:Depends}, ${misc:Depends}, ${perl:Depends}, ${python3:Depends} Suggests: apparmor-docs, vim-addon-manager Description: Utilities for controlling AppArmor This provides the utilities to operate on AppArmor profiles. Profiles can be created, updated, enforced, set to complain mode, and disabled. Package: apparmor-profiles Architecture: all Depends: ${misc:Depends} Recommends: apparmor Description: Profiles for AppArmor Security policies This provides various AppArmor profiles that have not been shipped by the packages they provide confinement for. By default, they ship in complain mode so that users can test and choose which are desired. Package: apparmor-docs Section: doc Architecture: all Depends: ${misc:Depends} Description: Documentation for AppArmor Thie provides some technical documentation for the AppArmor Mandatory Access Control system. Currently this is only a single PDF covering basic operation, written some time ago. Package: libapparmor-dev Section: libdevel Architecture: any Multi-Arch: same Depends: libapparmor1 (= ${binary:Version}), ${misc:Depends} Breaks: libapparmor1 ( << 2.8.95~2395-0ubuntu1 ) Replaces: libapparmor1 ( << 2.8.95~2395-0ubuntu1 ) Description: AppArmor development libraries and header files This package provides the develpment libraries and header files needed to link against the AppArmor changehat and log parsing functions. Also includes the manpages for library functions. Package: libapparmor1 Section: libs Architecture: any Multi-Arch: same Depends: ${shlibs:Depends}, ${misc:Depends} Description: changehat AppArmor library This package provides the shared library used for making use of the AppArmor profile and changehat functionality, as well as common log parsing routines. Package: libapparmor-perl Section: perl Architecture: any Depends: ${perl:Depends}, ${shlibs:Depends}, ${misc:Depends} Description: AppArmor library Perl bindings This provides the Perl module that contains the language bindings for the AppArmor library, libapparmor, which were autogenerated via SWIG. Package: libapache2-mod-apparmor Pre-Depends: ${misc:Pre-Depends} Section: libs Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} Description: changehat AppArmor library as an Apache module This provides the Apache module needed to declare various differing confinement policies when running virtual hosts in the webserver by using the changehat abilities exposed through libapparmor. Package: libpam-apparmor Section: libs Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} Description: changehat AppArmor library as a PAM module This provides the PAM module needed to declare various differing confinement policies when starting PAM sessions by using the changehat abilities exposed through libapparmor. Package: apparmor-notify Architecture: all Depends: libapparmor-perl, ${perl:Depends}, ${misc:Depends} Suggests: libnotify-bin Description: AppArmor notification system This package provides a utility to display AppArmor denial messages via desktop notifications. The utility can also be used to generate summary reports. Package: python-libapparmor Section: python Architecture: any Depends: ${python:Depends}, ${shlibs:Depends}, ${misc:Depends} XS-Python-Version: ${python:Versions} Description: AppArmor library Python bindings This provides the Python module that contains the language bindings for the AppArmor library, libapparmor, which were autogenerated via SWIG. Package: python3-libapparmor Section: python Architecture: any Depends: ${python3:Depends}, ${shlibs:Depends}, ${misc:Depends} XS-Python-Version: ${python3:Versions} Description: AppArmor library Python3 bindings This provides the Python3 module that contains the language bindings for the AppArmor library, libapparmor, which were autogenerated via SWIG. Package: python-apparmor Section: python Architecture: any Depends: ${python:Depends}, ${shlibs:Depends}, ${misc:Depends}, python-libapparmor, python-pkg-resources XS-Python-Version: ${python:Versions} Description: AppArmor Python utility library This provides the Python modules that implement the higher-level AppArmor applications. Package: python3-apparmor Section: python Architecture: any Depends: ${python3:Depends}, ${shlibs:Depends}, ${misc:Depends}, python3-libapparmor, python3-pkg-resources Breaks: apparmor-easyprof ( << 2.8.95~2385-0ubuntu1 ) Replaces: apparmor-easyprof ( << 2.8.95~2385-0ubuntu1 ) XS-Python-Version: ${python3:Versions} Description: AppArmor Python3 utility library This provides the Python3 modules that implement the higher-level AppArmor applications. Package: dh-apparmor Section: devel Architecture: all Multi-Arch: foreign Depends: ${perl:Depends}, ${misc:Depends} Suggests: apparmor-easyprof Breaks: debhelper (<< 9.20120115ubuntu3) Replaces: debhelper (<< 9.20120115ubuntu3) Description: AppArmor debhelper routines This provides the debhelper tools used to install and migrate AppArmor profiles. This is normally used from package maintainer scripts during install and removal. Package: apparmor-easyprof Section: admin Architecture: all Multi-Arch: foreign Depends: ${python3:Depends}, ${misc:Depends}, python3-apparmor Breaks: apparmor-utils (<< 2.8.0-0ubuntu14) Replaces: apparmor-utils (<< 2.8.0-0ubuntu14) Description: AppArmor easyprof profiling tool This provides the aa-easyprof utility which is an easy to use interface for AppArmor policy generation. aa-easyprof supports the use of templates and policy groups to quickly profile an application. debian/apparmor.maintscript0000664000000000000000000000027412315045675013303 0ustar rm_conffile /etc/apparmor/functions 2.5.1-0ubuntu4 rm_conffile /etc/apparmor/rc.apparmor.functions 2.5.1-0ubuntu4 rm_conffile /etc/apparmor.d/abstractions/ubuntu-sdk-base 2.8.0-0ubuntu20~ debian/apparmor-profiles.postrm0000664000000000000000000000200112315045675014101 0ustar #!/bin/sh # postrm script for apparmor-profiles # # see: dh_installdeb(1) set -e case "$1" in purge) if [ -e /etc/apparmor.d/abstractions/ubuntu-browsers.d/chromium-browser ]; then rm -f /etc/apparmor.d/abstractions/ubuntu-browsers.d/chromium-browser fi # We automatically create local/* files in postinst, so we need to remove them on purge if [ -e "/var/lib/dpkg/info/apparmor-profiles.list" ]; then grep "/etc/apparmor.d/" /var/lib/dpkg/info/apparmor-profiles.list | while read profile ; do f="/etc/apparmor.d/local/`basename $profile`" if [ -f "$f" ]; then rm -f "$f" fi done fi ;; remove|upgrade|failed-upgrade|disappear) ;; *) echo "postrm called with unknown argument \`$1'" >&2 exit 1 ;; esac # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# exit 0 debian/notify/0000775000000000000000000000000012315045676010511 5ustar debian/notify/notify.conf0000664000000000000000000000102712315045675012667 0ustar # ------------------------------------------------------------------ # # Copyright (C) 2010 Canonical Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # ------------------------------------------------------------------ # Set to 'yes' to enable AppArmor DENIED notifications globally show_notifications="yes" # Only people in use_group can use apparmor-notify use_group="sudo" debian/notify/apparmor-notify.desktop0000664000000000000000000000037012315045675015232 0ustar [Desktop Entry] Type=Application Name=AppArmor Notify Comment=Receive on screen notifications of AppArmor denials TryExec=/usr/bin/aa-notify Exec=/usr/bin/aa-notify -p -s 1 -w 60 StartupNotify=false NoDisplay=true X-Ubuntu-Gettext-Domain=aa-notify debian/apparmor.install0000664000000000000000000000124312315045675012411 0ustar debian/apport/source_apparmor.py /usr/share/apport/package-hooks/ debian/lib/apparmor/functions /lib/apparmor/ etc/apparmor/subdomain.conf sbin/apparmor_parser usr/sbin/aa-exec usr/sbin/aa-status usr/sbin/apparmor_status etc/apparmor.d/tunables/alias etc/apparmor.d/tunables/apparmorfs etc/apparmor.d/tunables/dovecot etc/apparmor.d/tunables/global etc/apparmor.d/tunables/home etc/apparmor.d/tunables/kernelvars etc/apparmor.d/tunables/proc etc/apparmor.d/tunables/multiarch etc/apparmor.d/tunables/securityfs etc/apparmor.d/tunables/sys etc/apparmor.d/tunables/xdg-user-dirs etc/apparmor.d/tunables/xdg-user-dirs.d etc/apparmor.d/abstractions/* etc/apparmor.d/local/README debian/changelog0000664000000000000000000034616712317446163011072 0ustar apparmor (2.8.95~2430-0ubuntu5) trusty; urgency=medium * debian/control: add versioned Breaks to apparmor for lxc, libvirt-bin, lightdm and apparmor-easyprof-ubuntu -- Jamie Strandboge Fri, 04 Apr 2014 01:07:24 -0500 apparmor (2.8.95~2430-0ubuntu4) trusty; urgency=medium [ John Johansen, Steve Beattie ] * Add userspace support for AppArmor signals and ptrace mediation (LP: #1298611) + debian/patches/mediate-signals.patch, debian/patches/change-signal-syntax.patch: Parse signal rules with apparmor_parser. See the apparmor.d(5) man page for syntax details. + debian/patches/change-ptrace-syntax.patch, debian/patches/mediate-ptrace.patch: Parse ptrace rules with apparmor_parser. See the apparmor.d(5) man page for syntax details. + debian/patches/test-signal-rules.patch, debian/patches/test-ptrace-rules.patch, debian/patches/update-tests-for-new-semantics.patch: Update existing tests and add new tests for signal and ptrace mediation + debian/patches/fix-garbage-in-preprocessor-output.patch: Fix bug causing apparmor_parser preprocessor output to contain garbage after include statements + debian/patches/fix-double-comma-in-preprocessor-output.patch: Fix bug causing apparmor_parser preprocessor output to contain double commas after some rules + debian/patches/symtab-tests-and-seenlist-bug.patch, debian/patches/add-profile-name-variable.patch: Add ${profile_name} variable for use in profiles when rules need to specify the current profile's name. This is useful for signal and ptrace rules that specify + debian/patches/fix-names-treated-as-condlistid.patch: Fix apparmor_parser bug that caused mount and dbus rules to fail for sets of values [ Jamie Strandboge ] * debian/patches/update-base-abstraction-for-signals-and-ptrace.patch: Adjust the base abstraction for signals and ptrace mediation. Profiles that use the base abstraction can deny any of the granted permissions to achieve tighter confinement. * debian/patches/manpage-signal-ptrace.patch: Update the apparmor.d man page to document signal rules, ptrace rules, and variables for use in AppArmor profiles * debian/patches/dnsmasq-libvirtd-signal-ptrace.patch: Update the dnsmasq profile to allow libvirtd to send signals to and ptrace read the dnsmasq process * debian/patches/update-chromium-browser.patch: Adjust the chromium-browser profile for permissions needed in newer chromium-browser versions and add the rules needed for AppArmor ptrace mediation [ Tyler Hicks ] * Add new rule type support to aa.py to fix tracebacks when using the Python utilities in apparmor-utils on systems with AppArmor profiles containing previously unsupported rule types - debian/patches/python-utils-file-support.patch: Support path rules containing the "file" prefix (LP: #1295346) - debian/patches/python-utils-signal-support.patch: Parse and write signal rules (LP: #1300316) - debian/patches/python-utils-ptrace-support.patch: Parse and write ptrace rules (LP: #1300317) - debian/patches/python-utils-pivot_root-support.patch: Parse and write pivot_root rules (LP: #1298678) -- Tyler Hicks Thu, 03 Apr 2014 15:50:26 -0500 apparmor (2.8.95~2430-0ubuntu3) trusty; urgency=medium [ Jamie Strandboge ] * debian/lib/apparmor/functions: properly calculate number of profiles in /var/lib/apparmor/profiles (LP: #1295816) * autostart aa-notify via /etc/xdg/autostart instead of /etc/X11/Xsession.d (LP: #1288241) - remove debian/notify/90apparmor-notify - add debian/notify/apparmor-notify.desktop - debian/apparmor-notify.install: adjust for the above - add debian/apparmor-notify.maintscript to remove 90apparmor-notify * debian/notify/notify.conf: use_group should be set to "sudo" instead of "admin" (LP: #1009666) [ Tyler Hicks ] * debian/patches/initialize-mount-flags.patch: Initialize the variables containing mount rule flags to zero. Otherwise, the parser may set unexpected bits in the mount flags field for rules that do not specify mount flags. The uninitialized mount flag variables may have caused unexpected AppArmor denials during mount mediation. (LP: #1296459) * debian/patches/fix-typo-in-dbus_write.patch: Fix a bug in the apparmor/aa.py module that caused the utilities in the apparmor-utils package to write out network rules instead of dbus rules * debian/patches/limited-mount-rule-support.patch: Fix a bug in the apparmor/aa.py module that caused the utilities in the apparmor-utils package to traceback when encountering a mount rule (LP: #1294825) * debian/patches/bare-capability-rule-support.patch: Fix a bug in the apparmor/aa.py module that caused the utilities in the apparmor-utils package to traceback when encountering a bare capability rule (LP: #1294819) * debian/patches/check-config-for-sysctl.patch, debian/patches/increase-swap-size.patch: Fix bugs in the regression test suite that caused errors when running on ppc64el * debian/patches/test-v6-policy.patch, debian/patches/test-mount-mediation.patch: Improve the regression tests by increasing the mount rule test coverage -- Tyler Hicks Thu, 27 Mar 2014 14:12:29 -0500 apparmor (2.8.95~2430-0ubuntu2) trusty; urgency=medium * debian/control: Depends on python-pkg-resources for python-apparmor and python3-pkg-resources for python3-apparmor to fix autopkgtests in click-apparmor and apparmor-easyprof-ubuntu -- Jamie Strandboge Thu, 20 Mar 2014 19:33:51 -0500 apparmor (2.8.95~2430-0ubuntu1) trusty; urgency=low [ Jamie Strandboge ] * debian/debhelper/dh_apparmor: exit with error if aa-easyprof does not exist * debian/control: drop Depends on apparmor-easyprof to Suggests for dh-apparmor [ Seth Arnold, Jamie Strandboge, Steve Beattie, John Johansen, Tyler Hicks ] * New upstream snapshot (LP: #1278702, #1061693, #1285653) dropping very large Ubuntu delta and fixing the following bugs: - Adjust fonts abstraction for libthai (LP: #1278702) - Support translated XDG user directories (LP: #1061693) - Adjust abstractions/web-data to include /var/www/html (LP: #1285653) Refresh 0002-add-debian-integration-to-lighttpd.patch to include /etc/lighttpd/conf-available/*.conf - Adjust debian/libapparmor1.symbols to reflect new upstream versioning for the aa_query_label() function - Raise exceptions in Python bindings when something fails * ship new Python replacements for previous Perl-based tools - debian/apparmor-utils.install: remove usr/share/perl5/Immunix/*.pm and add usr/sbin/aa-autodep, usr/sbin/aa-cleanprof and usr/sbin/aa-mergeprof - debian/control: + remove various Perl dependencies + add python-apparmor and python3-apparmor + python3-apparmor Breaks: apparmor-easyprof to move the file since it ships dist-packages/apparmor/__init__.py now - debian/apparmor-utils.manpages: ship new manpages for aa-cleanprof and aa-mergeprof - debian/rules: build and install Python tools * debian/apparmor.install: - install apparmorfs, dovecot, kernelvars, securityfs, sys, and xdg-user-dirs tunables and xdg-user-dirs.d directory * debian/apparmor.dirs: - install /etc/apparmor.d/tunables/xdg-user-dirs.d * debian/rules: delete upstream-provided xdg-user-dirs.d/site.local * debian/apparmor.postinst: create xdg-user-dirs.d/site.local * debian/apparmor.postrm: remove xdg-user-dirs.d * Remaining patches: - add-chromium-browser.patch - add-debian-integration-to-lighttpd.patch - ubuntu-manpage-updates.patch - libapparmor-layout-deb.patch - libapparmor-mention-dbus-method-in-getcon-man.patch - etc-writable.patch - aa-utils_are_bilingual.patch * New patches: - convert-to-rules.patch - list-fns.patch - parse-mode.patch - add-decimal-interp.patch - policy_mediates.patch - fix-failpath.patch - feature_file.patch - fix-network.patch - aare-to-class.patch - add-mediation-unix.patch - parser_version.patch - caching.patch - label-class.patch - fix-lexer-debug.patch - use-diff-encode.patch - fix-serialize.patch - fix-ppc-endian-ftbfs.patch - opt_arg.patch - tests-cond-dbus.patch * Move manpages from libapparmor1 to libapparmor-dev - debian/libapparmor-dev.manpages: install aa_change_hat.2, aa_change_profile.2, aa_find_mountpoint.2, aa_getcon.2 - debian/control: libapparmor-dev Replaces: and Breaks: libapparmor1 * Move /usr/lib/python3/dist-packages/apparmor/__init__.py from apparmor-easyprof to python3-apparmor - debian/control: python3-apparmor Breaks: apparmor-easyprof - debian/apparmor-easyprof.install: remove usr/lib/python*.*/site-packages/apparmor* * New profiles and abstractions: - debian/apparmor.install: tunables/dovecot, tunables/kernelvars, tunables/xdg-user-dirs, tunables/xdg-user-dirs.d -- Seth Arnold Wed, 19 Mar 2014 20:29:27 -0700 apparmor (2.8.94-0ubuntu1.4) trusty; urgency=low * Test merge from upstream new pyutils branch (rev 2385) -- Steve Beattie Thu, 13 Feb 2014 14:16:24 -0800 apparmor (2.8.0-0ubuntu38) trusty; urgency=low [ Tyler Hicks ] * 0084-parser-add-dbus-eavesdrop-perm.patch: Add an eavesdrop permission to the dbus rule type, allowing confined applications to eavesdrop. The only valid conditional for eavesdrop rules is 'bus'. See the apparmor.d(5) man page for more information. (LP: #1262440) [ Steve Beattie ] * 0085-push-normalize-tree-ops-into-expr-tree-classes.patch: Improve parser performance in some cases [ John Johansen ] * 0086-add-diff-state-compression-to-dfa.patch: Implement differential state compression in the parser * 0087-fix-dfa-minimization.patch: Fix a parser bug that caused some DFAs to not be fully minimized (LP: #1262938) * 0088-fix-pol-generation-for-small-dfas.patch: Fixes bugs in the parser when generating policy for some small DFAs -- Tyler Hicks Mon, 13 Jan 2014 11:17:42 -0600 apparmor (2.8.0-0ubuntu37) trusty; urgency=low [ Jan Rękorajski ] * 0082-parser-fix-FTBFS-with-bison-3.patch: Fix parser FTBFS with bison 3 [ Steve Beattie ] * 0083-libapparmor-require-libtoolize.patch: Fix FTBFS by switching the autogen.sh script to use libtoolize instead of libtool -- Tyler Hicks Fri, 10 Jan 2014 13:48:43 -0600 apparmor (2.8.0-0ubuntu36) trusty; urgency=medium * Rebuild for python3.4 as a supported python version. -- Matthias Klose Sat, 04 Jan 2014 18:30:59 +0000 apparmor (2.8.0-0ubuntu35) trusty; urgency=low * abstractions/nameservice: Also allow access to the sssd nss pipe. -- Stéphane Graber Fri, 29 Nov 2013 13:44:49 -0500 apparmor (2.8.0-0ubuntu34) trusty; urgency=low [ Tyler Hicks ] * 0078-parser-check-for-dbus-kernel-support.patch: The parser should not include D-Bus rules in the binary policy that it loads into the kernel if the kernel does not support D-Bus rules (LP: #1231778) * 0079-utils-ignore-unsupported-log-events.patch: aa-logprof should ignore audit events that it does not yet support instead of treating them as errors (LP: #1243932) * 0080-tests-use-ldconfig-for-library-detection.patch: Fix libapparmor detection in regression tests after the multiarch changes [ Jamie Strandboge ] * 0081-python-abstraction-updates.patch: Add rules in support of Python 3.3 [ Chad Miller ] * debian/patches/0001-add-chromium-browser.patch: Follow new chromium-browser sandbox name. Keep old name for now to allow transition. LP: #1247269 -- Tyler Hicks Mon, 04 Nov 2013 15:57:30 -0800 apparmor (2.8.0-0ubuntu33) trusty; urgency=low * Convert to dh. * Bump to debhelper compat level 9 for multiarch support. * Mark libapparmor1, libapparmor-dev Multi-Arch: same. LP: #1246067. -- Steve Langasek Thu, 31 Oct 2013 13:23:57 -0700 apparmor (2.8.0-0ubuntu32) trusty; urgency=low * no change rebuild for perl 5.18 -- Jamie Strandboge Mon, 21 Oct 2013 13:28:26 -0500 apparmor (2.8.0-0ubuntu31) saucy; urgency=low * 0077_aa-status-is-bilingual.patch: aa-status was written to work with python 2 or 3. Upstream is still using 2, so adjust ours to use /usr/bin/python3 to avoid pulling python 2 back to the desktop images -- Jamie Strandboge Fri, 11 Oct 2013 15:35:03 -0500 apparmor (2.8.0-0ubuntu30) saucy; urgency=low [ Tyler Hicks ] * debian/patches/0059-dbus-rules-for-dbus-abstractions.patch: Add an abstraction for the accessibility bus. It is currently very permissive, like the dbus and dbus-session abstractions, and grants all permissions on the accessibility bus. (LP: #1226141) * debian/patches/0071-lp1226356.patch: Fix issues in parsing D-Bus and mount rules. Both rule classes suffered from unexpected auditing behavior when using the 'deny' and 'audit deny' rule modifiers. The 'deny' modifier resulting in accesses being audited and the 'audit deny' modifier resulting in accesses not being audited. (LP: #1226356) * debian/patches/0072-lp1229393.patch: Fix cache location for .features file, which was not being written to the proper location if the parameter --cache-loc= is passed to apparmor_parser. This bug resulted in using the .features file from /etc/apparmor.d/cache or always recompiling policy. Patch thanks to John Johansen. (LP: #1229393) * debian/patches/0073-lp1208988.patch: Update AppArmor file rules of UNIX domain sockets to include read and write permissions. Both permissions are required when a process connects to a UNIX domain socket. Also include new tests for mediation of UNIX domain sockets. Thanks to Jamie Strandboge for helping with the policy updates and testing. (LP: #1208988) * debian/patches/0075-lp1211380.patch: Adjust the audio abstraction to only grant access to specific pulseaudio files in the pulse runtime directory to remove access to potentially dangerous files (LP: #1211380) [ Jamie Strandboge ] * debian/patches/0074-lp1228882.patch: typo in ubuntu-browsers.d/multimedia (LP: #1228882) * 0076_sanitized_helper_dbus_access.patch: allow applications run under sanitized_helper to connect to DBus -- Tyler Hicks Fri, 04 Oct 2013 17:29:52 -0700 apparmor (2.8.0-0ubuntu29) saucy; urgency=low * Add 0070-etc-writable.patch: Allow reading time configuration from /etc/writable, as we have it on the phone. (LP: #1227520) -- Martin Pitt Tue, 01 Oct 2013 09:55:15 +0200 apparmor (2.8.0-0ubuntu28) saucy; urgency=low [ Tyler Hicks ] * Move the aa-exec man page out of apparmor-utils into apparmor, since aa-exec is now in apparmor - debian/control: adjust Breaks/Replaces to use apparmor-utils (<< 2.8.0-0ubuntu28) - debian/apparmor.manpages: install the aa-exec man page - debian/apparmor-utils.manpages: don't install the aa-exec man page * debian/patches/0065-lp1220861.patch: Always NUL-terminate confinement context strings returned from libapparmor (LP: #1220861) * debian/patches/0066-lp1196880.patch: Don't assign mode pointer in aa_getprocattr() if caller passed in NULL (LP: #1196880) * debian/patches/0067-libapparmor-mode-strings-are-not-to-be-freed.patch: Update man page and code comments to make it clear that freeing the *con string returned from libapparmor's getcon functions also frees the *mode string * debian/patches/0068-libapparmor-mention-dbus-method-in-getcon-man.patch: Document the D-Bus method, in the aa_getcon man page, that returns the AppArmor task confinement string of a D-Bus connection [ Jamie Strandboge ] * debian/patches/0069-p11kit-abstraction.patch: p11-kit needs access to /usr/share/p11-kit/modules -- Jamie Strandboge Tue, 10 Sep 2013 12:06:06 -0500 apparmor (2.8.0-0ubuntu27) saucy; urgency=low * debian/apport/source_apparmor.py: AppArmor logs DBus messages to syslog, adjust apport hook to also search there for denials -- Jamie Strandboge Tue, 03 Sep 2013 10:25:45 -0500 apparmor (2.8.0-0ubuntu26) saucy; urgency=low * debian/patches/0064-lp1218099.patch: add support for variable expansion in dbus rules (LP: #1218099) -- Jamie Strandboge Thu, 29 Aug 2013 16:28:36 -0500 apparmor (2.8.0-0ubuntu25) saucy; urgency=low [ Tyler Hicks ] * Add support for mediation of D-Bus messages and services. AppArmor D-Bus rules are described in the apparmor.d(5) man page. dbus-daemon will use libapparmor to perform queries against the AppArmor policies to determine if a connection should be able to send messages to another connection, if a connection should be able to receive messages from another connection, and if a connection should be able to bind to a well-known name. - 0042-Fix-mount-rule-preprocessor-output.patch, 0043-libapparmor-Safeguard-aa_getpeercon-buffer-reallocat.patch, 0044-libapparmor-fix-return-value-of-aa_getpeercon_raw.patch, 0045-libapparmor-Move-mode-parsing-into-separate-function.patch, 0046-libapparmor-Parse-mode-from-confinement-string-in-ge.patch, 0047-libapparmor-Make-aa_getpeercon_raw-similar-to-aa_get.patch, 0048-libapparmor-Update-aa_getcon-man-page-to-reflect-get.patch: Backport parser and libapparmor pre-requisites for D-Bus mediation - 0049-parser-Update-man-page-for-DBus-rules.patch: Update apparmor.d man page - 0050-parser-Add-support-for-DBus-rules.patch, 0051-parser-Regression-tests-for-DBus-rules.patch, 0052-parser-Binary-profile-equality-tests-for-DBus-rules.patch: Add apparmor_parser support for D-Bus mediation rules - 0053-libapparmor-Export-a-label-based-query-interface.patch, debian/libapparmor1.symbols: Provide the libapparmor interface necessary for trusted helpers to make security decisions based upon AppArmor policy - 0054-libaalogparse-Parse-dbus-daemon-audit-messages.patch, 0055-libaalogparse-Regression-tests-for-dbus-daemon-audit.patch: Allow applications to parse denials, generated by dbus-daemon, using libaalogparse and add a set of regression tests - 0056-tests-Add-an-optional-final-check-to-checktestfg.patch, 0057-tests-Add-required-features-check.patch, 0058-tests-Add-regression-tests-for-dbus.patch: Add regression tests which start their own dbus-daemon, load profiles containing D-Bus rules, and confine simple D-Bus service and client applications - 0059-dbus-rules-for-dbus-abstractions.patch: Add bus-specific, but otherwise permissive, D-Bus rules to the dbus and dbus-session abstractions. Confined applications that use D-Bus should already be including these abstractions in their profiles so this should be a seamless transition for those profiles. * 0060-utils-make_clean_fixup.patch: Clean up the Python cache in the AppArmor tests directory * 0061-profiles-dnsmasq-needs-dbus-abstraction.patch: Dnsmasq uses the system D-Bus when it is started with --enable-dbus, so its AppArmor profile needs to include the system bus abstraction * 0062-fix-clone-test-on-arm.patch: Fix compiler error when building regression tests on ARM * 0063-utils-ignore-unsupported-rules.patch: Utilities that use the Immunix::AppArmor perl module, such as aa-logprof and aa-genprof, error out when they encounter rules unsupported by the perl module. This patch ignores unsupported rules. [ Jamie Strandboge ] * debian/control: don't have easyprof Depends on apparmor-easyprof-ubuntu -- Tyler Hicks Mon, 26 Aug 2013 15:32:12 -0700 apparmor (2.8.0-0ubuntu24) saucy; urgency=low * 0040-libapparmor-support-pkg-config.patch: Make it easier for other sources to build against libapparmor with pkg-config - debian/control: Add pkg-config as a Build-Depends - debian/libapparmor-dev.install: Install libapparmor pkg-config file * 0041-parser-fix-flags.patch: Minimal fix for cache failures when the feature file is larger than the feature buffer used for cache version comparison -- Tyler Hicks Thu, 15 Aug 2013 16:34:53 -0700 apparmor (2.8.0-0ubuntu23) saucy; urgency=low * debian/patches/0038-lp1200392.patch: allow mmap of fglrx dri libraries (LP: #1200392) * debian/patches/0039-fix-parser-cache-loc.patch: fix apparmor cache tempfile location to use passed arg * debian/lib/apparmor/functions: update to also load from /var/lib/apparmor/profiles and write cache to /var/cache/apparmor * debian/apparmor.dirs: create /var/cache/apparmor and /var/lib/apparmor/profiles -- Jamie Strandboge Tue, 23 Jul 2013 21:36:40 -0500 apparmor (2.8.0-0ubuntu22) saucy; urgency=low * Refresh easyprof - drop 0034-easyprof-dont-add-vendor-dir.patch - drop 0035-easyprof-update-manpage-for-sdk-base.patch * debian/patches/0037-easyprof-sdk-pt2.patch: update easyprof for the following: - don't add vendor directory to self.templates and self.policy_groups - utils/aa-easyprof: adjust error message for manifest read failure - utils/aa-easyprof: adjust to use EnvironmentError on failed read of the manifest - utils/apparmor/easyprof.py: clean up set_template() - utils/apparmor/easyprof.py: read_paths should use 'rk' - utils/test/test-aa-easyprof.py: adjust tests for above - utils/apparmor/easyprof.py + valid_path should verify os.path.normpath(path) == (path) + adjust valid_profile_name() to start with alpha-numeric and allow Debian source package names and version, plus '_' + adjust tests for above - update valid_variable() to check for valid_path if '/' is in the value - adjust valid_path() to have a relative_ok flag (default to False) - adjust valid_path() to verify path is same as normalized path - add some valid_path() test cases - adjust to always quote template vars in policy output - add a couple tests that have spaces in the binary and template var - update manifest JSON structure to use m['security']['profiles']['profile_name'] instead of m['security']['profile_name'] -- Jamie Strandboge Sun, 07 Jul 2013 19:37:56 -0500 apparmor (2.8.0-0ubuntu21) saucy; urgency=low * Apache 2.4 transition (LP: #1197617, Closes: 666808). Based on patch from intrigeri - debian/control: + Build-Depends on apache2-dev and dh-apache2 instead of apache2-prefork-dev + adjust libapache2-mod-apparmor to not Depends on apache2.2-common + adjust libapache2-mod-apparmor to Pre-Depends: ${misc:Pre-Depends} - create debian/libapache2-mod-apparmor.apache2 - debian/rules: adjust to use dh_apache2 --noenable - debian/libapache2-mod-apparmor.maintscript: remove old prefork profile - debian/libapache2-mod-apparmor.install: install new usr.sbin.apache2 profile - debian/libapache2-mod-apparmor.{preinst,postinst,postrm}: update to use usr.sbin.apache2 - debian/libapache2-mod-apparmor.postinst: remove the disable symlink for old prefork profile - debian/patches/0036-libapache2-mod-apparmor-profile-2.4.patch: update mod_apparmor man page to mention loading mpm_prefork, add new usr.sbin.apache2 profile and remove old prefork profile * debian/rules: honor DEB_BUILD_OPTIONS=nocheck -- Jamie Strandboge Thu, 04 Jul 2013 10:20:20 -0500 apparmor (2.8.0-0ubuntu20) saucy; urgency=low * remove debian/patches/0033-add-ubuntu-sdk-abstractions.patch. We will for now ship policy groups instead of abstractions like this * debian/apparmor.maintscript: rm_conffile on ubuntu-sdk-base * debian/patches/0035-easyprof-update-manpage-for-sdk-base.patch: add sdk-base as a typical policy group -- Jamie Strandboge Wed, 03 Jul 2013 17:29:57 -0500 apparmor (2.8.0-0ubuntu19) saucy; urgency=low * debian/patches/0034-easyprof-dont-add-vendor-dir.patch: don't add vendor directory to self.templates and self.policy_groups * debian/patches/0030-easyprof-sdk.patch: mentioned patch has been forwarded upstream -- Jamie Strandboge Tue, 02 Jul 2013 09:24:23 -0500 apparmor (2.8.0-0ubuntu18) saucy; urgency=low * debian/patches/0030-easyprof-sdk.patch: refreshed for the following: - man page updates - add --output-format=json option - add --verify-manifest - add --policy-version and --policy-vendor which to better work with vendor templates (ie, with apparmor-easyprof-ubuntu) - restructed JSON format (should be final version now). This converts abstractions and policy_groups to proper JSON lists and allows for multiple profiles in the JSON file, keyed off of the profile name - add --output-directory option as an alternative to stdout (particularly useful when using multiple profiles in a JSON file) - also remove ubuntu-sdk-base abstraction. This may move out but for now put it in a different patch - add verify_options() and some utility functions for input validation - unconditionally quote profile name and binary - remove Ubuntu-specific checks in verify_manifest and check profile_name with binary harder * debian/patches/0033-add-ubuntu-sdk-abstractions.patch: add ubuntu-sdk-base abstraction -- Jamie Strandboge Mon, 01 Jul 2013 17:20:33 -0500 apparmor (2.8.0-0ubuntu17) saucy; urgency=low * debian/patches/0032-lp1195362.patch: don't pull in unused perl modules (LP: #1195362) * debian/rules: use dh_perl -d with libapparmor-perl to Depends on perl-base instead of perl * debian/patches/0030-easyprof-sdk.patch: update to remove the ubuntu specific templates and policy groups. These will be shipped in apparmor-easyprof-ubuntu * debian/control: have apparmor-easyprof Depends on apparmor-easyprof-ubuntu -- Jamie Strandboge Fri, 28 Jun 2013 12:01:06 -0500 apparmor (2.8.0-0ubuntu16) saucy; urgency=low * debian/patches/0030-easyprof-sdk.patch: update to have - /usr/share/icons/gnome/index.theme should have 'rk' added to qmlscene policy group - add ubuntu-sdk-html5 template - add qmlscene-webview policygroup * debian/patches/0031-move-poppler-cmap-to-fonts.patch: more than just gnome applications access /usr/share/poppler/cMap/** -- Jamie Strandboge Tue, 25 Jun 2013 15:58:33 -0500 apparmor (2.8.0-0ubuntu15) saucy; urgency=low * move aa-exec out of apparmor-utils into apparmor, since we want it in the default install - debian/control: adjust Breaks/Replaces to use apparmor-utils <<2.8.0-0ubuntu15) and have apparmor Depends on libapparmor-perl - debian/apparmor.install: install aa-exec - debian/apparmor-utils.install: don't install aa-exec -- Jamie Strandboge Tue, 25 Jun 2013 11:48:25 -0500 apparmor (2.8.0-0ubuntu14) saucy-proposed; urgency=low * debian/patches/0029-easyprof-update-for-aa-sandbox.patch: add aa-sandbox utility to source, but don't install yet. This includes code refactoring for easyprof, which is required for the next patch * debian/patches/0030-easyprof-sdk.patch: add SDK support to easyprof (don't include DBus includes yet) * create apparmor-easyprof package - adjust debian/control for new packages and Breaks/Replaces on apparmor-utils 2.8.0-0ubuntu14 - create debian/apparmor-easyprof.install - debian/apparmor-utils.install: don't install easyprof. python libraries moved to easyprof for now since it is the only consumer - debian/apparmor-utils.manpages: move easyprof manpage to debian/apparmor-easyprof.manpages - debian/rules: dh_python3 should also run on apparmor-easyprof * debian/control: dh-apparmor should Depends on apparmor-easyprof * debian/debhelper/dh_apparmor: update to support --manifest argument -- Jamie Strandboge Mon, 24 Jun 2013 09:49:44 -0500 apparmor (2.8.0-0ubuntu13) saucy-proposed; urgency=low * 0021-webapps_abstraction.patch: update to allow 'w' access to ~/.local/share/unity-webapps/availableapps*.db and 'rk' access to ~/.config/libaccounts-glib/accounts.db (LP: #1169633) -- Jamie Strandboge Mon, 10 Jun 2013 10:49:46 -0500 apparmor (2.8.0-0ubuntu12) saucy; urgency=low * 0027-add-gnome-keyring-to-strict.patch: add @{HOME}/.gnome2/keyrings/** to abstractions/private-files-strict * 0028-add-upstart-to-private.patch: deny writes to upstart user sessions jobs in abstractions/private-files -- Jamie Strandboge Mon, 13 May 2013 13:04:54 -0500 apparmor (2.8.0-0ubuntu11) raring; urgency=low * 0025-update-pulseaudio-paths.patch: update path for pulseaudio directory and cookie files * 0026-add-vm_overcommit_memory.patch: add read access to @{PROC}/sys/vm/overcommit_memory * update 0001-add-chromium-browser.patch: - additional accesses required by newer chromium-browser. Patch based on work by Simon Deziel (LP: #1154164) - don't include abstractions already included via gnome abstraction - allow access to dconf/gsettings, required now -- Jamie Strandboge Mon, 08 Apr 2013 14:57:14 -0500 apparmor (2.8.0-0ubuntu10) raring; urgency=low * debian/patches/0001-add-chromium-browser.patch: add accesses for chromium 23 (LP: #1091862) -- Jamie Strandboge Tue, 18 Dec 2012 15:20:05 -0600 apparmor (2.8.0-0ubuntu9) raring; urgency=low * debian/control: make libnotify-bin a Suggests rather than a Recommends since it is assumed to already be installed on the desktop and so server environments don't have to pull in a lot of X dependencies (LP: #1061879) -- Jamie Strandboge Tue, 18 Dec 2012 10:47:50 -0600 apparmor (2.8.0-0ubuntu8) raring; urgency=low [ Steve Beattie ] * 0024-lp1091642-parser-reset_matchflags.patch: prevent reuse of matchflags in parser dfa backend and add testcase demonstrating the problem (LP: #1091642) [ Jamie Strandboge ] * debian/debhelper/postinst-apparmor: quote all occurences of #PROFILE#. -- Steve Beattie Tue, 18 Dec 2012 04:53:28 -0800 apparmor (2.8.0-0ubuntu7) raring; urgency=low * Rebuild to drop python3.2 extension. -- Matthias Klose Thu, 08 Nov 2012 11:15:26 +0000 apparmor (2.8.0-0ubuntu6) raring-proposed; urgency=low * Build python swig modules for all supported pythons. * Use dh_python2 instead of obsolete dh_python. * Remove duplicate chrpath from control. * Remove unneeded quilt dependency. * Bump standards version to 3.9.4, no changes needed. -- Dmitrijs Ledkovs Tue, 23 Oct 2012 12:37:39 +0100 apparmor (2.8.0-0ubuntu5) quantal; urgency=low [ Micah Gersten ] * Allow /etc/vdpau_wrapper.cfg r and /var/lib/xine/gxine.desktop r in the multimedia browser abstraction (LP: #1057642) - update profiles/apparmor.d/abstractions/ubuntu-browsers.d/multimedia [ Steve Beattie ] * debian/control: make libnotify-bin a Recommends rather than a Depends for use in server environments (LP: #1061879) * debian/patches/0020-coredump_tests.patch: fix coredump regression tests (LP: #1050430) * debian/patches/0021-webapps_abstraction.patch: add a few items triggered by using and installing webapps in firefox (LP: #1056418) * debian/patches/0022-aa-decode-stdin.patch: fix aa-decode to process stdin correctly and decode encoded profiles names -- Steve Beattie Tue, 09 Oct 2012 12:44:56 -0700 apparmor (2.8.0-0ubuntu4) quantal; urgency=low * Allow /var/lib/sss/mc/{group|passwd} for systems using sssd. (LP: #1056391) -- Stéphane Graber Tue, 25 Sep 2012 14:59:57 -0400 apparmor (2.8.0-0ubuntu3) quantal; urgency=low * remove 0010-lp972367.patch and 0012-lp964510.patch which should have been dropped in 2.8.0-0ubuntu1 since they are included upstream * debian/patches/0001-add-chromium-browser.patch: - add a couple of small accesses - add a child profile for xdgsettings (LP: #1045986) -- Jamie Strandboge Mon, 17 Sep 2012 08:26:46 -0500 apparmor (2.8.0-0ubuntu2) quantal; urgency=low * 0015-fontconfig.patch: update fonts abstraction for new fontconfig paths * 0016-cap-block-suspend.patch: add CAP_BLOCK_SUSPEND to severity.db. In the next version of AppArmor, this will replace 0006-cap-epollwakeup.patch * 0017-gnome-poppler-data.patch: update gnome abstraction for poppler cMap tables -- Jamie Strandboge Tue, 14 Aug 2012 11:27:15 -0500 apparmor (2.8.0-0ubuntu1) quantal; urgency=low * New upstream release - Drop the following patches, now included upstream: 0003-add-aa-easyprof.patch 0005-clean-common-from-vim.patch 0006-use-linux-capability-h.patch 0008-apparmor-lp963756.patch 0009-apparmor-lp959560-part1.patch 0010-apparmor-lp959560-part2.patch 0011-apparmor-lp872446.patch 0012-apparmor-lp978584.patch 0013-apparmor-lp800826.patch 0014-apparmor-lp979095.patch 0015-apparmor-lp963756.patch 0016-apparmor-lp968956.patch 0017-apparmor-lp979135.patch 0018-lp990931.patch * Rename 0007-ubuntu-manpage-updates.patch to 0003 * debian/patches/0005-lp1019274.patch: add python3 support. Patch based on work from Dmitrijs Ledkovs. (LP: #1019274) * debian/patches/0006-cap-epollwakeup.patch: adjust severity.db for CAP_EPOLLWAKEUP * debian/patches/0007-setuptools-python3.patch: adjust setuptools-python3 to adjust scripts to use PYTHON if it is defined * debian/patches/0008-libapparmor-layout-deb.patch: use --install-layout=deb when calling setup.py * enable python3 in the build: - debian/rules: + use python3 as default PYTHON + build libapparmor with both python2 and python3 - debian/control: + Build-Depends on python3-all-dev and python3 + adjust apparmor to Depends on ${python3:Depends} + adjust apparmor-utils to Depends on ${python3:Depends} + add python3-libapparmor package - add debian/python3-libapparmor.install - debian/python-libapparmor.install: adjust to use python2 and dist-packages * debian/patches/0009-lp1003856.patch: update ubuntu-browsers.d/java for IcedTea 7 (LP: #1003856) * debian/patches/0010-lp972367.patch: allow software center to work again from browsers (LP: #972367) * debian/patches/0011-lp1013887.patch: let sanitized helper work with /usr/local. Patch based on work by Reuben Thomas. (LP: #1013887) * debian/patches/0012-lp964510.patch: allow Google Chrome and chromium-browser to work under sanitized helper (LP: #964510) * debian/patches/0013-lp987578.patch: ubuntu-integration does not work properly with exo-open. Fix thanks to Mark Ramsell (LP: #987578) * debian/patches/0014-lp933440.patch: update skype example profile to work with latest skype. Based on work by Ivan Frederiks (LP: #933440) -- Jamie Strandboge Thu, 05 Jul 2012 10:53:17 -0500 apparmor (2.7.102-0ubuntu5) quantal; urgency=low * debian/debhelper/postrm.apparmor: do not delete local files if main conffile still exists since it probably means it is owned by a new/different package. (LP: #986892) -- Clint Byrum Mon, 11 Jun 2012 21:40:33 -0700 apparmor (2.7.102-0ubuntu4) quantal; urgency=low * Fix FTBFS (LP: #1000055). Patch thanks to Steve Beattie. - debian/control: Build-Depends on texlive-latex-recommended - debian/rules: add V=1 for 'make' and 'make check' when building the parser * debian/patches/0018-lp990931.patch: adjust path for thunderbird to include non-versioned path - LP: #990931 -- Jamie Strandboge Fri, 18 May 2012 15:02:02 -0500 apparmor (2.7.102-0ubuntu3) precise; urgency=low [ Jamie Strandboge ] * debian/patches/0007-ubuntu-manpage-updates.patch: update apparmor(5) to describe Ubuntu's two-stage policy load and how to add utilize it when developing policy (LP: #974089) [ Serge Hallyn ] * debian/apparmor.init: do nothing in a container. This can be removed once stacked profiles are supported and used by lxc. (LP: #978297) [ Steve Beattie ] * debian/patches/0008-apparmor-lp963756.patch: Fix permission mapping for change_profile onexec (LP: #963756) * debian/patches/0009-apparmor-lp959560-part1.patch, debian/patches/0010-apparmor-lp959560-part2.patch: Update the parser to support the 'in' keyword for value lists, and make mount operations aware of 'in' keyword so they can affect the flags build list (LP: #959560) * debian/patches/0011-apparmor-lp872446.patch: fix logprof missing exec events in complain mode (LP: #872446) * debian/patches/0012-apparmor-lp978584.patch: allow inet6 access in dovecot imap-login profile (LP: #978584) * debian/patches/0013-apparmor-lp800826.patch: fix libapparmor log parsing library from dropping apparmor network events that contain ip addresses or ports in them (LP: #800826) * debian/patches/0014-apparmor-lp979095.patch: document new mount rule syntax and usage in apparmor.d(5) manpage (LP: #979095) * debian/patches/0015-apparmor-lp963756.patch: Fix change_onexec for profiles without attachment specification (LP: #963756, LP: #978038) * debian/patches/0016-apparmor-lp968956.patch: Fix protocol error when loading policy to kernels without compat patches (LP: #968956) * debian/patches/0017-apparmor-lp979135.patch: Fix change_profile to grant access to /proc/attr api (LP: #979135) -- Steve Beattie Thu, 12 Apr 2012 06:17:42 -0500 apparmor (2.7.102-0ubuntu2) precise; urgency=low * debian/control: Make dh-apparmor Multi-Arch: foreign, so that it can satisfy cross-build-dependencies. -- Colin Watson Sat, 31 Mar 2012 02:28:05 +0100 apparmor (2.7.102-0ubuntu1) precise; urgency=low * New upstream release. Fixes the following issues in support of LXC AppArmor support for beta-2: - Fix the return size of aa_getprocattr (LP: #962521) - Fix mnt_flags passed for remount - Fix dfa minimization around the nonmatching state - Factor all the permissions dump code into a single perms method * debian/apparmor-utils.install: - AppArmor now installs apparmor.vim. Move it into place - install aa-exec * debian/apparmor-utils.manpages: install aa-exec man page * debian/patches/0003-add-aa-easyprof.patch: refresh for Makefile changes * debian/patches/0005-clean-common-from-vim.patch: clean up 'common' symlink * 0006-use-linux-capability-h.patch: Use linux/capability.h instead of sys/capability.h -- Jamie Strandboge Thu, 22 Mar 2012 15:39:56 -0500 apparmor (2.7.101-0ubuntu1) precise; urgency=low * New upstream release. Fixes: LP: #948147 * debian/lib/apparmor/functions: Update to support the feature directory so that caching will work on kernels that support the feature dir. Patch based on work from John Johansen. LP: #954469 -- Jamie Strandboge Thu, 15 Mar 2012 15:57:02 -0500 apparmor (2.7.100-0ubuntu1) precise; urgency=low * New upstream bug fix release which fixes (in addition to other bugs): - LP: #940362 - LP: #947617 - LP: #949891 * Drop the following patches, included upstream: - 0004-lp918879.patch - 0007-lp941506.patch - 0008-lp941503.patch - 0009-lp943161.patch * Drop the following patch, no longer required: - 0005-disable-minimization.patch * Rename 0006-lp941808.patch 0004-lp941808.patch * debian/patches/0001-add-chromium-browser.patch: update for additional denials with newer chromium-browser. (LP: #937723) * debian/put-all-profiles-in-complain-mode.sh: deal with existing flags -- Jamie Strandboge Fri, 09 Mar 2012 06:56:48 -0600 apparmor (2.7.99-0ubuntu4) precise; urgency=low * Restore dpkg-maintscript-helper changes from 2.7.0-0ubuntu6, lost in 2.7.99-0ubuntu1. -- Colin Watson Mon, 05 Mar 2012 16:11:01 +0000 apparmor (2.7.99-0ubuntu3) precise; urgency=low * debian/patches/0009-lp943161.patch: update to not fail when default-jre-headless is installed (LP: #945019) -- Jamie Strandboge Fri, 02 Mar 2012 12:47:03 -0600 apparmor (2.7.99-0ubuntu2) precise; urgency=low * debian/control: dh-apparmor should Breaks/Replaces on debhelper 9.20120115ubuntu3, not 9.20120115ubuntu2 * debian/patches/0006-lp941808.patch: allow writes to /{,var/}run/sendsigs.omit.d/*dnsmasq.pid for network manager integration (LP: #941808) * debian/patches/0007-lp941506.patch: allow reads to ~/.drirc in the X abstraction (LP: #941506) * debian/patches/0008-lp941503.patch: allow read access to /usr/share/texmf/fonts in fonts abstraction (LP: #941503) * debian/patches/0009-lp943161.patch: fix path to java in ubuntu-browsers.d/java (LP: #943161) -- Jamie Strandboge Fri, 02 Mar 2012 07:50:50 -0600 apparmor (2.7.99-0ubuntu1) precise; urgency=low * New upstream release which also pulls in 2.7.0-1 changes from Debian. For the sake of simplicity, I have added the 2.7.0-1 changelog entry after 2.7.0-0ubuntu7 even though chronologically it appeared in Debian between 2.7.0-0ubuntu4 and 2.7.0-0ubuntu5. - LP: #940422 (FFe) * Drop the following patches, included upstream: - 0003-commits-through-r1882.patch - 0004-lp887992.patch - 0005-lp884748.patch - 0006-lp870992.patch - 0007-lp860856.patch - 0008-lp852062.patch - 0009-lp851977.patch - 0010-lp890894.patch - 0011-lp817956.patch - 0012-lp458922.patch - 0013-lp769148.patch - 0014-lp904548.patch - 0015-lp712584.patch - 0016-lp562831.patch - 0017-lp662906.patch - 0018-deny-home-pki-so.patch - 0019-lp899963.patch - 0020-lp912754a.patch - 0021-lp912754b.patch - 0022-workaround-lp851986.patch - 0023-syslog-ng-needs-dac-read-search.patch - 0024-fix-python-and-ruby-autogeneration.patch - 0025-lp914184.patch - 0026-lp914190.patch - 0027-lp914386.patch - 0028-testsuite-fixes.patch - 0029-lp917628.patch - 0030-lp916285.patch - 0031-lp917639.patch - 0032-lp917641.patch - 0033-add-ubuntu-helpers-to-plugins-common.patch - 0034-lp917859.patch - 0035-kde-should-use-kde4.patch - 0036-lp929531.patch - 0036-fix-manpage-errors.patch * Rename 0037-add-aa-easyprof.patch 0003-add-aa-easyprof.patch * debian/apparmor-profiles.postrm: clean out autogenerated files created by apparmor-profiles.postinst (Closes: 656451) * debian/patches/0004-lp918879.patch: allow /etc/drirc in the X abstraction (LP: #918879) * debian/patches/0005-disable-minimization.patch: do to LP: 940362, minimization is not working correctly. Disable it for now. -- Jamie Strandboge Fri, 24 Feb 2012 09:04:45 -0600 apparmor (2.7.0-1) unstable; urgency=low * debian/po/pt.po add new Portuguese translation, thanks to Pedro Ribeiro, (Closes: 651434). * debian/control: do not require initramfs-tools on !linux-any (Closes: 651297). * debian/{control,rules,debhelper/*}: move dh_apparmor into separate binary package, out of debhelper (Closes: 649784). * debian/{control,rules}: fix up lack of real build-indep. * debian/patches/0036-fix-manpage-errors.patch: minor man page cleanups. * merge changes from Ubuntu (r1443). -- Kees Cook Thu, 09 Feb 2012 15:24:08 -0800 apparmor (2.7.0-0ubuntu7) precise; urgency=low * debian/patches/0037-add-aa-easyprof.patch: add the aa-easyprof tool * apparmor-utils.dirs, apparmor-utils.install, apparmor-utils.manpages: install aa-easyprof and supporting files * python-libapparmor.install: only install LibAppArmor* * debian/rules: use dh_python2 with apparmor-utils * debian/control: apparmor-utils should Depends on ${python:Depends} -- Jamie Strandboge Wed, 15 Feb 2012 07:40:38 -0600 apparmor (2.7.0-0ubuntu6) precise; urgency=low * debian/apparmor.{preinst,postinst,postrm,maintscript}, debian/control: Use maintscript support in dh_installdeb rather than writing out dpkg-maintscript-helper commands by hand. We now simply Pre-Depend on a new enough version of dpkg rather than using 'dpkg-maintscript-helper supports' guards, leading to more predictable behaviour on upgrades. -- Colin Watson Sat, 11 Feb 2012 15:11:01 +0000 apparmor (2.7.0-0ubuntu5) precise; urgency=low * debian/patches/0036-lp929531.patch: adjust base abstraction to allow read access to /sys/devices/system/cpu/online (LP: #929531) -- Jamie Strandboge Thu, 09 Feb 2012 08:04:13 -0600 apparmor (2.7.0-0ubuntu4) precise; urgency=low * debian/patches/0034-lp917859.patch: adjust aspell abstraction for user customizable dictionaries (LP: #917859) * debian/patches/0035-kde-should-use-kde4.patch: adjust abstractions to use kde{,4} instead of kde * debian/control: update Vcs-Bzr -- Jamie Strandboge Wed, 18 Jan 2012 16:27:30 -0600 apparmor (2.7.0-0ubuntu3) precise; urgency=low * debian/patches/0029-lp917628.patch: Adjust dnsmasq profile for NetworkManager integration (LP: #917628) * debian/patches/0030-lp916285.patch: update ubuntu-browsers.d/text-editors to work with emacs2[2-9] (LP: #916285) * debian/patches/0031-lp917639.patch: update p11-kit to allow mmap of libraries in pkcs directories (LP: #917639) * debian/patches/0032-lp917641.patch: ubuntu-integration abstraction for multiarch with gst-plugin-scanner (LP: #917641) * debian/patches/0033-add-ubuntu-helpers-to-plugins-common.patch: include ubuntu-helpers in the plugins-common abstraction -- Jamie Strandboge Tue, 17 Jan 2012 07:18:34 -0600 apparmor (2.7.0-0ubuntu2) precise; urgency=low * debian/patches/0022-workaround-lp851986.patch: update sanitized_helper to include inet6 -- Jamie Strandboge Fri, 13 Jan 2012 11:21:30 +0100 apparmor (2.7.0-0ubuntu1) precise; urgency=low * New upstream release. Fixes the following: - LP: #794974 - LP: #815883 - LP: #840973 * Drop the following patches, included upstream: - af_names-generation.patch - 0004-adjust-logprof-log-search-order.patch - 0005-lp826914.patch - 0006-lp838275.patch - 0007-fix-introspection-tests.patch * Rename 0003-add-debian-integration-to-lighttpd.patch to 0002 * debian/patches/0003-commits-through-r1882.patch: several bug, documentation and performance fixes on our road to AppArmor 2.8 (LP: #840734, LP: #905412) * debian/patches/0004-lp887992.patch: cups-client abstraction should allow owner read of @{HOME}/.cups/client.conf and @{HOME}/.cups/lpoptions (LP: #887992) * update debian/patches/0001-add-chromium-browser.patch for deeper directories of /sys/devices/pci (LP: #885833) * debian/patches/0005-lp884748.patch: allow kate as text editor in the browsers abstraction (LP: #884748) * debian/patches/0006-lp870992.patch: abstractions/fonts should allow access to ~/.fonts.conf.d (LP: #870992) * debian/patches/0007-lp860856.patch: allow read access to sitecustomize.py in the python abstraction, which is needed for apport hooks to work in python applications (LP: #860856) * debian/patches/0008-lp852062.patch: update binaries for transmission clients (LP: #852062) * debian/patches/0009-lp851977.patch: allow ixr access to exo-open for Xubuntu and friends (LP: #851977) * debian/patches/0010-lp890894.patch: allow access to Thunar as well as thunar in ubuntu-integration abstraction (LP: #890894) * debian/patches/0011-lp817956.patch: update usr.sbin.sshd example profile (LP: #817956) * debian/patches/0012-lp458922.patch: update dovecot deliver profile to access various .conf files for dovecot (LP: #458922) * debian/patches/0013-lp769148.patch: allow avahi to do dbus introspection (LP: #769148) * debian/patches/0014-lp904548.patch: fix typo for multiarch line for gconv (LP: #904548) * debian/patches/0015-lp712584.patch: Nvidia users need access to /dev/nvidia* files for various plugins to work right. Since these are all focused around multimedia, add the acceses to the multimedia abstraction. (LP: #712584) * debian/patches/0016-lp562831.patch: allow fireclam plugin to work (LP: #562831) * debian/patches/0017-lp662906.patch: allow software-center in the ubuntu integration browser abstraction (LP: #662906) * debian/patches/0018-deny-home-pki-so.patch: update private-files abstraction to deny write and link to ~/.pki/nssdb/*so files (LP: #911847) * debian/patches/0019-lp899963.patch: add audacity to the ubuntu-media-players abstraction (LP: #899963) * debian/patches/0020-lp912754a.patch,0021-lp912754b.patch: add p11-kit abstraction and add it to the authentication abstraction (LP: #912754) * debian/patches/0022-workaround-lp851986.patch: instead of using Ux in the ubuntu and launchpad abstractions, use a helper child profile. This will help work around the lack of environment filtering (LP: #851986) * debian/patches/0023-syslog-ng-needs-dac-read-search.patch: adjust syslog-ng profile for dac_read_search * debian/patches/0024-fix-python-and-ruby-autogeneration.patch: fix python and ruby autogeneration when using aa-autodep and aa-genprof * debian/patches/0025-lp914184.patch: allow the creation of enchant .config directory in the enchant abstraction (LP: #914184) * debian/patches/0026-lp914190.patch: block write access to ~/.kde/env because KDE automatically sources scripts in that folder on startup (LP: #914190) * debian/pathes/0027-lp914386.patch: add xdg-desktop abstraction and adjust gnome and kde abstractions to use it (LP: #914386) * debian/patches/0028-testsuite-fixes.patch: testsuite fixes in the kernel regression tests -- Jamie Strandboge Thu, 12 Jan 2012 12:55:17 +0100 apparmor (2.7.0~beta1+bzr1774-1ubuntu3) precise; urgency=low * Rebuild for Perl 5.14. -- Colin Watson Tue, 15 Nov 2011 22:10:05 +0000 apparmor (2.7.0~beta1+bzr1774-1ubuntu2) oneiric; urgency=low * 0007-fix-introspection-tests.patch: Add missing introspection regression test that should have been checked in with the introspection patches. -- Jamie Strandboge Tue, 04 Oct 2011 13:13:05 -0500 apparmor (2.7.0~beta1+bzr1774-1ubuntu1) oneiric; urgency=low * 0004-adjust-logprof-log-search-order.patch: Adjust the search order to use just /var/log/audit/audit.log and /var/log/syslog. (LP: #835838) * 0005-lp826914.patch: fix missing multiarch in abstraction/X (LP: #826914) * 0006-lp838275.patch: adjust ubuntu-email abstraction for thunderbird 7 (LP: #838275) -- Jamie Strandboge Fri, 02 Sep 2011 12:30:10 -0500 apparmor (2.7.0~beta1+bzr1774-1) unstable; urgency=low * New upstream devel snapshot: - drop 0002-lp750381.patch, taken upstream. - drop 0004-lp754889.patch, taken upstream. - drop 0005-lp761217.patch, taken upstream. - drop 0100-manpage-typo.patch, taken upstream. - drop 0101-declarations.patch, solved differently upstream. - drop 0102-manpage-release-name.patch, taken upstream. - drop 0103-kfreebsd-compile.patch, taken upstream. - drop define-path-max.patch, taken upstream. - drop indep-build.patch, taken upstream. - debian/libapparmor1.manpages: add new function man pages. * Merge with Ubuntu: - drop 0104-python-aa-status.patch, taken upstream. - drop 0105-lightdm.patch, taken upstream. - drop 0106-lp810270.patch, taken upstream. - drop 0107-lp767308.patch, taken upstream. - drop 0108-gnome-mimeinfo.patch, taken upstream. - drop 0109-add-profile-repo-info.patch, taken upstream. * Add af_names-generation.patch to allow arbitrary socket.h file location. -- Kees Cook Wed, 10 Aug 2011 18:12:34 -0700 apparmor (2.6.1-4ubuntu5) oneiric; urgency=low * debian/patches/0109-add-profile-repo-info.patch: add a blurb about the new profiles repository to aa-genprof, along with a link to the wiki page. -- Marc Deslauriers Mon, 18 Jul 2011 10:49:13 -0400 apparmor (2.6.1-4ubuntu4) oneiric; urgency=low * debian/patches/0106-lp810270.patch: updated to use upstream commits -- Jamie Strandboge Fri, 15 Jul 2011 14:08:38 -0500 apparmor (2.6.1-4ubuntu3) oneiric; urgency=low * debian/patches/0106-lp810270.patch: adjustments for /var/run -> /run, /var/lock -> /run/lock and /dev/shm -> /run/shm transition (LP: #810270) * debian/patches/0107-lp767308.patch: allow read access to /usr/local/share/ca-certificates (LP: #767308) * debian/patches/0001-add-chromium-browser.patch: updates for newer chromium (LP: #776648) * debian/patches/0108-gnome-mimeinfo.patch: allow read access to /usr/share/gnome/applications/mimeinfo.cache in the gnome abstraction -- Jamie Strandboge Thu, 14 Jul 2011 09:39:49 -0500 apparmor (2.6.1-4ubuntu2) oneiric; urgency=low * debian/patches/0105-lightdm.patch: allow owner read access to /var/run/lightdm/authority/[0-9]* -- Jamie Strandboge Wed, 22 Jun 2011 16:29:11 -0500 apparmor (2.6.1-4ubuntu1) oneiric; urgency=low * Get rid of Perl in main AppArmor package so we can remove perl-modules from the installation cd: - debian/patches/0104-python-aa-status.patch: switch aa-status to Python - debian/apparmor.*, debian/apparmor-utils.*: move aa-status, symlink and manpages to main apparmor package. - debian/control: add appropriate Breaks/Replaces/Depends because of the file move, add ${python:Depends} to apparmor Depends, add apparmor-utils to apparmor Suggests. - debian/rules: add apparmor package to dh_python2. * debian/lib/apparmor/functions: fix hat separator (LP: #788616) - Based on upstream revision 1733 -- Marc Deslauriers Wed, 01 Jun 2011 11:03:20 -0400 apparmor (2.6.1-4) unstable; urgency=low * debian/po: add new translations: - zh_CN.po: Simplified Chinese, thanks to Aron Xu (Closes: 624853). - da.po: Danish, thanks to Joe Dalton (Closes: 625252). - sv.po: Swedish, thanks to Martin Bagge (Closes: 625264). - cs.po: Czech, thanks to Michal Šimůnek (Closes: 625465). - de.po: German, thanks to Chris Leick (Closes: 625931). - nl.po: Dutch, thanks to Jeroen Schot (Closes: 626269). - ja.po: Japanese, thanks to Hideki Yamane (Closes: 626803). - it.po: Italian, thanks to Dario Santamaria (Closes: 626836). - fr.po: French, thanks to Julien Patriarca (Closes: 626903). - es.po: Spanish, thanks to Francisco Javier Cuadrado (Closes: 627031). * debian/patches/define-path-max.patch: fix Hurd FTBFS. * debian/patches/indep-build.patch: allow split indep/arch builds. * debian/{control,rules,non-linux}: add fake parser for non-Linux builds so that apparmor-utils is installable (Closes: 625977). -- Kees Cook Fri, 27 May 2011 13:51:18 -0700 apparmor (2.6.1-3) unstable; urgency=low * debian/control: add sneaky missing Build-Dep on liblocale-gettext-perl (fixes FTBFS on some extremely minimal chroots, Closes: 624566). * debian/patches/0101-declarations.patch: add missing declarations needed for sensitive compilers (fixes FTBFS on mips/mipsel). * debian/patches/0102-manpage-release-name.patch: update manpage release names to match others. * debian/patches/0103-kfreebsd-compile.patch, debian/{control,rules}: attempt to build as much as possible (no parser) on non-Linux systems. * debian/po/ru.po: add translation, thanks to Yuri Kozlov (Closes: 624741). -- Kees Cook Sun, 01 May 2011 19:29:07 -0700 apparmor (2.6.1-2) unstable; urgency=low * debian/copyright: clarify for some full organization names. -- Kees Cook Wed, 27 Apr 2011 10:38:07 -0700 apparmor (2.6.1-1) unstable; urgency=low * Initial Debian upload (Closes: 622922). * debian/patches/0100-manpage-typo.patch: fix lintian error in manpage. * debian/clean: update for Debian build. * debian/copyright: rearrange and add a few missing files. * debian/source/format, debian/rules: convert to 3.0 quilt format. * debian/{rules,apparmor-profiles.postinst}: deal with lack of dh_apparmor. -- Kees Cook Sat, 23 Apr 2011 12:14:55 -0700 apparmor (2.6.1-0ubuntu3) natty; urgency=low * debian/patches/0003-add-debian-integration-to-lighttpd.patch: updates for lighttpd example profile to work in Debian/Ubuntu (LP: #582814) * debian/patches/0004-lp754889.patch: add several image viewers to ubuntu-browsers.d/multimedia abstraction (LP: #754889) * debian/patches/0005-lp761217.patch: abstractions/private-files updates for zsh and several other shells (LP: #761217) * debian/patches/0001-add-chromium-browser.patch: fixes for multiarch and crash reporter (LP: #764786) -- Jamie Strandboge Mon, 18 Apr 2011 09:23:50 -0500 apparmor (2.6.1-0ubuntu2) natty; urgency=low * debian/patches/0002-lp750381.path: adjust ubuntu-media-players abstraction to allow reading of configs required by gnash and owner writing of @{HOME}/.gnash (LP: #750381) -- Jamie Strandboge Thu, 07 Apr 2011 10:09:24 -0500 apparmor (2.6.1-0ubuntu1) natty; urgency=low * New upstream release. - Fixes breakage of mod_apparmor apache2 module (LP: #737074) - Fixes profile matching when an attachement doesn't contain a regex (LP: #731155) - Fixes parser acceptance of missing network protocols (LP: #732837) - Patches taken upstream and dropped: + debian/patches/0002-lp727478.patch + debian/patches/0003-test-lp727478.patch + debian/patches/0004-lp736870.patch * debian/apparmor.install, debian/apparmor.dirs: add new multiarch tunable file and directory * debian/python-libapparmor.install: loosen directory specification for resiliancy against different python versions -- Steve Beattie Thu, 24 Mar 2011 01:55:12 -0700 apparmor (2.6.0-0ubuntu4) natty; urgency=low * Update debian/patches/0004-lp736870.patch (LP: #736870): - armel triplet doesn't match '*-linux-gnu' - /lib/tls for libc6-xen needs handling - gnome, kde, kerberosclient, and authentication abstractions also need updating for multiarch. -- Steve Langasek Tue, 22 Mar 2011 15:18:54 -0700 apparmor (2.6.0-0ubuntu3) natty; urgency=low * debian/patches/0004-lp736870.patch: add multiarch support to abstractions (LP: #736870) -- Jamie Strandboge Thu, 17 Mar 2011 09:17:01 -0500 apparmor (2.6.0-0ubuntu2) natty; urgency=low * debian/patches/0002-lp727478.patch: Override AF_MAX for kernels that don't support proper masking. Patch thanks to John Johansen (LP: #727478) * debian/patches/0003-test-lp727478.patch: add tcp.sh test as partial networking test -- Jamie Strandboge Thu, 03 Mar 2011 16:40:08 -0600 apparmor (2.6.0-0ubuntu1) natty; urgency=low [ Steve Beattie ] * New upstream 2.6.0 release (LP: #724193) - Patches taken upstream and dropped: + 0001-ubuntu-buildd.patch + 0003-add-libvirt-support-to-dnsmasq.patch + 0004-lp698194.patch + 0005-aa-disable.patch - debian/rules: remove library path settings for mod_apparmor and pam_apprmor builds; upstream handles this properly now. - debian/apparmor-utils.install: handle upstream SubDomain.pm => AppArmor.pm renaming * debian/lib/apparmor/functions: handle profile names with embedded spaces (LP: #655523) * debian/rules, debian/control, debian/python-libapparmor: build a python-libapparmor package. [ Jamie Strandboge ] * debian/copyright: update and reformat according to DEP-5 * debian/lib/apparmor/functions: don't unload dynamically generated libvirt profiles on reload, restart, and force-reload (LP: #702774) * debian/control: use Section: python for python-libapparmor -- Steve Beattie Thu, 24 Feb 2011 01:41:58 -0800 apparmor (2.6~devel+bzr1617-0ubuntu2) natty; urgency=low * debian/patches/0005-aa-disable.patch: add aa-disable * debian/apparmor-utils.install: install aa-disable * debian/apparmor-utils.manpages: install aa-disable man page -- Jamie Strandboge Mon, 07 Feb 2011 11:23:50 -0600 apparmor (2.6~devel+bzr1617-0ubuntu1) natty; urgency=low * Merge with upstream bzr revision 1617. Closes the following bugs: - LP: #692406: temporarily disable the defunct repository until an alternative can be used - LP: #649497: add ibus abstraction - LP: #652562: allow 'rw' to /var/log/samba/cores/ - LP: #658135: allow access to /usr/lib32 and /usr/lib64 for dri modules * 0002-add-chromium-browser.patch: add /dev/shm/.org.chromium.* (LP: #692866) * rename debian/patches/0010-ubuntu-buildd.patch to 0001-ubuntu-buildd.patch and adjust debian/patches/series * debian/patches/0003-add-libvirt-support-to-dnsmasq.patch (LP: #697239): - allow read and write access to libvirt pid files for dnsmasq - allow net_admin capability for DHCP server - allow net_raw and network inet raw for ICMP pings when used as a DHCP server * debian/patches/0004-lp698194 (LP: #698194): - abstractions/private-files: don't allow wl to autostart directories - abstractions/private-files-strict: don't allow access to chromium, kwallet and popular mail clients -- Jamie Strandboge Fri, 07 Jan 2011 12:44:26 -0600 apparmor (2.6~devel+bzr1601-0ubuntu1) natty; urgency=low * Merge with upstream bzr revision 1601 to gain parser speed improvements and man page fixes. Closes the following bugs: - LP: #349049: document audit, deny and owner rule qualifiers - LP: #466228: ubuntu-browsers.d/multimedia: allow flash printing - LP: #644983: add ubuntu-browsers.d/ubuntu-integration-xul - LP: #692216: use aa_change_hat() instead of change_hat() - LP: #692217: add aa_change_profile.pod manpage * debian/control: explicitly depend on gettext module. * ship apparmor vim syntax file (LP: #646800): - debian/vim-apparmor.yaml: vim addon definition file. - debian/apparmor-utils.install: add apparmor.vim and vim-apparmor.yaml. * debian/libapparmor1.manpages: ship aa_change_profile manpage. -- Kees Cook Mon, 20 Dec 2010 14:37:38 -0800 apparmor (2.6~devel+bzr1527-0ubuntu1) natty; urgency=low * Merge with upstream bzr revision 1527, drop patches taken upstream: - debian/patches/0001-fix-release.patch - debian/patches/0003-local-includes.patch - debian/patches/0004-ubuntu-abstractions-updates.patch - debian/patches/0005-lp648900.patch - debian/patches/0006-testsuite-fixes.patch - debian/patches/0007-honor-cflags.patch - debian/patches/0008-lp652674.patch - debian/patches/0009-sensible-browser-pix.patch * Rework packaging for more sanity. - debian/control: - bump debhelper build depend to Ubuntu-specific v8. - switch apparmor-profiles to arch all as it ships only text. - update Homepage to new domain. - expand long descriptions to keep lintian happy. - debian/compat: bump to 8. - README.Debian: removed, hopelessly out of date. - debian/copyright: - updated for changes to upstream source layout. - fixed lintian warnings. - debian/rules: - ditch mv/install in favor of *.install,*.dir files. - replace "dh_clean -k" with "dh_prep" - use dh_clean's debian/clean file instead of manual rm. - scan for all profiles to run through dh_apparmor. - debian/*.{install,dirs,manpages,docs}: - explicitly list all files needed for packaging - debian/apparmor.{preinst,postinst,postrm}: - add dpkg-maintscript-helper calls to clean up old script locations. - drop old conffile cleanups, since they predate Lucid. - debian/apparmor.init: - move functions to /lib/apparmor. - start on $remote_fs due to using /usr tools during init. - use LC_COLLATE=C for proper sorting. - debian/libapparmor1.symbols: created initial symbols file. - debian/apparmor-docs.doc-base: include doc-base details for techdoc. - debian/notify/90apparmor-notify: use new command name. - lib/apparmor/functions: use LC_COLLATE=C for proper sorting. -- Kees Cook Thu, 04 Nov 2010 18:06:34 -0700 apparmor (2.5.1-0ubuntu4) natty; urgency=low * debian/patches/0004-ubuntu-abstractions-updates.patch: updated to add /usr/bin/emacs-snapshot-gtk PUxr * debian/patches/0009-sensible-browser-pix.patch: use Pix for sensible-browser * debian/patches/0010-ubuntu-buildd.patch: skip parser caching test if the AppArmor securityfs introspection directory is not mounted, as is the case on Ubuntu buildds. -- Jamie Strandboge Tue, 02 Nov 2010 12:17:21 -0500 apparmor (2.5.1-0ubuntu3) natty; urgency=low * debian/control: use the correct version for Conflicts/Replaces -- Jamie Strandboge Tue, 19 Oct 2010 19:53:26 -0500 apparmor (2.5.1-0ubuntu2) natty; urgency=low * debian/{rules,control}: move apache2 abstractions into the base package so we can put apache2 profiles into the -profiles package without aa-logprof bailing out. Patch by Marc Deslauriers. (LP: #539441) -- Jamie Strandboge Tue, 19 Oct 2010 15:44:43 -0500 apparmor (2.5.1-0ubuntu1) natty; urgency=low * New upstream release (LP: #660077) - The following patches were refreshed: + 0001-fix-release.patch + 0003-local-includes.patch + 0008-lp648900.patch: renamed as 0005-lp648900.patch - The following patches were dropped (included upstream): + 0005-lp601583.patch + 0006-network-interface-enumeration.patch + 0007-gnome-updates.patch * debian/patches/0006-testsuite-fixes.patch: testsuite fixes from head of 2.5 branch. These are needed for QRT and SRU testing (LP: #652211) * debian/patches/0007-honor-cflags.patch: have the parser makefile honor CFLAGS environment variable. Brings back missing symbols for the retracer * debian/patches/0008-lp652674.patch: fix warnings for messages without denied or requested masks (LP: #652674) * debian/apparmor.init: fix path to aa-status (LP: #654841) * debian/apport/source_apparmor.py: apport hook should use root_command_hook() for running apparmor_status (LP: #655529) * debian/apport/source_apparmor.py: use ProcKernelCmdline and don't clobber cmdline details (LP: #657091) -- Jamie Strandboge Fri, 15 Oct 2010 12:23:00 -0500 apparmor (2.5.1~rc1-0ubuntu2) maverick; urgency=low * abstractions/ubuntu-email: adjustment for ever-changing thunderbird path (LP: #648900) -- Jamie Strandboge Mon, 27 Sep 2010 09:00:06 -0500 apparmor (2.5.1~rc1-0ubuntu1) maverick; urgency=low [ Jamie Strandboge ] * New upstream RC release (revision 1413). In addition to getting the tools to work with the maverick kernel, this update fixes: - LP: #619521 - LP: #633369 - LP: #626451 - LP: #581525 - LP: #623467 (link and unlink still need to be addressed) * Dropped the following patches, included upstream: - 0002-lp615177.patch - 0004-ubuntu-pux.patch - 0006-kde4-config-pux.patch - 0007-lp605835.patch - 0012-lp625041.patch - 0013-lp623586.patch * Update the following patches: - rename 0010-fix-release.patch as 0001-fix-release.patch since this will likely always need to be here - rename 0005-add-chromium-browser.patch as 0002-add-chromium-browser.patch - rename 0001-local-includes.patch as 0003-local-includes.patch and update to use r1493 (from trunk) of local/README file. This can be dropped in 2.6. - collect the ubuntu abstractions updates pulled from trunk into 0004-ubuntu-abstractions-updates.patch. This can be dropped in 2.6. - rename 0008-lp601583.patch as 0005-lp601583.patch. This can be dropped in 2.5.1 final. * fix up some lintian warnings: - debian/control: + don't use 'Section' in apparmor-notify, since it is the same as the source + updates Standards-Version to 3.9.1 + add ${misc:Depends} to libapparmor-dev and apparmor-notify - add debian/source/format - debian/libapache2-mod-apparmor.postrm: use #DEBHELPER# - debian/libapache2-mod-apparmor.preinst: use #DEBHELPER# - add debian/watch * debian/notify/notify.conf: set show_notifications="yes" by default * debian/patches/0006-network-interface-enumeration.patch: allow network interface enumeration. This can be dropped in 2.5.1 final. * debian/patches/0007-gnome-updates.patch: update for font/icon/mime locations in current gnome. This can be dropped in 2.5.1 final. [ Kees Cook ] * debian/apparmor.init: rename "stop" to "teardown", drop caches on "stop" and warn about the dangers of "teardown". -- Jamie Strandboge Fri, 10 Sep 2010 11:07:19 -0500 apparmor (2.5.1~pre1393-0ubuntu6) maverick; urgency=low * debian/profiles/chromium-browser: updated to have the proper path to local/ * debian/patches/0011-lp514356+573344+593413.patch: browser abstraction updates for /net, kmozillahelper and gnome-appearance-properties (LP: #593413, LP: #514356, LP: #573344) * debian/patches/0012-lp625041.patch: add sensible-browser (LP: #625041) * debian/patches/0013-lp623586.patch: allow access to ghostscript fonts when not using defoma (LP: #623586) -- Jamie Strandboge Fri, 03 Sep 2010 07:39:31 -0500 apparmor (2.5.1~pre1393-0ubuntu5) maverick; urgency=low * debian/patches/0007-lp605835.patch: allow ca-certificates in ssl_certs abstraction (LP: #605835) * debian/patches/0008-lp601583.patch: adjust X abstraction for newer gdm (LP: #601583) * debian/patches/0009-lp565753.patch: add ubuntu-feed-readers abstraction and have ubuntu-browsers.d/multimedia use it (LP: #565753) * debian/apparmor.config: don't try to read in the existing value from /etc/apparmor.d/tunables/home.d/ubuntu, but instead always use what is in debconf. (LP: #561694) * add aa-update-browser for giving a programmatic way to update browser profiles to use browser abstractions - add debian/aa-update-browser - add debian/aa-update-browser.8 - debian/rules: install aa-update-browser* * debian/patches/0003-ubuntu-browsers-d.patch: updated to generalize java child profile names * debian/patches/0010-fix-release.patch: update common/Make.rules to use lsb_release -- Jamie Strandboge Wed, 11 Aug 2010 09:24:23 -0500 apparmor (2.5.1~pre1393-0ubuntu4) maverick; urgency=low * debian/patches/0001-local-includes.patch: updated to adjust local/README to have upstream clarifications * debian/patches/0003-ubuntu-browsers-d.patch: add ubuntu-browsers.d/* abstractions * debian/patches/0004-ubuntu-pux.patch: use 'PUx' instead of 'Ux' in abstractions/ubuntu-* * add chromium-browser profile. All this can be removed once chromium-browser ships its own profile: - debian/patches/0005-add-chromium-browser.patch: add preliminary profiles/apparmor.d/usr.bin.chromium-browser - debian/profiles/chromium-browser: added for use with ubuntu-browsers.d - debian/rules: ship debian/profiles/chromium-browser in apparmor-profiles * don't make /etc/apparmor.d/local/* from apparmor-profiles conffiles - debian/control: Build-Depends on debhelper 7.4.20ubuntu5 - debian/rules: use dh_apparmor instead of shipping the files as conffiles - debian/apparmor-profiles.postinst: move DEBHELPER before initscript reload - debian/apparmor-profiles.postrm: added to remove chromium-browser config file * debian/patches/0006-kde4-config-pux.patch: remove kde4-config from kde abstraction and add it to kde ubuntu-browsers abstraction -- Jamie Strandboge Tue, 10 Aug 2010 14:31:32 -0500 apparmor (2.5.1~pre1393-0ubuntu3) maverick; urgency=low * debian/patches/0002-lp615177.patch: 'owner' match in commit 1406 too strict for /tmp/ and /var/tmp/ (LP: #615177) -- Jamie Strandboge Mon, 09 Aug 2010 10:17:05 -0500 apparmor (2.5.1~pre1393-0ubuntu2) maverick; urgency=low * debian/rules: move local/usr.lib.apache2.mpm-prefork.apache2 to libapache2-mod-apparmor -- Jamie Strandboge Fri, 06 Aug 2010 13:38:59 -0500 apparmor (2.5.1~pre1393-0ubuntu1) maverick; urgency=low * Update to upstream bzr revision 1393 from lp:apparmor/2.5. * add dbus-session abstraction (LP: #566207) * require owner in user-tmp abstraction (LP: #578922) * don't use uninitialized $opt_s (LP: #582075) * allow thunderbird 3 in abstractions/ubuntu-email (LP: #590462) * allow gmplayer in abstractions/ubuntu-media-players (LP: #591421) * debian/control: updated branches. * debian/patches/0001-local-includes.patch: backported patch from trunk to allow local administrators to customize their profiles without modifying a shipped profile * debian/rules: - don't pass RELEASE to libapparmor's 'make install' as it breaks the build and isn't used by the Makfile anyway - install apparmor.d/local/README in apparmor, not apparmor-profiles - don't install apparmor.d/local/usr.sbin.ntpd * Drop the following patches already included upstream: - 0001-lp538561.patch - 0002-aalogprof-warnings.patch - 0003-fix-memleaks.patch - 0004-lp549557.patch - 0005-lp538661.patch - 0006-lp611248.patch -- Jamie Strandboge Thu, 05 Aug 2010 16:10:46 -0500 apparmor (2.5-0ubuntu4) maverick; urgency=low * debian/patches/0006-lp611248.patch: allow access to gdk-pixbuf loaders LP: #611248 -- Jamie Strandboge Tue, 03 Aug 2010 09:32:10 -0500 apparmor (2.5-0ubuntu3) lucid; urgency=low [ Jamie Strandboge ] * debian/patches/lp-549557.patch: have apparmor_notify deal with log file rotation. (LP: #549557) * debian/notify/notify.conf: set show_notifications="yes" * debian/patches/0005-lp538661.patch: adjust php5 abstraction for cgi config file path and extensions (LP: #538661) [ Kees Cook ] * debian/apparmor.functions: do not load in parallel, this is causing weird side-effects. -- Jamie Strandboge Tue, 30 Mar 2010 11:31:49 -0500 apparmor (2.5-0ubuntu2) lucid; urgency=low [ Jamie Strandboge ] * debian/patches/0001-lp538561.patch: add 'k' to /var/lib/samba/**.tdb in the samba abstraction (LP: #538561) [ Marc Deslauriers ] * debian/patches/0002-aalogprof-warnings.patch: get rid of warnings when aa-logprof is run. * debian/{rules,control}: move apache2 abstractions into the base package so we can put apache2 profiles into the -profiles package without aa-logprof bailing out. (LP: #539441) * debian/patches/0003-fix-memleaks.patch: include a couple of leak patches from upstream. -- Marc Deslauriers Fri, 26 Mar 2010 11:39:18 -0400 apparmor (2.5-0ubuntu1) lucid; urgency=low * New upstream release. * debian/control: updated branches. * debian/copyright: updated download locations. * debian/rules: drop unneeded build variables. * common/Make.rules: set distributor. -- Kees Cook Thu, 11 Mar 2010 00:08:08 -0800 apparmor (2.5~pre+bzr1367-0ubuntu1) lucid; urgency=low * Update to upstream bzr revision 1367 * debian/notify/90apparmor-notify: sleep for 60 seconds for boot speed and to make sure that X is all the way up so the notifications look pretty -- Jamie Strandboge Mon, 08 Mar 2010 13:53:50 -0600 apparmor (2.5~pre+bzr1364-0ubuntu1) lucid; urgency=low * Update to upstream bzr revision 1364. * debian/apparmor.functions: ignore .dpkg-bak files when loading too. -- Kees Cook Wed, 17 Feb 2010 13:36:21 -0800 apparmor (2.5~pre+bzr1362-0ubuntu2) lucid; urgency=low * debian/apparmor.postinst: on upgrades, prepopulate apparmor/homedirs if it is not preseeded. Will check /etc/passwd for UIDs >= 1000 and < 30000 for unique dirnames of home directories that are not /home. Fully resolves (LP: #447292) -- Jamie Strandboge Wed, 17 Feb 2010 09:42:55 -0600 apparmor (2.5~pre+bzr1362-0ubuntu1) lucid; urgency=low [ Kees Cook ] * Update to upstream bzr revision 1362. - This release includes DFA minimization, transition table compression, and improved partitioning performance (LP: #503869). - drop 0001-tunable-alias.patch, now upstream. * debian/apparmor.postinst: update home.d template to note the trailing slash, even if the debconf template mentions it too. * debian/apparmor.functions: go fully parallel with parsing to use all CPUs in the case of needing to regenerate caches. * debian/rules: enable library testsuite during build. * debian/control: add dejagnu for library testsuite. * debian/{rules,control}: use chrpath to drop rpath in libapparmor-perl. [ Jamie Strandboge ] * debian/control: add apparmor-notify * add debian/notify/notify.conf * add debian/notify/90apparmor-notify * add debian/apparmor-notify.install: install notify.conf to /etc/apparmor and 90apparmor-notify to /etc/X11/Xsession.d * debian/rules: - remove upstream notify.conf since we will install our own via debhelper - move apparmor_notify script and man pages to apparmor-notify -- Kees Cook Sat, 13 Feb 2010 12:19:30 -0800 apparmor (2.3.1+bzr1312-0ubuntu4) lucid; urgency=low * 0001-tunable-alias.patch: backport r1330 to make it easier for people to use AppArmor's alias rules (LP: #160002) -- Jamie Strandboge Mon, 11 Jan 2010 14:31:06 -0600 apparmor (2.3.1+bzr1312-0ubuntu3) lucid; urgency=low * debian/apparmor.{init,functions}: - add "recache" argument to init script for liveCD cache generation. - skip start/stop/reload when running on liveCD. -- Kees Cook Fri, 08 Jan 2010 08:39:14 -0800 apparmor (2.3.1+bzr1312-0ubuntu2) lucid; urgency=low * debian/rules: disable profiling support for released version. -- Kees Cook Wed, 06 Jan 2010 16:57:58 -0800 apparmor (2.3.1+bzr1312-0ubuntu1) lucid; urgency=low [ Kees Cook ] * Update to upstream bzr revision 1312. * debian/apparmor.postrm: fix comment typo. * debain/rules: switch to bzr for upstream versioning. * debian/rules: install apache2-* abstractions into apache2-mod package. * drop debian/patches/0001-likewise-home-tunables.patch: this is causing too much time in the parser (see LP 503869). The default install is suffering, so move this configuration to likewise-open (see LP 274350). [ Jamie Strandboge ] * debian/rules: - don't ship tunables/home.d/site.local - correct path for moving apache2 abstraction * add debconf question for adjusting HOMEDIRS (LP: #447292) - add debian/apparmor.config - debian/apparmor.postinst: query debconf and adjust tunables/home.d/ubuntu - debian/apparmor.postrm: on purge, remove tunables/home.d/ubuntu and run db_purge - debian/control: Build-Depends on po-debconf and have apparmor Depends on debconf - add debian/po/* - debian/rules: use dh_installdebconf -papparmor - added debian/templates -- Kees Cook Wed, 06 Jan 2010 15:51:33 -0800 apparmor (2.3.1+1403-0ubuntu31) lucid; urgency=low * Remove initramfs hooks, as early profile loading is handled on a service-by-service basis with Upstart jobs now. -- Kees Cook Fri, 04 Dec 2009 13:22:04 -0800 apparmor (2.3.1+1403-0ubuntu30) lucid; urgency=low [ Jamie Strandboge ] * convert to using quilt - debian/control: Build-Depends on quilt - add debian/README.source - debian/rules: include /usr/share/quilt/quilt.make and adjust targets for patching * debian/patches/0001-likewise-home-tunables.patch: tunables/home: add /home/likewise-open/*/ to HOMEDIRS (LP: #274350) * Merge to upstream bzr rev 1308. - really add chromium-browser (LP: #488559) - add official google-chrome (LP: #481661) [ Kees Cook ] * parser/parser_main.c: use nanosec ctime resolution when checking cache file times. * parser/tst/caching.sh: add tests for cache use based on timestamps. -- Jamie Strandboge Fri, 04 Dec 2009 11:11:01 -0600 apparmor (2.3.1+1403-0ubuntu29) lucid; urgency=low * parser/Makefile: generate af_names.h based on bits/socket.h since linux/socket.h no longer has what we need (LP: #474751) * usr.sbin.dnsmasq: fully address LP: #445818 - more pidfile refinements - allow access to /var/run/dnsmasq - allow access to /etc/dnsmasq.d - allow dac_override so it can write its pidfile * abstractions/ubuntu-browsers: add chromium-browser -- Jamie Strandboge Wed, 04 Nov 2009 17:07:23 -0600 apparmor (2.3.1+1403-0ubuntu28) lucid; urgency=low [ Jamie Strandboge ] * update skype profile in extras. Based on work by Андрей Калинин. (LP: #226624) * abstractions/ubuntu-browsers: add opera and icecat (LP: #432778) * abstractions/ubuntu-browsers: add epiphany (epiphany-browser and epiphany-webkit were already present, but the recent changes in epiphany packaging require /usr/bin/epiphany) (LP: #472952) * usr.sbin.dnsmasq: allow pidfiles for /var/run/dnsmasq*.pid (LP: #445818) * abstractions/gnome: allow access to ~/.themes (LP: #460125) * abstractions/kde: allow access to /etc/kde4rc and /usr/bin/kde4-config (LP: #447006) [ Marc Deslauriers ] * utils/Subdomain.pm: don't skip reading profiles that are also in the cache directory (LP: #446449) * utils/Subdomain.pm: correctly parse PUxr modes * utils/Subdomain.pm: support include directories -- Jamie Strandboge Wed, 04 Nov 2009 11:02:27 -0600 apparmor (2.3.1+1403-0ubuntu27) karmic; urgency=low * utils/SubDomain.pm: handle new format "null" log entries (LP: #446524) -- Marc Deslauriers Fri, 16 Oct 2009 14:40:04 -0400 apparmor (2.3.1+1403-0ubuntu26) karmic; urgency=low * abstractions/ubuntu-browsers: add Dooble * abstractions/ubuntu-browsers: add chromium (LP: #448812) * abstractions/gnome: add read for /etc/orbitrc * abstractions/audio: add read for /etc/pulse/* for when ~/.pulse/* doesn't exist and these files are used for fallback -- Jamie Strandboge Wed, 14 Oct 2009 07:59:03 -0500 apparmor (2.3.1+1403-0ubuntu25) karmic; urgency=low * Do not use tools in /usr during initial start-up (LP: #439726). -- Kees Cook Fri, 02 Oct 2009 16:52:04 -0700 apparmor (2.3.1+1403-0ubuntu24) karmic; urgency=low * abstractions/X: allow mouse themes (LP: #438051) -- Jamie Strandboge Thu, 01 Oct 2009 16:07:25 -0500 apparmor (2.3.1+1403-0ubuntu23) karmic; urgency=low [ Kees Cook ] * Really fix quiet mode in initramfs (LP: #435285). * Handle older kernel versions when loading profiles (LP: #429872): - parser/parser_{interface,main}.c: detect kernel version and downgrade. - debian/apparmor.functions, parser/parser_main.c: keep kernel features recorded in cache directory. - parser/parser_{interface,main}.c: add --skip-kernel-load for testing. - parser/tst/caching.*: add caching tests. [ Jamie Strandboge ] * abstractions/audio: add a few more files for pulseaudio -- Kees Cook Fri, 25 Sep 2009 09:54:01 -0700 apparmor (2.3.1+1403-0ubuntu22) karmic; urgency=low * Do not run AppArmor on the LiveCD, again (LP: #131976). * More aggressively stay quiet when booting in quiet mode (LP: #435285). -- Kees Cook Wed, 23 Sep 2009 15:40:22 -0700 apparmor (2.3.1+1403-0ubuntu21) karmic; urgency=low * debian/apparmor.{init-bottom,functions,initramfs}: perform initial apparmor rule loading in initramfs. -- Kees Cook Mon, 21 Sep 2009 14:16:26 -0700 apparmor (2.3.1+1403-0ubuntu20) karmic; urgency=low * added disabled apache2 profile (FFE LP: #430812): - add profiles/apparmor.d/usr.lib.apache2.mpm-prefork.apache2: new apache2 profile - add profiles/apparmor.d/apache2.d/phpsysinfo: example profile for the phpsysinfo application - profiles/Makefile: handle the apache2.d directory - add debian/libapache2-mod-apparmor.postinst: reload apparmor after installation since we now ship a profile in this package - add debian/libapache2-mod-apparmor.preinst: disable apache2 profile if the user does not already have a profile defined - add debian/libapache2-mod-apparmor.postrm: remove disabled symlink on purge - debian/rules: move apache2 profile to the libapache2-mod-apparmor package and create apache2.d directory * utils/SubDomain.pm: handle "open" log entries (LP: #427966) * added ouid parsing support (LP: #431929): - libraries/libapparmor/testsuite/test_multi.c - libraries/libapparmor/src/{scanner.l,grammar.y,aalogparse.h, libaalogparse.c} -- Marc Deslauriers Sat, 19 Sep 2009 09:32:02 -0400 apparmor (2.3.1+1403-0ubuntu19) karmic; urgency=low [ Jamie Strandboge ] * abstractions/fonts: allow links in @{HOME}/.fontconfig/** [ Kees Cook ] * debian/apparmor.init: expect that the securityfs is mounted, and only test for the mounted filesystem against the type column when it is not found. -- Kees Cook Wed, 09 Sep 2009 11:42:07 -0700 apparmor (2.3.1+1403-0ubuntu18) karmic; urgency=low * added the following abstractions: - ubuntu-browsers: Ux transitions to graphical browsers - ubuntu-console-browsers: Ux transitions to text-mode browsers - ubuntu-console-email: Ux transitions to text-mode email clients - ubuntu-email: Ux transitions to graphical email clients - ubuntu-gnome-terminal: ix transition for gnome-terminal - ubuntu-konsole: ix transition for konsole - ubuntu-xterm: ix transition for xterm -- Jamie Strandboge Thu, 03 Sep 2009 11:57:39 -0500 apparmor (2.3.1+1403-0ubuntu17) karmic; urgency=low * abstractions/base: workaround for ecryptfs and apparmor by allowing 'owner' match for files in .Private. (LP: #359338) -- Jamie Strandboge Mon, 31 Aug 2009 15:38:54 -0500 apparmor (2.3.1+1403-0ubuntu16) karmic; urgency=low * profiles/apparmor.d/*dovecot*: add first-pass at complain-only profiles for basic dovecot operation. -- Kees Cook Wed, 26 Aug 2009 15:19:46 -0700 apparmor (2.3.1+1403-0ubuntu15) karmic; urgency=low * utils/SubDomain.pm: don't abort when an include file only contains hats (LP: #400367) -- Marc Deslauriers Wed, 26 Aug 2009 11:35:58 -0400 apparmor (2.3.1+1403-0ubuntu14) karmic; urgency=low * Pull upstream changes for 64bit capabilities (svn 1427, 1437, 1438). * Pull upstream changes for pux exec mode (svn 1439). * debian/apparmor.init: "find" -name is not brace-aware (LP: #418364). -- Kees Cook Mon, 24 Aug 2009 18:01:05 -0700 apparmor (2.3.1+1403-0ubuntu13) karmic; urgency=low [ Kees Cook ] * parser/parser_main.c: add --skip-read-cache to force reading of uncached profiles while still allowing for --write-cache to work. * parser/apparmor_parser.pod: add all missing option documentation. [ Jamie Strandboge ] * abstractions/kde: update for kde4 -- Jamie Strandboge Wed, 19 Aug 2009 12:07:06 -0500 apparmor (2.3.1+1403-0ubuntu12) karmic; urgency=low * abstractions/base: add more locale paths (LP: #413454) -- Jamie Strandboge Fri, 14 Aug 2009 07:31:03 -0500 apparmor (2.3.1+1403-0ubuntu11) karmic; urgency=low * utils/enforce: remove /etc/apparmor.d/disable/ symlink LP: #413153 * debian/rules: don't install usr.sbin.ntpd or tunables/ntpd. Can remove this when we create a new orig.tar.gz -- Jamie Strandboge Wed, 12 Aug 2009 10:04:34 -0500 apparmor (2.3.1+1403-0ubuntu10) karmic; urgency=low * remove apparmor.d/usr.sbin.ntpd and apparmor.d/tunables/ntpd since ntpd will begin shipping its own profile -- Jamie Strandboge Wed, 12 Aug 2009 10:02:53 -0500 apparmor (2.3.1+1403-0ubuntu9) karmic; urgency=low * Revert 64-bit capabilities (LP: #408773). -- Kees Cook Tue, 04 Aug 2009 11:51:27 +0100 apparmor (2.3.1+1403-0ubuntu8) karmic; urgency=low * Update to upstream subversion r1431. - change_profile can use regex (LP: #390810, #401931) * debian/apparmor.init: always clear cache on reload. -- Kees Cook Mon, 03 Aug 2009 07:46:33 -0700 apparmor (2.3.1+1403-0ubuntu7) karmic; urgency=low * profiles/apparmor.d/abstractions/base: add /proc/sys/crypto (LP: #392337). -- Kees Cook Sat, 25 Jul 2009 09:04:46 -0700 apparmor (2.3.1+1403-0ubuntu6) karmic; urgency=low [ Kees Cook ] * parser/parser_policy.c: return errors instead of exiting. * debian/apparmor.init: skip more suffixes. * parser/parser_lex.l: define file suffixes to ignore. * parser/parser_main.c: disable cache for parsing reports. * debian/apparmor.init: also remove unparsed profiles. [ Jamie Strandboge ] * update gnome abstraction for /var/run/gdm/auth*/database * utils/SubDomain.pm: parse profiles in subdirectories, not just include files (LP: #401935) -- Jamie Strandboge Mon, 20 Jul 2009 11:45:24 -0500 apparmor (2.3.1+1403-0ubuntu5) karmic; urgency=low * Always use --replace when loading profiles so that if profiles are loaded outside of the init script (e.g. dhcp3), the init script does not abort (LP: #401109). * parser/parser_main.c: more carefully create cache files. -- Kees Cook Sun, 19 Jul 2009 07:48:11 -0700 apparmor (2.3.1+1403-0ubuntu4) karmic; urgency=low * utils/SubDomain.pm: exclude new cache directory. * parser/parser_main.c: - allow OPTION_REMOVE to work again (LP: #400781). - warn about using stdin. - do not cache disabled profiles. - report cached loading if not quiet. * debian/apparmor.init: - do not depend on aa-status. - only write cache from init script. -- Kees Cook Fri, 17 Jul 2009 10:10:05 -0700 apparmor (2.3.1+1403-0ubuntu3) karmic; urgency=low * debian/apparmor.init: more cleanly handle disabled AppArmor. -- Kees Cook Fri, 17 Jul 2009 00:12:19 -0700 apparmor (2.3.1+1403-0ubuntu2) karmic; urgency=low * improve profile loading speed (LP: #382944): - parser/parser_lex.l: move include handling into flex parser. - parser/parser_main.c: - move disable/complain logic into loader. - add binary caching. - debian/apparmor.init: reduce to bare minimum. -- Kees Cook Wed, 15 Jul 2009 17:05:49 -0700 apparmor (2.3.1+1403-0ubuntu1) karmic; urgency=low [ Kees Cook ] * New upstream bundle (svn1403). * debian/apparmor.init: add specific Start/Stop dependencies (LP: #372441). * debian/control: correctly use lsb-base not sysv for Depends. [ Jamie Strandboge ] * add abstractions/launchpad-integration * abstractions/audio: add pulseaudio * add abstractions/private-files* for explicitly denying access to sensitive files. -- Kees Cook Fri, 10 Jul 2009 08:37:54 -0700 apparmor (2.3+1289-0ubuntu15) karmic; urgency=low * Depend on upstart 0.6.0 which contains upstart-compat-sysv now -- Scott James Remnant Fri, 10 Jul 2009 10:28:45 +0100 apparmor (2.3+1289-0ubuntu14) jaunty; urgency=low * abstractions/smbpass: Add *.ldb used in Samba 3.2 and above (LP: #357581) -- Thierry Carrez Wed, 08 Apr 2009 13:42:21 +0200 apparmor (2.3+1289-0ubuntu13) jaunty; urgency=low [ Kees Cook ] * abstractions/gnome: allow /proc/$pid/mounts for gvfs. * abstractions/python: clean up allowed paths (LP: #350820), thanks to Jonathan Davies. [ Jamie Strandboge ] * abstractions/user-tmp: allow 'k' for files in tmp dirs (LP: #351275) -- Jamie Strandboge Tue, 31 Mar 2009 09:57:57 -0500 apparmor (2.3+1289-0ubuntu12) jaunty; urgency=low * expand allowed library paths to handle unexpected architectures (LP: #349819). -- Kees Cook Fri, 27 Mar 2009 13:48:11 -0700 apparmor (2.3+1289-0ubuntu11) jaunty; urgency=low * fix path to winbindd_privileged/pipe in winbind abstraction (LP: #348541) -- Jamie Strandboge Fri, 27 Mar 2009 08:29:13 -0500 apparmor (2.3+1289-0ubuntu10) jaunty; urgency=low * utils/SubDomain.pm: - teach utils about rearranged syslog audit messages (LP: #340183) from upstream commit https://forgesvn1.novell.com/viewsvn/apparmor?view=rev&revision=1393 - fix corruption of profiles, from upstream commit https://forgesvn1.novell.com/viewsvn/apparmor?view=rev&revision=1354 - don't ask about networking events over and over again, from upstream commit https://forgesvn1.novell.com/viewsvn/apparmor?view=rev&revision=1296 - use apparmor logdir instead of /tmp to write debugging log -- Steve Beattie Thu, 19 Mar 2009 03:05:07 -0700 apparmor (2.3+1289-0ubuntu9) jaunty; urgency=low [ Kees Cook ] * abstractions/base: allow /proc/$pid/maps (LP: #343287). * abstractions/*: clean up lib, lib32, lib64 semantics (LP: #342200). * abstractions/nameservice: fix up paths for nscd (LP: #342198). * parser/rc.apparmor.functions, debian/apparmor.init: LSB-ify startup messages (LP: #295200). [ Steve Beattie ] * libapparmor/src/scanner.l: adjust lexer to fix matching updated audit messages (LP: #340183) from upstream commit https://forgesvn1.novell.com/viewsvn/apparmor?view=rev&revision=1389 * debian/source_apparmor.py: add a per-package apport hook (LP: #342554). -- Kees Cook Wed, 18 Mar 2009 21:18:01 -0700 apparmor (2.3+1289-0ubuntu8) jaunty; urgency=low * abstractions/ssl_keys: allow read access to all of /etc/ssl (LP: #317109) * utils/SubDomain.pm: re-add dropped patch to not process disable/ as include files, and also don't process force-complain/ (LP: #331534) -- Jamie Strandboge Thu, 12 Mar 2009 12:53:08 -0500 apparmor (2.3+1289-0ubuntu7) jaunty; urgency=low * abstractions/dbus: add machine-id * abstractions/audio: add libcanberra paths * abstractions/freedesktop.org: add user-dirs.dirs -- Jamie Strandboge Thu, 12 Feb 2009 11:28:15 -0600 apparmor (2.3+1289-0ubuntu6) jaunty; urgency=low [ Kees Cook ] * abstractions/X: add DRI paths. * parser/Makefile: blacklist AF_PHONET. [ Jamie Strandboge ] * update usr.sbin.smbd profile to write to /var/lib/samba/** and read/write to /var/run/dbus/system_bus_socket (LP: #294802) * abstractions/freedesktop.org: use /usr/share/mime/**, @{HOME}/.icons/, and @{HOME}/.recently-used.xbel* * abstractions/gnome: add gvfs remote-volume-monitors paths and printing files -- Kees Cook Mon, 22 Dec 2008 17:20:10 -0800 apparmor (2.3+1289-0ubuntu5) jaunty; urgency=low * abstractions/nameservice: allow read access to /etc/resolvconf/run/resolv.conf (LP: #286080) * adjust src/grammar.y and src/scanner.l to account for the moved type=NNNN field in 2.6.27 kernels and capture non-matching logfile input instead of printing it to stdout (LP: #271252). Patch thanks to Jesse Michael and Steve Beattie. - https://forgesvn1.novell.com/viewsvn/apparmor?view=rev&revision=1310 * add syslog test cases to testsuite. Patch thanks to Steve Beattie. - https://forgesvn1.novell.com/viewsvn/apparmor?view=rev&revision=1307 - https://forgesvn1.novell.com/viewsvn/apparmor?view=rev&revision=1308 - https://forgesvn1.novell.com/viewsvn/apparmor?view=rev&revision=1309 -- Jamie Strandboge Tue, 21 Oct 2008 09:09:58 -0500 apparmor (2.3+1289-0ubuntu4) intrepid; urgency=low * parser/rc.apparmor.functions: fix typo seen when admin changes the default location of the apparmor.d directory (LP: #280467). * abstractions/{samba,base}: clean up unneeded "m" permissions. * abstractions/perl: add missing default perl paths. -- Kees Cook Wed, 08 Oct 2008 16:42:10 -0700 apparmor (2.3+1289-0ubuntu3) intrepid; urgency=low * add locking permission to /var/log/wtmp abstraction, thanks to Martin Pitt (LP: #253328). * utils/logprof.conf: repository updated for Intrepid (LP: #258818). * profiles/apparmor.d/usr.sbin.nscd: added cache directory (LP: #144383). * parser/rc.apparmor.functions: redirect stderr (LP: #244013). * parser/Makefile: blacklist "AF_ISDN". -- Kees Cook Wed, 30 Jul 2008 09:29:03 -0700 apparmor (2.3+1289-0ubuntu2) intrepid; urgency=low [ Mathias Gug ] * debian/control: - move apparmor-profiles to a suggested package by apparmor. [ Kees Cook ] * debian/control - move libterm-readline-gnu-perl to "suggests". - drop apparmor-modules-source since it no longer exists. -- Kees Cook Wed, 02 Jul 2008 12:35:12 -0700 apparmor (2.3+1289-0ubuntu1) intrepid; urgency=low * Updated to upstream subversion v1289. - new parser requires new AppArmor kernel LSM. * debian/control: - add libapparmor-perl, and associated Depends - bump standards version to 3.7.3.0 (no changes needed) * debian/rules: - adjust "clean" rule to be more effective. -- Kees Cook Sat, 28 Jun 2008 15:38:12 -0700 apparmor (2.1+1075-0ubuntu10) intrepid; urgency=low [ Jamie Strandboge ] * added abstractions/smbpass and #include it in abstractions/authentication to allow access to /var/lib/samba/*.tdb. LP: #217787 [ Mathias Gug ] * update likewise-open authentication abstraction: allow access to privileged pipe (LP: #235646). * Update smbd profile to include access to /var/spool/samba/ (printer sharing) and utmp update (LP: #237066). * Update esound location in audio profile (LP: #229127). Thanks to Adam Mondl. * Add dnsmasq profile (LP: #148590). Thanks to John Dong. -- Mathias Gug Mon, 09 Jun 2008 18:24:09 -0400 apparmor (2.1+1075-0ubuntu9) hardy; urgency=low * parser/rc.apparmor.functions: do not abort if parser is missing, in the case of an unpurged "apparmor" init script running under SELinux. -- Kees Cook Mon, 07 Apr 2008 13:25:06 -0700 apparmor (2.1+1075-0ubuntu8) hardy; urgency=low * Sync bugfixes from upstream 8.04 branch, svn 1161. - documentation updated to reflect AppArmor 2.1 features. - minor profile updates (nscd, ntpd, opera) - util/SubDomain.pm: corrected mask merging and type detection. -- Kees Cook Wed, 02 Apr 2008 15:48:58 -0700 apparmor (2.1+1075-0ubuntu7) hardy; urgency=low * profiles/apparmor.d/abstractions/nameservice: (LP: #207912) - fix ldap path - add nsswitch "db" backend paths -- Kees Cook Thu, 27 Mar 2008 14:19:06 -0700 apparmor (2.1+1075-0ubuntu6) hardy; urgency=low [ Kees Cook ] * utils/SubDomain.pm: - fix up mask parsing to match kernel version (LP: #202920). - fix up syslog parsing regexp to match broken kernels (LP: #202888). * profiles/apparmor.d/abstractions/base: add licenses path for reading. * profiles/apparmor.d/abstractions/freedesktop.org: include /usr/local. * profiles/apparmor.d/usr.sbin.smbd: include print client abstraction. * profiles/apparmor.d/abstractions/nameservice: include missing gai.conf (LP: #202991). [ Jamie Strandboge ] * add Debian Policy compliant way to toggle complain mode (LP: #203137) - parser/rc.apparmor.functions: add '-C' to PARSER_ARGS if force-complain/ exists - utils/enforce: remove symlink in force-complain/ - debian/rules: create /etc/apparmor.d/force-complain -- Kees Cook Mon, 17 Mar 2008 10:28:23 -0700 apparmor (2.1+1075-0ubuntu5) hardy; urgency=low * profiles/apparmor.d/abstractions/python: update shared python locations. * debian/control: adjust Depends to allow sysvinit (LP: #199871). -- Kees Cook Tue, 11 Mar 2008 15:25:11 -0700 apparmor (2.1+1075-0ubuntu4) hardy; urgency=low [ Jamie Strandboge ] * removed usr.sbin.named and usr.sbin.mysqld, as these will be provided be bind9 and mysql-server-5.0, respectively. [ Mathias Gug ] * profiles/apparmor.d/abstractions/ssl_keys: add ssl_keys abstraction, to be used by profiles accessing ssl privates keys. [ Rick Clark ] * added abstraction for likewise-open. -- Mathias Gug Wed, 13 Feb 2008 19:16:12 -0500 apparmor (2.1+1075-0ubuntu3) hardy; urgency=low * profiles/apparmor.d/abstractions/fonts: add missing ~/.fonts.conf * profiles/apparmor.d/sbin.klogd: add newly needed @{PROC}/kallsyms -- Kees Cook Wed, 16 Jan 2008 14:16:18 -0800 apparmor (2.1+1075-0ubuntu2) hardy; urgency=low * utils/apparmor_status: fix module loaded test to handle built-in. -- Kees Cook Thu, 03 Jan 2008 17:24:40 -0800 apparmor (2.1+1075-0ubuntu1) hardy; urgency=low [ Mathias Gug ] * profiles/apparmor.d/abstractions/nameservice: update nameservice abstraction to support nscd setup. [ Kees Cook ] * merge with upstream trunk revision 1075. * debian/{control,apparmor.postrm,apparmor.postinst,apparmor.initramfs}: dropped module hook since module is loaded in kernel automatically now. * debian/rules: tweaked get-orig-source to use defined variables. * debian/copyright: mention "get-orig-source" build rule. * debian/{rules,control,libpam-apparmor.docs}: add libpam-apparmor now that PAM is 0.99. -- Kees Cook Thu, 03 Jan 2008 13:29:31 -0800 apparmor (2.1+993-0ubuntu3) gutsy; urgency=low [ Mathias Gug ] * Add mdns4 resolution to nameservice abstraction. (LP: #148579). * Update syslog-ng profile. (LP: #148708). * Add xen tls libraries to base abstraction. (LP: #150282). * Update cups-client abstraction: add /var/run/cups/cups.sock. (LP: #151269) [ Kees Cook ] * Adjust KDE abstractions for Ubuntu paths (LP: #148309). -- Kees Cook Fri, 12 Oct 2007 12:54:36 -0700 apparmor (2.1+993-0ubuntu2) gutsy; urgency=low [ Mathias Gug ] * debian/control: Set maintainer to Ubuntu Core Developers. * utils/SubDomain.pm, utils/logprog.conf: refactor readprofiledir() to not fail on non-existing profile directory. Fixes LP: #141128. * debian/rules: don't compress profiles in doc/extras/. * utils/SubDomain.pm: Fix regex so that aa-logprof can find audit messages in syslog files. Fixes LP: #140508. * Update usr.sbin.nscd profile. Fixes LP: #144383. [ Kees Cook ] * abstractions/gnupg: drop bad attempt at general-purpose client rule. * abstractions/fonts: adjust for new syntax, add more local fonts paths. * abstractions/nameservice: add mmap permission to some /etc files. -- Kees Cook Tue, 25 Sep 2007 10:23:29 -0700 apparmor (2.1+993-0ubuntu1) gutsy; urgency=low * new merge from upstream: * fixes to support new audit messages sent by the kernel module. * bump in minor library version for libapparmor. * debian/control: Add perl libterm-readkey-perl and librpc-xml-perl dependencies for apparmor-utils. Fixes LP: #139757, LP: #139091. * utils/SubDomain.pm: Re-enable RPC client for remote repositories. * profiles/apparmor.d/sbin.syslogd: update profile. Fixes LP: #140672, LP: #140274. -- Mathias Gug Tue, 18 Sep 2007 11:12:50 -0400 apparmor (2.1+961-0ubuntu5) gutsy; urgency=low * utils/SubDomain.pm, parser/rc.apparmor.functions: skip .dpkg-dist profiles. * debian/rules, debian/apparmor.postinst: fix postinst script failure on upgrades. Fix LP: #139683. -- Mathias Gug Fri, 14 Sep 2007 17:20:01 -0400 apparmor (2.1+961-0ubuntu4) gutsy; urgency=low [ Mathias Gug ] * debian/rules: Fix libapparmor-dev build. * apparmor-profiles: remove gnupg.moved. [ Kees Cook ] * abstractions: adjust gnome for new syntax. * abstractions: adjust aspell to add locking. -- Kees Cook Fri, 14 Sep 2007 09:34:15 -0700 apparmor (2.1+961-0ubuntu3) gutsy; urgency=low [ Mathias Gug ] * Update avahi-daemon profile: add m permission to /etc/password and /etc/group. [ Kees Cook ] * Rename libapparmor1-dev back to libapparmor-dev. -- Kees Cook Thu, 13 Sep 2007 15:44:30 -0700 apparmor (2.1+961-0ubuntu2) gutsy; urgency=low [ Mathias Gug ] * Disable html documentation: Fixes LP: #139091. * parser/Makefile, debian/rules: disable html documentation building. * debian/control: remove latex2html dependency. * profiles/apparmor.d/usr.sbin.avahi-daemon: add sys_chroot capability. Fixes LP: #139092. [ Kees Cook ] * profiles/apparmor.d/abstractions/user-tmp: adjust directory permissions for newly unmasked /tmp handling (LP: #138978). * utils/SubDomain.pm: disable remote repositories until RPC::XML MIR clears (LP: 139091). * utils/*.pod: adjust for Ubuntu paths and "aa-" prefixes (LP: #116647). * Fix upgrades to not unload profiles, which would cause programs to become unconfined: - debian/rules: don't stop apparmor on upgrades. - debian/apparmor.postinst: reload profiles after a configure. -- Kees Cook Wed, 12 Sep 2007 13:14:02 -0700 apparmor (2.1+961-0ubuntu1) gutsy; urgency=low * New upstream version. * Support resolvconf. Fix LP: #132468. * Move package maintainance to bzr: * Apply all patches directly into the tree with dpatch apply-all. * debian/patches/: remove all patches as they are applied inline now. * debian/control, debian/control.modules.in: remove dpatch from Build Depends. * debian/rules: * remove dpatch include. * remove patch and unpatch dependencies * debian/control: * Rename libapparmor-dev to libapparmor1-dev. Add Provides: and Conflict: tags. * Remove universe component in Section tag. * Remove apparmor-utils depends on bsdutils. * Update apparmor-modules Recommends to apparmor-modules-2.1. * utils/: * Add audit man page. * Fix mod_appamor library: remove rpath info. * debian/rules: remove rpath info. * debian/control: add chrpath as a build dependency. * Remove apparmor-modules-source package: * debian/conrol: remove apparmor-modules-source package. * debian/apparmor.postinst, debian/apparmor.preinst, debian/apparmor.prerm: remove error_handler function. * debian/rules: remove error_handler option from dh_installinit. * debian/apparmor-modules-_KVERS_.postinst.modules.in, debian/control.modules.in: remove control and postinst files. -- Mathias Gug Tue, 11 Sep 2007 10:44:56 -0400 apparmor (2.0.1+510.dfsg-0ubuntu25) gutsy; urgency=low * debian/rules: move tunables/ and abstractions/ in apparmor package. Fixes LP: #130114. -- Mathias Gug Mon, 06 Aug 2007 14:40:37 -0400 apparmor (2.0.1+510.dfsg-0ubuntu24) gutsy; urgency=low * Cannot Depend on apparmor-modules-* in apparmor due to germinate issues. Moved to Recommends. -- Kees Cook Mon, 23 Jul 2007 11:08:38 -0700 apparmor (2.0.1+510.dfsg-0ubuntu23) gutsy; urgency=low * debian/control: add explicit Depends on l-u-m apparmor kernel modules. -- Kees Cook Wed, 18 Jul 2007 21:07:03 -0700 apparmor (2.0.1+510.dfsg-0ubuntu22) gutsy; urgency=low * 13-subdomain.pm-skip-files.dpatch: update isSkippable function in SubDomain.pm to skip the same files as rc.apparmor.functions (used by the init script) : .dpkg-old, .dpkg-new and symlinks in disable/ sub-directory. -- Mathias Gug Thu, 12 Jul 2007 06:56:45 -0400 apparmor (2.0.1+510.dfsg-0ubuntu21) gutsy; urgency=low * 07-apparmor-init-script.dpatch, debian/rules: skip profiles that have a link in /etc/apparmor.d/disable. Update rules file : create /etc/apparmor.d/disable. -- Mathias Gug Mon, 09 Jul 2007 11:07:29 -0400 apparmor (2.0.1+510.dfsg-0ubuntu20) gutsy; urgency=low * debian/control - fix typo in XS-Vcs. - adjust apparmor-modules-source to no longer be required and document the fact that the modules come from the linux-ubuntu-modules package now. - add initramfs-tools for loading apparmor modules early. * debian/apparmor.{initramfs,postinst,prerm}, debian/rules: install initramfs hook and update-initramfs for adding armor modules for boot. -- Kees Cook Fri, 06 Jul 2007 03:41:06 -0700 apparmor (2.0.1+510.dfsg-0ubuntu19) gutsy; urgency=low * Update 11-getprocattr-api.dpatch: pass back the correct string pointer so as to not corrupt kernel memory (LP: #123081). * debian/control: add XS-Vcs for bzr branch. -- Kees Cook Tue, 03 Jul 2007 09:07:52 -0700 apparmor (2.0.1+510.dfsg-0ubuntu18) gutsy; urgency=low * 02-profile-abstractions-ubuntu.dpatch: add m permission for all libraries under /usr/lib/**, so that ssl libraries optimized for i686 can be accessed. * 09-profile-usr-sbin-mysqld.dpatch: add m permission to /etc/passwd, /etc/group. * 12-profile-samba.dpatch: add profile for smbd and nmbd daemons from samba. * 99-complain-all-profiles.dpatch: turn complain mode for smbd and nmbd profiles. -- Mathias Gug Fri, 29 Jun 2007 15:19:15 +0200 apparmor (2.0.1+510.dfsg-0ubuntu17) gutsy; urgency=low * Update 11-getprocattr-api.dpatch: match upstream more closely, check for errors. -- Kees Cook Tue, 26 Jun 2007 16:00:08 -0700 apparmor (2.0.1+510.dfsg-0ubuntu16) gutsy; urgency=low * Added 11-getprocattr-api.dpatch: update kernel module for getprocattr API change (LP: #122444). -- Kees Cook Tue, 26 Jun 2007 15:21:54 -0700 apparmor (2.0.1+510.dfsg-0ubuntu15) gutsy; urgency=low * debian/apparmor.init: do not unload apparmor module on stop, since it already defaults to capabilities-compatible fall back and we don't want to lose the started process knowledge of the module for the next load of the parser. * Added 10-namespace-header.dpatch: include namespace_sem extern, since mnt_namespace.h is missing it currently. * Updated 07-apparmor-init-script.dpatch: ignore .dpkg-old profiles. -- Kees Cook Tue, 26 Jun 2007 10:04:54 -0700 apparmor (2.0.1+510.dfsg-0ubuntu14) gutsy; urgency=low * Correct missing libapparmor1 file contents. -- Kees Cook Thu, 21 Jun 2007 08:04:42 -0700 apparmor (2.0.1+510.dfsg-0ubuntu13) gutsy; urgency=low * 02-profile-abstractions-ubuntu.dpatch: add /lib/tls/i686/cmov/lib* to base abstraction to support i686 optimized libraries from libc6-i686 package. * 09-profile-usr-sbin-mysqld.dpatch: * add profile usr.sbin.mysqld * update abstractions/mysql * debian/rules: remove extras/usr.sbin.mysqld. * 99-complain-all-profiles.dpatch: * put mysqld profile in complain mode. * put named profile in complain mode. -- Mathias Gug Wed, 20 Jun 2007 12:12:28 -0400 apparmor (2.0.1+510.dfsg-0ubuntu12) gutsy; urgency=low * Add missing dh_makeshlibs call to rules, fix up libapparmor naming. -- Kees Cook Wed, 20 Jun 2007 09:15:48 -0700 apparmor (2.0.1+510.dfsg-0ubuntu11) gutsy; urgency=low * Packaged libapparmor, libapparmor-dev, and libapache2-mod-apparmor. -- Kees Cook Mon, 18 Jun 2007 18:27:46 -0700 apparmor (2.0.1+510.dfsg-0ubuntu10) gutsy; urgency=low * 02-profile-abstractions-ubuntu.dpatch, 06-profile-usr-sbin-named.dpatch: move /dev/random into abstractions/base. * 06-profile-usr-sbin-named.dpatch: Add sys_chroot capability. * debian/rules: don't package aa-eventd and Reports.pm as they use perl modules not maintained in main. Reports.pm is only used by Yast for now. aa-eventd maintains an sqlite database of audit messages which is used by Reports.pm. If configured (not by default), aa-eventd can also send emails when AppArmor audit messages are emited. * debian/control: Add universe component to Section: header. Needed to make it work with PPA. -- Mathias Gug Fri, 15 Jun 2007 12:47:05 -0400 apparmor (2.0.1+510.dfsg-0ubuntu9) gutsy; urgency=low * 06-profile-usr-sbin-named.dpatch : Generate a new profile for /usr/sbin/named to make it work with bind9. * debian/apparmor.init, 07-apparmor-init-script.dpatch: merge ubuntu changes with the latest version from upstream. * 99-complain-all-profiles.dpatch : put all profiles into complain mode by default. Add a small script (put-all-profiles-in-complain-mode.sh) in debian/ that takes care of automatically setting all profiles into complain mode. This script should be used by the maintainer to set all profiles in complain mode before packaging them. -- Mathias Gug Wed, 6 Jun 2007 13:41:57 -0400 apparmor (2.0.1+510.dfsg-0ubuntu8) gutsy; urgency=low * Start apparmor as early as possible in the boot process : just after mountall in rcS.d. Add preinst script to remove symlinks previously installed in rc*.d/. (LP: #116624). * Sync 04-apparmor-status.dpatch with upstream apparmor_status. The previous patch has been merged in upstream. * Update klogd profile : add /var/run/klogd/klogd.pid and /var/run/klogd/kmsg to the profile. -- Mathias Gug Thu, 31 May 2007 14:26:03 -0400 apparmor (2.0.1+510.dfsg-0ubuntu7) gutsy; urgency=low * 03-profile-usr-sbin-ntpd.dpatch: udpdate profile for ntpd daemon. Add /var/lib/ntp/ntp.drift and /var/log/ntpstats/peerstats* to the profile. * 04-apparmor-status.dpatch: improve apparmor_status script. Report more detailed information. -- Mathias Gug Tue, 29 May 2007 13:05:55 -0400 apparmor (2.0.1+510.dfsg-0ubuntu6) gutsy; urgency=low * 02-profile-abstractions-ubuntu.dpatch: Update abstractions for changes specific to Gnome, Debian, and 32bit on 64bit environments. * debian/control: adjust Recommends to apparmor-modules-source (LP: #113553). * debian/apparmor.init: moved rmmod/modprobe into init script, and dropped alias to avoid confusion and move control of the LSM closer to loading the profiles and work around capability already being loaded in the initrd (LP: #113887). -- Kees Cook Thu, 17 May 2007 20:34:41 -0700 apparmor (2.0.1+510.dfsg-0ubuntu5) gutsy; urgency=low * 01-logger-path.dpatch: Fix path to logger (LP: #112147). -- Kees Cook Thu, 03 May 2007 11:59:34 -0700 apparmor (2.0.1+510.dfsg-0ubuntu4) feisty; urgency=low * debian/control: move apparmor-modules to Recommends to Avoid uninstallable situation when AppArmor modules haven't yet been compiled/installed. -- Kees Cook Wed, 11 Apr 2007 11:39:39 -0700 apparmor (2.0.1+510.dfsg-0ubuntu3) feisty; urgency=low * debian/rules, debian/apparmor.{postinst,prerm}: ignore init script failures so that they don't block package installs/upgrades/uninstalls. -- Kees Cook Wed, 11 Apr 2007 08:52:37 -0700 apparmor (2.0.1+510.dfsg-0ubuntu2) feisty; urgency=low * debian/control: add missing Depend on 'dpatch' for modules-source. -- Kees Cook Sat, 7 Apr 2007 09:35:16 -0700 apparmor (2.0.1+510.dfsg-0ubuntu1) feisty; urgency=low * Initial release, thanks to Magnus Runesson and Jesse Michael (LP: #95334). -- Kees Cook Fri, 23 Mar 2007 16:42:01 -0700 debian/apparmor.postinst0000664000000000000000000000761612315045675012640 0ustar #!/bin/sh # postinst script for apparmor # # see: dh_installdeb(1) set -e . /usr/share/debconf/confmodule # summary of how this script can be called: # * `configure' # * `abort-upgrade' # * `abort-remove' `in-favour' # # * `abort-remove' # * `abort-deconfigure' `in-favour' # `removing' # # for details, see http://www.debian.org/doc/debian-policy/ or # the debian-policy package case "$1" in configure|abort-remove|abort-deconfigure) # Try to determine values for apparmor/homedirs if the administrator # hasn't already. if dpkg --compare-versions "$2" lt-nl "2.5~pre+bzr1362-0ubuntu2"; then db_get apparmor/homedirs if [ -z "$RET" ]; then # Get unique dirnames for uids between 1000 and 30000, then # format them appropriately for AppArmor dirs=`awk -F: '$3 >= 1000 && $3 < 30000 {printf "%s\n", $6}' /etc/passwd | xargs -d '\n' -n 1 dirname | grep -v '^/home$' | sed -e 's#\(.*\)#\\1/#g' | sed -e '/ / { s#\(.*\)#"\\1"#g }' | sort -u | tr '\n' ' '` if [ -n "$dirs" ]; then db_set apparmor/homedirs "$dirs" fi fi fi db_get apparmor/homedirs tmp=`mktemp` cat > "$tmp" <> "$tmp" <> "$tmp" </dev/null || true mv -f "$tmp" /etc/apparmor.d/tunables/home.d/ubuntu chmod 644 /etc/apparmor.d/tunables/home.d/ubuntu if [ ! -e /etc/apparmor.d/tunables/xdg-user-dirs.d/site.local ]; then tmp=`mktemp` cat > "$tmp" </dev/null || true mv -n "$tmp" /etc/apparmor.d/tunables/xdg-user-dirs.d/site.local chmod 644 /etc/apparmor.d/tunables/xdg-user-dirs.d/site.local fi ;; abort-upgrade) # Nothing to do ;; *) echo "postinst called with unknown argument \`$1'" >&2 exit 1 ;; esac # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# # Now that AppArmor is started, attempt to reload profiles in the # case of upgrades (since dh_installinit has been forced not to unload # the profiles in the case of an upgrade). case "$1" in configure) if [ -x "/etc/init.d/apparmor" ]; then if [ -x "`which invoke-rc.d 2>/dev/null`" ]; then invoke-rc.d apparmor reload || true else /etc/init.d/apparmor reload || true fi fi ;; esac exit 0 debian/libapparmor-dev.install0000664000000000000000000000017112315045675013653 0ustar usr/lib/*/libapparmor.a usr/lib/*/libapparmor.la usr/lib/*/libapparmor.so usr/lib/*/pkgconfig/libapparmor* usr/include/* debian/python-apparmor.install0000664000000000000000000000005112315045675013724 0ustar usr/lib/python2*/dist-packages/apparmor* debian/apparmor-notify.maintscript0000664000000000000000000000011012315045675014576 0ustar rm_conffile /etc/X11/Xsession.d/90apparmor-notify 2.8.95~2430-0ubuntu3~ debian/python3-libapparmor.install0000664000000000000000000000005412315045675014501 0ustar usr/lib/python3*/dist-packages/LibAppArmor* debian/apparmor-utils.dirs0000664000000000000000000000007512315045675013044 0ustar /etc/apparmor /usr/bin /usr/share/apparmor /var/log/apparmor debian/apport/0000775000000000000000000000000012315045676010506 5ustar debian/apport/source_apparmor.py0000664000000000000000000000440212315045675014260 0ustar '''apport package hook for apparmor (c) 2009-2013 Canonical Ltd. Author: Steve Beattie Jamie Strandboge License: GPLv2 ''' from apport.hookutils import * import os import re def recent_kernlog(pattern): '''Extract recent messages from kern.log or message which match a regex. pattern should be a "re" object. ''' lines = '' if os.path.exists('/var/log/kern.log'): file = '/var/log/kern.log' elif os.path.exists('/var/log/messages'): file = '/var/log/messages' else: return lines for line in open(file): if pattern.search(line): lines += line return lines def recent_syslog(pattern): '''Extract recent messages from syslog which match a regex. pattern should be a "re" object. ''' lines = '' if os.path.exists('/var/log/syslog'): file = '/var/log/syslog' else: return lines for line in open(file): if pattern.search(line): lines += line return lines def add_info(report): attach_file(report, '/proc/version_signature', 'ProcVersionSignature') attach_file(report, '/proc/cmdline', 'ProcKernelCmdline') sec_re = re.compile('audit\(|apparmor|selinux|security', re.IGNORECASE) report['KernLog'] = recent_kernlog(sec_re) # DBus messages are reported to syslog dbus_sec_re = re.compile('dbus.* apparmor', re.IGNORECASE) report['Syslog'] = recent_syslog(dbus_sec_re) packages=['apparmor', 'apparmor-utils', 'libapparmor1', 'libapparmor-dev', 'libapparmor-perl', 'apparmor-utils', 'apparmor-docs', 'apparmor-profiles', 'libapache2-mod-apparmor', 'libpam-apparmor', 'auditd', 'libaudit0'] versions = '' for package in packages: try: version = packaging.get_version(package) except ValueError: version = 'N/A' if version is None: version = 'N/A' versions += '%s %s\n' % (package, version) report['ApparmorPackages'] = versions # These need to be run as root report['ApparmorStatusOutput'] = root_command_output(['/usr/sbin/apparmor_status']) report['PstreeP'] = command_output(['/usr/bin/pstree', '-p']) attach_file_if_exists(report, '/var/log/audit/audit.log', 'audit.log') debian/rules0000775000000000000000000001240312315045675010260 0ustar #!/usr/bin/make -f export DEB_HOST_ARCH_OS ?= $(shell dpkg-architecture -qDEB_HOST_ARCH_OS) export PYTHON=/usr/bin/python3 export PYTHON_VERSION=3 export PYTHON_VERSIONS=python3 %: dh $@ --with=python2,python3,apache2 override_dh_auto_configure: cd libraries/libapparmor && sh ./autogen.sh dh_auto_configure -D libraries/libapparmor -- --with-perl override_dh_auto_build: # Build perl dh_auto_build -D libraries/libapparmor # Build pythons for py in $(shell pyversions -s) $(shell py3versions -s) ; do \ cp -a $(CURDIR)/libraries/libapparmor $(CURDIR)/libraries/libapparmor.$$py && \ PYTHON=/usr/bin/$$py dh_auto_configure \ -D libraries/libapparmor.$$py -- --with-python && \ PYTHON=/usr/bin/$$py dh_auto_build \ -D libraries/libapparmor.$$py; \ done # Don't run '$(MAKE) check' because of too many perl dependencies # and various apparmor files installed on the system # Build pythons cd utils && $(MAKE) for py in $(shell pyversions -s) $(shell py3versions -s) ; do \ cp -a $(CURDIR)/utils $(CURDIR)/utils.$$py && \ (cd utils.$$py && PYTHON=/usr/bin/$$py $(MAKE)) ; \ done ifneq (,$(filter $(DEB_HOST_ARCH_OS), kfreebsd knetbsd hurd )) cd parser && $(MAKE) indep else cd parser && $(MAKE) V=1 endif cd profiles && $(MAKE) override_dh_auto_test: ifeq (,$(filter $(DEB_HOST_ARCH_OS), kfreebsd knetbsd hurd )) dh_auto_test -Dparser -- V=1 endif override_dh_auto_clean: for i in utils parser profiles changehat/mod_apparmor \ changehat/pam_apparmor ; do \ [ ! -f $$i/Makefile ] || $(MAKE) -C $$i clean; \ rm -f $$i/common; \ done # Remove the python build dirs rm -rf $(CURDIR)/libraries/libapparmor.python* rm -rf $(CURDIR)/utils.python* # Try to clean up from an autogen'd build cd libraries/libapparmor && [ ! -f Makefile ] || $(MAKE) distclean # Remove generated debhelper documentation. rm -f $(CURDIR)/debian/debhelper/dh_apparmor.1 override_dh_auto_install: # Utils cd utils; $(MAKE) \ DESTDIR=$(CURDIR)/debian/tmp \ PERLDIR=$(CURDIR)/debian/tmp/usr/share/perl5/Immunix \ install for py in $(shell pyversions -s) $(shell py3versions -s) ; do \ (cd utils.$$py && PYTHON=/usr/bin/$$py $(MAKE) \ DESTDIR=$(CURDIR)/debian/tmp \ PERLDIR=$(CURDIR)/debian/tmp/usr/share/perl5/Immunix \ install) ; \ done # Parser ifneq (,$(filter $(DEB_HOST_ARCH_OS), kfreebsd knetbsd hurd )) install -D -m 755 $(CURDIR)/debian/non-linux/apparmor_parser \ $(CURDIR)/debian/tmp/sbin/apparmor_parser cd parser; $(MAKE) \ DESTDIR=$(CURDIR)/debian/tmp \ install-indep else cd parser; $(MAKE) \ DESTDIR=$(CURDIR)/debian/tmp \ install endif # Changehat via libapparmor cd libraries/libapparmor; $(MAKE) \ DESTDIR=$(CURDIR)/debian/tmp \ install # fixup rpath for libapparmor-perl find $(CURDIR)/debian/tmp/usr/lib/perl5 -name '*.so' | xargs chrpath --delete # Install python swig modules for py in $(shell pyversions -s) $(shell py3versions -s); do \ PYTHON=/usr/bin/$$py \ $(MAKE) -C libraries/libapparmor.$$py \ DESTDIR=$(CURDIR)/debian/tmp install; \ done # Changehat via mod_apparmor cd changehat/mod_apparmor; $(MAKE) \ DESTDIR=$(CURDIR)/debian/tmp \ install # Fix rpath in mod_apparmor.so chrpath -d $(CURDIR)/debian/tmp/usr/lib/apache2/modules/mod_apparmor.so # Changehat via libpam-apparmor cd changehat/pam_apparmor; $(MAKE) \ DESTDIR=$(CURDIR)/debian/tmp \ install # Fix rpath in pam_apparmor.so chrpath -d $(CURDIR)/debian/tmp/lib/security/pam_apparmor.so # Profiles # We'd like to keep site.local from being a conffile rm ./profiles/apparmor.d/tunables/xdg-user-dirs.d/site.local cd profiles; $(MAKE) \ DESTDIR=$(CURDIR)/debian/tmp \ EXTRAS_DEST=$(CURDIR)/debian/tmp/usr/share/doc/apparmor-profiles/extras \ install # set all profiles in apparmor-profiles to complain mode cd $(CURDIR)/debian/tmp && sh $(CURDIR)/debian/put-all-profiles-in-complain-mode.sh # Build debhelper documentation. pod2man -c Debhelper -r "$(DEB_VERSION)" $(CURDIR)/debian/debhelper/dh_apparmor $(CURDIR)/debian/debhelper/dh_apparmor.1 override_dh_installinit: dh_installinit --update-rcd-params='start 37 S .' --no-restart-on-upgrade --error-handler=true override_dh_compress: dh_compress -Xextras override_dh_perl: dh_perl -p libapparmor-perl -d dh_perl --no-package=libapparmor-perl override_dh_apache2: dh_apache2 --noenable override_dh_install: for profile in $(shell grep ^etc/apparmor.d/ $(CURDIR)/debian/apparmor-profiles.install | \ cut -d/ -f3- | grep -v /); do \ if [ -x /usr/bin/dh_apparmor ]; then \ dh_apparmor --profile-name=$$profile -papparmor-profiles; \ fi; \ done dh_install VERSION_SEP=+ VERSION=$(shell dpkg-parsechangelog | grep ^Version | cut -d$(VERSION_SEP) -f1 | cut -d\ -f2) BZR_RELEASE=$(shell dpkg-parsechangelog | grep ^Version | cut -d$(VERSION_SEP) -f2 | cut -d. -f1 | cut -d- -f1 | sed -e 's/bzr//') ORIG_FILE=$(CURDIR)/../apparmor_$(VERSION)$(VERSION_SEP)bzr$(BZR_RELEASE).orig.tar.gz BZR_CO_DIR=$(CURDIR)/apparmor-$(VERSION)$(VERSION_SEP)bzr$(BZR_RELEASE) get-orig-source: test ! -e $(ORIG_FILE) test ! -e $(BZR_CO_DIR) bzr checkout --lightweight -r $(BZR_RELEASE) lp:~apparmor-dev/apparmor/master $(BZR_CO_DIR) tar czf $(ORIG_FILE) -C `dirname $(BZR_CO_DIR)` --exclude .bzr `basename $(BZR_CO_DIR)` rm -rf $(BZR_CO_DIR) debian/non-linux/0000775000000000000000000000000012315045676011130 5ustar debian/non-linux/apparmor_parser0000775000000000000000000000006112315045675014247 0ustar #!/bin/sh echo "AppArmor unavailable" >&2 exit 1 debian/apparmor-utils.install0000664000000000000000000000067412315045675013556 0ustar debian/aa-update-browser /usr/sbin/ debian/vim-apparmor.yaml /usr/share/vim/registry/ usr/share/apparmor/apparmor.vim /usr/share/vim/addons/syntax/ etc/apparmor/logprof.conf etc/apparmor/severity.db usr/sbin/aa-autodep usr/sbin/aa-complain usr/sbin/aa-decode usr/sbin/aa-genprof usr/sbin/aa-audit usr/sbin/aa-logprof usr/sbin/aa-cleanprof usr/sbin/aa-mergeprof usr/sbin/aa-autodep usr/sbin/aa-unconfined usr/sbin/aa-enforce usr/sbin/aa-disable debian/aa-update-browser0000664000000000000000000000670512315045675012455 0ustar #!/bin/sh # # Copyright (C) 2010 Canonical, Ltd. # Author: Jamie Strandboge # License: GPLv2 # # Program for updating browser abstractions in Ubuntu. The program will # search the specified profile for an include directive for a file in # abstractions/ubuntu-browsers.d and update this file with the specified # browsers abstractions. set -e topdir="/etc/apparmor.d" reldir="abstractions/ubuntu-browsers.d" dir="$topdir/$reldir" if [ ! -d "$dir" ]; then echo "'$dir' is not a directory" >&2 exit 1 fi help() { cat < -u comma separated list of abstractions for profile to use -d dry-run. Only show what would be done. -l list available abstractions -h this message Eg: $ aa-update-browser -l # aa-update-browser -u multimedia,productivity /etc/apparmor.d/usr.bin.firefox EOM } find_browser_include() { fn="$1" r=`egrep " *#include <$reldir/.*> *(|#.*)" "$fn" | cut -f 2 -d '<' | cut -f 1 -d '>'` if [ -z "$r" ]; then echo "Could not find '#include <$reldir/...>' in" >&2 echo "$fn" >&2 return fi basename "$r" } existing_abstractions="" for i in $dir/* ; do if [ ! -s "$i" ]; then continue fi if head -1 "$i" | grep -q '^# This file is updated' ; then continue fi # This has a leading space, which we use below. existing_abstractions="$existing_abstractions `basename $i`" done updated= dryrun= while getopts "dhlu:" opt do case "$opt" in d) dryrun="yes";; u) updated="$OPTARG";; l) echo "$existing_abstractions" exit 0 ;; h) help exit 0 ;; ?) help exit 1 ;; esac done shift $(($OPTIND - 1)) if [ -z "$1" ]; then help exit 1 fi for p in $* ; do if [ ! -s "$p" ]; then echo "Could not find '$p'" >&2 exit 1 fi include=`find_browser_include $p` if [ -z "$include" ]; then exit 1 fi if echo "$existing_abstractions" | grep -q " $include" ; then echo "'$reldir/$include' is an existing abstraction" >&2 exit 1 fi tmp=`mktemp` plugins_common_path="$dir/plugins-common" cat > "$tmp" < EOM for a in `echo "$updated" | tr [,] ' '`; do echo "$existing_abstractions" | egrep -q " $a( |$)" || { echo "'$a' is not an existing abstraction. Skipping." >&2 continue } if [ -f "$dir/$a" ]; then # TODO: add $plugins_common_path only for those browser abstractions # that actually need it. if [ -n "$plugins_common_path" ] && [ -e "$plugins_common_path" ]; then echo "#include <$reldir/`basename $plugins_common_path`>" >> "$tmp" plugins_common_path="" fi echo "#include <$reldir/$a>" >> "$tmp" else echo "Skipping '$a' (not found in '$dir')" >&2 continue fi done if [ "$dryrun" = "yes" ]; then echo "Skipping commit to '$dir/$include' (dry run)" >&2 cat "$tmp" rm -f "$tmp" continue fi mv -f "$tmp" "$dir/$include" || { rm -f "$tmp" exit 1 } chmod 644 "$dir/$include" done debian/libpam-apparmor.install0000664000000000000000000000003512315045675013651 0ustar lib/security/pam_apparmor.so debian/apparmor-docs.docs0000664000000000000000000000002312315045675012614 0ustar parser/techdoc.pdf debian/apparmor-profiles.postinst0000664000000000000000000000405512315045675014453 0ustar #!/bin/sh # postinst script for apparmor-profiles # # see: dh_installdeb(1) set -e # summary of how this script can be called: # * `configure' # * `abort-upgrade' # * `abort-remove' `in-favour' # # * `abort-remove' # * `abort-deconfigure' `in-favour' # `removing' # # for details, see http://www.debian.org/doc/debian-policy/ or # the debian-policy package # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. case "$1" in configure) if [ ! -e /etc/apparmor.d/abstractions/ubuntu-browsers.d/chromium-browser ]; then cp /usr/share/apparmor-profiles/abstractions/ubuntu-browsers.d/chromium-browser /etc/apparmor.d/abstractions/ubuntu-browsers.d || true fi ;; esac #DEBHELPER# # If dh_apparmor did not exist, rebuild the local files manually if [ "$1" = "configure" ]; then for profile in $(dpkg -L apparmor-profiles | egrep '^/etc/apparmor.d/[^/]+$') do APP_PROFILE="$profile" if [ -f "$APP_PROFILE" ]; then # Add the local/ include PROFILE_NAME=$(basename "$profile") LOCAL_APP_PROFILE=/etc/apparmor.d/local/"$PROFILE_NAME" test -e "$LOCAL_APP_PROFILE" || { tmp=`mktemp` cat < "$tmp" # Site-specific additions and overrides for $PROFILE_NAME. # For more details, please see /etc/apparmor.d/local/README. EOM mkdir `dirname $LOCAL_APP_PROFILE` 2>/dev/null || true mv -f "$tmp" "$LOCAL_APP_PROFILE" chmod 644 "$LOCAL_APP_PROFILE" } fi done fi case "$1" in configure) invoke-rc.d apparmor reload || true ;; abort-upgrade|abort-remove|abort-deconfigure) ;; *) echo "postinst called with unknown argument \`$1'" >&2 exit 1 ;; esac exit 0 debian/apparmor-profiles.install0000664000000000000000000001474012315045675014240 0ustar debian/profiles/chromium-browser usr/share/apparmor-profiles/abstractions/ubuntu-browsers.d/ etc/apparmor.d/apache2.d/phpsysinfo etc/apparmor.d/bin.ping etc/apparmor.d/program-chunks/postfix-common etc/apparmor.d/sbin.klogd etc/apparmor.d/sbin.syslogd etc/apparmor.d/sbin.syslog-ng etc/apparmor.d/usr.bin.chromium-browser etc/apparmor.d/usr.lib.dovecot.deliver etc/apparmor.d/usr.lib.dovecot.dovecot-auth etc/apparmor.d/usr.lib.dovecot.imap etc/apparmor.d/usr.lib.dovecot.imap-login etc/apparmor.d/usr.lib.dovecot.managesieve-login etc/apparmor.d/usr.lib.dovecot.pop3 etc/apparmor.d/usr.lib.dovecot.pop3-login etc/apparmor.d/usr.sbin.avahi-daemon etc/apparmor.d/usr.sbin.dnsmasq etc/apparmor.d/usr.sbin.dovecot etc/apparmor.d/usr.sbin.identd etc/apparmor.d/usr.sbin.mdnsd etc/apparmor.d/usr.sbin.nmbd etc/apparmor.d/usr.sbin.nscd etc/apparmor.d/usr.sbin.smbd etc/apparmor.d/usr.sbin.traceroute usr/share/doc/apparmor-profiles/extras/README usr/share/doc/apparmor-profiles/extras/bin.netstat usr/share/doc/apparmor-profiles/extras/etc.cron.daily.logrotate usr/share/doc/apparmor-profiles/extras/etc.cron.daily.slocate.cron usr/share/doc/apparmor-profiles/extras/etc.cron.daily.tmpwatch usr/share/doc/apparmor-profiles/extras/sbin.dhclient usr/share/doc/apparmor-profiles/extras/sbin.dhcpcd usr/share/doc/apparmor-profiles/extras/sbin.portmap usr/share/doc/apparmor-profiles/extras/sbin.resmgrd usr/share/doc/apparmor-profiles/extras/sbin.rpc.lockd usr/share/doc/apparmor-profiles/extras/sbin.rpc.statd usr/share/doc/apparmor-profiles/extras/usr.NX.bin.nxclient usr/share/doc/apparmor-profiles/extras/usr.bin.acroread usr/share/doc/apparmor-profiles/extras/usr.bin.apropos usr/share/doc/apparmor-profiles/extras/usr.bin.evolution-2.10 usr/share/doc/apparmor-profiles/extras/usr.bin.fam usr/share/doc/apparmor-profiles/extras/usr.bin.freshclam usr/share/doc/apparmor-profiles/extras/usr.bin.gaim usr/share/doc/apparmor-profiles/extras/usr.bin.man usr/share/doc/apparmor-profiles/extras/usr.bin.mlmmj-bounce usr/share/doc/apparmor-profiles/extras/usr.bin.mlmmj-maintd usr/share/doc/apparmor-profiles/extras/usr.bin.mlmmj-make-ml.sh usr/share/doc/apparmor-profiles/extras/usr.bin.mlmmj-process usr/share/doc/apparmor-profiles/extras/usr.bin.mlmmj-recieve usr/share/doc/apparmor-profiles/extras/usr.bin.mlmmj-send usr/share/doc/apparmor-profiles/extras/usr.bin.mlmmj-sub usr/share/doc/apparmor-profiles/extras/usr.bin.mlmmj-unsub usr/share/doc/apparmor-profiles/extras/usr.bin.opera usr/share/doc/apparmor-profiles/extras/usr.bin.passwd usr/share/doc/apparmor-profiles/extras/usr.bin.procmail usr/share/doc/apparmor-profiles/extras/usr.bin.skype usr/share/doc/apparmor-profiles/extras/usr.bin.spamc usr/share/doc/apparmor-profiles/extras/usr.bin.svnserve usr/share/doc/apparmor-profiles/extras/usr.bin.wireshark usr/share/doc/apparmor-profiles/extras/usr.bin.xfs usr/share/doc/apparmor-profiles/extras/usr.lib.GConf.2.gconfd-2 usr/share/doc/apparmor-profiles/extras/usr.lib.RealPlayer10.realplay usr/share/doc/apparmor-profiles/extras/usr.lib.bonobo.bonobo-activation-server usr/share/doc/apparmor-profiles/extras/usr.lib.evolution-data-server.evolution-data-server-1.10 usr/share/doc/apparmor-profiles/extras/usr.lib.firefox.firefox usr/share/doc/apparmor-profiles/extras/usr.lib.firefox.firefox.sh usr/share/doc/apparmor-profiles/extras/usr.lib.firefox.mozilla-xremote-client usr/share/doc/apparmor-profiles/extras/usr.lib.man-db.man usr/share/doc/apparmor-profiles/extras/usr.lib.postfix.anvil usr/share/doc/apparmor-profiles/extras/usr.lib.postfix.bounce usr/share/doc/apparmor-profiles/extras/usr.lib.postfix.cleanup usr/share/doc/apparmor-profiles/extras/usr.lib.postfix.discard usr/share/doc/apparmor-profiles/extras/usr.lib.postfix.error usr/share/doc/apparmor-profiles/extras/usr.lib.postfix.flush usr/share/doc/apparmor-profiles/extras/usr.lib.postfix.lmtp usr/share/doc/apparmor-profiles/extras/usr.lib.postfix.local usr/share/doc/apparmor-profiles/extras/usr.lib.postfix.master usr/share/doc/apparmor-profiles/extras/usr.lib.postfix.nqmgr usr/share/doc/apparmor-profiles/extras/usr.lib.postfix.oqmgr usr/share/doc/apparmor-profiles/extras/usr.lib.postfix.pickup usr/share/doc/apparmor-profiles/extras/usr.lib.postfix.pipe usr/share/doc/apparmor-profiles/extras/usr.lib.postfix.proxymap usr/share/doc/apparmor-profiles/extras/usr.lib.postfix.qmgr usr/share/doc/apparmor-profiles/extras/usr.lib.postfix.qmqpd usr/share/doc/apparmor-profiles/extras/usr.lib.postfix.scache usr/share/doc/apparmor-profiles/extras/usr.lib.postfix.showq usr/share/doc/apparmor-profiles/extras/usr.lib.postfix.smtp usr/share/doc/apparmor-profiles/extras/usr.lib.postfix.smtpd usr/share/doc/apparmor-profiles/extras/usr.lib.postfix.spawn usr/share/doc/apparmor-profiles/extras/usr.lib.postfix.tlsmgr usr/share/doc/apparmor-profiles/extras/usr.lib.postfix.trivial-rewrite usr/share/doc/apparmor-profiles/extras/usr.lib.postfix.verify usr/share/doc/apparmor-profiles/extras/usr.lib.postfix.virtual usr/share/doc/apparmor-profiles/extras/usr.lib64.GConf.2.gconfd-2 usr/share/doc/apparmor-profiles/extras/usr.sbin.cupsd usr/share/doc/apparmor-profiles/extras/usr.sbin.dhcpd usr/share/doc/apparmor-profiles/extras/usr.sbin.httpd2-prefork usr/share/doc/apparmor-profiles/extras/usr.sbin.imapd usr/share/doc/apparmor-profiles/extras/usr.sbin.in.fingerd usr/share/doc/apparmor-profiles/extras/usr.sbin.in.ftpd usr/share/doc/apparmor-profiles/extras/usr.sbin.in.ntalkd usr/share/doc/apparmor-profiles/extras/usr.sbin.ipop2d usr/share/doc/apparmor-profiles/extras/usr.sbin.ipop3d usr/share/doc/apparmor-profiles/extras/usr.sbin.lighttpd usr/share/doc/apparmor-profiles/extras/usr.sbin.nmbd usr/share/doc/apparmor-profiles/extras/usr.sbin.oidentd usr/share/doc/apparmor-profiles/extras/usr.sbin.popper usr/share/doc/apparmor-profiles/extras/usr.sbin.postalias usr/share/doc/apparmor-profiles/extras/usr.sbin.postdrop usr/share/doc/apparmor-profiles/extras/usr.sbin.postmap usr/share/doc/apparmor-profiles/extras/usr.sbin.postqueue usr/share/doc/apparmor-profiles/extras/usr.sbin.sendmail usr/share/doc/apparmor-profiles/extras/usr.sbin.sendmail.postfix usr/share/doc/apparmor-profiles/extras/usr.sbin.sendmail.sendmail usr/share/doc/apparmor-profiles/extras/usr.sbin.smbd usr/share/doc/apparmor-profiles/extras/usr.sbin.spamd usr/share/doc/apparmor-profiles/extras/usr.sbin.squid usr/share/doc/apparmor-profiles/extras/usr.sbin.sshd usr/share/doc/apparmor-profiles/extras/usr.sbin.useradd usr/share/doc/apparmor-profiles/extras/usr.sbin.userdel usr/share/doc/apparmor-profiles/extras/usr.sbin.vsftpd usr/share/doc/apparmor-profiles/extras/usr.sbin.xinetd debian/patches/0000775000000000000000000000000012317347533010627 5ustar debian/patches/add-chromium-browser.patch0000664000000000000000000001621112315045675015703 0ustar Author: Jamie Strandboge Description: chromium-browser profile Forwarded: yes Index: apparmor/profiles/apparmor.d/usr.bin.chromium-browser =================================================================== --- /dev/null +++ apparmor/profiles/apparmor.d/usr.bin.chromium-browser @@ -0,0 +1,221 @@ +# Author: Jamie Strandboge +#include + +# We need 'flags=(attach_disconnected)' in newer chromium versions +/usr/lib/chromium-browser/chromium-browser flags=(attach_disconnected) { + #include + #include + #include + #include + #include + #include + #include + + # This include specifies which ubuntu-browsers.d abstractions to use. Eg, if + # you want access to productivity applications, adjust the following file + # accordingly. + #include + + # Networking + network inet stream, + network inet6 stream, + @{PROC}/[0-9]*/net/if_inet6 r, + @{PROC}/[0-9]*/net/ipv6_route r, + + # Should maybe be in abstractions + /etc/mime.types r, + /etc/mailcap r, + /etc/mtab r, + /etc/xdg/xubuntu/applications/defaults.list r, + owner @{HOME}/.local/share/applications/defaults.list r, + owner @{HOME}/.local/share/applications/mimeinfo.cache r, + + @{PROC}/[0-9]*/fd/ r, + @{PROC}/filesystems r, + @{PROC}/ r, + @{PROC}/[0-9]*/task/[0-9]*/stat r, + owner @{PROC}/[0-9]*/cmdline r, + owner @{PROC}/[0-9]*/io r, + @{PROC}/[0-9]*/smaps r, + owner @{PROC}/[0-9]*/stat r, + @{PROC}/[0-9]*/statm r, + owner @{PROC}/[0-9]*/status r, + + # Newer chromium needs these now + /etc/udev/udev.conf r, + /sys/devices/system/cpu/cpu*/cpufreq/cpuinfo_max_freq r, + /sys/devices/pci[0-9]*/**/class r, + /sys/devices/pci[0-9]*/**/device r, + /sys/devices/pci[0-9]*/**/irq r, + /sys/devices/pci[0-9]*/**/resource r, + /sys/devices/pci[0-9]*/**/vendor r, + /sys/devices/pci[0-9]*/**/removable r, + /sys/devices/pci[0-9]*/**/uevent r, + /sys/devices/pci[0-9]*/**/block/**/size r, + /sys/devices/virtual/block/**/removable r, + /sys/devices/virtual/block/**/uevent r, + /sys/devices/virtual/block/**/size r, + # This is requested, but doesn't seem to actually be needed so deny for now + deny /run/udev/data/** r, + + # Needed for the crash reporter + owner @{PROC}/[0-9]*/auxv r, + + # chromium mmaps all kinds of things for speed. + /etc/passwd m, + /usr/share/fonts/truetype/**/*.tt[cf] m, + /usr/share/fonts/**/*.pfb m, + /usr/share/mime/mime.cache m, + /usr/share/icons/**/*.cache m, + owner /{dev,run}/shm/pulse-shm* m, + owner @{HOME}/.local/share/mime/mime.cache m, + owner /tmp/** m, + + @{PROC}/sys/kernel/shmmax r, + owner /{dev,run}/shm/{,.}org.chromium.* mrw, + + /usr/lib/chromium-browser/*.pak mr, + /usr/lib/chromium-browser/locales/* mr, + + # Noisy + deny /usr/lib/chromium-browser/** w, + + # Make browsing directories work + / r, + /**/ r, + + # Allow access to documentation and other files the user may want to look + # at in /usr + /usr/{include,share,src}** r, + + # Default profile allows downloads to ~/Downloads and uploads from ~/Public + owner @{HOME}/ r, + owner @{HOME}/Public/ r, + owner @{HOME}/Public/* r, + owner @{HOME}/Downloads/ r, + owner @{HOME}/Downloads/* rw, + + # Helpers + /usr/bin/xdg-open ixr, + /usr/bin/gnome-open ixr, + /usr/bin/gvfs-open ixr, + # TODO: kde, xfce + + # Importing firefox settings (requires 'r' access to @{HOME}/.mozilla/** + # which is provided by abstractions/ubuntu-browsers.d/user-files). + @{PROC}/[0-9]*/oom_{,score_}adj w, + /etc/firefox/profile/bookmarks.html r, + owner @{HOME}/.mozilla/** k, + + # Chromium configuration + owner @{HOME}/.pki/nssdb/* rwk, + owner @{HOME}/.cache/chromium/ rw, + owner @{HOME}/.cache/chromium/** rw, + owner @{HOME}/.cache/chromium/Cache/* mr, + owner @{HOME}/.config/chromium/ rw, + owner @{HOME}/.config/chromium/** rwk, + owner @{HOME}/.config/chromium/**/Cache/* mr, + owner @{HOME}/.config/chromium/Dictionaries/*.bdic mr, + owner @{HOME}/.config/chromium/**/Dictionaries/*.bdic mr, + + # Allow transitions to ourself and our sandbox + /usr/lib/chromium-browser/chromium-browser ix, + /usr/lib/chromium-browser/chromium-browser-sandbox cx -> chromium_browser_sandbox, + /usr/lib/chromium-browser/chrome-sandbox cx -> chromium_browser_sandbox, + + /bin/ps Uxr, + /usr/lib/chromium-browser/xdg-settings Cxr -> xdgsettings, + /usr/bin/xdg-settings Cxr -> xdgsettings, + + # GSettings + owner /{,var/}run/user/*/dconf/ rw, + owner /{,var/}run/user/*/dconf/user rw, + owner @{HOME}/.config/dconf/user r, + + profile xdgsettings { + #include + #include + + /bin/dash ixr, + + /etc/ld.so.cache r, + /usr/bin/xdg-settings r, + /usr/lib/chromium-browser/xdg-settings r, + /usr/share/applications/*.desktop r, + + # Checking default browser + /bin/grep ixr, + /bin/readlink ixr, + /bin/sed ixr, + /bin/which ixr, + /usr/bin/basename ixr, + /usr/bin/cut ixr, + + # Setting the default browser + /bin/mkdir ixr, + /bin/mv ixr, + /bin/touch ixr, + /usr/bin/dirname ixr, + /usr/bin/gconftool-2 ix, + /usr/bin/[gm]awk ixr, + /usr/bin/xdg-mime ixr, + owner @{HOME}/.local/share/applications/ w, + owner @{HOME}/.local/share/applications/mimeapps.list* rw, + } + + # Site-specific additions and overrides. See local/README for details. + #include + +profile chromium_browser_sandbox { + # Be fanatical since it is setuid root and don't use an abstraction + /lib/libgcc_s.so* mr, + /lib{,32,64}/libm-*.so* mr, + /lib/@{multiarch}/libm-*.so* mr, + /lib{,32,64}/libpthread-*.so* mr, + /lib/@{multiarch}/libpthread-*.so* mr, + /lib{,32,64}/libc-*.so* mr, + /lib/@{multiarch}/libc-*.so* mr, + /lib{,32,64}/libld-*.so* mr, + /lib/@{multiarch}/libld-*.so* mr, + /lib{,32,64}/ld-*.so* mr, + /lib/@{multiarch}/ld-*.so* mr, + /lib/tls/*/{cmov,nosegneg}/libm-*.so* mr, + /lib/tls/*/{cmov,nosegneg}/libpthread-*.so* mr, + /lib/tls/*/{cmov,nosegneg}/libc-*.so* mr, + /usr/lib/libstdc++.so* mr, + /etc/ld.so.cache r, + + # Required for dropping into PID namespace. Keep in mind that until the + # process drops this capability it can escape confinement, but once it + # drops CAP_SYS_ADMIN we are ok. + capability sys_admin, + + # All of these are for sanely dropping from root and chrooting + capability chown, + capability fsetid, + capability setgid, + capability setuid, + capability dac_override, + capability sys_chroot, + + # *Sigh* + capability sys_ptrace, + + @{PROC}/ r, + @{PROC}/[0-9]*/ r, + @{PROC}/[0-9]*/fd/ r, + @{PROC}/[0-9]*/oom_adj w, + @{PROC}/[0-9]*/oom_score_adj w, + @{PROC}/[0-9]*/status r, + @{PROC}/[0-9]*/task/[0-9]*/stat r, + + /usr/bin/chromium-browser r, + /usr/lib/chromium-browser/chromium-browser Px, + /usr/lib/chromium-browser/chromium-browser-sandbox r, + /usr/lib/chromium-browser/chrome-sandbox r, + + /dev/null rw, + + owner /tmp/** rw, + } +} debian/patches/limited-mount-rule-support.patch0000664000000000000000000002114512315312536017112 0ustar Description: utils: Add very limited support for mount rules . Bug: https://bugs.launchpad.net/bugs/1294825 . This patch is inspired by sbeattie's patch to add limited dbus rule support. It adds does very dumb parsing of mount rules. Basically, it stores mount, remount, and umount rules as raw strings wrapped in a class. . Signed-off-by: Tyler Hicks Acked-by: Steve Beattie Acked-by: Christian Boltz Origin: commit, revision id: tyhicks@canonical.com-20140320192542-we2ydn5rk0p05dtt Author: Tyler Hicks Bug: https://launchpad.net/bugs/1294825 Last-Update: 2014-03-20 X-Bzr-Revision-Id: tyhicks@canonical.com-20140320192542-we2ydn5rk0p05dtt === modified file 'utils/apparmor/aa.py' --- old/utils/apparmor/aa.py 2014-03-20 19:19:40 +0000 +++ new/utils/apparmor/aa.py 2014-03-20 19:25:42 +0000 @@ -2616,6 +2616,7 @@ RE_NETWORK_FAMILY_TYPE = re.compile('\s+(\S+)\s+(\S+)\s*,$') RE_NETWORK_FAMILY = re.compile('\s+(\S+)\s*,$') RE_PROFILE_DBUS = re.compile('^\s*(audit\s+)?(allow\s+|deny\s+)?(dbus[^#]*\s*,)\s*(#.*)?$') +RE_PROFILE_MOUNT = re.compile('^\s*(audit\s+)?(allow\s+|deny\s+)?((mount|remount|umount)[^#]*\s*,)\s*(#.*)?$') # match anything that's not " or #, or matching quotes with anything except quotes inside __re_no_or_quoted_hash = '([^#"]|"[^"]*")*' @@ -2693,6 +2694,7 @@ profile_data[profile][hat]['allow']['netdomain'] = hasher() profile_data[profile][hat]['allow']['path'] = hasher() profile_data[profile][hat]['allow']['dbus'] = list() + profile_data[profile][hat]['allow']['mount'] = list() # Save the initial comment if initial_comment: profile_data[profile][hat]['initial_comment'] = initial_comment @@ -2966,6 +2968,28 @@ dbus_rules.append(dbus_rule) profile_data[profile][hat][allow]['dbus'] = dbus_rules + elif RE_PROFILE_MOUNT.search(line): + matches = RE_PROFILE_MOUNT.search(line).groups() + + if not profile: + raise AppArmorException(_('Syntax Error: Unexpected mount entry found in file: %s line: %s') % (file, lineno + 1)) + + audit = False + if matches[0]: + audit = True + allow = 'allow' + if matches[1] and matches[1].strip() == 'deny': + allow = 'deny' + mount = matches[2] + + mount_rule = parse_mount_rule(mount) + mount_rule.audit = audit + mount_rule.deny = (allow == 'deny') + + mount_rules = profile_data[profile][hat][allow].get('mount', list()) + mount_rules.append(mount_rule) + profile_data[profile][hat][allow]['mount'] = mount_rules + elif RE_PROFILE_CHANGE_HAT.search(line): matches = RE_PROFILE_CHANGE_HAT.search(line).groups() @@ -3060,6 +3084,10 @@ # return aarules.DBUS_Rule() #print(line) +def parse_mount_rule(line): + # XXX Do real parsing here + return aarules.Raw_Mount_Rule(line) + def separate_vars(vs): """Returns a list of all the values for a variable""" data = [] @@ -3268,6 +3296,24 @@ data += write_dbus_rules(prof_data, depth, 'allow') return data +def write_mount_rules(prof_data, depth, allow): + pre = ' ' * depth + data = [] + + # no mount rules, so return + if not prof_data[allow].get('mount', False): + return data + + for mount_rule in prof_data[allow]['mount']: + data.append('%s%s' % (pre, mount_rule.serialize())) + data.append('') + return data + +def write_mount(prof_data, depth): + data = write_mount_rules(prof_data, depth, 'deny') + data += write_mount_rules(prof_data, depth, 'allow') + return data + def write_link_rules(prof_data, depth, allow): pre = ' ' * depth data = [] @@ -3361,6 +3407,7 @@ data += write_capabilities(prof_data, depth) data += write_netdomain(prof_data, depth) data += write_dbus(prof_data, depth) + data += write_mount(prof_data, depth) data += write_links(prof_data, depth) data += write_paths(prof_data, depth) data += write_change_profile(prof_data, depth) @@ -3509,6 +3556,7 @@ 'capability': write_capabilities, 'netdomain': write_netdomain, 'dbus': write_dbus, + 'mount': write_mount, 'link': write_links, 'path': write_paths, 'change_profile': write_change_profile, @@ -3600,6 +3648,7 @@ data += write_capabilities(write_prof_data[name], depth) data += write_netdomain(write_prof_data[name], depth) data += write_dbus(write_prof_data[name], depth) + data += write_mount(write_prof_data[name], depth) data += write_links(write_prof_data[name], depth) data += write_paths(write_prof_data[name], depth) data += write_change_profile(write_prof_data[name], depth) === modified file 'utils/apparmor/rules.py' --- old/utils/apparmor/rules.py 2014-03-07 17:58:54 +0000 +++ new/utils/apparmor/rules.py 2014-03-20 19:25:42 +0000 @@ -55,3 +55,15 @@ return "%s%s%s" % ('audit ' if self.audit else '', 'deny ' if self.deny else '', self.rule) + +class Raw_Mount_Rule(object): + audit = False + deny = False + + def __init__(self, rule): + self.rule = rule + + def serialize(self): + return "%s%s%s" % ('audit ' if self.audit else '', + 'deny ' if self.deny else '', + self.rule) === added file 'utils/test/test-mount_parse.py' --- old/utils/test/test-mount_parse.py 1970-01-01 00:00:00 +0000 +++ new/utils/test/test-mount_parse.py 2014-03-20 19:25:42 +0000 @@ -0,0 +1,70 @@ +#! /usr/bin/env python +# ------------------------------------------------------------------ +# +# Copyright (C) 2014 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. +# +# ------------------------------------------------------------------ + +import apparmor.aa as aa +import unittest + +class AAParseMountTest(unittest.TestCase): + + def test_parse_plain_mount_rule(self): + rule = 'mount,' + mount = aa.parse_mount_rule(rule) + self.assertEqual(rule, mount.serialize(), + 'mount object returned "%s", expected "%s"' % (mount.serialize(), rule)) + + def test_parse_ro_mount(self): + rule = 'mount -o ro,' + mount = aa.parse_mount_rule(rule) + self.assertEqual(rule, mount.serialize(), + 'mount object returned "%s", expected "%s"' % (mount.serialize(), rule)) + + def test_parse_rw_mount_with_mount_points(self): + rule = 'mount -o rw /dev/sdb1 -> /mnt/external,' + mount = aa.parse_mount_rule(rule) + self.assertEqual(rule, mount.serialize(), + 'mount object returned "%s", expected "%s"' % (mount.serialize(), rule)) + +class AAParseRemountTest(unittest.TestCase): + + def test_parse_plain_remount_rule(self): + rule = 'remount,' + mount = aa.parse_mount_rule(rule) + self.assertEqual(rule, mount.serialize(), + 'mount object returned "%s", expected "%s"' % (mount.serialize(), rule)) + + def test_parse_ro_remount(self): + rule = 'remount -o ro,' + mount = aa.parse_mount_rule(rule) + self.assertEqual(rule, mount.serialize(), + 'mount object returned "%s", expected "%s"' % (mount.serialize(), rule)) + + def test_parse_ro_remount_with_mount_point(self): + rule = 'remount -o ro /,' + mount = aa.parse_mount_rule(rule) + self.assertEqual(rule, mount.serialize(), + 'mount object returned "%s", expected "%s"' % (mount.serialize(), rule)) + +class AAParseUmountTest(unittest.TestCase): + + def test_parse_plain_umount_rule(self): + rule = 'umount,' + mount = aa.parse_mount_rule(rule) + self.assertEqual(rule, mount.serialize(), + 'mount object returned "%s", expected "%s"' % (mount.serialize(), rule)) + + def test_parse_umount_with_mount_point(self): + rule = 'umount /mnt/external,' + mount = aa.parse_mount_rule(rule) + self.assertEqual(rule, mount.serialize(), + 'mount object returned "%s", expected "%s"' % (mount.serialize(), rule)) + +if __name__ == '__main__': + unittest.main() debian/patches/aare-to-class.patch0000664000000000000000000004262512315045675014314 0ustar Author: John Johansen Forwarded: Yes Subject: Convert aare_rules into a class This cleans things up a bit and fixes a bug where not all rules are getting properly counted so that the addition of policy_mediation rules fails to generate the policy dfa in some cases. Because the policy dfa is being generated correctly now we need to fix some tests to use the new -M flag to specify the expected features set of the test. Signed-off-by: John Johansen --- parser/dbus.c | 24 ++++------ parser/libapparmor_re/aare_rules.cc | 80 +++++++++++------------------------- parser/libapparmor_re/aare_rules.h | 34 +++++++-------- parser/mount.c | 47 +++++++++------------ parser/parser_regex.c | 79 +++++++++++++++-------------------- parser/profile.cc | 4 - parser/profile.h | 6 +- 7 files changed, 114 insertions(+), 160 deletions(-) --- 2.9-test.orig/parser/dbus.c +++ 2.9-test/parser/dbus.c @@ -301,28 +301,26 @@ } if (mode & AA_DBUS_BIND) { - if (!aare_add_rule_vec(prof.policy.rules, deny, - mode & AA_DBUS_BIND, - audit & AA_DBUS_BIND, - 2, vec, dfaflags)) + if (!prof.policy.rules->add_rule_vec(deny, mode & AA_DBUS_BIND, + audit & AA_DBUS_BIND, + 2, vec, dfaflags)) goto fail; } if (mode & (AA_DBUS_SEND | AA_DBUS_RECEIVE)) { - if (!aare_add_rule_vec(prof.policy.rules, deny, - mode & (AA_DBUS_SEND | AA_DBUS_RECEIVE), - audit & (AA_DBUS_SEND | AA_DBUS_RECEIVE), - 6, vec, dfaflags)) + if (!prof.policy.rules->add_rule_vec(deny, + mode & (AA_DBUS_SEND | AA_DBUS_RECEIVE), + audit & (AA_DBUS_SEND | AA_DBUS_RECEIVE), + 6, vec, dfaflags)) goto fail; } if (mode & AA_DBUS_EAVESDROP) { - if (!aare_add_rule_vec(prof.policy.rules, deny, - mode & AA_DBUS_EAVESDROP, - audit & AA_DBUS_EAVESDROP, - 1, vec, dfaflags)) + if (!prof.policy.rules->add_rule_vec(deny, + mode & AA_DBUS_EAVESDROP, + audit & AA_DBUS_EAVESDROP, + 1, vec, dfaflags)) goto fail; } - prof.policy.count++; return RULE_OK; fail: --- 2.9-test.orig/parser/libapparmor_re/aare_rules.cc +++ 2.9-test/parser/libapparmor_re/aare_rules.cc @@ -34,38 +34,20 @@ #include "chfa.h" #include "../immunix.h" -struct aare_ruleset { - int reverse; - Node *root; -}; -aare_ruleset_t *aare_new_ruleset(int reverse) -{ - aare_ruleset_t *container = (aare_ruleset_t *) malloc(sizeof(aare_ruleset_t)); - if (!container) - return NULL; - - container->root = NULL; - container->reverse = reverse; - - return container; -} -void aare_delete_ruleset(aare_ruleset_t *rules) +aare_rules::~aare_rules(void) { - if (rules) { - if (rules->root) - rules->root->release(); - free(rules); - } + if (root) + root->release(); aare_reset_matchflags(); } -int aare_add_rule(aare_ruleset_t *rules, const char *rule, int deny, - uint32_t perms, uint32_t audit, dfaflags_t flags) +bool aare_rules::add_rule(const char *rule, int deny, uint32_t perms, + uint32_t audit, dfaflags_t flags) { - return aare_add_rule_vec(rules, deny, perms, audit, 1, &rule, flags); + return add_rule_vec(deny, perms, audit, 1, &rule, flags); } #define FLAGS_WIDTH 2 @@ -94,9 +76,8 @@ #undef RESET_FLAGS } -int aare_add_rule_vec(aare_ruleset_t *rules, int deny, - uint32_t perms, uint32_t audit, - int count, const char **rulev, dfaflags_t flags) +bool aare_rules::add_rule_vec(int deny, uint32_t perms, uint32_t audit, + int count, const char **rulev, dfaflags_t flags) { Node *tree = NULL, *accept; int exact_match; @@ -105,15 +86,15 @@ assert(perms != 0); if (regex_parse(&tree, rulev[0])) - return 0; + return false; for (int i = 1; i < count; i++) { Node *subtree = NULL; Node *node = new CharNode(0); if (!node) - return 0; + return false; tree = new CatNode(tree, node); if (regex_parse(&subtree, rulev[i])) - return 0; + return false; tree = new CatNode(tree, subtree); } @@ -132,26 +113,15 @@ exact_match = 0; } - if (rules->reverse) + if (reverse) flip_tree(tree); /* 0x7f == 4 bits x mods + 1 bit unsafe mask + 1 bit ix, + 1 pux after shift */ #define EXTRACT_X_INDEX(perm, shift) (((perm) >> (shift + 7)) & 0x7f) -//if (perms & ALL_AA_EXEC_TYPE && (!perms & AA_EXEC_BITS)) -// fprintf(stderr, "adding X rule without MAY_EXEC: 0x%x %s\n", perms, rulev[0]); - -//if (perms & ALL_EXEC_TYPE) -// fprintf(stderr, "adding X rule %s 0x%x\n", rulev[0], perms); - -//if (audit) -//fprintf(stderr, "adding rule with audit bits set: 0x%x %s\n", audit, rulev[0]); - -//if (perms & AA_CHANGE_HAT) -// fprintf(stderr, "adding change_hat rule %s\n", rulev[0]); -/* the permissions set is assumed to be non-empty if any audit - * bits are specified */ + /* the permissions set is assumed to be non-empty if any audit + * bits are specified */ accept = NULL; for (unsigned int n = 0; perms && n < (sizeof(perms) * 8); n++) { uint32_t mask = 1 << n; @@ -230,44 +200,44 @@ cerr << "\n\n"; } - if (rules->root) - rules->root = new AltNode(rules->root, new CatNode(tree, accept)); + if (root) + root = new AltNode(root, new CatNode(tree, accept)); else - rules->root = new CatNode(tree, accept); + root = new CatNode(tree, accept); - return 1; + rule_count++; + return true; } /* create a dfa from the ruleset * returns: buffer contain dfa tables, @size set to the size of the tables * else NULL on failure */ -void *aare_create_dfa(aare_ruleset_t *rules, size_t *size, - dfaflags_t flags) +void *aare_rules::create_dfa(size_t *size, dfaflags_t flags) { char *buffer = NULL; - label_nodes(rules->root); + label_nodes(root); if (flags & DFA_DUMP_TREE) { cerr << "\nDFA: Expression Tree\n"; - rules->root->dump(cerr); + root->dump(cerr); cerr << "\n\n"; } if (flags & DFA_CONTROL_TREE_SIMPLE) { - rules->root = simplify_tree(rules->root, flags); + root = simplify_tree(root, flags); if (flags & DFA_DUMP_SIMPLE_TREE) { cerr << "\nDFA: Simplified Expression Tree\n"; - rules->root->dump(cerr); + root->dump(cerr); cerr << "\n\n"; } } stringstream stream; try { - DFA dfa(rules->root, flags); + DFA dfa(root, flags); if (flags & DFA_DUMP_UNIQ_PERMS) dfa.dump_uniq_perms("dfa"); --- 2.9-test.orig/parser/libapparmor_re/aare_rules.h +++ 2.9-test/parser/libapparmor_re/aare_rules.h @@ -24,26 +24,24 @@ #include #include "apparmor_re.h" +#include "expr-tree.h" -#ifdef __cplusplus -extern "C" { -#endif +class aare_rules { + Node *root; +public: + int reverse; + int rule_count; + aare_rules(): root(NULL), reverse(0), rule_count(0) { }; + aare_rules(int reverse): root(NULL), reverse(reverse), rule_count(0) { }; + ~aare_rules(); + + bool add_rule(const char *rule, int deny, uint32_t perms, + uint32_t audit, dfaflags_t flags); + bool add_rule_vec(int deny, uint32_t perms, uint32_t audit, int count, + const char **rulev, dfaflags_t flags); + void *create_dfa(size_t *size, dfaflags_t flags); +}; -struct aare_ruleset; - -typedef struct aare_ruleset aare_ruleset_t; - -aare_ruleset_t *aare_new_ruleset(int reverse); -void aare_delete_ruleset(aare_ruleset_t *rules); -int aare_add_rule(aare_ruleset_t *rules, const char *rule, int deny, uint32_t perms, - uint32_t audit, dfaflags_t flags); -int aare_add_rule_vec(aare_ruleset_t *rules, int deny, uint32_t perms, - uint32_t audit, int count, const char **rulev, - dfaflags_t flags); -void *aare_create_dfa(aare_ruleset_t *rules, size_t *size, dfaflags_t flags); void aare_reset_matchflags(void); -#ifdef __cplusplus -} -#endif #endif /* __LIBAA_RE_RULES_H */ --- 2.9-test.orig/parser/mount.c +++ 2.9-test/parser/mount.c @@ -631,9 +631,9 @@ tmpallow = allow; /* rule for match without required data || data MATCH_CONT */ - if (!aare_add_rule_vec(prof.policy.rules, deny, tmpallow, - audit | AA_AUDIT_MNT_DATA, 4, - vec, dfaflags)) + if (!prof.policy.rules->add_rule_vec(deny, tmpallow, + audit | AA_AUDIT_MNT_DATA, 4, + vec, dfaflags)) goto fail; count++; @@ -643,10 +643,9 @@ if (!build_mnt_opts(optsbuf, opts)) goto fail; vec[4] = optsbuf.c_str(); - if (!aare_add_rule_vec(prof.policy.rules, deny, - allow, - audit | AA_AUDIT_MNT_DATA, - 5, vec, dfaflags)) + if (!prof.policy.rules->add_rule_vec(deny, allow, + audit | AA_AUDIT_MNT_DATA, + 5, vec, dfaflags)) goto fail; count++; } @@ -674,8 +673,8 @@ if (!build_mnt_flags(flagsbuf, PATH_MAX, tmpflags, tmpinv_flags)) goto fail; vec[3] = flagsbuf; - if (!aare_add_rule_vec(prof.policy.rules, deny, allow, - audit, 4, vec, dfaflags)) + if (!prof.policy.rules->add_rule_vec(deny, allow, audit, 4, vec, + dfaflags)) goto fail; count++; } @@ -703,8 +702,8 @@ if (!build_mnt_flags(flagsbuf, PATH_MAX, tmpflags, tmpinv_flags)) goto fail; vec[3] = flagsbuf; - if (!aare_add_rule_vec(prof.policy.rules, deny, allow, - audit, 4, vec, dfaflags)) + if (!prof.policy.rules->add_rule_vec(deny, allow, audit, 4, vec, + dfaflags)) goto fail; count++; } @@ -733,8 +732,8 @@ if (!build_mnt_flags(flagsbuf, PATH_MAX, tmpflags, tmpinv_flags)) goto fail; vec[3] = flagsbuf; - if (!aare_add_rule_vec(prof.policy.rules, deny, allow, - audit, 4, vec, dfaflags)) + if (!prof.policy.rules->add_rule_vec(deny, allow, audit, 4, vec, + dfaflags)) goto fail; count++; } @@ -773,9 +772,9 @@ tmpallow = allow; /* rule for match without required data || data MATCH_CONT */ - if (!aare_add_rule_vec(prof.policy.rules, deny, tmpallow, - audit | AA_AUDIT_MNT_DATA, 4, - vec, dfaflags)) + if (!prof.policy.rules->add_rule_vec(deny, tmpallow, + audit | AA_AUDIT_MNT_DATA, 4, + vec, dfaflags)) goto fail; count++; @@ -785,10 +784,9 @@ if (!build_mnt_opts(optsbuf, opts)) goto fail; vec[4] = optsbuf.c_str(); - if (!aare_add_rule_vec(prof.policy.rules, deny, - allow, - audit | AA_AUDIT_MNT_DATA, - 5, vec, dfaflags)) + if (!prof.policy.rules->add_rule_vec(deny, allow, + audit | AA_AUDIT_MNT_DATA, + 5, vec, dfaflags)) goto fail; count++; } @@ -799,8 +797,8 @@ if (!convert_entry(mntbuf, mnt_point)) goto fail; vec[0] = mntbuf.c_str(); - if (!aare_add_rule_vec(prof.policy.rules, deny, allow, - audit, 1, vec, dfaflags)) + if (!prof.policy.rules->add_rule_vec(deny, allow, audit, 1, vec, + dfaflags)) goto fail; count++; } @@ -813,8 +811,8 @@ if (!clear_and_convert_entry(devbuf, device)) goto fail; vec[1] = devbuf.c_str(); - if (!aare_add_rule_vec(prof.policy.rules, deny, allow, - audit, 2, vec, dfaflags)) + if (!prof.policy.rules->add_rule_vec(deny, allow, audit, 2, vec, + dfaflags)) goto fail; count++; } @@ -823,7 +821,6 @@ /* didn't actually encode anything */ goto fail; - prof.policy.count++; return RULE_OK; fail: --- 2.9-test.orig/parser/parser_regex.c +++ 2.9-test/parser/parser_regex.c @@ -431,11 +431,11 @@ prof->xmatch_size = 0; } else { /* build a dfa */ - aare_ruleset_t *rule = aare_new_ruleset(0); - if (!rule) + aare_rules *rules = new aare_rules(); + if (!rules) return FALSE; - if (!aare_add_rule(rule, tbuf.c_str(), 0, AA_MAY_EXEC, 0, dfaflags)) { - aare_delete_ruleset(rule); + if (!rules->add_rule(tbuf.c_str(), 0, AA_MAY_EXEC, 0, dfaflags)) { + delete rules; return FALSE; } if (prof->altnames) { @@ -450,15 +450,14 @@ len = strlen(alt->name); if (len < prof->xmatch_len) prof->xmatch_len = len; - if (!aare_add_rule(rule, tbuf.c_str(), 0, AA_MAY_EXEC, 0, dfaflags)) { - aare_delete_ruleset(rule); + if (!rules->add_rule(tbuf.c_str(), 0, AA_MAY_EXEC, 0, dfaflags)) { + delete rules; return FALSE; } } } - prof->xmatch = aare_create_dfa(rule, &prof->xmatch_size, - dfaflags); - aare_delete_ruleset(rule); + prof->xmatch = rules->create_dfa(&prof->xmatch_size, dfaflags); + delete rules; if (!prof->xmatch) return FALSE; } @@ -466,7 +465,7 @@ return TRUE; } -static int process_dfa_entry(aare_ruleset_t *dfarules, struct cod_entry *entry) +static int process_dfa_entry(aare_rules *dfarules, struct cod_entry *entry) { std::string tbuf; pattern_t ptype; @@ -498,13 +497,13 @@ * entry of the pair */ if (entry->deny && (entry->mode & AA_LINK_BITS)) { - if (!aare_add_rule(dfarules, tbuf.c_str(), entry->deny, - entry->mode & ~AA_LINK_BITS, - entry->audit & ~AA_LINK_BITS, dfaflags)) + if (!dfarules->add_rule(tbuf.c_str(), entry->deny, + entry->mode & ~AA_LINK_BITS, + entry->audit & ~AA_LINK_BITS, dfaflags)) return FALSE; } else if (entry->mode & ~AA_CHANGE_PROFILE) { - if (!aare_add_rule(dfarules, tbuf.c_str(), entry->deny, entry->mode, - entry->audit, dfaflags)) + if (!dfarules->add_rule(tbuf.c_str(), entry->deny, entry->mode, + entry->audit, dfaflags)) return FALSE; } @@ -526,7 +525,7 @@ perms |= LINK_TO_LINK_SUBSET(perms); vec[1] = "/[^/].*"; } - if (!aare_add_rule_vec(dfarules, entry->deny, perms, entry->audit & AA_LINK_BITS, 2, vec, dfaflags)) + if (!dfarules->add_rule_vec(entry->deny, perms, entry->audit & AA_LINK_BITS, 2, vec, dfaflags)) return FALSE; } if (entry->mode & AA_CHANGE_PROFILE) { @@ -545,12 +544,12 @@ vec[index++] = tbuf.c_str(); /* regular change_profile rule */ - if (!aare_add_rule_vec(dfarules, 0, AA_CHANGE_PROFILE | AA_ONEXEC, 0, index - 1, &vec[1], dfaflags)) + if (!dfarules->add_rule_vec(0, AA_CHANGE_PROFILE | AA_ONEXEC, 0, index - 1, &vec[1], dfaflags)) return FALSE; /* onexec rules - both rules are needed for onexec */ - if (!aare_add_rule_vec(dfarules, 0, AA_ONEXEC, 0, 1, vec, dfaflags)) + if (!dfarules->add_rule_vec(0, AA_ONEXEC, 0, 1, vec, dfaflags)) return FALSE; - if (!aare_add_rule_vec(dfarules, 0, AA_ONEXEC, 0, index, vec, dfaflags)) + if (!dfarules->add_rule_vec(0, AA_ONEXEC, 0, index, vec, dfaflags)) return FALSE; } return TRUE; @@ -560,15 +559,12 @@ { int ret = TRUE; struct cod_entry *entry; - int count = 0; list_for_each(prof->entries, entry) { if (!process_dfa_entry(prof->dfa.rules, entry)) ret = FALSE; - count++; } - prof->dfa.count = count; return ret; } @@ -579,17 +575,17 @@ if (!process_profile_name_xmatch(prof)) goto out; - prof->dfa.rules = aare_new_ruleset(0); + prof->dfa.rules = new aare_rules(); if (!prof->dfa.rules) goto out; if (!post_process_entries(prof)) goto out; - if (prof->dfa.count > 0) { - prof->dfa.dfa = aare_create_dfa(prof->dfa.rules, &prof->dfa.size, - dfaflags); - aare_delete_ruleset(prof->dfa.rules); + if (prof->dfa.rules->rule_count > 0) { + prof->dfa.dfa = prof->dfa.rules->create_dfa(&prof->dfa.size, + dfaflags); + delete prof->dfa.rules; prof->dfa.rules = NULL; if (!prof->dfa.dfa) goto out; @@ -683,7 +679,7 @@ { int error = -1; - prof->policy.rules = aare_new_ruleset(0); + prof->policy.rules = new aare_rules(); if (!prof->policy.rules) goto out; @@ -694,26 +690,21 @@ * to be supported */ - if (kernel_supports_mount) { - if (!aare_add_rule(prof->policy.rules, mediates_mount, 0, AA_MAY_READ, 0, dfaflags)) + if (kernel_supports_mount && + !prof->policy.rules->add_rule(mediates_mount, 0, AA_MAY_READ, 0, dfaflags)) goto out; - prof->policy.count++; - } - if (kernel_supports_dbus) { - if (!aare_add_rule(prof->policy.rules, mediates_dbus, 0, AA_MAY_READ, 0, dfaflags)) - goto out; - prof->policy.count++; - } - if (prof->policy.count > 0) { - prof->policy.dfa = aare_create_dfa(prof->policy.rules, - &prof->policy.size, - dfaflags); - aare_delete_ruleset(prof->policy.rules); + if (kernel_supports_dbus && + !prof->policy.rules->add_rule(mediates_dbus, 0, AA_MAY_READ, 0, dfaflags)) + goto out; + if (prof->policy.rules->rule_count > 0) { + prof->policy.dfa = prof->policy.rules->create_dfa(&prof->policy.size, dfaflags); + delete prof->policy.rules; + prof->policy.rules = NULL; if (!prof->policy.dfa) goto out; } else { - aare_delete_ruleset(prof->policy.rules); + delete prof->policy.rules; prof->policy.rules = NULL; } @@ -722,7 +713,7 @@ error = 0; out: - aare_delete_ruleset(prof->policy.rules); + delete prof->policy.rules; prof->policy.rules = NULL; return error; --- 2.9-test.orig/parser/profile.cc +++ 2.9-test/parser/profile.cc @@ -67,11 +67,11 @@ for (RuleList::iterator i = rule_ents.begin(); i != rule_ents.end(); i++) delete *i; if (dfa.rules) - aare_delete_ruleset(dfa.rules); + delete dfa.rules; if (dfa.dfa) free(dfa.dfa); if (policy.rules) - aare_delete_ruleset(policy.rules); + delete policy.rules; if (policy.dfa) free(policy.dfa); if (xmatch) --- 2.9-test.orig/parser/profile.h +++ 2.9-test/parser/profile.h @@ -18,6 +18,7 @@ #include "parser.h" #include "rule.h" +#include "libapparmor_re/aare_rules.h" class Profile; @@ -120,12 +121,11 @@ }; struct dfa_stuff { - aare_ruleset_t *rules; - int count; + aare_rules *rules; void *dfa; size_t size; - dfa_stuff(void): rules(NULL), count(0), dfa(NULL), size(0) { } + dfa_stuff(void): rules(NULL), dfa(NULL), size(0) { } }; class Profile { -- AppArmor mailing list AppArmor@lists.ubuntu.com Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/apparmor debian/patches/fix-serialize.patch0000664000000000000000000005065712315045675014440 0ustar Author: John Johansen Forwarded: Yes Subject: Move buffer management for the interface to C++ ostringstream class with sbeattie's pad calculation fix. Signed-off-by: John Johansen --- parser/parser.h | 5 parser/parser_interface.c | 510 +++++++++++++--------------------------------- parser/parser_policy.c | 8 3 files changed, 151 insertions(+), 372 deletions(-) --- 2.9-test.orig/parser/parser.h +++ 2.9-test/parser/parser.h @@ -415,9 +415,8 @@ extern int profile_merge_rules(Profile *prof); /* parser_interface.c */ -typedef struct __sdserialize sd_serialize; extern int load_profile(int option, Profile *prof); -extern int sd_serialize_profile(sd_serialize *p, Profile *prof, +extern void sd_serialize_profile(std::ostringstream &buf, Profile *prof, int flatten); extern int sd_load_buffer(int option, char *buffer, int size); extern int cache_fd; @@ -438,7 +437,7 @@ extern int merge_hat_rules(Profile *prof); extern Profile *merge_policy(Profile *a, Profile *b); extern int load_policy(int option); -extern int load_hats(sd_serialize *p, Profile *prof); +extern int load_hats(std::ostringstream &buf, Profile *prof); extern int load_flattened_hats(Profile *prof, int option); extern void dump_policy_hats(Profile *prof); extern void dump_policy_names(void); --- 2.9-test.orig/parser/parser_interface.c +++ 2.9-test/parser/parser_interface.c @@ -27,6 +27,9 @@ #include #define _(s) gettext(s) +#include +#include + #include "parser.h" #include "profile.h" #include "libapparmor_re/apparmor_re.h" @@ -41,8 +44,6 @@ #define _(s) gettext(s) -#define BUFFERINC 65536 -//#define BUFFERINC 16 #define SD_CODE_SIZE (sizeof(u8)) @@ -194,301 +195,172 @@ "SD_OFFSET" }; -/* Currently we will just use a contiguous block of memory - be we are going to just hide this for the moment. */ -struct __sdserialize { - u8 *buffer; - u8 *pos; - u8 *extent; -}; - -sd_serialize *alloc_sd_serial(void) -{ - sd_serialize *p = (sd_serialize *) calloc(1, sizeof(sd_serialize)); - if (!p) - return NULL; - p->buffer = (u8 *) malloc(BUFFERINC); - if (!p->buffer) { - free(p); - return NULL; - } - p->pos = p->buffer; - p->extent = p->buffer + BUFFERINC; - return p; -} - -void free_sd_serial(sd_serialize *p) -{ - if (p) { - if (p->buffer) - free(p->buffer); - free(p); - } -} -/*check if something of size length is in sd_serial bounds */ -static inline int sd_inbounds(sd_serialize *p, int size) +inline void sd_write8(std::ostringstream &buf, u8 b) { - return (p->pos + size <= p->extent); + buf.write((const char *) &b, 1); } -static inline void sd_inc(sd_serialize *p, int size) +inline void sd_write16(std::ostringstream &buf, u16 b) { - if (sd_inbounds(p, size)) { - p->pos += size; - } else { - PERROR(_("PANIC bad increment buffer %p pos %p ext %p size %d res %p\n"), - p->buffer, p->pos, p->extent, size, p->pos + size); - exit(-1); - } + u16 tmp; + tmp = cpu_to_le16(b); + buf.write((const char *) &tmp, 2); } -inline long sd_serial_size(sd_serialize *p) +inline void sd_write32(std::ostringstream &buf, u32 b) { - return (long) (p->pos) - (long) (p->buffer); + u32 tmp; + tmp = cpu_to_le32(b); + buf.write((const char *) &tmp, 4); } -/* routines for writing data to the serialization buffer */ -inline int sd_prepare_write(sd_serialize *p, enum sd_code code, size_t size) +inline void sd_write64(std::ostringstream &buf, u64 b) { - int num = (size / BUFFERINC) + 1; - if (p->pos + SD_CODE_SIZE + size > p->extent) { - long pos; - /* try and reallocate the buffer */ - u8 *buffer = (u8 *) malloc((long)(p->extent) - (long)(p->buffer) + (BUFFERINC * num)); - memcpy(buffer, p->buffer, (long)(p->extent) - (long)(p->buffer)); - - pos = (long)(p->pos) - (long)(p->buffer); - if (buffer == NULL || errno == ENOMEM) - return 0; - - p->extent = buffer + ((long)(p->extent) - (long)(p->buffer)) + (BUFFERINC * num); - free(p->buffer); - p->buffer = buffer; - p->pos = buffer + pos; - } - *(u8 *) (p->pos) = code; - sd_inc(p, SD_CODE_SIZE); - return 1; + u64 tmp; + tmp = cpu_to_le64(b); + buf.write((const char *) &tmp, 8); } -inline int sd_write8(sd_serialize *p, u8 b) +inline void sd_write_uint8(std::ostringstream &buf, u8 b) { - u8 *c; - if (!sd_prepare_write(p, SD_U8, sizeof(b))) - return 0; - c = (u8 *) p->pos; - *c = b; - sd_inc(p, 1); - return 1; + sd_write8(buf, SD_U8); + sd_write8(buf, b); } -inline int sd_write16(sd_serialize *p, u16 b) +inline void sd_write_uint16(std::ostringstream &buf, u16 b) { - u16 tmp; - if (!sd_prepare_write(p, SD_U16, sizeof(b))) - return 0; - tmp = cpu_to_le16(b); - memcpy(p->pos, &tmp, sizeof(tmp)); - sd_inc(p, sizeof(tmp)); - return 1; + sd_write8(buf, SD_U16); + sd_write16(buf, b); } -inline int sd_write32(sd_serialize *p, u32 b) +inline void sd_write_uint32(std::ostringstream &buf, u32 b) { - u32 tmp; - if (!sd_prepare_write(p, SD_U32, sizeof(b))) - return 0; - tmp = cpu_to_le32(b); - memcpy(p->pos, &tmp, sizeof(tmp)); - sd_inc(p, sizeof(tmp)); - return 1; + sd_write8(buf, SD_U32); + sd_write32(buf, b); } -inline int sd_write64(sd_serialize *p, u64 b) +inline void sd_write_uint64(std::ostringstream &buf, u64 b) { - u64 tmp; - if (!sd_prepare_write(p, SD_U64, sizeof(b))) - return 0; - tmp = cpu_to_le64(b); - memcpy(p->pos, &tmp, sizeof(tmp)); - sd_inc(p, sizeof(tmp)); - return 1; + sd_write8(buf, SD_U64); + sd_write64(buf, b); } -inline int sd_write_name(sd_serialize *p, const char *name) +inline void sd_write_name(std::ostringstream &buf, const char *name) { - long size = 0; PDEBUG("Writing name '%s'\n", name); if (name) { - u16 tmp; - size = strlen(name) + 1; - if (!sd_prepare_write(p, SD_NAME, SD_STR_LEN + size)) - return 0; - tmp = cpu_to_le16(size); - memcpy(p->pos, &tmp, sizeof(tmp)); - sd_inc(p, sizeof(tmp)); - memcpy(p->pos, name, size); - sd_inc(p, size); + sd_write8(buf, SD_NAME); + sd_write16(buf, strlen(name) + 1); + buf.write(name, strlen(name) + 1); } - return 1; } -inline int sd_write_blob(sd_serialize *p, void *b, int buf_size, char *name) +inline void sd_write_blob(std::ostringstream &buf, void *b, int buf_size, char *name) { - u32 tmp; - if (!sd_write_name(p, name)) - return 0; - if (!sd_prepare_write(p, SD_BLOB, 4 + buf_size)) - return 0; - tmp = cpu_to_le32(buf_size); - memcpy(p->pos, &tmp, sizeof(tmp)); - sd_inc(p, sizeof(tmp)); - memcpy(p->pos, b, buf_size); - sd_inc(p, buf_size); - return 1; + sd_write_name(buf, name); + sd_write8(buf, SD_BLOB); + sd_write32(buf, buf_size); + buf.write((const char *) b, buf_size); } + +static char zeros[64]; #define align64(X) (((X) + (typeof(X)) 7) & ~((typeof(X)) 7)) -inline int sd_write_aligned_blob(sd_serialize *p, void *b, int buf_size, +inline void sd_write_aligned_blob(std::ostringstream &buf, void *b, int b_size, const char *name) { - size_t pad; - u32 tmp; - if (!sd_write_name(p, name)) - return 0; - pad = align64(p->pos + 5 - p->buffer) - (p->pos + 5 - p->buffer); - if (!sd_prepare_write(p, SD_BLOB, 4 + buf_size + pad)) - return 0; - tmp = cpu_to_le32(buf_size + pad); - memcpy(p->pos, &tmp, sizeof(tmp)); - sd_inc(p, sizeof(tmp)); - memset(p->pos, 0, pad); - sd_inc(p, pad); - memcpy(p->pos, b, buf_size); - sd_inc(p, buf_size); - return 1; + sd_write_name(buf, name); + /* pad calculation MUST come after name is written */ + size_t pad = align64(buf.tellp() + ((std::streamoff) 5l)) - (buf.tellp() + ((std::streamoff) 5l)); + sd_write8(buf, SD_BLOB); + sd_write32(buf, b_size + pad); + buf.write(zeros, pad); + buf.write((const char *) b, b_size); } -static int sd_write_strn(sd_serialize *p, char *b, int size, const char *name) +static void sd_write_strn(std::ostringstream &buf, char *b, int size, const char *name) { - u16 tmp; - if (!sd_write_name(p, name)) - return 0; - if (!sd_prepare_write(p, SD_STRING, SD_STR_LEN + size)) - return 0; - tmp = cpu_to_le16(size); - memcpy(p->pos, &tmp, sizeof(tmp)); - sd_inc(p, sizeof(tmp)); - memcpy(p->pos, b, size); - sd_inc(p, size); - return 1; + sd_write_name(buf, name); + sd_write8(buf, SD_STRING); + sd_write16(buf, size); + buf.write(b, size); } -inline int sd_write_string(sd_serialize *p, char *b, const char *name) +inline void sd_write_string(std::ostringstream &buf, char *b, const char *name) { - return sd_write_strn(p, b, strlen(b) + 1, name); + sd_write_strn(buf, b, strlen(b) + 1, name); } -inline int sd_write_struct(sd_serialize *p, const char *name) +inline void sd_write_struct(std::ostringstream &buf, const char *name) { - if (!sd_write_name(p, name)) - return 0; - if (!sd_prepare_write(p, SD_STRUCT, 0)) - return 0; - return 1; + sd_write_name(buf, name); + sd_write8(buf, SD_STRUCT); } -inline int sd_write_structend(sd_serialize *p) +inline void sd_write_structend(std::ostringstream &buf) { - if (!sd_prepare_write(p, SD_STRUCTEND, 0)) - return 0; - return 1; + sd_write8(buf, SD_STRUCTEND); } -inline int sd_write_array(sd_serialize *p, const char *name, int size) +inline void sd_write_array(std::ostringstream &buf, const char *name, int size) { - u16 tmp; - if (!sd_write_name(p, name)) - return 0; - if (!sd_prepare_write(p, SD_ARRAY, 2)) - return 0; - tmp = cpu_to_le16(size); - memcpy(p->pos, &tmp, sizeof(tmp)); - sd_inc(p, sizeof(tmp)); - return 1; + sd_write_name(buf, name); + sd_write8(buf, SD_ARRAY); + sd_write16(buf, size); } -inline int sd_write_arrayend(sd_serialize *p) +inline void sd_write_arrayend(std::ostringstream &buf) { - if (!sd_prepare_write(p, SD_ARRAYEND, 0)) - return 0; - return 1; + sd_write8(buf, SD_ARRAYEND); } -inline int sd_write_list(sd_serialize *p, const char *name) +inline void sd_write_list(std::ostringstream &buf, const char *name) { - if (!sd_write_name(p, name)) - return 0; - if (!sd_prepare_write(p, SD_LIST, 0)) - return 0; - return 1; + sd_write_name(buf, name); + sd_write8(buf, SD_LIST); } -inline int sd_write_listend(sd_serialize *p) +inline void sd_write_listend(std::ostringstream &buf) { - if (!sd_prepare_write(p, SD_LISTEND, 0)) - return 0; - return 1; + sd_write8(buf, SD_LISTEND); } -int sd_serialize_dfa(sd_serialize *p, void *dfa, size_t size) +void sd_serialize_dfa(std::ostringstream &buf, void *dfa, size_t size) { - if (dfa && !sd_write_aligned_blob(p, dfa, size, "aadfa")) - return 0; - - return 1; + if (dfa) + sd_write_aligned_blob(buf, dfa, size, "aadfa"); } -int sd_serialize_rlimits(sd_serialize *p, struct aa_rlimits *limits) +void sd_serialize_rlimits(std::ostringstream &buf, struct aa_rlimits *limits) { - int i; if (!limits->specified) - return 1; - if (!sd_write_struct(p, "rlimits")) - return 0; - if (!sd_write32(p, limits->specified)) - return 0; - if (!sd_write_array(p, NULL, RLIM_NLIMITS)) - return 0; - for (i = 0; i < RLIM_NLIMITS; i++) { - if (!sd_write64(p, limits->limits[i])) - return 0; - } - if (!sd_write_arrayend(p)) - return 0; - if (!sd_write_structend(p)) - return 0; - return 1; + return; + + sd_write_struct(buf, "rlimits"); + sd_write_uint32(buf, limits->specified); + sd_write_array(buf, NULL, RLIM_NLIMITS); + for (int i = 0; i < RLIM_NLIMITS; i++) { + sd_write_uint64(buf, limits->limits[i]); + } + sd_write_arrayend(buf); + sd_write_structend(buf); } -int sd_serialize_xtable(sd_serialize *p, char **table) +void sd_serialize_xtable(std::ostringstream &buf, char **table) { - int count, i; + int count; if (!table[4]) - return 1; - if (!sd_write_struct(p, "xtable")) - return 0; + return; + sd_write_struct(buf, "xtable"); count = 0; - for (i = 4; i < AA_EXEC_COUNT; i++) { + for (int i = 4; i < AA_EXEC_COUNT; i++) { if (table[i]) count++; } - if (!sd_write_array(p, NULL, count)) - return 0; - - for (i = 4; i < count + 4; i++) { + sd_write_array(buf, NULL, count); + for (int i = 4; i < count + 4; i++) { int len = strlen(table[i]) + 1; /* if its a namespace make sure the second : is overwritten @@ -498,88 +370,45 @@ char *tmp = table[i] + 1; strsep(&tmp, ":"); } - if (!sd_write_strn(p, table[i], len, NULL)) - return 0; - - } - if (!sd_write_arrayend(p)) - return 0; - - if (!sd_write_structend(p)) - return 0; - return 1; -} - -int count_file_ents(struct cod_entry *list) -{ - struct cod_entry *entry; - int count = 0; - list_for_each(list, entry) { - if (entry->pattern_type == ePatternBasic) { - count++; - } + sd_write_strn(buf, table[i], len, NULL); } - return count; + sd_write_arrayend(buf); + sd_write_structend(buf); } -int count_tailglob_ents(struct cod_entry *list) -{ - struct cod_entry *entry; - int count = 0; - list_for_each(list, entry) { - if (entry->pattern_type == ePatternTailGlob) { - count++; - } - } - return count; -} - -int sd_serialize_profile(sd_serialize *p, Profile *profile, +void sd_serialize_profile(std::ostringstream &buf, Profile *profile, int flattened) { uint64_t allowed_caps; - if (!sd_write_struct(p, "profile")) - return 0; + sd_write_struct(buf, "profile"); if (flattened) { assert(profile->parent); - int res; - char *name = (char *) malloc(3 + strlen(profile->name) + strlen(profile->parent->name)); if (!name) - return 0; + return; sprintf(name, "%s//%s", profile->parent->name, profile->name); - res = sd_write_string(p, name, NULL); + sd_write_string(buf, name, NULL); free(name); - if (!res) - return 0; } else { - if (!sd_write_string(p, profile->name, NULL)) - return 0; + sd_write_string(buf, profile->name, NULL); } /* only emit this if current kernel at least supports "create" */ if (perms_create) { if (profile->xmatch) { - if (!sd_serialize_dfa(p, profile->xmatch, profile->xmatch_size)) - return 0; - if (!sd_write32(p, profile->xmatch_len)) - return 0; + sd_serialize_dfa(buf, profile->xmatch, profile->xmatch_size); + sd_write_uint32(buf, profile->xmatch_len); } } - if (!sd_write_struct(p, "flags")) - return 0; + sd_write_struct(buf, "flags"); /* used to be flags.debug, but that's no longer supported */ - if (!sd_write32(p, profile->flags.hat)) - return 0; - if (!sd_write32(p, profile->flags.complain)) - return 0; - if (!sd_write32(p, profile->flags.audit)) - return 0; - if (!sd_write_structend(p)) - return 0; + sd_write_uint32(buf, profile->flags.hat); + sd_write_uint32(buf, profile->flags.complain); + sd_write_uint32(buf, profile->flags.audit); + sd_write_structend(buf); if (profile->flags.path) { int flags = 0; if (profile->flags.path & PATH_CHROOT_REL) @@ -591,102 +420,71 @@ if (profile->flags.path & PATH_CHROOT_NSATTACH) flags |= 0x10; - if (!sd_write_name(p, "path_flags") || - !sd_write32(p, flags)) - return 0; + sd_write_name(buf, "path_flags"); + sd_write_uint32(buf, flags); } #define low_caps(X) ((u32) ((X) & 0xffffffff)) #define high_caps(X) ((u32) (((X) >> 32) & 0xffffffff)) allowed_caps = (profile->caps.allow) & ~profile->caps.deny; - if (!sd_write32(p, low_caps(allowed_caps))) - return 0; - if (!sd_write32(p, low_caps(allowed_caps & profile->caps.audit))) - return 0; - if (!sd_write32(p, low_caps(profile->caps.deny & profile->caps.quiet))) - return 0; - if (!sd_write32(p, 0)) - return 0; - - if (!sd_write_struct(p, "caps64")) - return 0; - if (!sd_write32(p, high_caps(allowed_caps))) - return 0; - if (!sd_write32(p, high_caps(allowed_caps & profile->caps.audit))) - return 0; - if (!sd_write32(p, high_caps(profile->caps.deny & profile->caps.quiet))) - return 0; - if (!sd_write32(p, 0)) - return 0; - if (!sd_write_structend(p)) - return 0; + sd_write_uint32(buf, low_caps(allowed_caps)); + sd_write_uint32(buf, low_caps(allowed_caps & profile->caps.audit)); + sd_write_uint32(buf, low_caps(profile->caps.deny & profile->caps.quiet)); + sd_write_uint32(buf, 0); + + sd_write_struct(buf, "caps64"); + sd_write_uint32(buf, high_caps(allowed_caps)); + sd_write_uint32(buf, high_caps(allowed_caps & profile->caps.audit)); + sd_write_uint32(buf, high_caps(profile->caps.deny & profile->caps.quiet)); + sd_write_uint32(buf, 0); + sd_write_structend(buf); - if (!sd_serialize_rlimits(p, &profile->rlimits)) - return 0; + sd_serialize_rlimits(buf, &profile->rlimits); if (profile->net.allow && kernel_supports_network) { size_t i; - if (!sd_write_array(p, "net_allowed_af", get_af_max())) - return 0; + sd_write_array(buf, "net_allowed_af", get_af_max()); for (i = 0; i < get_af_max(); i++) { - u16 allowed = profile->net.allow[i] & - ~profile->net.deny[i]; - if (!sd_write16(p, allowed)) - return 0; - if (!sd_write16(p, allowed & profile->net.audit[i])) - return 0; - if (!sd_write16(p, profile->net.deny[i] & profile->net.quiet[i])) - return 0; + u16 allowed = profile->net.allow[i] & + ~profile->net.deny[i]; + sd_write_uint16(buf, allowed); + sd_write_uint16(buf, allowed & profile->net.audit[i]); + sd_write_uint16(buf, profile->net.deny[i] & profile->net.quiet[i]); } - if (!sd_write_arrayend(p)) - return 0; + sd_write_arrayend(buf); } else if (profile->net.allow) pwarn(_("profile %s network rules not enforced\n"), profile->name); if (profile->policy.dfa) { - if (!sd_write_struct(p, "policydb")) - return 0; - if (!sd_serialize_dfa(p, profile->policy.dfa, profile->policy.size)) - return 0; - if (!sd_write_structend(p)) - return 0; + sd_write_struct(buf, "policydb"); + sd_serialize_dfa(buf, profile->policy.dfa, profile->policy.size); + sd_write_structend(buf); } /* either have a single dfa or lists of different entry types */ - if (!sd_serialize_dfa(p, profile->dfa.dfa, profile->dfa.size)) - return 0; - - if (!sd_serialize_xtable(p, profile->exec_table)) - return 0; + sd_serialize_dfa(buf, profile->dfa.dfa, profile->dfa.size); + sd_serialize_xtable(buf, profile->exec_table); - if (!sd_write_structend(p)) - return 0; - - return 1; + sd_write_structend(buf); } -int sd_serialize_top_profile(sd_serialize *p, Profile *profile) +void sd_serialize_top_profile(std::ostringstream &buf, Profile *profile) { uint32_t version; version = ENCODE_VERSION(force_complain, policy_version, parser_abi_version, kernel_abi_version); - if (!sd_write_name(p, "version")) - return 0; - - if (!sd_write32(p, version)) - return 0; + sd_write_name(buf, "version"); + sd_write_uint32(buf, version); if (profile_ns) { - if (!sd_write_string(p, profile_ns, "namespace")) - return 0; + sd_write_string(buf, profile_ns, "namespace"); } else if (profile->ns) { - if (!sd_write_string(p, profile->ns, "namespace")) - return 0; + sd_write_string(buf, profile->ns, "namespace"); } - return sd_serialize_profile(p, profile, profile->parent ? 1 : 0); + sd_serialize_profile(buf, profile, profile->parent ? 1 : 0); } int cache_fd = -1; @@ -694,7 +492,7 @@ { int fd = -1; int error = -ENOMEM, size, wsize; - sd_serialize *work_area; + std::ostringstream work_area; char *filename = NULL; switch (option) { @@ -782,26 +580,12 @@ if (prof->parent || ns) free(name); } else { + sd_serialize_top_profile(work_area, prof); - work_area = alloc_sd_serial(); - if (!work_area) { - close(fd); - PERROR(_("unable to create work area\n")); - error = -ENOMEM; - goto exit; - } - - if (!sd_serialize_top_profile(work_area, prof)) { - close(fd); - free_sd_serial(work_area); - PERROR(_("unable to serialize profile %s\n"), - prof->name); - goto exit; - } - - size = (long) (work_area->pos) - (long)(work_area->buffer); + size = (long) work_area.tellp(); if (kernel_load || option == OPTION_STDOUT || option == OPTION_OFILE) { - wsize = write(fd, work_area->buffer, size); + std::string tmp = work_area.str(); + wsize = write(fd, tmp.c_str(), size); if (wsize < 0) { error = -errno; } else if (wsize < size) { @@ -811,7 +595,8 @@ } } if (cache_fd != -1) { - wsize = write(cache_fd, work_area->buffer, size); + std::string tmp = work_area.str(); + wsize = write(cache_fd, tmp.c_str(), size); if (wsize < 0) { error = -errno; } else if (wsize < size) { @@ -820,7 +605,6 @@ error = -EIO; } } - free_sd_serial(work_area); } close(fd); --- 2.9-test.orig/parser/parser_policy.c +++ 2.9-test/parser/parser_policy.c @@ -243,14 +243,10 @@ return load_policy_list(policy_list, option); } -int load_hats(sd_serialize *p, Profile *prof) +int load_hats(std::ostringstream &buf, Profile *prof) { for (ProfileList::iterator i = prof->hat_table.begin(); i != prof->hat_table.end(); i++) { - if (!sd_serialize_profile(p, *i, 0)) { - PERROR(_("ERROR in profile %s, failed to load\n"), - (*i)->name); - return -EINVAL; - } + sd_serialize_profile(buf, *i, 0); } return 0; -- AppArmor mailing list AppArmor@lists.ubuntu.com Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/apparmor debian/patches/libapparmor-mention-dbus-method-in-getcon-man.patch0000664000000000000000000000331512315045675022474 0ustar Description: Document D-Bus getcon method in aa_getcon man page . This patch should be submitted to upstream AppArmor after the AppArmor mediation patches are submitted to upstream D-Bus. Author: Tyler Hicks Forwarded: no Index: apparmor-2.8.0/libraries/libapparmor/doc/aa_getcon.pod =================================================================== --- apparmor-2.8.0.orig/libraries/libapparmor/doc/aa_getcon.pod 2013-09-05 10:44:00.363697315 -0700 +++ apparmor-2.8.0/libraries/libapparmor/doc/aa_getcon.pod 2013-09-05 11:55:34.719609188 -0700 @@ -28,6 +28,8 @@ aa_getcon, aa_gettaskcon - get task conf aa_getpeercon - get the confinement of a socket's other end (peer) +org.freedesktop.DBus.GetConnectionAppArmorSecurityContext - get the task confinement of a D-Bus connection's owner + =head1 SYNOPSIS B<#include Esys/apparmor.hE> @@ -46,6 +48,10 @@ B when compiling. +Additionally, a D-Bus method is available: + +B + =head1 DESCRIPTION The aa_getcon function gets the current AppArmor confinement context for the @@ -74,6 +80,11 @@ an allocated buffer. The aa_getprocattr_raw() is the backend for the aa_getprocattr function and does not handle buffer allocation. +The org.freedesktop.DBus.GetConnectionAppArmorSecurityContext() D-Bus method +gets the AppArmor confinement string associated with the unique connection +name. If D-Bus is not performing AppArmor mediation, the +org.freedesktop.DBus.Error.AppArmorSecurityContextUnknown error is returned. + =head1 RETURN VALUE On success size of data placed in the buffer is returned, this includes the debian/patches/fix-ppc-endian-ftbfs.patch0000664000000000000000000000504512315045675015560 0ustar Author: Steve Beattie Forwarded: Yes Subject: parser: use htoleXX functions instead of testing for endianess --- This patch applies on top of John's last submission. It makes use of the htoleXX() functions (see endian(3)) defined as part of endian.h (already included in parser_interface.c), instead of defining a function differently based on the detection of endian related macros. This fixes a build failure experienced on powerpc with John's patch set applied. Signed-off-by: Steve Beattie --- parser/parser.h | 15 ++++++--------- parser/parser_interface.c | 3 --- parser/parser_main.c | 6 +----- 3 files changed, 7 insertions(+), 17 deletions(-) Index: b/parser/parser_interface.c =================================================================== --- a/parser/parser_interface.c +++ b/parser/parser_interface.c @@ -37,9 +37,6 @@ #include #include -/* only for x86 at the moment */ -#include -#include #include #define _(s) gettext(s) Index: b/parser/parser.h =================================================================== --- a/parser/parser.h +++ b/parser/parser.h @@ -23,9 +23,11 @@ #define __AA_PARSER_H +#include #include #include #include + #include "immunix.h" #include "libapparmor_re/apparmor_re.h" #include "libapparmor_re/aare_rules.h" @@ -258,15 +260,10 @@ #define u16 uint16_t #define u32 uint32_t #define u64 uint64_t -#if __BYTE_ORDER == __BIG_ENDIAN -# define cpu_to_le16(x) ((u16)(bswap_16 ((u16) x))) -# define cpu_to_le32(x) ((u32)(bswap_32 ((u32) x))) -# define cpu_to_le64(x) ((u64)(bswap_64 ((u64) x))) -#else -# define cpu_to_le16(x) ((u16)(x)) -# define cpu_to_le32(x) ((u32)(x)) -# define cpu_to_le64(x) ((u64)(x)) -#endif + +#define cpu_to_le16(x) ((u16)(htole16 ((u16) x))) +#define cpu_to_le32(x) ((u32)(htole32 ((u32) x))) +#define cpu_to_le64(x) ((u64)(htole64 ((u64) x))) /* The encoding for kernal abi > 5 is * 28-31: reserved Index: b/parser/parser_main.c =================================================================== --- a/parser/parser_main.c +++ b/parser/parser_main.c @@ -946,11 +946,7 @@ return rc; } -#if __BYTE_ORDER == __BIG_ENDIAN -# define le16_to_cpu(x) ((uint16_t)(bswap_16 (*(uint16_t *) x))) -#else -# define le16_to_cpu(x) (*(uint16_t *)(x)) -#endif +#define le16_to_cpu(x) ((uint16_t)(le16toh (*(uint16_t *) x))) const char header_string[] = "\004\010\000version\000\002"; #define HEADER_STRING_SIZE 12 debian/patches/fix-typo-in-dbus_write.patch0000664000000000000000000000145512315312536016176 0ustar Description: utils: Fix typo in write_dbus() . Signed-off-by: Tyler Hicks Acked-by: Steve Beattie Origin: commit, revision id: tyhicks@canonical.com-20140320191940-ygolw53q0oaqw3k0 Author: Tyler Hicks Last-Update: 2014-03-20 X-Bzr-Revision-Id: tyhicks@canonical.com-20140320191940-ygolw53q0oaqw3k0 === modified file 'utils/apparmor/aa.py' --- old/utils/apparmor/aa.py 2014-03-16 15:06:42 +0000 +++ new/utils/apparmor/aa.py 2014-03-20 19:19:40 +0000 @@ -3265,7 +3265,7 @@ def write_dbus(prof_data, depth): data = write_dbus_rules(prof_data, depth, 'deny') - data += write_net_rules(prof_data, depth, 'allow') + data += write_dbus_rules(prof_data, depth, 'allow') return data def write_link_rules(prof_data, depth, allow): debian/patches/fix-double-comma-in-preprocessor-output.patch0000664000000000000000000000143712315366262021471 0ustar Author: John Johansen Origin: https://lists.ubuntu.com/archives/apparmor/2014-March/005566.html Subject: Fix output of apparmor_parser -p having double comma For some rules the output of apparmor_parser -p has a double comma Eg. ptrace (tracedby), dbus (send,receive), is output as ptrace (tracedby),, dbus (send,receive),, Signed-off-by: John Johansen --- parser/parser_lex.l | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) --- 2.9-test.orig/parser/parser_lex.l +++ 2.9-test/parser/parser_lex.l @@ -604,7 +604,7 @@ { {END_OF_RULE} { if (YY_START != INITIAL) - POP(); + POP_NODUMP(); RETURN_TOKEN(TOK_END_OF_RULE); } debian/patches/add-decimal-interp.patch0000664000000000000000000001011712315045675015273 0ustar Author: John Johansen Forwarded: Yes Subject: cleanup/fix escape sequences in the backend and add support for \d the octal escape sequence was broken, so that short escapes \0, \00 \xa, didn't work and actually resulted in some encoding bugs. Also we were missing support for the decimal # conversion \d123 Signed-off-by: John Johansen --- parser/libapparmor_re/parse.y | 122 +++++++++++++++++++++++++++++------------- 1 file changed, 85 insertions(+), 37 deletions(-) --- 2.9-test.orig/parser/libapparmor_re/parse.y +++ 2.9-test/parser/libapparmor_re/parse.y @@ -156,29 +156,100 @@ %% +int isodigit(char c) +{ + return (c >= '0' && c <= '7') ? 1 : 0; +} + int octdigit(char c) { - if (c >= '0' && c <= '7') + if (isodigit(c)) + return c - '0'; + return -1; +} + +int decdigit(char c) +{ + if (isdigit(c)) return c - '0'; return -1; } int hexdigit(char c) { - if (c >= '0' && c <= '9') + if (isdigit(c)) return c - '0'; else if (c >= 'A' && c <= 'F') return 10 + c - 'A'; else if (c >= 'a' && c <= 'f') return 10 + c - 'a'; - else - return -1; + return -1; } -int regex_lex(YYSTYPE *val, const char **pos) +/* take the largest sequence of character that is in range of 0-255 + * - will consume at most 3 digits. + * - if a 3 digit sequence has value greater than 255 it will take + * the first 2 digits. + * eg. for the sequence \444, \44 will be taken as the octal number + * and the third 4 will not be consumed (ie pos will point to it) + */ +int convert_octseq(const char **pos) { - int c; + int val, c; + + for (val = 0; (c = octdigit(**pos)) >= 0; (*pos)++) { + int tmp = (val << 3) + c; + if (tmp > 255) + break; + val = tmp; + } + + return val; +} + +/* take the largest sequence of character that is in range of 0-255 + * - will consume at most 3 digits. + * - if a 3 digit sequence has value greater than 255 it will take + * the first 2 digits. + * eg. for the sequence \d444, \d44 will be taken as the decimal number + * and the third 4 will not be consumed (ie pos will point to it) + */ +int convert_decseq(const char **pos) +{ + int val, c; + + for (val = 0; (c = decdigit(**pos)) >= 0; (*pos)++) { + int tmp = (val * 10) + c; + if (tmp > 255) + break; + val = tmp; + } + + return val; +} +/* take the largest sequence of character that is in range of 0-255 + * - will consume at most 2 digits. + * - if there is not two valid hex characters only the first will be taken + * eg. for the sequence \x4z, \x4 will be taken as the hex number + */ +int convert_hexseq(const char **pos) +{ + int val, c; + + for (val = 0; (c = hexdigit(**pos)) >= 0; (*pos)++) { + int tmp = (val << 4) + c; + if (tmp > 255) + break; + val = tmp; + } + + return val; +} + + +int regex_lex(YYSTYPE *val, const char **pos) +{ val->c = **pos; switch(*(*pos)++) { case '\0': @@ -191,6 +262,11 @@ case '\\': val->c = **pos; + if (isodigit(**pos)) { + val->c = convert_octseq(pos); + break; + } + switch(*(*pos)++) { case '\0': (*pos)--; @@ -198,55 +274,27 @@ case '\\': val->c = '\\'; break; - - case '0': - val->c = 0; - if ((c = octdigit(**pos)) >= 0) { - val->c = c; - (*pos)++; - } - if ((c = octdigit(**pos)) >= 0) { - val->c = (val->c << 3) + c; - (*pos)++; - } - if ((c = octdigit(**pos)) >= 0) { - val->c = (val->c << 3) + c; - (*pos)++; - } + case 'd': + val->c = convert_decseq(pos); break; - case 'x': - val->c = 0; - if ((c = hexdigit(**pos)) >= 0) { - val->c = c; - (*pos)++; - } - if ((c = hexdigit(**pos)) >= 0) { - val->c = (val->c << 4) + c; - (*pos)++; - } + val->c = convert_hexseq(pos); break; - case 'a': val->c = '\a'; break; - case 'e': val->c = 033 /* ESC */; break; - case 'f': val->c = '\f'; break; - case 'n': val->c = '\n'; break; - case 'r': val->c = '\r'; break; - case 't': val->c = '\t'; break; -- AppArmor mailing list AppArmor@lists.ubuntu.com Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/apparmor debian/patches/python-utils-pivot_root-support.patch0000664000000000000000000003201212317337306020236 0ustar Author: Tyler Hicks Origin: https://lists.ubuntu.com/archives/apparmor/2014-April/005602.html Bug-Ubuntu: https://bugs.launchpad.net/bugs/1298678 Subject: utils: Basic support for pivot_root rules This patch does bare bones parsing of pivot_root rules and stores the raw strings for writing them out later. It is meant to be a simple change to prevent aa.py from emitting a traceback when encountering pivot_root rules. Signed-off-by: Tyler Hicks Index: ipc-fixes-and-improvements/utils/apparmor/aa.py =================================================================== --- ipc-fixes-and-improvements.orig/utils/apparmor/aa.py 2014-04-03 12:58:24.104545313 -0500 +++ ipc-fixes-and-improvements/utils/apparmor/aa.py 2014-04-03 12:58:24.100545313 -0500 @@ -2626,6 +2626,7 @@ RE_PROFILE_DBUS = re.compile('^\s*(audit RE_PROFILE_MOUNT = re.compile('^\s*(audit\s+)?(allow\s+|deny\s+)?((mount|remount|umount)[^#]*\s*,)\s*(#.*)?$') RE_PROFILE_SIGNAL = re.compile('^\s*(audit\s+)?(allow\s+|deny\s+)?((signal)[^#]*\s*,)\s*(#.*)?$') RE_PROFILE_PTRACE = re.compile('^\s*(audit\s+)?(allow\s+|deny\s+)?((ptrace)[^#]*\s*,)\s*(#.*)?$') +RE_PROFILE_PIVOT_ROOT = re.compile('^\s*(audit\s+)?(allow\s+|deny\s+)?((pivot_root)[^#]*\s*,)\s*(#.*)?$') # match anything that's not " or #, or matching quotes with anything except quotes inside __re_no_or_quoted_hash = '([^#"]|"[^"]*")*' @@ -2706,6 +2707,7 @@ def parse_profile_data(data, file, do_in profile_data[profile][hat]['allow']['mount'] = list() profile_data[profile][hat]['allow']['signal'] = list() profile_data[profile][hat]['allow']['ptrace'] = list() + profile_data[profile][hat]['allow']['pivot_root'] = list() # Save the initial comment if initial_comment: profile_data[profile][hat]['initial_comment'] = initial_comment @@ -3110,6 +3112,28 @@ def parse_profile_data(data, file, do_in ptrace_rules.append(ptrace_rule) profile_data[profile][hat][allow]['ptrace'] = ptrace_rules + elif RE_PROFILE_PIVOT_ROOT.search(line): + matches = RE_PROFILE_PIVOT_ROOT.search(line).groups() + + if not profile: + raise AppArmorException(_('Syntax Error: Unexpected ptrace entry found in file: %s line: %s') % (file, lineno + 1)) + + audit = False + if matches[0]: + audit = True + allow = 'allow' + if matches[1] and matches[1].strip() == 'deny': + allow = 'deny' + pivot_root = matches[2].strip() + + pivot_root_rule = parse_pivot_root_rule(pivot_root) + pivot_root_rule.audit = audit + pivot_root_rule.deny = (allow == 'deny') + + pivot_root_rules = profile_data[profile][hat][allow].get('pivot_root', list()) + pivot_root_rules.append(pivot_root_rule) + profile_data[profile][hat][allow]['pivot_root'] = pivot_root_rules + elif RE_PROFILE_CHANGE_HAT.search(line): matches = RE_PROFILE_CHANGE_HAT.search(line).groups() @@ -3216,6 +3240,10 @@ def parse_ptrace_rule(line): # XXX Do real parsing here return aarules.Raw_Ptrace_Rule(line) +def parse_pivot_root_rule(line): + # XXX Do real parsing here + return aarules.Raw_Pivot_Root_Rule(line) + def separate_vars(vs): """Returns a list of all the values for a variable""" data = [] @@ -3481,6 +3509,24 @@ def write_ptrace(prof_data, depth): data += write_ptrace_rules(prof_data, depth, 'allow') return data +def write_pivot_root_rules(prof_data, depth, allow): + pre = ' ' * depth + data = [] + + # no pivot_root rules, so return + if not prof_data[allow].get('pivot_root', False): + return data + + for pivot_root_rule in prof_data[allow]['pivot_root']: + data.append('%s%s' % (pre, pivot_root_rule.serialize())) + data.append('') + return data + +def write_pivot_root(prof_data, depth): + data = write_pivot_root_rules(prof_data, depth, 'deny') + data += write_pivot_root_rules(prof_data, depth, 'allow') + return data + def write_link_rules(prof_data, depth, allow): pre = ' ' * depth data = [] @@ -3589,6 +3635,7 @@ def write_rules(prof_data, depth): data += write_mount(prof_data, depth) data += write_signal(prof_data, depth) data += write_ptrace(prof_data, depth) + data += write_pivot_root(prof_data, depth) data += write_links(prof_data, depth) data += write_paths(prof_data, depth) data += write_change_profile(prof_data, depth) @@ -3740,6 +3787,7 @@ def serialize_profile_from_old_profile(p 'mount': write_mount, 'signal': write_signal, 'ptrace': write_ptrace, + 'pivot_root': write_pivot_root, 'link': write_links, 'path': write_paths, 'change_profile': write_change_profile, @@ -3834,6 +3882,7 @@ def serialize_profile_from_old_profile(p data += write_mount(write_prof_data[name], depth) data += write_signal(write_prof_data[name], depth) data += write_ptrace(write_prof_data[name], depth) + data += write_pivot_root(write_prof_data[name], depth) data += write_links(write_prof_data[name], depth) data += write_paths(write_prof_data[name], depth) data += write_change_profile(write_prof_data[name], depth) Index: ipc-fixes-and-improvements/utils/apparmor/rules.py =================================================================== --- ipc-fixes-and-improvements.orig/utils/apparmor/rules.py 2014-04-03 12:58:24.104545313 -0500 +++ ipc-fixes-and-improvements/utils/apparmor/rules.py 2014-04-03 12:58:24.100545313 -0500 @@ -91,3 +91,15 @@ class Raw_Ptrace_Rule(object): return "%s%s%s" % ('audit ' if self.audit else '', 'deny ' if self.deny else '', self.rule) + +class Raw_Pivot_Root_Rule(object): + audit = False + deny = False + + def __init__(self, rule): + self.rule = rule + + def serialize(self): + return "%s%s%s" % ('audit ' if self.audit else '', + 'deny ' if self.deny else '', + self.rule) Index: ipc-fixes-and-improvements/utils/test/test-pivot_root_parse.py =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ ipc-fixes-and-improvements/utils/test/test-pivot_root_parse.py 2014-04-03 12:58:24.100545313 -0500 @@ -0,0 +1,36 @@ +#! /usr/bin/env python +# ------------------------------------------------------------------ +# +# Copyright (C) 2014 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. +# +# ------------------------------------------------------------------ + +import apparmor.aa as aa +import unittest + +class AAParsePivotRootTest(unittest.TestCase): + + def _test_parse_pivot_root_rule(self, rule): + pivot_root = aa.parse_pivot_root_rule(rule) + print(pivot_root.serialize()) + self.assertEqual(rule, pivot_root.serialize(), + 'pivot_root object returned "%s", expected "%s"' % (pivot_root.serialize(), rule)) + + def test_parse_plain_pivot_root_rule(self): + self._test_parse_pivot_root_rule('pivot_root,') + + def test_parse_old_pivot_root_rule(self): + self._test_parse_pivot_root_rule('pivot_root /old,') + + def test_parse_new_pivot_root_rule(self): + self._test_parse_pivot_root_rule('pivot_root /old /new,') + + def test_parse_child_pivot_root_rule(self): + self._test_parse_pivot_root_rule('pivot_root /old /new -> /usr/bin/child,') + +if __name__ == '__main__': + unittest.main() Index: ipc-fixes-and-improvements/utils/test/test-regex_matches.py =================================================================== --- ipc-fixes-and-improvements.orig/utils/test/test-regex_matches.py 2014-04-03 12:58:24.104545313 -0500 +++ ipc-fixes-and-improvements/utils/test/test-regex_matches.py 2014-04-03 12:58:24.100545313 -0500 @@ -53,6 +53,11 @@ regex_has_comma_testcases = [ ('ptrace (tracedby, readby)%s', 'embedded parens ptrace 01'), ('ptrace (trace) peer=/usr/bin/foo%s', 'embedded parens ptrace 02'), + ('pivot_root%s', 'bare pivot_root'), + ('pivot_root /old%s', 'pivot_root with old'), + ('pivot_root /old new%s', 'pivot_root with new'), + ('pivot_root /old /new -> child%s', 'pivot_root with child'), + # the following fail due to inadequacies in the regex # ('dbus (r, w, %s', 'incomplete dbus action'), # ('member="{Hello,AddMatch,RemoveMatch, %s', 'incomplete {} regex'), # also invalid policy @@ -113,6 +118,8 @@ regex_split_comment_testcases = [ ('signal receive set=(usr1 usr2) peer=foo,', False), ('ptrace, # comment', ('ptrace, ', '# comment')), ('ptrace (trace read) peer=/usr/bin/foo,', False), + ('pivot_root, # comment', ('pivot_root, ', '# comment')), + ('pivot_root /old /new -> child,', False), ] def setup_split_comment_testcases(): @@ -399,6 +406,77 @@ class AARegexPtrace(unittest.TestCase): self.assertEqual(parsed, rule, 'Expected ptrace rule "%s", got "%s"' % (rule, parsed)) +class AARegexPivotRoot(unittest.TestCase): + '''Tests for RE_PROFILE_PIVOT_ROOT''' + + def test_bare_pivot_root_01(self): + '''test ' pivot_root,' ''' + + rule = 'pivot_root,' + line = ' %s' % rule + result = aa.RE_PROFILE_PIVOT_ROOT.search(line) + self.assertTrue(result, 'Couldn\'t find pivot_root rule in "%s"' % line) + parsed = result.groups()[2].strip() + self.assertEqual(parsed, rule, 'Expected pivot_root rule "%s", got "%s"' + % (rule, parsed)) + + def test_bare_pivot_root_02(self): + '''test ' audit pivot_root,' ''' + + rule = 'pivot_root,' + line = ' audit %s' % rule + result = aa.RE_PROFILE_PIVOT_ROOT.search(line) + self.assertTrue(result, 'Couldn\'t find pivot_root rule in "%s"' % line) + self.assertTrue(result.groups()[0], 'Couldn\'t find audit modifier in "%s"' % line) + parsed = result.groups()[2].strip() + self.assertEqual(parsed, rule, 'Expected pivot_root rule "%s", got "%s"' + % (rule, parsed)) + + def test_old_pivot_root_01(self): + '''test ' pivot_root /old,' ''' + + rule = 'pivot_root /old,' + line = ' %s' % rule + result = aa.RE_PROFILE_PIVOT_ROOT.search(line) + self.assertTrue(result, 'Couldn\'t find pivot_root rule in "%s"' % line) + parsed = result.groups()[2].strip() + self.assertEqual(parsed, rule, 'Expected pivot_root rule "%s", got "%s"' + % (rule, parsed)) + + def test_new_pivot_root_01(self): + '''test ' pivot_root /old /new,' ''' + + rule = 'pivot_root /old /new,' + line = ' %s' % rule + result = aa.RE_PROFILE_PIVOT_ROOT.search(line) + self.assertTrue(result, 'Couldn\'t find pivot_root rule in "%s"' % line) + parsed = result.groups()[2].strip() + self.assertEqual(parsed, rule, 'Expected pivot_root rule "%s", got "%s"' + % (rule, parsed)) + + def test_child_pivot_root_01(self): + '''test ' pivot_root /old /new -> child,' ''' + + rule = 'pivot_root /old /new -> child,' + line = ' %s' % rule + result = aa.RE_PROFILE_PIVOT_ROOT.search(line) + self.assertTrue(result, 'Couldn\'t find pivot_root rule in "%s"' % line) + parsed = result.groups()[2].strip() + self.assertEqual(parsed, rule, 'Expected pivot_root rule "%s", got "%s"' + % (rule, parsed)) + + def test_child_pivot_root_02(self): + '''test ' audit pivot_root /old /new -> child,' ''' + + rule = 'pivot_root /old /new -> child,' + line = ' audit %s' % rule + result = aa.RE_PROFILE_PIVOT_ROOT.search(line) + self.assertTrue(result, 'Couldn\'t find pivot_root rule in "%s"' % line) + self.assertTrue(result.groups()[0], 'Couldn\'t find audit modifier in "%s"' % line) + parsed = result.groups()[2].strip() + self.assertEqual(parsed, rule, 'Expected pivot_root rule "%s", got "%s"' + % (rule, parsed)) + if __name__ == '__main__': verbosity = 2 @@ -412,6 +490,7 @@ if __name__ == '__main__': test_suite.addTest(unittest.TestLoader().loadTestsFromTestCase(AARegexFile)) test_suite.addTest(unittest.TestLoader().loadTestsFromTestCase(AARegexSignal)) test_suite.addTest(unittest.TestLoader().loadTestsFromTestCase(AARegexPtrace)) + test_suite.addTest(unittest.TestLoader().loadTestsFromTestCase(AARegexPivotRoot)) result = unittest.TextTestRunner(verbosity=verbosity).run(test_suite) if not result.wasSuccessful(): exit(1) debian/patches/test-v6-policy.patch0000664000000000000000000001076112315312536014453 0ustar Description: tests: Update the regression tests for v6 policy . This updates the regression tests for v6 policy. It refactors the required_features test into a have_features fn, and a new requires_features fn (renamed to catch all instances make sure they where right) . The have_features fn is then applied to several test to make them conditionally apply based off of availability of the feature and policy version. . Signed-off-by: John Johansen Acked-by: Tyler Hicks Origin: commit, revision id: tyhicks@canonical.com-20140327020859-njwpwlyvqjbrurvl Author: John Johansen Last-Update: 2014-03-27 X-Bzr-Revision-Id: tyhicks@canonical.com-20140327020859-njwpwlyvqjbrurvl === modified file 'tests/regression/apparmor/dbus_eavesdrop.sh' --- old/tests/regression/apparmor/dbus_eavesdrop.sh 2013-12-06 19:19:33 +0000 +++ new/tests/regression/apparmor/dbus_eavesdrop.sh 2014-03-27 02:08:59 +0000 @@ -18,7 +18,7 @@ bin=$pwd . $bin/prologue.inc -required_features dbus +requires_features dbus . $bin/dbus.inc args="--session" === modified file 'tests/regression/apparmor/dbus_message.sh' --- old/tests/regression/apparmor/dbus_message.sh 2013-08-29 19:34:13 +0000 +++ new/tests/regression/apparmor/dbus_message.sh 2014-03-27 02:08:59 +0000 @@ -18,7 +18,7 @@ bin=$pwd . $bin/prologue.inc -required_features dbus +requires_features dbus . $bin/dbus.inc listnames="--type=method_call --session --name=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.ListNames" === modified file 'tests/regression/apparmor/dbus_service.sh' --- old/tests/regression/apparmor/dbus_service.sh 2013-08-20 19:14:03 +0000 +++ new/tests/regression/apparmor/dbus_service.sh 2014-03-27 02:08:59 +0000 @@ -17,7 +17,7 @@ bin=$pwd . $bin/prologue.inc -required_features dbus +requires_features dbus . $bin/dbus.inc service="--$bus --name=$dest $path $iface" === modified file 'tests/regression/apparmor/prologue.inc' --- old/tests/regression/apparmor/prologue.inc 2013-09-28 00:33:09 +0000 +++ new/tests/regression/apparmor/prologue.inc 2014-03-27 02:08:59 +0000 @@ -21,19 +21,32 @@ # # For this file, functions are first, entry point code is at end, see "MAIN" -required_features() +#use $() to retreive the failure message or "true" if success +have_features() { if [ ! -e "/sys/kernel/security/apparmor/features/" ] ; then - echo "Kernel feature masks not supported. Skipping tests ..." - exit 0 + echo "Kernel feature masks not supported." + return 1; fi for f in $@ ; do if [ ! -e "/sys/kernel/security/apparmor/features/$f" ] ; then - echo "Required feature $f not available. Skipping tests ..." - exit 0 + echo "Required feature '$f' not available." + return 2; fi done + + echo "true" + return 0; +} + +requires_features() +{ + local res=$(have_features $@) + if [ "$res" != "true" ] ; then + echo "$res. Skipping tests ..." + exit 0 + fi } requires_query_interface() === modified file 'tests/regression/apparmor/tcp.sh' --- old/tests/regression/apparmor/tcp.sh 2011-03-02 13:02:45 +0000 +++ new/tests/regression/apparmor/tcp.sh 2014-03-27 02:08:59 +0000 @@ -15,6 +15,7 @@ bin=$pwd . $bin/prologue.inc +requires_features network port=34567 ip="127.0.0.1" === modified file 'tests/regression/apparmor/unix_fd_server.sh' --- old/tests/regression/apparmor/unix_fd_server.sh 2013-10-29 17:35:51 +0000 +++ new/tests/regression/apparmor/unix_fd_server.sh 2014-03-27 02:08:59 +0000 @@ -132,10 +132,12 @@ sleep 1 rm -f ${socket} -# FAIL - confined client, no access to the socket file - -genprofile $file:$okperm $socket:rw $fd_client:px -- image=$fd_client $file:$okperm -runchecktest "fd passing; confined client w/o socket access" fail $file $socket $fd_client - -sleep 1 -rm -f ${socket} +if [ "$(have_features policy/versions/v6)" == "true" ] ; then + # FAIL - confined client, no access to the socket file + + genprofile $file:$okperm $socket:rw $fd_client:px -- image=$fd_client $file:$okperm + runchecktest "fd passing; confined client w/o socket access" fail $file $socket $fd_client + + sleep 1 + rm -f ${socket} +fi === modified file 'tests/regression/apparmor/unix_socket_file.sh' --- old/tests/regression/apparmor/unix_socket_file.sh 2013-10-29 17:35:51 +0000 +++ new/tests/regression/apparmor/unix_socket_file.sh 2014-03-27 02:08:59 +0000 @@ -27,6 +27,7 @@ bin=$pwd . $bin/prologue.inc +requires_features policy/versions/v6 client=$bin/unix_socket_file_client socket=${tmpdir}/unix_socket_file.sock debian/patches/use-diff-encode.patch0000664000000000000000000000415312315045675014610 0ustar Author: John Johansen Forwarded: Yes Subject: Turn on diff-encoding if the kernel supports it Signed-off-by: John Johansen --- parser/parser.h | 1 + parser/parser_common.c | 3 ++- parser/parser_main.c | 6 ++++++ 3 files changed, 9 insertions(+), 1 deletion(-) --- 2.9-test.orig/parser/parser.h +++ 2.9-test/parser/parser.h @@ -298,6 +298,7 @@ extern int kernel_load; extern int kernel_supports_network; extern int kernel_supports_policydb; +extern int kernel_supports_diff_encode; extern int kernel_supports_mount; extern int kernel_supports_dbus; extern int conf_verbose; --- 2.9-test.orig/parser/parser_common.c +++ 2.9-test/parser/parser_common.c @@ -70,13 +70,14 @@ int kernel_supports_policydb = 0; /* kernel supports new policydb */ int kernel_supports_mount = 0; /* kernel supports mount rules */ int kernel_supports_dbus = 0; /* kernel supports dbus rules */ +int kernel_supports_diff_encode = 0; /* kernel supports diff_encode */ int conf_verbose = 0; int conf_quiet = 0; int names_only = 0; int current_lineno = 1; int option = OPTION_ADD; -dfaflags_t dfaflags = (dfaflags_t)(DFA_CONTROL_TREE_NORMAL | DFA_CONTROL_TREE_SIMPLE | DFA_CONTROL_MINIMIZE ); +dfaflags_t dfaflags = (dfaflags_t)(DFA_CONTROL_TREE_NORMAL | DFA_CONTROL_TREE_SIMPLE | DFA_CONTROL_MINIMIZE | DFA_CONTROL_DIFF_ENCODE); char *subdomainbase = NULL; const char *progname = __FILE__; --- 2.9-test.orig/parser/parser_main.c +++ 2.9-test/parser/parser_main.c @@ -306,6 +306,7 @@ return 1; } } + return 0; } @@ -847,6 +848,11 @@ kernel_supports_mount = 1; if (strstr(features_string, "dbus")) kernel_supports_dbus = 1; + if (strstr(features_string, "diff_encode")) + kernel_supports_diff_encode = 1; + else if (dfaflags & DFA_CONTROL_DIFF_ENCODE) + /* clear diff_encode because it is not supported */ + dfaflags &= ~DFA_CONTROL_DIFF_ENCODE; } int process_binary(int option, const char *profilename) -- AppArmor mailing list AppArmor@lists.ubuntu.com Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/apparmor debian/patches/increase-swap-size.patch0000664000000000000000000000235712315312536015361 0ustar Description: regression swap test: 640 KiB not enough swap for everyone . On ppc64el platforms, the minimum swapfile size is 640KiB. Our swap test aborts there because it creates a swapfile of size 512KiB. This patch adjusts the size to 768KiB, to satisfy ppc64el and to try to keep the size down for embedded and otherwise limited platforms (e.g. phones). . Signed-off-by: Steve Beattie Acked-by: John Johansen Origin: commit, revision id: sbeattie@ubuntu.com-20140320182851-iwz354gzejfxr3x6 Author: Steve Beattie Last-Update: 2014-03-20 X-Bzr-Revision-Id: sbeattie@ubuntu.com-20140320182851-iwz354gzejfxr3x6 === modified file 'tests/regression/apparmor/swap.sh' --- old/tests/regression/apparmor/swap.sh 2014-03-19 18:53:26 +0000 +++ new/tests/regression/apparmor/swap.sh 2014-03-20 18:28:51 +0000 @@ -29,7 +29,9 @@ swap_file=$tmpdir/swapfile -dd if=/dev/zero of=${swap_file} bs=1024 count=512 2> /dev/null +# ppc64el wants this to be larger than 640KiB +# arm/small machines want this as small as possible +dd if=/dev/zero of=${swap_file} bs=1024 count=768 2> /dev/null /sbin/mkswap -f ${swap_file} > /dev/null # TEST 1. Make sure can enable and disable swap unconfined debian/patches/fix-failpath.patch0000664000000000000000000000147712315045675014235 0ustar Author: John Johansen Forwarded: Yes Subject: fix failure paths around policy that can result in a crash Signed-off-by: John Johansen --- parser/parser_regex.c | 6 ++++++ 1 file changed, 6 insertions(+) --- 2.9-test.orig/parser/parser_regex.c +++ 2.9-test/parser/parser_regex.c @@ -712,6 +712,9 @@ prof->policy.rules = NULL; if (!prof->policy.dfa) goto out; + } else { + aare_delete_ruleset(prof->policy.rules); + prof->policy.rules = NULL; } aare_reset_matchflags(); @@ -719,6 +722,9 @@ error = 0; out: + aare_delete_ruleset(prof->policy.rules); + prof->policy.rules = NULL; + return error; } -- AppArmor mailing list AppArmor@lists.ubuntu.com Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/apparmor debian/patches/aa-utils_are_bilingual.patch0000664000000000000000000001041412315045675016244 0ustar Author: Jamie Strandboge Description: aa-status was written to work with python 2 or 3. Upstream is still using 2, so adjust ours to use /usr/bin/python3 to avoid pulling python 2 back to the desktop images Forwarded: no --- utils/aa-audit | 2 +- utils/aa-autodep | 2 +- utils/aa-cleanprof | 2 +- utils/aa-complain | 2 +- utils/aa-disable | 2 +- utils/aa-enforce | 2 +- utils/aa-genprof | 2 +- utils/aa-logprof | 2 +- utils/aa-mergeprof | 2 +- utils/aa-status | 2 +- utils/aa-unconfined | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) Index: b/utils/aa-status =================================================================== --- a/utils/aa-status +++ b/utils/aa-status @@ -1,4 +1,4 @@ -#! /usr/bin/env python +#!/usr/bin/python3 # ------------------------------------------------------------------ # # Copyright (C) 2005-2006 Novell/SUSE Index: b/utils/aa-audit =================================================================== --- a/utils/aa-audit +++ b/utils/aa-audit @@ -1,4 +1,4 @@ -#! /usr/bin/env python +#!/usr/bin/python3 # ---------------------------------------------------------------------- # Copyright (C) 2013 Kshitij Gupta # Index: b/utils/aa-autodep =================================================================== --- a/utils/aa-autodep +++ b/utils/aa-autodep @@ -1,4 +1,4 @@ -#! /usr/bin/env python +#!/usr/bin/python3 # ---------------------------------------------------------------------- # Copyright (C) 2013 Kshitij Gupta # Index: b/utils/aa-cleanprof =================================================================== --- a/utils/aa-cleanprof +++ b/utils/aa-cleanprof @@ -1,4 +1,4 @@ -#! /usr/bin/env python +#!/usr/bin/python3 # ---------------------------------------------------------------------- # Copyright (C) 2013 Kshitij Gupta # Index: b/utils/aa-complain =================================================================== --- a/utils/aa-complain +++ b/utils/aa-complain @@ -1,4 +1,4 @@ -#! /usr/bin/env python +#!/usr/bin/python3 # ---------------------------------------------------------------------- # Copyright (C) 2013 Kshitij Gupta # Index: b/utils/aa-disable =================================================================== --- a/utils/aa-disable +++ b/utils/aa-disable @@ -1,4 +1,4 @@ -#! /usr/bin/env python +#!/usr/bin/python3 # ---------------------------------------------------------------------- # Copyright (C) 2013 Kshitij Gupta # Index: b/utils/aa-enforce =================================================================== --- a/utils/aa-enforce +++ b/utils/aa-enforce @@ -1,4 +1,4 @@ -#! /usr/bin/env python +#!/usr/bin/python3 # ---------------------------------------------------------------------- # Copyright (C) 2013 Kshitij Gupta # Index: b/utils/aa-genprof =================================================================== --- a/utils/aa-genprof +++ b/utils/aa-genprof @@ -1,4 +1,4 @@ -#! /usr/bin/env python +#!/usr/bin/python3 # ---------------------------------------------------------------------- # Copyright (C) 2013 Kshitij Gupta # Index: b/utils/aa-logprof =================================================================== --- a/utils/aa-logprof +++ b/utils/aa-logprof @@ -1,4 +1,4 @@ -#! /usr/bin/env python +#!/usr/bin/python3 # ---------------------------------------------------------------------- # Copyright (C) 2013 Kshitij Gupta # Index: b/utils/aa-mergeprof =================================================================== --- a/utils/aa-mergeprof +++ b/utils/aa-mergeprof @@ -1,4 +1,4 @@ -#! /usr/bin/env python +#!/usr/bin/python3 # ---------------------------------------------------------------------- # Copyright (C) 2013 Kshitij Gupta # Index: b/utils/aa-unconfined =================================================================== --- a/utils/aa-unconfined +++ b/utils/aa-unconfined @@ -1,4 +1,4 @@ -#! /usr/bin/env python +#!/usr/bin/python3 # ---------------------------------------------------------------------- # Copyright (C) 2013 Kshitij Gupta # debian/patches/manpage-signal-ptrace.patch0000664000000000000000000001451212317332371016004 0ustar Author: John Johansen , Jamie Strandboge Origin: https://lists.ubuntu.com/archives/apparmor/2014-April/005595.html Description: man page updates for signals, ptrace and new variables Acked-By: Jamie Strandboge Acked-by: John Johansen === modified file 'parser/apparmor.d.pod' --- a/parser/apparmor.d.pod 2013-12-06 19:18:17 +0000 +++ b/parser/apparmor.d.pod 2014-04-03 13:19:48 +0000 @@ -3,7 +3,7 @@ # 2008, 2009 # NOVELL (All rights reserved) # -# Copyright (c) 2010 - 2013 +# Copyright (c) 2010 - 2014 # Canonical Ltd. (All rights reserved) # # This program is free software; you can redistribute it and/or @@ -99,6 +99,32 @@ B = ( I | I ) ... +B = [ 'audit' ] [ 'deny' ] 'ptrace' [ I ] [ I ] + +B = I | I + +B = '(' Comma or space separated list of I ')' + +B = ( 'r' | 'w' | 'rw' | 'read' | 'readby' | 'trace' | 'tracedby' ) + +B = 'peer' '=' I + +B = [ 'audit' ] [ 'deny' ] 'signal' [ I ] [ I ] [ I ] + +B = I | I + +B = '(' Comma or space separated list of I ')' + +B = ( 'r' | 'w' | 'rw' | 'read' | 'write' | 'send' | 'receive' ) + +B = 'set' '=' '(' I ')' + +B = Comma or space separated list of I + +B = ( 'hup' | 'int' | 'quit' | 'ill' | 'trap' | 'abrt' | 'bus' | 'fpe' | 'kill' | 'usr1' | 'segv' | 'usr2' | 'pipe' | 'alrm' | 'term' | 'stkflt' | 'chld' | 'cont' | 'stop' | 'stp' | 'ttin' | 'ttou' | 'urg' | 'xcpu' | 'xfsz' | 'vtalrm' | 'prof' | 'winch' | 'io' | 'pwr' | 'sys' | 'emt' | 'exists' ) + +B = 'peer' '=' I + B = ( I | I | I | I ) B = [ 'audit' ] [ 'deny' ] 'dbus' [ I ] [ I ] [ I ] [ I ] [ I ] [ I ] @@ -655,6 +681,78 @@ =back +=head2 PTrace rules + +AppArmor supports mediation of ptrace(2). AppArmor PTrace rules are accumulated +so that the granted PTrace permissions are the union of all the listed PTrace +rule permissions. + +AppArmor PTrace permissions are implied when a rule does not explicitly state +an access list. By default, all PTrace permissions are implied. + +The trace and tracedby permissions govern ptrace(2) while read and readby +govern certain proc(5) filesystem accesses, kcmp(2), futexes +(get_robust_list(2)) and perf trace events. + +For a ptrace operation to be allowed the profile of the tracing process and the +profile of the target task must both have the correct permissions. For example, +the profile of the process attaching to another task must have the trace +permission for the target task's profile, and the task being traced must have +the tracedby permission for the tracing process' profile. + +Example AppArmor PTrace rules: + + # Allow all PTrace access + ptrace, + + # Explicitly allow all PTrace access, + ptrace (read, readby, trace, tracedby), + + # Explicitly deny use of ptrace(2) + deny ptrace (trace), + + # Allow unconfined processes (eg, a debugger) to ptrace us + ptrace (readby, tracedby) peer=unconfined, + + # Allow ptrace of a process running under the /usr/bin/foo profile + ptrace (trace) peer=/usr/bin/foo, + +=head2 Signal rules + +AppArmor supports mediation of signal(7). AppArmor signal rules are accumulated +so that the granted signal permissions are the union of all the listed signal +rule permissions. + +AppArmor signal permissions are implied when a rule does not explicitly state +an access list. By default, all signal permissions are implied. + +For the sending of a signal to be allowed, the profile of the sending process +and the profile of the target task must both have the correct permissions. For +example, the profile of a process sending a signal to another task must have +the send permission for the target task's profile, and the task receiving the +signal must have a receive permission for the sending process' profile. + +Example AppArmor signal rules: + + # Allow all signal access + signal, + + # Explicitly deny sending the HUP and INT signals + deny signal (send) set=(hup, int), + + # Allow unconfined processes to send us signals + signal (receive) peer=unconfined, + + # Allow sending of signals to a process running under the /usr/bin/foo + # profile + signal (send) peer=/usr/bin/foo, + + # Allow checking for PID existence + signal (receive, send) set=("exists"), + + # Allow us to signal ourselves using the built-in @{profile_name} variable + signal peer=@{profile_name}, + =head2 DBus rules AppArmor supports DBus mediation. The mediation is performed in conjunction @@ -725,11 +823,36 @@ that they have been assigned; it is an error to reference a variable without setting at least one value. -At the time of this writing, only B<@{HOME}> and B<@{HOMEDIRS}> are defined -in the AppArmor policy provided, in the F -file; these variables are used in many of the abstractions described later. +At the time of this writing, the following variables are defined in the +provided AppArmor policy: + + @{HOME} + @{HOMEDIRS} + @{multiarch} + @{pid} + @{PROC} + @{securityfs} + @{sys} + @{tid} + @{XDG_DESKTOP_DIR} + @{XDG_DOWNLOAD_DIR} + @{XDG_TEMPLATES_DIR} + @{XDG_PUBLICSHARE_DIR} + @{XDG_DOCUMENTS_DIR} + @{XDG_MUSIC_DIR} + @{XDG_PICTURES_DIR} + @{XDG_VIDEOS_DIR} + +These are defined in files in F and are used in many +of the abstractions described later. + You may also add files in F for -site-specific customization of B<@{HOMEDIRS}>. +site-specific customization of B<@{HOMEDIRS}>, +F for B<@{multiarch}> and +F for B<@{XDG_*}>. + +The special B<@{profile_name}> variable is set to the profile name and may be +used in all policy. =head2 Alias rules debian/patches/initialize-mount-flags.patch0000664000000000000000000000140612315312536016235 0ustar Subject: Initialize mount flag variables Author: Steve Beattie Origin: https://lists.ubuntu.com/archives/apparmor/2014-March/005498.html Index: apparmor-2.8.95~2430/parser/mount.c =================================================================== --- apparmor-2.8.95~2430.orig/parser/mount.c 2014-03-25 15:20:57.018085658 -0500 +++ apparmor-2.8.95~2430/parser/mount.c 2014-03-25 15:20:57.010085658 -0500 @@ -389,7 +389,7 @@ mnt_rule::mnt_rule(struct cond_entry *sr struct cond_entry *dst_conds __unused, char *mnt_point_p, int allow_p): mnt_point(mnt_point_p), device(device_p), trans(NULL), opts(NULL), - audit(0), deny(0) + flags(0), inv_flags(0), audit(0), deny(0) { /* FIXME: dst_conds are ignored atm */ aa_class = AA_CLASS_MOUNT; debian/patches/change-ptrace-syntax.patch0000664000000000000000000000357412315363521015677 0ustar Author: John Johansen Origin: https://lists.ubuntu.com/archives/apparmor/2014-March/005558.html Subject: change syntax of ptrace target change from ptrace /foo, to ptrace peer=/foo, Signed-off-by: John Johansen --- parser/parser_yacc.y | 7 +------ parser/ptrace.c | 13 ++++++++----- parser/ptrace.h | 2 +- 3 files changed, 10 insertions(+), 12 deletions(-) --- 2.9-test.orig/parser/parser_yacc.y +++ 2.9-test/parser/parser_yacc.y @@ -1349,12 +1349,7 @@ ptrace_rule: TOK_PTRACE opt_ptrace_perm opt_conds TOK_END_OF_RULE { - ptrace_rule *ent = new ptrace_rule($2, $3, NULL); - $$ = ent; - } - | TOK_PTRACE opt_ptrace_perm opt_conds TOK_ID TOK_END_OF_RULE - { - ptrace_rule *ent = new ptrace_rule($2, $3, $4); + ptrace_rule *ent = new ptrace_rule($2, $3); $$ = ent; } --- 2.9-test.orig/parser/ptrace.c +++ 2.9-test/parser/ptrace.c @@ -39,14 +39,17 @@ if (!cond_ent->eq) yyerror("keyword \"in\" is not allowed in ptrace rules\n"); - /* no valid conditionals atm */ - yyerror("invalid ptrace rule conditional \"%s\"\n", - cond_ent->name); + if (strcmp(cond_ent->name, "peer") == 0) { + move_conditional_value("ptrace", &peer_label, cond_ent); + } else { + yyerror("invalid ptrace rule conditional \"%s\"\n", + cond_ent->name); + } } } -ptrace_rule::ptrace_rule(int mode_p, struct cond_entry *conds, char *peer): - peer_label(peer), audit(0), deny(0) +ptrace_rule::ptrace_rule(int mode_p, struct cond_entry *conds): + peer_label(NULL), audit(0), deny(0) { if (mode_p) { if (mode_p & ~AA_VALID_PTRACE_PERMS) --- 2.9-test.orig/parser/ptrace.h +++ 2.9-test/parser/ptrace.h @@ -37,7 +37,7 @@ int audit; int deny; - ptrace_rule(int mode, struct cond_entry *conds, char *peer); + ptrace_rule(int mode, struct cond_entry *conds); virtual ~ptrace_rule() { free(peer_label); debian/patches/fix-garbage-in-preprocessor-output.patch0000664000000000000000000000254612315365764020525 0ustar Author: John Johansen Origin: https://lists.ubuntu.com/archives/apparmor/2014-March/005565.html Subject: Fix garbage characters in -p profile preprocessing output apparmor_parser -p is broken. Outputting garbage charcters after every include statement. eg. ##included ^@^@V>^?^@^@^NV>^?^@^@^Pu^@# ----------------------------------- ------------------------------- # This is happening because includes are handled specially and should not go through the usual preprocessing output dump. Signed-off-by: John Johansen --- parser/parser_lex.l | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) --- 2.9-test.orig/parser/parser_lex.l +++ 2.9-test/parser/parser_lex.l @@ -80,6 +80,12 @@ yy_pop_state(); \ } while (0) +#define POP_NODUMP() \ +do { \ + PDEBUG(" (pop_to(%s)): Matched: %s\n", state_names[yy_top_state()].c_str(), yytext); \ + yy_pop_state(); \ +} while (0) + #define PUSH(X) \ do { \ DUMP_AND_DEBUG(" (push(%s)): Matched: %s\n", state_names[(X)].c_str(), yytext); \ @@ -278,12 +284,12 @@ char *filename = strndup(yytext, yyleng - 1); include_filename(filename + 1, *filename == '<'); free(filename); - POP(); + POP_NODUMP(); } [^\<\>\" \t\n]+ { /* filename */ include_filename(yytext, 0); - POP(); + POP_NODUMP(); } } debian/patches/update-base-abstraction-for-signals-and-ptrace.patch0000664000000000000000000000257112316304763022611 0ustar Author: Jamie Strandboge Subject: Adjust base abstraction for ptrace and signal mediation Index: ipc-fixes-and-improvements/profiles/apparmor.d/abstractions/base =================================================================== --- ipc-fixes-and-improvements.orig/profiles/apparmor.d/abstractions/base 2014-03-31 10:08:32.737980772 -0500 +++ ipc-fixes-and-improvements/profiles/apparmor.d/abstractions/base 2014-03-31 10:16:03.468978582 -0500 @@ -104,6 +104,24 @@ # glibc malloc (man 5 proc) @{PROC}/sys/vm/overcommit_memory r, + # Allow other processes to read our /proc entries, futexes, perf tracing and + # kcmp for now + ptrace (readby), + + # Allow other processes to trace us by default (they will need 'trace' in + # the first place). Administrators can override with: + # deny ptrace (tracedby) ... + ptrace (tracedby), + + # Allow unconfined processes to send us signals by default + signal (receive) peer=unconfined, + + # Allow us to signal ourselves + signal peer=@{profile_name}, + + # Checking for PID existence is quite common so add it by default for now + signal (receive, send) set=("exists"), + # Workaround https://launchpad.net/bugs/359338 until upstream handles stacked # filesystems generally. This does not appreciably decrease security with # Ubuntu profiles because the user is expected to have access to files owned debian/patches/test-mount-mediation.patch0000664000000000000000000002121012315312536015723 0ustar Description: tests: Improve mount rule tests . The mount.sh regression test script was not testing with actual AppArmor mount rules. This patch improves mkprofile.pl by adding the ability to generate mount rules and adds tests to mount.sh that verify mount mediation is working properly. . Signed-off-by: John Johansen [tyhicks: Fixed a couple typos and added fstype tests] Signed-off-by: Tyler Hicks Acked-by: Steve Beattie Origin: commit, revision id: tyhicks@canonical.com-20140327021004-2ydtqsjx74mjujfv Author: John Johansen Last-Update: 2014-03-27 X-Bzr-Revision-Id: tyhicks@canonical.com-20140327021004-2ydtqsjx74mjujfv === modified file 'tests/regression/apparmor/mkprofile.pl' --- old/tests/regression/apparmor/mkprofile.pl 2013-09-20 13:48:56 +0000 +++ new/tests/regression/apparmor/mkprofile.pl 2014-03-27 02:10:04 +0000 @@ -174,6 +174,78 @@ } } +sub gen_mount($) { + my $rule = shift; + my @rules = split (/:/, $rule); + if (@rules == 2) { + if ($rules[1] =~ /^ALL$/) { + push (@{$output_rules{$hat}}, " mount,\n"); + } else { + push (@{$output_rules{$hat}}, " mount $rules[1],\n"); + } + } elsif (@rules == 3) { + push (@{$output_rules{$hat}}, " mount $rules[1] $rules[2],\n"); + } elsif (@rules == 4) { + push (@{$output_rules{$hat}}, " mount $rules[1] $rules[2] $rules[3],\n"); + } elsif (@rules == 5) { + push (@{$output_rules{$hat}}, " mount $rules[1] $rules[2] $rules[3] $rules[4],\n"); + } elsif (@rules == 6) { + push (@{$output_rules{$hat}}, " mount $rules[1] $rules[2] $rules[3] $rules[4] $rules[5],\n"); + } elsif (@rules == 7) { + push (@{$output_rules{$hat}}, " mount $rules[1] $rules[2] $rules[3] $rules[4] $rules[5] $rules[6],\n"); + } else { + (!$nowarn) && print STDERR "Warning: invalid mount description '$rule', ignored\n"; + } +} + +sub gen_remount($) { + my $rule = shift; + my @rules = split (/:/, $rule); + if (@rules == 2) { + if ($rules[1] =~ /^ALL$/) { + push (@{$output_rules{$hat}}, " remount,\n"); + } else { + push (@{$output_rules{$hat}}, " remount $rules[1],\n"); + } + } elsif (@rules == 3) { + push (@{$output_rules{$hat}}, " remount $rules[1] $rules[2],\n"); + } elsif (@rules == 4) { + push (@{$output_rules{$hat}}, " remount $rules[1] $rules[2] $rules[3],\n"); + } elsif (@rules == 5) { + push (@{$output_rules{$hat}}, " remount $rules[1] $rules[2] $rules[3] $rules[4],\n"); + } elsif (@rules == 6) { + push (@{$output_rules{$hat}}, " remount $rules[1] $rules[2] $rules[3] $rules[4] $rules[5],\n"); + } elsif (@rules == 7) { + push (@{$output_rules{$hat}}, " remount $rules[1] $rules[2] $rules[3] $rules[4] $rules[5] $rules[6],\n"); + } else { + (!$nowarn) && print STDERR "Warning: invalid remount description '$rule', ignored\n"; + } +} + +sub gen_umount($) { + my $rule = shift; + my @rules = split (/:/, $rule); + if (@rules == 2) { + if ($rules[1] =~ /^ALL$/) { + push (@{$output_rules{$hat}}, " umount,\n"); + } else { + push (@{$output_rules{$hat}}, " umount $rules[1],\n"); + } + } elsif (@rules == 3) { + push (@{$output_rules{$hat}}, " umount $rules[1] $rules[2],\n"); + } elsif (@rules == 4) { + push (@{$output_rules{$hat}}, " umount $rules[1] $rules[2] $rules[3],\n"); + } elsif (@rules == 5) { + push (@{$output_rules{$hat}}, " umount $rules[1] $rules[2] $rules[3] $rules[4],\n"); + } elsif (@rules == 6) { + push (@{$output_rules{$hat}}, " umount $rules[1] $rules[2] $rules[3] $rules[4] $rules[5],\n"); + } elsif (@rules == 7) { + push (@{$output_rules{$hat}}, " umount $rules[1] $rules[2] $rules[3] $rules[4] $rules[5] $rules[6],\n"); + } else { + (!$nowarn) && print STDERR "Warning: invalid umount description '$rule', ignored\n"; + } +} + sub gen_file($) { my $rule = shift; my @rules = split (/:/, $rule); @@ -260,6 +332,12 @@ gen_network($rule); } elsif ($rule =~ /^cap:/) { gen_cap($rule); + } elsif ($rule =~ /^mount:/) { + gen_mount($rule); + } elsif ($rule =~ /^remount:/) { + gen_remount($rule); + } elsif ($rule =~ /^umount:/) { + gen_umount($rule); } elsif ($rule =~ /^flag:/) { gen_flag($rule); } elsif ($rule =~ /^hat:/) { === modified file 'tests/regression/apparmor/mount.sh' --- old/tests/regression/apparmor/mount.sh 2012-02-24 12:29:08 +0000 +++ new/tests/regression/apparmor/mount.sh 2014-03-27 02:10:04 +0000 @@ -28,11 +28,29 @@ mount_file=$tmpdir/mountfile mount_point=$tmpdir/mountpoint +mount_bad=$tmpdir/mountbad loop_device="unset" +fstype="ext2" + +setup_mnt() { + /bin/mount -t${fstype} ${loop_device} ${mount_point} +# /bin/mount -t${fstype} ${loop_device} ${mount_bad} +} +remove_mnt() { + mountpoint -q "${mount_point}" + if [ $? -eq 0 ] ; then + /bin/umount -t${fstype} ${mount_point} + fi + mountpoint -q "${mount_bad}" + if [ $? -eq 0 ] ; then + /bin/umount -t${fstype} ${mount_bad} + fi +} dd if=/dev/zero of=${mount_file} bs=1024 count=512 2> /dev/null -/sbin/mkfs -text2 -F ${mount_file} > /dev/null 2> /dev/null +/sbin/mkfs -t${fstype} -F ${mount_file} > /dev/null 2> /dev/null /bin/mkdir ${mount_point} +/bin/mkdir ${mount_bad} # in a modular udev world, the devices won't exist until the loopback # module is loaded. @@ -56,32 +74,95 @@ fatalerror 'Unable to find a free loop device' fi + # TEST 1. Make sure can mount and umount unconfined - runchecktest "MOUNT (unconfined)" pass mount ${loop_device} ${mount_point} +remove_mnt + +setup_mnt runchecktest "UMOUNT (unconfined)" pass umount ${loop_device} ${mount_point} - -# TEST A2. confine MOUNT - -genprofile -runchecktest "MOUNT (confined)" fail mount ${loop_device} ${mount_point} - -# TEST A3. confine MOUNT - cap sys_admin is not sufficient to mount -genprofile capability:sys_admin -runchecktest "MOUNT (confined)" fail mount ${loop_device} ${mount_point} - -/bin/umount -text2 ${mount_point} - -# TEST A4. confine UMOUNT - -/bin/mount -text2 ${loop_device} ${mount_point} - -genprofile -runchecktest "UMOUNT (confined)" fail umount ${loop_device} ${mount_point} - -# TEST A4. confine UMOUNT - cap sys_admin allows unmount -genprofile capability:sys_admin -runchecktest "UMOUNT (confined)" pass umount ${loop_device} ${mount_point} +remove_mnt + +# TEST A2. confine MOUNT no perms +genprofile +runchecktest "MOUNT (confined no perm)" fail mount ${loop_device} ${mount_point} +remove_mnt + +setup_mnt +runchecktest "UMOUNT (confined no perm)" fail umount ${loop_device} ${mount_point} +remove_mnt + + +if [ "$(have_features mount)" != "true" ] ; then + genprofile capability:sys_admin + runchecktest "MOUNT (confined cap)" pass mount ${loop_device} ${mount_point} + remove_mnt + + setup_mnt + runchecktest "UMOUNT (confined cap)" pass umount ${loop_device} ${mount_point} + remove_mnt +else + echo " using mount rules ..." + + genprofile capability:sys_admin + runchecktest "MOUNT (confined cap)" fail mount ${loop_device} ${mount_point} + remove_mnt + + setup_mnt + runchecktest "UMOUNT (confined cap)" fail umount ${loop_device} ${mount_point} + remove_mnt + + + genprofile mount:ALL + runchecktest "MOUNT (confined mount:ALL)" fail mount ${loop_device} ${mount_point} + remove_mnt + + + genprofile "mount:-> ${mount_point}/" + runchecktest "MOUNT (confined bad mntpnt mount -> mntpnt)" fail mount ${loop_device} ${mount_bad} + remove_mnt + + runchecktest "MOUNT (confined mount -> mntpnt)" fail mount ${loop_device} ${mount_point} + remove_mnt + + + + genprofile umount:ALL + setup_mnt + runchecktest "UMOUNT (confined umount:ALL)" fail umount ${loop_device} ${mount_point} + remove_mnt + + + genprofile mount:ALL cap:sys_admin + runchecktest "MOUNT (confined cap mount:ALL)" pass mount ${loop_device} ${mount_point} + remove_mnt + + + genprofile cap:sys_admin "mount:-> ${mount_point}/" + runchecktest "MOUNT (confined bad mntpnt cap mount -> mntpnt)" fail mount ${loop_device} ${mount_bad} + remove_mnt + + runchecktest "MOUNT (confined cap mount -> mntpnt)" pass mount ${loop_device} ${mount_point} + remove_mnt + + + genprofile cap:sys_admin "mount:fstype=${fstype}XXX" + runchecktest "MOUNT (confined cap mount bad fstype)" fail mount ${loop_device} ${mount_point} + remove_mnt + + genprofile cap:sys_admin "mount:fstype=${fstype}" + runchecktest "MOUNT (confined cap mount fstype)" pass mount ${loop_device} ${mount_point} + remove_mnt + + + genprofile cap:sys_admin umount:ALL + setup_mnt + runchecktest "UMOUNT (confined cap umount:ALL)" pass umount ${loop_device} ${mount_point} + remove_mnt + +fi + +#need tests for move mount, remount, bind mount, pivot root, chroot # cleanup, umount file /bin/umount ${loop_device} > /dev/null 2> /dev/null || /sbin/losetup -d ${loop_device} > /dev/null 2> /dev/null debian/patches/python-utils-signal-support.patch0000664000000000000000000003423512317337253017321 0ustar Author: Tyler Hicks Forwarded: https://lists.ubuntu.com/archives/apparmor/2014-April/005603.html Bug-Ubuntu: https://bugs.launchpad.net/bugs/1300316 Subject: utils: Basic support for signal rules This patch does bare bones parsing of signal rules and stores the raw strings for writing them out later. It is meant to be a simple change to prevent aa.py from emitting a traceback when encountering signal rules. Signed-off-by: Tyler Hicks Index: ipc-fixes-and-improvements/utils/apparmor/aa.py =================================================================== --- ipc-fixes-and-improvements.orig/utils/apparmor/aa.py 2014-04-03 12:57:36.408546292 -0500 +++ ipc-fixes-and-improvements/utils/apparmor/aa.py 2014-04-03 12:57:36.404546292 -0500 @@ -2624,6 +2624,7 @@ RE_NETWORK_FAMILY_TYPE = re.compile('\s+ RE_NETWORK_FAMILY = re.compile('\s+(\S+)\s*,$') RE_PROFILE_DBUS = re.compile('^\s*(audit\s+)?(allow\s+|deny\s+)?(dbus[^#]*\s*,)\s*(#.*)?$') RE_PROFILE_MOUNT = re.compile('^\s*(audit\s+)?(allow\s+|deny\s+)?((mount|remount|umount)[^#]*\s*,)\s*(#.*)?$') +RE_PROFILE_SIGNAL = re.compile('^\s*(audit\s+)?(allow\s+|deny\s+)?((signal)[^#]*\s*,)\s*(#.*)?$') # match anything that's not " or #, or matching quotes with anything except quotes inside __re_no_or_quoted_hash = '([^#"]|"[^"]*")*' @@ -2702,6 +2703,7 @@ def parse_profile_data(data, file, do_in profile_data[profile][hat]['allow']['path'] = hasher() profile_data[profile][hat]['allow']['dbus'] = list() profile_data[profile][hat]['allow']['mount'] = list() + profile_data[profile][hat]['allow']['signal'] = list() # Save the initial comment if initial_comment: profile_data[profile][hat]['initial_comment'] = initial_comment @@ -3062,6 +3064,28 @@ def parse_profile_data(data, file, do_in mount_rules.append(mount_rule) profile_data[profile][hat][allow]['mount'] = mount_rules + elif RE_PROFILE_SIGNAL.search(line): + matches = RE_PROFILE_SIGNAL.search(line).groups() + + if not profile: + raise AppArmorException(_('Syntax Error: Unexpected signal entry found in file: %s line: %s') % (file, lineno + 1)) + + audit = False + if matches[0]: + audit = True + allow = 'allow' + if matches[1] and matches[1].strip() == 'deny': + allow = 'deny' + signal = matches[2].strip() + + signal_rule = parse_signal_rule(signal) + signal_rule.audit = audit + signal_rule.deny = (allow == 'deny') + + signal_rules = profile_data[profile][hat][allow].get('signal', list()) + signal_rules.append(signal_rule) + profile_data[profile][hat][allow]['signal'] = signal_rules + elif RE_PROFILE_CHANGE_HAT.search(line): matches = RE_PROFILE_CHANGE_HAT.search(line).groups() @@ -3160,6 +3184,10 @@ def parse_mount_rule(line): # XXX Do real parsing here return aarules.Raw_Mount_Rule(line) +def parse_signal_rule(line): + # XXX Do real parsing here + return aarules.Raw_Signal_Rule(line) + def separate_vars(vs): """Returns a list of all the values for a variable""" data = [] @@ -3389,6 +3417,24 @@ def write_mount(prof_data, depth): data += write_mount_rules(prof_data, depth, 'allow') return data +def write_signal_rules(prof_data, depth, allow): + pre = ' ' * depth + data = [] + + # no signal rules, so return + if not prof_data[allow].get('signal', False): + return data + + for signal_rule in prof_data[allow]['signal']: + data.append('%s%s' % (pre, signal_rule.serialize())) + data.append('') + return data + +def write_signal(prof_data, depth): + data = write_signal_rules(prof_data, depth, 'deny') + data += write_signal_rules(prof_data, depth, 'allow') + return data + def write_link_rules(prof_data, depth, allow): pre = ' ' * depth data = [] @@ -3495,6 +3541,7 @@ def write_rules(prof_data, depth): data += write_netdomain(prof_data, depth) data += write_dbus(prof_data, depth) data += write_mount(prof_data, depth) + data += write_signal(prof_data, depth) data += write_links(prof_data, depth) data += write_paths(prof_data, depth) data += write_change_profile(prof_data, depth) @@ -3644,6 +3691,7 @@ def serialize_profile_from_old_profile(p 'netdomain': write_netdomain, 'dbus': write_dbus, 'mount': write_mount, + 'signal': write_signal, 'link': write_links, 'path': write_paths, 'change_profile': write_change_profile, @@ -3736,6 +3784,7 @@ def serialize_profile_from_old_profile(p data += write_netdomain(write_prof_data[name], depth) data += write_dbus(write_prof_data[name], depth) data += write_mount(write_prof_data[name], depth) + data += write_signal(write_prof_data[name], depth) data += write_links(write_prof_data[name], depth) data += write_paths(write_prof_data[name], depth) data += write_change_profile(write_prof_data[name], depth) Index: ipc-fixes-and-improvements/utils/apparmor/rules.py =================================================================== --- ipc-fixes-and-improvements.orig/utils/apparmor/rules.py 2014-04-03 12:57:36.408546292 -0500 +++ ipc-fixes-and-improvements/utils/apparmor/rules.py 2014-04-03 12:57:36.404546292 -0500 @@ -67,3 +67,15 @@ class Raw_Mount_Rule(object): return "%s%s%s" % ('audit ' if self.audit else '', 'deny ' if self.deny else '', self.rule) + +class Raw_Signal_Rule(object): + audit = False + deny = False + + def __init__(self, rule): + self.rule = rule + + def serialize(self): + return "%s%s%s" % ('audit ' if self.audit else '', + 'deny ' if self.deny else '', + self.rule) Index: ipc-fixes-and-improvements/utils/test/test-regex_matches.py =================================================================== --- ipc-fixes-and-improvements.orig/utils/test/test-regex_matches.py 2014-04-03 12:57:36.408546292 -0500 +++ ipc-fixes-and-improvements/utils/test/test-regex_matches.py 2014-04-03 12:57:36.404546292 -0500 @@ -41,7 +41,12 @@ regex_has_comma_testcases = [ ('audit "/tmp/foo, # bar" rw%s # comment', 'comment embedded in quote 02'), # lifted from parser/tst/simple_tests/vars/vars_alternation_3.sd - ('/does/not/@{BAR},exist,notexist} r%s', 'partial alternation') + ('/does/not/@{BAR},exist,notexist} r%s', 'partial alternation'), + + ('signal%s', 'bare signal'), + ('signal receive%s', 'simple signal'), + ('signal (send, receive)%s', 'embedded parens signal 01'), + ('signal (send, receive) set=(hup, quit)%s', 'embedded parens signal 02'), # the following fail due to inadequacies in the regex # ('dbus (r, w, %s', 'incomplete dbus action'), @@ -99,6 +104,8 @@ regex_split_comment_testcases = [ ('file,', False), ('file, # bare', ('file, ', '# bare')), ('file /tmp/foo rw, # read-write', ('file /tmp/foo rw, ', '# read-write')), + ('signal, # comment', ('signal, ', '# comment')), + ('signal receive set=(usr1 usr2) peer=foo,', False), ] def setup_split_comment_testcases(): @@ -232,6 +239,88 @@ class AARegexFile(unittest.TestCase): result = aa.RE_PROFILE_FILE_ENTRY.search(line) self.assertFalse(result, 'RE_PROFILE_FILE_ENTRY unexpectedly matched "%s"' % line) +class AARegexSignal(unittest.TestCase): + '''Tests for RE_PROFILE_SIGNAL''' + + def test_bare_signal_01(self): + '''test ' signal,' ''' + + rule = 'signal,' + line = ' %s' % rule + result = aa.RE_PROFILE_SIGNAL.search(line) + self.assertTrue(result, 'Couldn\'t find signal rule in "%s"' % line) + parsed = result.groups()[2].strip() + self.assertEqual(parsed, rule, 'Expected signal rule "%s", got "%s"' + % (rule, parsed)) + + def test_bare_signal_02(self): + '''test ' audit signal,' ''' + + rule = 'signal,' + line = ' audit %s' % rule + result = aa.RE_PROFILE_SIGNAL.search(line) + self.assertTrue(result, 'Couldn\'t find signal rule in "%s"' % line) + self.assertTrue(result.groups()[0], 'Couldn\'t find audit modifier in "%s"' % line) + parsed = result.groups()[2].strip() + self.assertEqual(parsed, rule, 'Expected signal rule "%s", got "%s"' + % (rule, parsed)) + + def test_simple_signal_01(self): + '''test ' signal receive,' ''' + + rule = 'signal receive,' + line = ' %s' % rule + result = aa.RE_PROFILE_SIGNAL.search(line) + self.assertTrue(result, 'Couldn\'t find signal rule in "%s"' % line) + parsed = result.groups()[2].strip() + self.assertEqual(parsed, rule, 'Expected signal rule "%s", got "%s"' + % (rule, parsed)) + + def test_simple_signal_02(self): + '''test ' signal (send, receive),' ''' + + rule = 'signal (send, receive),' + line = ' %s' % rule + result = aa.RE_PROFILE_SIGNAL.search(line) + self.assertTrue(result, 'Couldn\'t find signal rule in "%s"' % line) + parsed = result.groups()[2].strip() + self.assertEqual(parsed, rule, 'Expected signal rule "%s", got "%s"' + % (rule, parsed)) + + def test_simple_signal_03(self): + '''test ' audit signal (receive),' ''' + + rule = 'signal (receive),' + line = ' audit %s' % rule + result = aa.RE_PROFILE_SIGNAL.search(line) + self.assertTrue(result, 'Couldn\'t find signal rule in "%s"' % line) + self.assertTrue(result.groups()[0], 'Couldn\'t find audit modifier in "%s"' % line) + parsed = result.groups()[2].strip() + self.assertEqual(parsed, rule, 'Expected signal rule "%s", got "%s"' + % (rule, parsed)) + + def test_set_signal_01(self): + '''test ' signal (send, receive) set=(usr1 usr2),' ''' + + rule = 'signal (send, receive) set=(usr1 usr2),' + line = ' %s' % rule + result = aa.RE_PROFILE_SIGNAL.search(line) + self.assertTrue(result, 'Couldn\'t find signal rule in "%s"' % line) + parsed = result.groups()[2].strip() + self.assertEqual(parsed, rule, 'Expected signal rule "%s", got "%s"' + % (rule, parsed)) + + def test_peer_signal_01(self): + '''test ' signal send set=(hup, quit) peer=/usr/sbin/daemon,' ''' + + rule = 'signal send set=(hup, quit) peer=/usr/sbin/daemon,' + line = ' %s' % rule + result = aa.RE_PROFILE_SIGNAL.search(line) + self.assertTrue(result, 'Couldn\'t find signal rule in "%s"' % line) + parsed = result.groups()[2].strip() + self.assertEqual(parsed, rule, 'Expected signal rule "%s", got "%s"' + % (rule, parsed)) + if __name__ == '__main__': verbosity = 2 @@ -243,6 +332,7 @@ if __name__ == '__main__': test_suite.addTest(unittest.TestLoader().loadTestsFromTestCase(AARegexSplitComment)) test_suite.addTest(unittest.TestLoader().loadTestsFromTestCase(AARegexPath)) test_suite.addTest(unittest.TestLoader().loadTestsFromTestCase(AARegexFile)) + test_suite.addTest(unittest.TestLoader().loadTestsFromTestCase(AARegexSignal)) result = unittest.TextTestRunner(verbosity=verbosity).run(test_suite) if not result.wasSuccessful(): exit(1) Index: ipc-fixes-and-improvements/utils/test/test-signal_parse.py =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ ipc-fixes-and-improvements/utils/test/test-signal_parse.py 2014-04-03 12:57:36.408546292 -0500 @@ -0,0 +1,63 @@ +#! /usr/bin/env python +# ------------------------------------------------------------------ +# +# Copyright (C) 2014 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. +# +# ------------------------------------------------------------------ + +import apparmor.aa as aa +import unittest + +class AAParseSignalTest(unittest.TestCase): + + def _test_parse_signal_rule(self, rule): + signal = aa.parse_signal_rule(rule) + print(signal.serialize()) + self.assertEqual(rule, signal.serialize(), + 'signal object returned "%s", expected "%s"' % (signal.serialize(), rule)) + + def test_parse_plain_signal_rule(self): + self._test_parse_signal_rule('signal,') + + def test_parse_receive_signal_rule(self): + self._test_parse_signal_rule('signal (receive),') + + def test_parse_send_signal_rule(self): + self._test_parse_signal_rule('signal (send),') + + def test_parse_send_receive_signal_rule(self): + self._test_parse_signal_rule('signal (send receive),') + + def test_parse_r_signal_rule(self): + self._test_parse_signal_rule('signal r,') + + def test_parse_w_signal_rule(self): + self._test_parse_signal_rule('signal w,') + + def test_parse_rw_signal_rule(self): + self._test_parse_signal_rule('signal rw,') + + def test_parse_set_1_signal_rule(self): + self._test_parse_signal_rule('signal send set=("hup"),') + + def test_parse_set_2_signal_rule(self): + self._test_parse_signal_rule('signal (receive) set=kill,') + + def test_parse_set_3_signal_rule(self): + self._test_parse_signal_rule('signal w set=(quit int),') + + def test_parse_peer_1_signal_rule(self): + self._test_parse_signal_rule('signal receive peer=foo,') + + def test_parse_peer_2_signal_rule(self): + self._test_parse_signal_rule('signal (send receive) peer=/usr/bin/bar,') + + def test_parse_peer_3_signal_rule(self): + self._test_parse_signal_rule('signal wr set=(pipe, usr1) peer=/sbin/baz,') + +if __name__ == '__main__': + unittest.main() debian/patches/convert-to-rules.patch0000664000000000000000000017620512315045675015113 0ustar Author: John Johansen Forwarded: Yes Subject: Convert mount and dbus to be subclasses of a generic rule class This will simplify add new features as most of the code can reside in its own class. There are still things to improve but its a start. Signed-off-by: John Johansen --- parser/Makefile | 13 - parser/dbus.c | 405 +++++++++++++++++++++++++--------- parser/dbus.h | 32 ++ parser/mount.c | 551 +++++++++++++++++++++++++++++++++++++---------- parser/mount.h | 32 +- parser/parser.h | 22 + parser/parser_misc.c | 101 -------- parser/parser_policy.c | 29 -- parser/parser_regex.c | 489 ----------------------------------------- parser/parser_variable.c | 66 +---- parser/parser_yacc.y | 51 ++-- parser/profile.cc | 6 parser/profile.h | 7 parser/rule.c | 23 + parser/rule.h | 51 ++++ 15 files changed, 940 insertions(+), 938 deletions(-) --- 2.9-test.orig/parser/Makefile +++ 2.9-test/parser/Makefile @@ -79,8 +79,8 @@ SRCS = parser_common.c parser_include.c parser_interface.c parser_lex.c \ parser_main.c parser_misc.c parser_merge.c parser_symtab.c \ parser_yacc.c parser_regex.c parser_variable.c parser_policy.c \ - parser_alias.c mount.c dbus.c lib.c profile.cc -HDRS = parser.h parser_include.h immunix.h mount.h dbus.h lib.h profile.h + parser_alias.c mount.c dbus.c lib.c profile.cc rule.c +HDRS = parser.h parser_include.h immunix.h mount.h dbus.h lib.h profile.h rule.h TOOLS = apparmor_parser OBJECTS = $(SRCS:.c=.o) @@ -188,7 +188,7 @@ parser_yacc.c parser_yacc.h: parser_yacc.y parser.h profile.h $(YACC) $(YFLAGS) -o parser_yacc.c parser_yacc.y -parser_lex.c: parser_lex.l parser_yacc.h parser.h profile.h +parser_lex.c: parser_lex.l parser_yacc.h parser.h profile.h mount.h dbus.h $(LEX) ${LEXFLAGS} -o$@ $< parser_lex.o: parser_lex.c parser.h parser_yacc.h @@ -230,18 +230,21 @@ parser_common.o: parser_common.c parser.h $(CXX) $(EXTRA_CFLAGS) -c -o $@ $< -mount.o: mount.c mount.h parser.h immunix.h +mount.o: mount.c mount.h parser.h immunix.h rule.h $(CXX) $(EXTRA_CFLAGS) -c -o $@ $< lib.o: lib.c lib.h parser.h $(CXX) $(EXTRA_CFLAGS) -c -o $@ $< -dbus.o: dbus.c dbus.h parser.h immunix.h parser_yacc.h $(APPARMOR_H) +dbus.o: dbus.c dbus.h parser.h immunix.h parser_yacc.h rule.h $(APPARMOR_H) $(CXX) $(EXTRA_CFLAGS) -c -o $@ $< profile.o: profile.cc profile.h parser.h $(CXX) $(EXTRA_CFLAGS) -c -o $@ $< +rule.o: rule.c rule.h policydb.h + $(CXX) $(EXTRA_CFLAGS) -c -o $@ $< + parser_version.h: Makefile @echo \#define PARSER_VERSION \"$(VERSION)\" > .ver @mv -f .ver $@ --- 2.9-test.orig/parser/dbus.c +++ 2.9-test/parser/dbus.c @@ -20,23 +20,91 @@ #include #include +#include +#include +#include +#include + #include "parser.h" #include "profile.h" #include "parser_yacc.h" #include "dbus.h" -void free_dbus_entry(struct dbus_entry *ent) +#define _(s) gettext(s) + +static int parse_dbus_sub_mode(const char *str_mode, int *result, int fail, const char *mode_desc __unused) { - if (!ent) - return; - free(ent->bus); - free(ent->name); - free(ent->peer_label); - free(ent->path); - free(ent->interface); - free(ent->member); + int mode = 0; + const char *p; + + PDEBUG("Parsing DBus mode: %s\n", str_mode); + + if (!str_mode) + return 0; + + p = str_mode; + while (*p) { + char current = *p; + char lower; + +reeval: + switch (current) { + case COD_READ_CHAR: + PDEBUG("Parsing DBus mode: found %s READ\n", mode_desc); + mode |= AA_DBUS_RECEIVE; + break; + + case COD_WRITE_CHAR: + PDEBUG("Parsing DBus mode: found %s WRITE\n", + mode_desc); + mode |= AA_DBUS_SEND; + break; + + /* error cases */ + + default: + lower = tolower(current); + switch (lower) { + case COD_READ_CHAR: + case COD_WRITE_CHAR: + PDEBUG("Parsing DBus mode: found invalid upper case char %c\n", + current); + warn_uppercase(); + current = lower; + goto reeval; + break; + default: + if (fail) + yyerror(_("Internal: unexpected DBus mode character '%c' in input"), + current); + else + return 0; + break; + } + break; + } + p++; + } - free(ent); + PDEBUG("Parsed DBus mode: %s 0x%x\n", str_mode, mode); + + *result = mode; + return 1; +} + +int parse_dbus_mode(const char *str_mode, int *mode, int fail) +{ + *mode = 0; + if (!parse_dbus_sub_mode(str_mode, mode, fail, "")) + return 0; + if (*mode & ~AA_VALID_DBUS_PERMS) { + if (fail) + yyerror(_("Internal error generated invalid DBus perm 0x%x\n"), + mode); + else + return 0; + } + return 1; } static int list_len(struct value_list *v) @@ -60,7 +128,7 @@ cond_ent->vals->value = NULL; } -static void move_conditionals(struct dbus_entry *ent, struct cond_entry *conds) +void dbus_rule::move_conditionals(struct cond_entry *conds) { struct cond_entry *cond_ent; @@ -73,17 +141,17 @@ cond_ent->name); if (strcmp(cond_ent->name, "bus") == 0) { - move_conditional_value(&ent->bus, cond_ent); + move_conditional_value(&bus, cond_ent); } else if (strcmp(cond_ent->name, "name") == 0) { - move_conditional_value(&ent->name, cond_ent); + move_conditional_value(&name, cond_ent); } else if (strcmp(cond_ent->name, "label") == 0) { - move_conditional_value(&ent->peer_label, cond_ent); + move_conditional_value(&peer_label, cond_ent); } else if (strcmp(cond_ent->name, "path") == 0) { - move_conditional_value(&ent->path, cond_ent); + move_conditional_value(&path, cond_ent); } else if (strcmp(cond_ent->name, "interface") == 0) { - move_conditional_value(&ent->interface, cond_ent); + move_conditional_value(&interface, cond_ent); } else if (strcmp(cond_ent->name, "member") == 0) { - move_conditional_value(&ent->member, cond_ent); + move_conditional_value(&member, cond_ent); } else { yyerror("invalid dbus conditional \"%s\"\n", cond_ent->name); @@ -91,129 +159,252 @@ } } -struct dbus_entry *new_dbus_entry(int mode, struct cond_entry *conds, - struct cond_entry *peer_conds) +dbus_rule::dbus_rule(int mode_p, struct cond_entry *conds, + struct cond_entry *peer_conds): + bus(NULL), name(NULL), peer_label(NULL), path(NULL), interface(NULL), member(NULL), + mode(0), audit(0), deny(0) { - struct dbus_entry *ent; int name_is_subject_cond = 0, message_rule = 0, service_rule = 0; - ent = (struct dbus_entry*) calloc(1, sizeof(struct dbus_entry)); - if (!ent) - goto out; - /* Move the global/subject conditionals over & check the results */ - move_conditionals(ent, conds); - if (ent->name) + move_conditionals(conds); + if (name) name_is_subject_cond = 1; - if (ent->peer_label) + if (peer_label) yyerror("dbus \"label\" conditional can only be used inside of the \"peer=()\" grouping\n"); /* Move the peer conditionals */ - move_conditionals(ent, peer_conds); + move_conditionals(peer_conds); - if (ent->path || ent->interface || ent->member || ent->peer_label || - (ent->name && !name_is_subject_cond)) + if (path || interface || member || peer_label || + (name && !name_is_subject_cond)) message_rule = 1; - if (ent->name && name_is_subject_cond) + if (name && name_is_subject_cond) service_rule = 1; if (message_rule && service_rule) yyerror("dbus rule contains message conditionals and service conditionals\n"); /* Copy mode. If no mode was specified, assign an implied mode. */ - if (mode) { - ent->mode = mode; - if (ent->mode & ~AA_VALID_DBUS_PERMS) + if (mode_p) { + mode = mode_p; + if (mode & ~AA_VALID_DBUS_PERMS) yyerror("mode contains unknown dbus accesss\n"); - else if (message_rule && (ent->mode & AA_DBUS_BIND)) + else if (message_rule && (mode & AA_DBUS_BIND)) yyerror("dbus \"bind\" access cannot be used with message rule conditionals\n"); - else if (service_rule && (ent->mode & (AA_DBUS_SEND | AA_DBUS_RECEIVE))) + else if (service_rule && (mode & (AA_DBUS_SEND | AA_DBUS_RECEIVE))) yyerror("dbus \"send\" and/or \"receive\" accesses cannot be used with service rule conditionals\n"); - else if (ent->mode & AA_DBUS_EAVESDROP && - (ent->path || ent->interface || ent->member || - ent->peer_label || ent->name)) { + else if (mode & AA_DBUS_EAVESDROP && + (path || interface || member || + peer_label || name)) { yyerror("dbus \"eavesdrop\" access can only contain a bus conditional\n"); } } else { if (message_rule) - ent->mode = (AA_DBUS_SEND | AA_DBUS_RECEIVE); + mode = (AA_DBUS_SEND | AA_DBUS_RECEIVE); else if (service_rule) - ent->mode = (AA_DBUS_BIND); + mode = (AA_DBUS_BIND); else - ent->mode = AA_VALID_DBUS_PERMS; + mode = AA_VALID_DBUS_PERMS; } -out: free_cond_list(conds); free_cond_list(peer_conds); - return ent; } -struct dbus_entry *dup_dbus_entry(struct dbus_entry *orig) +ostream &dbus_rule::dump(ostream &os) +{ + if (audit) + os << "audit "; + if (deny) + os << "deny "; + + os << "dbus ( "; + + if (mode & AA_DBUS_SEND) + os << "send "; + if (mode & AA_DBUS_RECEIVE) + os << "receive "; + if (mode & AA_DBUS_BIND) + os << "bind "; + if (mode & AA_DBUS_EAVESDROP) + os << "eavesdrop "; + os << ")"; + + if (bus) + os << " bus=\"" << bus << "\""; + if ((mode & AA_DBUS_BIND) && name) + os << " name=\"" << name << "\""; + if (path) + os << " path=\"" << path << "\""; + if (interface) + os << " interface=\"" << interface << "\""; + if (member) + os << " member=\"" << member << os << "\""; + + if (!(mode & AA_DBUS_BIND) && (peer_label || name)) { + os << " peer=( "; + if (peer_label) + os << "label=\"" << peer_label << "\" "; + if (name) + os << "name=\"" << name << "\" "; + os << ")"; + } + + os << ",\n"; + + return os; +} + +int dbus_rule::expand_variables(void) +{ + int error = expand_entry_variables(&bus); + if (error) + return error; + error = expand_entry_variables(&name); + if (error) + return error; + error = expand_entry_variables(&peer_label); + if (error) + return error; + error = expand_entry_variables(&path); + if (error) + return error; + error = expand_entry_variables(&interface); + if (error) + return error; + error = expand_entry_variables(&member); + if (error) + return error; + + return 0; +} + +/* do we want to warn once/profile or just once per compile?? */ +static void warn_once(const char *name) +{ + static const char *warned_name = NULL; + + if (warned_name != name) { + cerr << "Warning from profile " << name << " ("; + if (current_filename) + cerr << current_filename; + else + cerr << "stdin"; + cerr << ") dbus rules not enforced\n"; + warned_name = name; + } +} + +int dbus_rule::gen_policy_re(Profile &prof) { - struct dbus_entry *ent = NULL; - ent = (struct dbus_entry *) calloc(1, sizeof(struct dbus_entry)); - if (!ent) - return NULL; - - DUP_STRING(orig, ent, bus, err); - DUP_STRING(orig, ent, name, err); - DUP_STRING(orig, ent, peer_label, err); - DUP_STRING(orig, ent, path, err); - DUP_STRING(orig, ent, interface, err); - DUP_STRING(orig, ent, member, err); - ent->mode = orig->mode; - ent->audit = orig->audit; - ent->deny = orig->deny; - - ent->next = orig->next; - - return ent; - -err: - free_dbus_entry(ent); - return NULL; -} - -void print_dbus_entry(struct dbus_entry *ent) -{ - if (ent->audit) - fprintf(stderr, "audit "); - if (ent->deny) - fprintf(stderr, "deny "); - - fprintf(stderr, "dbus ( "); - - if (ent->mode & AA_DBUS_SEND) - fprintf(stderr, "send "); - if (ent->mode & AA_DBUS_RECEIVE) - fprintf(stderr, "receive "); - if (ent->mode & AA_DBUS_BIND) - fprintf(stderr, "bind "); - if (ent->mode & AA_DBUS_EAVESDROP) - fprintf(stderr, "eavesdrop "); - fprintf(stderr, ")"); - - if (ent->bus) - fprintf(stderr, " bus=\"%s\"", ent->bus); - if ((ent->mode & AA_DBUS_BIND) && ent->name) - fprintf(stderr, " name=\"%s\"", ent->name); - if (ent->path) - fprintf(stderr, " path=\"%s\"", ent->path); - if (ent->interface) - fprintf(stderr, " interface=\"%s\"", ent->interface); - if (ent->member) - fprintf(stderr, " member=\"%s\"", ent->member); - - if (!(ent->mode & AA_DBUS_BIND) && (ent->peer_label || ent->name)) { - fprintf(stderr, " peer=( "); - if (ent->peer_label) - fprintf(stderr, "label=\"%s\" ", ent->peer_label); - if (ent->name) - fprintf(stderr, "name=\"%s\" ", ent->name); - fprintf(stderr, ")"); + std::string busbuf; + std::string namebuf; + std::string peer_labelbuf; + std::string pathbuf; + std::string ifacebuf; + std::string memberbuf; + std::ostringstream buffer; + const char *vec[6]; + + pattern_t ptype; + int pos; + + if (!kernel_supports_dbus) { + warn_once(prof.name); + return RULE_NOT_SUPPORTED; + } + + buffer << "\\x" << std::setfill('0') << std::setw(2) << std::hex << AA_CLASS_DBUS; + busbuf.append(buffer.str()); + + if (bus) { + ptype = convert_aaregex_to_pcre(bus, 0, busbuf, &pos); + if (ptype == ePatternInvalid) + goto fail; + } else { + /* match any char except \000 0 or more times */ + busbuf.append(default_match_pattern); } + vec[0] = busbuf.c_str(); + + if (name) { + ptype = convert_aaregex_to_pcre(name, 0, namebuf, &pos); + if (ptype == ePatternInvalid) + goto fail; + vec[1] = namebuf.c_str(); + } else { + /* match any char except \000 0 or more times */ + vec[1] = default_match_pattern; + } + + if (peer_label) { + ptype = convert_aaregex_to_pcre(peer_label, 0, + peer_labelbuf, &pos); + if (ptype == ePatternInvalid) + goto fail; + vec[2] = peer_labelbuf.c_str(); + } else { + /* match any char except \000 0 or more times */ + vec[2] = default_match_pattern; + } + + if (path) { + ptype = convert_aaregex_to_pcre(path, 0, pathbuf, &pos); + if (ptype == ePatternInvalid) + goto fail; + vec[3] = pathbuf.c_str(); + } else { + /* match any char except \000 0 or more times */ + vec[3] = default_match_pattern; + } + + if (interface) { + ptype = convert_aaregex_to_pcre(interface, 0, ifacebuf, &pos); + if (ptype == ePatternInvalid) + goto fail; + vec[4] = ifacebuf.c_str(); + } else { + /* match any char except \000 0 or more times */ + vec[4] = default_match_pattern; + } + + if (member) { + ptype = convert_aaregex_to_pcre(member, 0, memberbuf, &pos); + if (ptype == ePatternInvalid) + goto fail; + vec[5] = memberbuf.c_str(); + } else { + /* match any char except \000 0 or more times */ + vec[5] = default_match_pattern; + } + + if (mode & AA_DBUS_BIND) { + if (!aare_add_rule_vec(prof.policy.rules, deny, + mode & AA_DBUS_BIND, + audit & AA_DBUS_BIND, + 2, vec, dfaflags)) + goto fail; + } + if (mode & (AA_DBUS_SEND | AA_DBUS_RECEIVE)) { + if (!aare_add_rule_vec(prof.policy.rules, deny, + mode & (AA_DBUS_SEND | AA_DBUS_RECEIVE), + audit & (AA_DBUS_SEND | AA_DBUS_RECEIVE), + 6, vec, dfaflags)) + goto fail; + } + if (mode & AA_DBUS_EAVESDROP) { + if (!aare_add_rule_vec(prof.policy.rules, deny, + mode & AA_DBUS_EAVESDROP, + audit & AA_DBUS_EAVESDROP, + 1, vec, dfaflags)) + goto fail; + } + + prof.policy.count++; + return RULE_OK; - fprintf(stderr, ",\n"); +fail: + return RULE_ERROR; } --- 2.9-test.orig/parser/dbus.h +++ 2.9-test/parser/dbus.h @@ -20,8 +20,14 @@ #define __AA_DBUS_H #include "parser.h" +#include "rule.h" +#include "profile.h" -struct dbus_entry { +extern int parse_dbus_mode(const char *str_mode, int *mode, int fail); + +class dbus_rule: public rule_t { + void move_conditionals(struct cond_entry *conds); +public: char *bus; /** * Be careful! ->name can be the subject or the peer name, depending on @@ -37,13 +43,23 @@ int audit; int deny; - struct dbus_entry *next; -}; + dbus_rule(int mode_p, struct cond_entry *conds, + struct cond_entry *peer_conds); + virtual ~dbus_rule() { + free(bus); + free(name); + free(peer_label); + free(path); + free(interface); + free(member); + }; + + virtual ostream &dump(ostream &os); + virtual int expand_variables(void); + virtual int gen_policy_re(Profile &prof); + virtual void post_process(Profile &prof __unused) { }; -void free_dbus_entry(struct dbus_entry *ent); -struct dbus_entry *new_dbus_entry(int mode, struct cond_entry *conds, - struct cond_entry *peer_conds); -struct dbus_entry *dup_dbus_entry(struct dbus_entry *ent); -void print_dbus_entry(struct dbus_entry *ent); + +}; #endif /* __AA_DBUS_H */ --- 2.9-test.orig/parser/mount.c +++ 2.9-test/parser/mount.c @@ -215,8 +215,12 @@ #include #include +#include +#include #include "parser.h" +#include "policydb.h" +#include "profile.h" #include "mount.h" struct mnt_keyword_table { @@ -389,146 +393,471 @@ return list; } -struct mnt_entry *new_mnt_entry(struct cond_entry *src_conds, char *device, - struct cond_entry *dst_conds __unused, char *mnt_point, - int allow) +mnt_rule::mnt_rule(struct cond_entry *src_conds, char *device_p, + struct cond_entry *dst_conds __unused, char *mnt_point_p, + int allow_p): + mnt_point(mnt_point_p), device(device_p), trans(NULL), opts(NULL), + audit(0), deny(0) { /* FIXME: dst_conds are ignored atm */ + aa_class = AA_CLASS_MOUNT; - struct mnt_entry *ent; - ent = (struct mnt_entry *) calloc(1, sizeof(struct mnt_entry)); - if (ent) { - ent->mnt_point = mnt_point; - ent->device = device; - ent->dev_type = extract_fstype(&src_conds); - - ent->flags = 0; - ent->inv_flags = 0; - - if (src_conds) { - unsigned int flags = 0, inv_flags = 0; - struct value_list *list = extract_options(&src_conds, 0); - - ent->opts = extract_options(&src_conds, 1); - if (ent->opts) - ent->flags = extract_flags(&ent->opts, - &ent->inv_flags); - - if (list) { - flags = extract_flags(&list, &inv_flags); - /* these flags are optional so set both */ - flags |= inv_flags; - inv_flags |= flags; - - ent->flags |= flags; - ent->inv_flags |= inv_flags; - - if (ent->opts) - list_append(ent->opts, list); - else if (list) - ent->opts = list; - } - } + dev_type = extract_fstype(&src_conds); - if (allow & AA_DUMMY_REMOUNT) { - allow = AA_MAY_MOUNT; - ent->flags |= MS_REMOUNT; - ent->inv_flags = 0; - } else if (!(ent->flags | ent->inv_flags)) { - /* no flag options, and not remount, allow everything */ - ent->flags = MS_ALL_FLAGS; - ent->inv_flags = MS_ALL_FLAGS; - } + if (src_conds) { + struct value_list *list = extract_options(&src_conds, 0); - ent->allow = allow; + opts = extract_options(&src_conds, 1); + if (opts) + flags = extract_flags(&opts, &inv_flags); - if (src_conds) { - PERROR(" unsupported mount conditions\n"); - exit(1); + if (list) { + unsigned int tmpflags, tmpinv_flags = 0; + + tmpflags = extract_flags(&list, &tmpinv_flags); + /* these flags are optional so set both */ + tmpflags |= tmpinv_flags; + tmpinv_flags |= tmpflags; + + flags |= tmpflags; + inv_flags |= tmpinv_flags; + + if (opts) + list_append(opts, list); + else if (list) + opts = list; } } - return ent; + if (allow_p & AA_DUMMY_REMOUNT) { + allow_p = AA_MAY_MOUNT; + flags |= MS_REMOUNT; + inv_flags = 0; + } else if (!(flags | inv_flags)) { + /* no flag options, and not remount, allow everything */ + flags = MS_ALL_FLAGS; + inv_flags = MS_ALL_FLAGS; + } + + allow = allow_p; + + if (src_conds) { + PERROR(" unsupported mount conditions\n"); + exit(1); + } } -void free_mnt_entry(struct mnt_entry *ent) +ostream &mnt_rule::dump(ostream &os) { - if (!ent) - return; + if (allow & AA_MAY_MOUNT) + os << "mount"; + else if (allow & AA_MAY_UMOUNT) + os << "umount"; + else if (allow & AA_MAY_PIVOTROOT) + os << "pivotroot"; + else + os << "error: unknonwn mount perm"; - free_mnt_entry(ent->next); - free_value_list(ent->opts); - free_value_list(ent->dev_type); - free(ent->device); - free(ent->mnt_point); - free(ent->trans); + os << " (0x" << hex << flags << " - 0x" << inv_flags << ") "; + if (dev_type) { + os << " type="; + print_value_list(dev_type); + } + if (opts) { + os << " options="; + print_value_list(opts); + } + if (device) + os << " " << device; + if (mnt_point) + os << " -> " << mnt_point; + if (trans) + os << " -> " << trans; + + const char *prefix = deny ? "deny" : ""; + os << " " << prefix << "(0x" << hex << allow << "/0x" << audit << ")"; + os << ",\n"; - free(ent); + return os; } -struct mnt_entry *dup_mnt_entry(struct mnt_entry *orig) +/* does not currently support expansion of vars in options */ +int mnt_rule::expand_variables(void) { - struct mnt_entry *entry = NULL; + int error = 0; - entry = (struct mnt_entry *) calloc(1, sizeof(struct mnt_entry)); - if (!entry) - return NULL; + error = expand_entry_variables(&mnt_point); + if (error) + return error; + error = expand_entry_variables(&device); + if (error) + return error; + error = expand_entry_variables(&trans); + if (error) + return error; - DUP_STRING(orig, entry, mnt_point, err); - DUP_STRING(orig, entry, device, err); - DUP_STRING(orig, entry, trans, err); + return 0; +} - entry->dev_type = dup_value_list(orig->dev_type); - if (orig->dev_type && !(entry->dev_type)) - goto err; +static int build_mnt_flags(char *buffer, int size, unsigned int flags, + unsigned int inv_flags) +{ + char *p = buffer; + int i, len = 0; - entry->opts = dup_value_list(orig->opts); - if (orig->opts && !(entry->opts)) - goto err; + if (flags == MS_ALL_FLAGS) { + /* all flags are optional */ + len = snprintf(p, size, "%s", default_match_pattern); + if (len < 0 || len >= size) + return FALSE; + return TRUE; + } + for (i = 0; i <= 31; ++i) { + if ((flags & inv_flags) & (1 << i)) + len = snprintf(p, size, "(\\x%02x|)", i + 1); + else if (flags & (1 << i)) + len = snprintf(p, size, "\\x%02x", i + 1); + else /* no entry = not set */ + continue; + + if (len < 0 || len >= size) + return FALSE; + p += len; + size -= len; + } - entry->flags = orig->flags; - entry->inv_flags = orig->inv_flags; + /* this needs to go once the backend is updated. */ + if (buffer == p) { + /* match nothing - use impossible 254 as regex parser doesn't + * like the empty string + */ + if (size < 9) + return FALSE; - entry->allow = orig->allow; - entry->audit = orig->audit; - entry->deny = orig->deny; + strcpy(p, "(\\xfe|)"); + } - entry->next = orig->next; + return TRUE; +} - return entry; +static int build_mnt_opts(std::string& buffer, struct value_list *opts) +{ + struct value_list *ent; + pattern_t ptype; + int pos; + + if (!opts) { + buffer.append(default_match_pattern); + return TRUE; + } + + list_for_each(opts, ent) { + ptype = convert_aaregex_to_pcre(ent->value, 0, buffer, &pos); + if (ptype == ePatternInvalid) + return FALSE; + + if (ent->next) + buffer.append(","); + } -err: - free_mnt_entry(entry); - return NULL; + return TRUE; } -void print_mnt_entry(struct mnt_entry *entry) +/* do we want to warn once/profile or just once per compile?? */ +static void warn_once(const char *name) { - if (entry->allow & AA_MAY_MOUNT) - fprintf(stderr, "mount"); - else if (entry->allow & AA_MAY_UMOUNT) - fprintf(stderr, "umount"); - else if (entry->allow & AA_MAY_PIVOTROOT) - fprintf(stderr, "pivotroot"); - else - fprintf(stderr, "error: unknonwn mount perm"); + static const char *warned_name = NULL; + + if (warned_name != name) { + cerr << "Warning from profile " << name << " ("; + if (current_filename) + cerr << current_filename; + else + cerr << "stdin"; + cerr << ") mount rules not enforced\n"; + warned_name = name; + } +} + +int mnt_rule::gen_policy_re(Profile &prof) +{ + std::string mntbuf; + std::string devbuf; + std::string typebuf; + char flagsbuf[PATH_MAX + 3]; + std::string optsbuf; + char class_mount_hdr[64]; + const char *vec[5]; + int count = 0; + unsigned int tmpflags, tmpinv_flags; + + if (!kernel_supports_mount) { + warn_once(prof.name); + return RULE_NOT_SUPPORTED; + } + + sprintf(class_mount_hdr, "\\x%02x", AA_CLASS_MOUNT); + + /* a single mount rule may result in multiple matching rules being + * created in the backend to cover all the possible choices + */ + + if ((allow & AA_MAY_MOUNT) && (flags & MS_REMOUNT) + && !device && !dev_type) { + int tmpallow; + /* remount can't be conditional on device and type */ + /* rule class single byte header */ + mntbuf.assign(class_mount_hdr); + if (mnt_point) { + /* both device && mnt_point or just mnt_point */ + if (!convert_entry(mntbuf, mnt_point)) + goto fail; + vec[0] = mntbuf.c_str(); + } else { + if (!convert_entry(mntbuf, device)) + goto fail; + vec[0] = mntbuf.c_str(); + } + /* skip device */ + vec[1] = default_match_pattern; + /* skip type */ + vec[2] = default_match_pattern; + + tmpflags = flags; + tmpinv_flags = inv_flags; + if (tmpflags != MS_ALL_FLAGS) + tmpflags &= MS_REMOUNT_FLAGS; + if (tmpinv_flags != MS_ALL_FLAGS) + tmpflags &= MS_REMOUNT_FLAGS; + if (!build_mnt_flags(flagsbuf, PATH_MAX, tmpflags, tmpinv_flags)) + goto fail; + vec[3] = flagsbuf; + + if (opts) + tmpallow = AA_MATCH_CONT; + else + tmpallow = allow; + + /* rule for match without required data || data MATCH_CONT */ + if (!aare_add_rule_vec(prof.policy.rules, deny, tmpallow, + audit | AA_AUDIT_MNT_DATA, 4, + vec, dfaflags)) + goto fail; + count++; + + if (opts) { + /* rule with data match required */ + optsbuf.clear(); + if (!build_mnt_opts(optsbuf, opts)) + goto fail; + vec[4] = optsbuf.c_str(); + if (!aare_add_rule_vec(prof.policy.rules, deny, + allow, + audit | AA_AUDIT_MNT_DATA, + 5, vec, dfaflags)) + goto fail; + count++; + } + } + if ((allow & AA_MAY_MOUNT) && (flags & MS_BIND) + && !dev_type && !opts) { + /* bind mount rules can't be conditional on dev_type or data */ + /* rule class single byte header */ + mntbuf.assign(class_mount_hdr); + if (!convert_entry(mntbuf, mnt_point)) + goto fail; + vec[0] = mntbuf.c_str(); + if (!clear_and_convert_entry(devbuf, device)) + goto fail; + vec[1] = devbuf.c_str(); + /* skip type */ + vec[2] = default_match_pattern; + + tmpflags = flags; + tmpinv_flags = inv_flags; + if (tmpflags != MS_ALL_FLAGS) + tmpflags &= MS_BIND_FLAGS; + if (tmpinv_flags != MS_ALL_FLAGS) + tmpflags &= MS_BIND_FLAGS; + if (!build_mnt_flags(flagsbuf, PATH_MAX, tmpflags, tmpinv_flags)) + goto fail; + vec[3] = flagsbuf; + if (!aare_add_rule_vec(prof.policy.rules, deny, allow, + audit, 4, vec, dfaflags)) + goto fail; + count++; + } + if ((allow & AA_MAY_MOUNT) && + (flags & (MS_UNBINDABLE | MS_PRIVATE | MS_SLAVE | MS_SHARED)) + && !device && !dev_type && !opts) { + /* change type base rules can not be conditional on device, + * device type or data + */ + /* rule class single byte header */ + mntbuf.assign(class_mount_hdr); + if (!convert_entry(mntbuf, mnt_point)) + goto fail; + vec[0] = mntbuf.c_str(); + /* skip device and type */ + vec[1] = default_match_pattern; + vec[2] = default_match_pattern; + + tmpflags = flags; + tmpinv_flags = inv_flags; + if (tmpflags != MS_ALL_FLAGS) + tmpflags &= MS_MAKE_FLAGS; + if (tmpinv_flags != MS_ALL_FLAGS) + tmpflags &= MS_MAKE_FLAGS; + if (!build_mnt_flags(flagsbuf, PATH_MAX, tmpflags, tmpinv_flags)) + goto fail; + vec[3] = flagsbuf; + if (!aare_add_rule_vec(prof.policy.rules, deny, allow, + audit, 4, vec, dfaflags)) + goto fail; + count++; + } + if ((allow & AA_MAY_MOUNT) && (flags & MS_MOVE) + && !dev_type && !opts) { + /* mount move rules can not be conditional on dev_type, + * or data + */ + /* rule class single byte header */ + mntbuf.assign(class_mount_hdr); + if (!convert_entry(mntbuf, mnt_point)) + goto fail; + vec[0] = mntbuf.c_str(); + if (!clear_and_convert_entry(devbuf, device)) + goto fail; + vec[1] = devbuf.c_str(); + /* skip type */ + vec[2] = default_match_pattern; + + tmpflags = flags; + tmpinv_flags = inv_flags; + if (tmpflags != MS_ALL_FLAGS) + tmpflags &= MS_MOVE_FLAGS; + if (tmpinv_flags != MS_ALL_FLAGS) + tmpflags &= MS_MOVE_FLAGS; + if (!build_mnt_flags(flagsbuf, PATH_MAX, tmpflags, tmpinv_flags)) + goto fail; + vec[3] = flagsbuf; + if (!aare_add_rule_vec(prof.policy.rules, deny, allow, + audit, 4, vec, dfaflags)) + goto fail; + count++; + } + if ((allow & AA_MAY_MOUNT) && + (flags | inv_flags) & ~MS_CMDS) { + int tmpallow; + /* generic mount if flags are set that are not covered by + * above commands + */ + /* rule class single byte header */ + mntbuf.assign(class_mount_hdr); + if (!convert_entry(mntbuf, mnt_point)) + goto fail; + vec[0] = mntbuf.c_str(); + if (!clear_and_convert_entry(devbuf, device)) + goto fail; + vec[1] = devbuf.c_str(); + typebuf.clear(); + if (!build_list_val_expr(typebuf, dev_type)) + goto fail; + vec[2] = typebuf.c_str(); + + tmpflags = flags; + tmpinv_flags = inv_flags; + if (tmpflags != MS_ALL_FLAGS) + tmpflags &= ~MS_CMDS; + if (tmpinv_flags != MS_ALL_FLAGS) + tmpinv_flags &= ~MS_CMDS; + if (!build_mnt_flags(flagsbuf, PATH_MAX, tmpflags, tmpinv_flags)) + goto fail; + vec[3] = flagsbuf; + + if (opts) + tmpallow = AA_MATCH_CONT; + else + tmpallow = allow; + + /* rule for match without required data || data MATCH_CONT */ + if (!aare_add_rule_vec(prof.policy.rules, deny, tmpallow, + audit | AA_AUDIT_MNT_DATA, 4, + vec, dfaflags)) + goto fail; + count++; + + if (opts) { + /* rule with data match required */ + optsbuf.clear(); + if (!build_mnt_opts(optsbuf, opts)) + goto fail; + vec[4] = optsbuf.c_str(); + if (!aare_add_rule_vec(prof.policy.rules, deny, + allow, + audit | AA_AUDIT_MNT_DATA, + 5, vec, dfaflags)) + goto fail; + count++; + } + } + if (allow & AA_MAY_UMOUNT) { + /* rule class single byte header */ + mntbuf.assign(class_mount_hdr); + if (!convert_entry(mntbuf, mnt_point)) + goto fail; + vec[0] = mntbuf.c_str(); + if (!aare_add_rule_vec(prof.policy.rules, deny, allow, + audit, 1, vec, dfaflags)) + goto fail; + count++; + } + if (allow & AA_MAY_PIVOTROOT) { + /* rule class single byte header */ + mntbuf.assign(class_mount_hdr); + if (!convert_entry(mntbuf, mnt_point)) + goto fail; + vec[0] = mntbuf.c_str(); + if (!clear_and_convert_entry(devbuf, device)) + goto fail; + vec[1] = devbuf.c_str(); + if (!aare_add_rule_vec(prof.policy.rules, deny, allow, + audit, 2, vec, dfaflags)) + goto fail; + count++; + } - fprintf(stderr, " (0x%x - 0x%x) ", entry->flags, entry->inv_flags); - if (entry->dev_type) { - fprintf(stderr, " type="); - print_value_list(entry->dev_type); - } - if (entry->opts) { - fprintf(stderr, " options="); - print_value_list(entry->opts); - } - if (entry->device) - fprintf(stderr, " %s", entry->device); - if (entry->mnt_point) - fprintf(stderr, " -> %s", entry->mnt_point); - if (entry->trans) - fprintf(stderr, " -> %s", entry->trans); + if (!count) + /* didn't actually encode anything */ + goto fail; + + prof.policy.count++; + return RULE_OK; + +fail: + PERROR("Enocoding of mount rule failed\n"); + return RULE_ERROR; +} - fprintf(stderr, " %s (0x%x/0x%x)", entry->deny ? "deny" : "", entry->allow, entry->audit); - fprintf(stderr, ",\n"); +void mnt_rule::post_process(Profile &prof) +{ + if (trans) { + unsigned int mode = 0; + int n = add_entry_to_x_table(&prof, trans); + if (!n) { + PERROR("Profile %s has too many specified profile transitions.\n", prof.name); + exit(1); + } + + if (allow & AA_USER_EXEC) + mode |= SHIFT_MODE(n << 10, AA_USER_SHIFT); + if (allow & AA_OTHER_EXEC) + mode |= SHIFT_MODE(n << 10, AA_OTHER_SHIFT); + allow = ((allow & ~AA_ALL_EXEC_MODIFIERS) | + (mode & AA_ALL_EXEC_MODIFIERS)); + + trans = NULL; + } } + + --- 2.9-test.orig/parser/mount.h +++ 2.9-test/parser/mount.h @@ -19,7 +19,11 @@ #ifndef __AA_MOUNT_H #define __AA_MOUNT_H +#include + #include "parser.h" +#include "rule.h" + #define MS_RDONLY (1 << 0) #define MS_RW 0 @@ -109,7 +113,8 @@ * remapped to a mount option*/ -struct mnt_entry { +class mnt_rule: public rule_t { +public: char *mnt_point; char *device; char *trans; @@ -120,17 +125,26 @@ int allow, audit; int deny; - struct mnt_entry *next; -}; -void print_mnt_entry(struct mnt_entry *entry); + mnt_rule(struct cond_entry *src_conds, char *device_p, + struct cond_entry *dst_conds __unused, char *mnt_point_p, + int allow_p); + virtual ~mnt_rule() + { + free_value_list(opts); + free_value_list(dev_type); + free(device); + free(mnt_point); + free(trans); + } + + virtual ostream &dump(ostream &os); + virtual int expand_variables(void); + virtual int gen_policy_re(Profile &prof); + virtual void post_process(Profile &prof __unused); +}; int is_valid_mnt_cond(const char *name, int src); -struct mnt_entry *new_mnt_entry(struct cond_entry *sconds, char *device, - struct cond_entry *dconds, char *mnt_point, - int mode); -struct mnt_entry *dup_mnt_entry(struct mnt_entry *orig); -void free_mnt_entry(struct mnt_entry *ent); #endif /* __AA_MOUNT_H */ --- 2.9-test.orig/parser/parser.h +++ 2.9-test/parser/parser.h @@ -30,12 +30,13 @@ #include "libapparmor_re/apparmor_re.h" #include "libapparmor_re/aare_rules.h" +#include + using namespace std; #include class Profile; - -struct mnt_ent; +class rule_t; /* Global variable to pass token to lexer. Will be replaced by parameter * when lexer and parser are made reentrant @@ -256,9 +257,14 @@ extern const char *basedir; /* parser_regex.c */ +extern const char *default_match_pattern; +extern pattern_t convert_aaregex_to_pcre(const char *aare, int anchor, + std::string& pcre, int *first_re_pos); +extern int build_list_val_expr(std::string& buffer, struct value_list *list); +extern int convert_entry(std::string& buffer, char *entry); +extern int clear_and_convert_entry(std::string& buffer, char *entry); extern int process_regex(Profile *prof); extern int post_process_entry(struct cod_entry *entry); -extern int process_dbus(Profile *prof); extern void reset_regex(void); @@ -267,11 +273,13 @@ extern int process_policy_ents(Profile *prof); /* parser_variable.c */ +int expand_entry_variables(char **name); extern int process_variables(Profile *prof); extern struct var_string *split_out_var(const char *string); extern void free_var_string(struct var_string *var); /* parser_misc.c */ +extern void warn_uppercase(void); extern int is_blacklisted(const char *name, const char *path); extern struct value_list *new_value_list(char *value); extern struct value_list *dup_value_list(struct value_list *list); @@ -289,7 +297,6 @@ extern int get_rlimit(const char *name); extern char *process_var(const char *var); extern int parse_mode(const char *mode); -extern int parse_dbus_mode(const char *str_mode, int *mode, int fail); extern struct cod_entry *new_entry(char *ns, char *id, int mode, char *link_id); extern struct aa_network_entry *new_network_ent(unsigned int family, unsigned int type, @@ -303,15 +310,13 @@ extern int str_to_boolean(const char* str); extern struct cod_entry *copy_cod_entry(struct cod_entry *cod); extern void free_cod_entries(struct cod_entry *list); -extern void free_mnt_entries(struct mnt_entry *list); -extern void free_dbus_entries(struct dbus_entry *list); extern void __debug_capabilities(uint64_t capset, const char *name); void __debug_network(unsigned int *array, const char *name); void debug_cod_entries(struct cod_entry *list); /* parser_symtab.c */ -struct set_value {; +struct set_value { char *val; struct set_value *next; }; @@ -345,9 +350,10 @@ /* parser_policy.c */ extern void add_to_list(Profile *profile); extern void add_hat_to_policy(Profile *policy, Profile *hat); +extern int add_entry_to_x_table(Profile *prof, char *name); extern void add_entry_to_policy(Profile *policy, struct cod_entry *entry); extern void post_process_file_entries(Profile *prof); -extern void post_process_mnt_entries(Profile *prof); +extern void post_process_rule_entries(Profile *prof); extern int post_process_policy(int debug_only); extern int process_profile_regex(Profile *prof); extern int process_profile_variables(Profile *prof); --- 2.9-test.orig/parser/parser_misc.c +++ 2.9-test/parser/parser_misc.c @@ -596,7 +596,7 @@ static int warned_uppercase = 0; -static void warn_uppercase(void) +void warn_uppercase(void) { if (!warned_uppercase) { pwarn(_("Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" @@ -792,81 +792,6 @@ return mode; } -static int parse_dbus_sub_mode(const char *str_mode, int *result, int fail, const char *mode_desc __unused) -{ - int mode = 0; - const char *p; - - PDEBUG("Parsing DBus mode: %s\n", str_mode); - - if (!str_mode) - return 0; - - p = str_mode; - while (*p) { - char current = *p; - char lower; - -reeval: - switch (current) { - case COD_READ_CHAR: - PDEBUG("Parsing DBus mode: found %s READ\n", mode_desc); - mode |= AA_DBUS_RECEIVE; - break; - - case COD_WRITE_CHAR: - PDEBUG("Parsing DBus mode: found %s WRITE\n", - mode_desc); - mode |= AA_DBUS_SEND; - break; - - /* error cases */ - - default: - lower = tolower(current); - switch (lower) { - case COD_READ_CHAR: - case COD_WRITE_CHAR: - PDEBUG("Parsing DBus mode: found invalid upper case char %c\n", - current); - warn_uppercase(); - current = lower; - goto reeval; - break; - default: - if (fail) - yyerror(_("Internal: unexpected DBus mode character '%c' in input"), - current); - else - return 0; - break; - } - break; - } - p++; - } - - PDEBUG("Parsed DBus mode: %s 0x%x\n", str_mode, mode); - - *result = mode; - return 1; -} - -int parse_dbus_mode(const char *str_mode, int *mode, int fail) -{ - *mode = 0; - if (!parse_dbus_sub_mode(str_mode, mode, fail, "")) - return 0; - if (*mode & ~AA_VALID_DBUS_PERMS) { - if (fail) - yyerror(_("Internal error generated invalid DBus perm 0x%x\n"), - mode); - else - return 0; - } - return 1; -} - struct cod_entry *new_entry(char *ns, char *id, int mode, char *link_id) { struct cod_entry *entry = NULL; @@ -938,30 +863,6 @@ free(list); } -void free_mnt_entries(struct mnt_entry *list) -{ - if (!list) - return; - if (list->next) - free_mnt_entries(list->next); - free(list->mnt_point); - free(list->device); - free_value_list(list->dev_type); - free_value_list(list->opts); - - free(list); -} - -void free_dbus_entries(struct dbus_entry *list) -{ - if (!list) - return; - if (list->next) - free_dbus_entries(list->next); - - free_dbus_entry(list); -} - static void debug_base_perm_mask(int mask) { if (HAS_MAY_READ(mask)) --- 2.9-test.orig/parser/parser_policy.c +++ 2.9-test/parser/parser_policy.c @@ -32,8 +32,6 @@ #include "parser.h" #include "profile.h" -#include "mount.h" -#include "dbus.h" #include "parser_yacc.h" /* #define DEBUG */ @@ -70,7 +68,7 @@ } } -static int add_entry_to_x_table(Profile *prof, char *name) +int add_entry_to_x_table(Profile *prof, char *name) { int i; for (i = (AA_EXEC_LOCAL >> 10) + 1; i < AA_EXEC_COUNT; i++) { @@ -192,29 +190,10 @@ } } -void post_process_mnt_entries(Profile *prof) +void post_process_rule_entries(Profile *prof) { - struct mnt_entry *entry; - - list_for_each(prof->mnt_ents, entry) { - if (entry->trans) { - unsigned int mode = 0; - int n = add_entry_to_x_table(prof, entry->trans); - if (!n) { - PERROR("Profile %s has too many specified profile transitions.\n", prof->name); - exit(1); - } - - if (entry->allow & AA_USER_EXEC) - mode |= SHIFT_MODE(n << 10, AA_USER_SHIFT); - if (entry->allow & AA_OTHER_EXEC) - mode |= SHIFT_MODE(n << 10, AA_OTHER_SHIFT); - entry->allow = ((entry->allow & ~AA_ALL_EXEC_MODIFIERS) | - (mode & AA_ALL_EXEC_MODIFIERS)); - - entry->trans = NULL; - } - } + for (RuleList::iterator i = prof->rule_ents.begin(); i != prof->rule_ents.end(); i++) + (*i)->post_process(*prof); } --- 2.9-test.orig/parser/parser_regex.c +++ 2.9-test/parser/parser_regex.c @@ -35,9 +35,8 @@ #include "profile.h" #include "libapparmor_re/apparmor_re.h" #include "libapparmor_re/aare_rules.h" -#include "mount.h" -#include "dbus.h" #include "policydb.h" +#include "rule.h" enum error_type { e_no_error, @@ -45,7 +44,7 @@ }; /* match any char except \000 0 or more times */ -static const char *default_match_pattern = "[^\\000]*"; +const char *default_match_pattern = "[^\\000]*"; /* Filters out multiple slashes (except if the first two are slashes, * that's a distinct namespace in linux) and trailing slashes. @@ -90,8 +89,8 @@ /* converts the apparmor regex in aare and appends pcre regex output * to pcre string */ -static pattern_t convert_aaregex_to_pcre(const char *aare, int anchor, - std::string& pcre, int *first_re_pos) +pattern_t convert_aaregex_to_pcre(const char *aare, int anchor, + std::string& pcre, int *first_re_pos) { #define update_re_pos(X) if (!(*first_re_pos)) { *first_re_pos = (X); } #define MAX_ALT_DEPTH 50 @@ -612,7 +611,7 @@ return error; } -static int build_list_val_expr(std::string& buffer, struct value_list *list) +int build_list_val_expr(std::string& buffer, struct value_list *list) { struct value_list *ent; pattern_t ptype; @@ -642,7 +641,7 @@ return FALSE; } -static int convert_entry(std::string& buffer, char *entry) +int convert_entry(std::string& buffer, char *entry) { pattern_t ptype; int pos; @@ -658,487 +657,19 @@ return TRUE; } -static int clear_and_convert_entry(std::string& buffer, char *entry) +int clear_and_convert_entry(std::string& buffer, char *entry) { buffer.clear(); return convert_entry(buffer, entry); } -static int build_mnt_flags(char *buffer, int size, unsigned int flags, - unsigned int inv_flags) +int post_process_policydb_ents(Profile *prof) { - char *p = buffer; - int i, len = 0; - - if (flags == MS_ALL_FLAGS) { - /* all flags are optional */ - len = snprintf(p, size, "%s", default_match_pattern); - if (len < 0 || len >= size) - return FALSE; - return TRUE; - } - for (i = 0; i <= 31; ++i) { - if ((flags & inv_flags) & (1 << i)) - len = snprintf(p, size, "(\\x%02x|)", i + 1); - else if (flags & (1 << i)) - len = snprintf(p, size, "\\x%02x", i + 1); - else /* no entry = not set */ - continue; - - if (len < 0 || len >= size) + for (RuleList::iterator i = prof->rule_ents.begin(); i != prof->rule_ents.end(); i++) { + if ((*i)->gen_policy_re(*prof) == RULE_ERROR) return FALSE; - p += len; - size -= len; - } - - /* this needs to go once the backend is updated. */ - if (buffer == p) { - /* match nothing - use impossible 254 as regex parser doesn't - * like the empty string - */ - if (size < 9) - return FALSE; - - strcpy(p, "(\\xfe|)"); - } - - return TRUE; -} - -static int build_mnt_opts(std::string& buffer, struct value_list *opts) -{ - struct value_list *ent; - pattern_t ptype; - int pos; - - if (!opts) { - buffer.append(default_match_pattern); - return TRUE; } - list_for_each(opts, ent) { - ptype = convert_aaregex_to_pcre(ent->value, 0, buffer, &pos); - if (ptype == ePatternInvalid) - return FALSE; - - if (ent->next) - buffer.append(","); - } - - return TRUE; -} - -static int process_mnt_entry(aare_ruleset_t *dfarules, struct mnt_entry *entry) -{ - std::string mntbuf; - std::string devbuf; - std::string typebuf; - char flagsbuf[PATH_MAX + 3]; - std::string optsbuf; - char class_mount_hdr[64]; - const char *vec[5]; - int count = 0; - unsigned int flags, inv_flags; - - sprintf(class_mount_hdr, "\\x%02x", AA_CLASS_MOUNT); - - /* a single mount rule may result in multiple matching rules being - * created in the backend to cover all the possible choices - */ - - if ((entry->allow & AA_MAY_MOUNT) && (entry->flags & MS_REMOUNT) - && !entry->device && !entry->dev_type) { - int allow; - /* remount can't be conditional on device and type */ - /* rule class single byte header */ - mntbuf.assign(class_mount_hdr); - if (entry->mnt_point) { - /* both device && mnt_point or just mnt_point */ - if (!convert_entry(mntbuf, entry->mnt_point)) - goto fail; - vec[0] = mntbuf.c_str(); - } else { - if (!convert_entry(mntbuf, entry->device)) - goto fail; - vec[0] = mntbuf.c_str(); - } - /* skip device */ - vec[1] = default_match_pattern; - /* skip type */ - vec[2] = default_match_pattern; - - flags = entry->flags; - inv_flags = entry->inv_flags; - if (flags != MS_ALL_FLAGS) - flags &= MS_REMOUNT_FLAGS; - if (inv_flags != MS_ALL_FLAGS) - flags &= MS_REMOUNT_FLAGS; - if (!build_mnt_flags(flagsbuf, PATH_MAX, flags, inv_flags)) - goto fail; - vec[3] = flagsbuf; - - if (entry->opts) - allow = AA_MATCH_CONT; - else - allow = entry->allow; - - /* rule for match without required data || data MATCH_CONT */ - if (!aare_add_rule_vec(dfarules, entry->deny, allow, - entry->audit | AA_AUDIT_MNT_DATA, 4, - vec, dfaflags)) - goto fail; - count++; - - if (entry->opts) { - /* rule with data match required */ - optsbuf.clear(); - if (!build_mnt_opts(optsbuf, entry->opts)) - goto fail; - vec[4] = optsbuf.c_str(); - if (!aare_add_rule_vec(dfarules, entry->deny, - entry->allow, - entry->audit | AA_AUDIT_MNT_DATA, - 5, vec, dfaflags)) - goto fail; - count++; - } - } - if ((entry->allow & AA_MAY_MOUNT) && (entry->flags & MS_BIND) - && !entry->dev_type && !entry->opts) { - /* bind mount rules can't be conditional on dev_type or data */ - /* rule class single byte header */ - mntbuf.assign(class_mount_hdr); - if (!convert_entry(mntbuf, entry->mnt_point)) - goto fail; - vec[0] = mntbuf.c_str(); - if (!clear_and_convert_entry(devbuf, entry->device)) - goto fail; - vec[1] = devbuf.c_str(); - /* skip type */ - vec[2] = default_match_pattern; - - flags = entry->flags; - inv_flags = entry->inv_flags; - if (flags != MS_ALL_FLAGS) - flags &= MS_BIND_FLAGS; - if (inv_flags != MS_ALL_FLAGS) - flags &= MS_BIND_FLAGS; - if (!build_mnt_flags(flagsbuf, PATH_MAX, flags, inv_flags)) - goto fail; - vec[3] = flagsbuf; - if (!aare_add_rule_vec(dfarules, entry->deny, entry->allow, - entry->audit, 4, vec, dfaflags)) - goto fail; - count++; - } - if ((entry->allow & AA_MAY_MOUNT) && - (entry->flags & (MS_UNBINDABLE | MS_PRIVATE | MS_SLAVE | MS_SHARED)) - && !entry->device && !entry->dev_type && !entry->opts) { - /* change type base rules can not be conditional on device, - * device type or data - */ - /* rule class single byte header */ - mntbuf.assign(class_mount_hdr); - if (!convert_entry(mntbuf, entry->mnt_point)) - goto fail; - vec[0] = mntbuf.c_str(); - /* skip device and type */ - vec[1] = default_match_pattern; - vec[2] = default_match_pattern; - - flags = entry->flags; - inv_flags = entry->inv_flags; - if (flags != MS_ALL_FLAGS) - flags &= MS_MAKE_FLAGS; - if (inv_flags != MS_ALL_FLAGS) - flags &= MS_MAKE_FLAGS; - if (!build_mnt_flags(flagsbuf, PATH_MAX, flags, inv_flags)) - goto fail; - vec[3] = flagsbuf; - if (!aare_add_rule_vec(dfarules, entry->deny, entry->allow, - entry->audit, 4, vec, dfaflags)) - goto fail; - count++; - } - if ((entry->allow & AA_MAY_MOUNT) && (entry->flags & MS_MOVE) - && !entry->dev_type && !entry->opts) { - /* mount move rules can not be conditional on dev_type, - * or data - */ - /* rule class single byte header */ - mntbuf.assign(class_mount_hdr); - if (!convert_entry(mntbuf, entry->mnt_point)) - goto fail; - vec[0] = mntbuf.c_str(); - if (!clear_and_convert_entry(devbuf, entry->device)) - goto fail; - vec[1] = devbuf.c_str(); - /* skip type */ - vec[2] = default_match_pattern; - - flags = entry->flags; - inv_flags = entry->inv_flags; - if (flags != MS_ALL_FLAGS) - flags &= MS_MOVE_FLAGS; - if (inv_flags != MS_ALL_FLAGS) - flags &= MS_MOVE_FLAGS; - if (!build_mnt_flags(flagsbuf, PATH_MAX, flags, inv_flags)) - goto fail; - vec[3] = flagsbuf; - if (!aare_add_rule_vec(dfarules, entry->deny, entry->allow, - entry->audit, 4, vec, dfaflags)) - goto fail; - count++; - } - if ((entry->allow & AA_MAY_MOUNT) && - (entry->flags | entry->inv_flags) & ~MS_CMDS) { - int allow; - /* generic mount if flags are set that are not covered by - * above commands - */ - /* rule class single byte header */ - mntbuf.assign(class_mount_hdr); - if (!convert_entry(mntbuf, entry->mnt_point)) - goto fail; - vec[0] = mntbuf.c_str(); - if (!clear_and_convert_entry(devbuf, entry->device)) - goto fail; - vec[1] = devbuf.c_str(); - typebuf.clear(); - if (!build_list_val_expr(typebuf, entry->dev_type)) - goto fail; - vec[2] = typebuf.c_str(); - - flags = entry->flags; - inv_flags = entry->inv_flags; - if (flags != MS_ALL_FLAGS) - flags &= ~MS_CMDS; - if (inv_flags != MS_ALL_FLAGS) - flags &= ~MS_CMDS; - if (!build_mnt_flags(flagsbuf, PATH_MAX, flags, inv_flags)) - goto fail; - vec[3] = flagsbuf; - - if (entry->opts) - allow = AA_MATCH_CONT; - else - allow = entry->allow; - - /* rule for match without required data || data MATCH_CONT */ - if (!aare_add_rule_vec(dfarules, entry->deny, allow, - entry->audit | AA_AUDIT_MNT_DATA, 4, - vec, dfaflags)) - goto fail; - count++; - - if (entry->opts) { - /* rule with data match required */ - optsbuf.clear(); - if (!build_mnt_opts(optsbuf, entry->opts)) - goto fail; - vec[4] = optsbuf.c_str(); - if (!aare_add_rule_vec(dfarules, entry->deny, - entry->allow, - entry->audit | AA_AUDIT_MNT_DATA, - 5, vec, dfaflags)) - goto fail; - count++; - } - } - if (entry->allow & AA_MAY_UMOUNT) { - /* rule class single byte header */ - mntbuf.assign(class_mount_hdr); - if (!convert_entry(mntbuf, entry->mnt_point)) - goto fail; - vec[0] = mntbuf.c_str(); - if (!aare_add_rule_vec(dfarules, entry->deny, entry->allow, - entry->audit, 1, vec, dfaflags)) - goto fail; - count++; - } - if (entry->allow & AA_MAY_PIVOTROOT) { - /* rule class single byte header */ - mntbuf.assign(class_mount_hdr); - if (!convert_entry(mntbuf, entry->mnt_point)) - goto fail; - vec[0] = mntbuf.c_str(); - if (!clear_and_convert_entry(devbuf, entry->device)) - goto fail; - vec[1] = devbuf.c_str(); - if (!aare_add_rule_vec(dfarules, entry->deny, entry->allow, - entry->audit, 2, vec, dfaflags)) - goto fail; - count++; - } - - if (!count) - /* didn't actually encode anything */ - goto fail; - - return TRUE; - -fail: - PERROR("Enocoding of mount rule failed\n"); - return FALSE; -} - - -static int process_dbus_entry(aare_ruleset_t *dfarules, struct dbus_entry *entry) -{ - std::string busbuf; - std::string namebuf; - std::string peer_labelbuf; - std::string pathbuf; - std::string ifacebuf; - std::string memberbuf; - std::ostringstream buffer; - const char *vec[6]; - - pattern_t ptype; - int pos; - - if (!entry) /* shouldn't happen */ - return TRUE; - - buffer << "\\x" << std::setfill('0') << std::setw(2) << std::hex << AA_CLASS_DBUS; - busbuf.append(buffer.str()); - - if (entry->bus) { - ptype = convert_aaregex_to_pcre(entry->bus, 0, busbuf, &pos); - if (ptype == ePatternInvalid) - goto fail; - } else { - /* match any char except \000 0 or more times */ - busbuf.append(default_match_pattern); - } - vec[0] = busbuf.c_str(); - - if (entry->name) { - ptype = convert_aaregex_to_pcre(entry->name, 0, namebuf, &pos); - if (ptype == ePatternInvalid) - goto fail; - vec[1] = namebuf.c_str(); - } else { - /* match any char except \000 0 or more times */ - vec[1] = default_match_pattern; - } - - if (entry->peer_label) { - ptype = convert_aaregex_to_pcre(entry->peer_label, 0, - peer_labelbuf, &pos); - if (ptype == ePatternInvalid) - goto fail; - vec[2] = peer_labelbuf.c_str(); - } else { - /* match any char except \000 0 or more times */ - vec[2] = default_match_pattern; - } - - if (entry->path) { - ptype = convert_aaregex_to_pcre(entry->path, 0, pathbuf, &pos); - if (ptype == ePatternInvalid) - goto fail; - vec[3] = pathbuf.c_str(); - } else { - /* match any char except \000 0 or more times */ - vec[3] = default_match_pattern; - } - - if (entry->interface) { - ptype = convert_aaregex_to_pcre(entry->interface, 0, ifacebuf, &pos); - if (ptype == ePatternInvalid) - goto fail; - vec[4] = ifacebuf.c_str(); - } else { - /* match any char except \000 0 or more times */ - vec[4] = default_match_pattern; - } - - if (entry->member) { - ptype = convert_aaregex_to_pcre(entry->member, 0, memberbuf, &pos); - if (ptype == ePatternInvalid) - goto fail; - vec[5] = memberbuf.c_str(); - } else { - /* match any char except \000 0 or more times */ - vec[5] = default_match_pattern; - } - - if (entry->mode & AA_DBUS_BIND) { - if (!aare_add_rule_vec(dfarules, entry->deny, - entry->mode & AA_DBUS_BIND, - entry->audit & AA_DBUS_BIND, - 2, vec, dfaflags)) - goto fail; - } - if (entry->mode & (AA_DBUS_SEND | AA_DBUS_RECEIVE)) { - if (!aare_add_rule_vec(dfarules, entry->deny, - entry->mode & (AA_DBUS_SEND | AA_DBUS_RECEIVE), - entry->audit & (AA_DBUS_SEND | AA_DBUS_RECEIVE), - 6, vec, dfaflags)) - goto fail; - } - if (entry->mode & AA_DBUS_EAVESDROP) { - if (!aare_add_rule_vec(dfarules, entry->deny, - entry->mode & AA_DBUS_EAVESDROP, - entry->audit & AA_DBUS_EAVESDROP, - 1, vec, dfaflags)) - goto fail; - } - return TRUE; - -fail: - return FALSE; -} - -static int post_process_mnt_ents(Profile *prof) -{ - int ret = TRUE; - int count = 0; - - /* Add fns for rules that should be added to policydb here */ - if (prof->mnt_ents && kernel_supports_mount) { - struct mnt_entry *entry; - list_for_each(prof->mnt_ents, entry) { - if (!process_mnt_entry(prof->policy.rules, entry)) - ret = FALSE; - count++; - } - } else if (prof->mnt_ents && !kernel_supports_mount) - pwarn("profile %s mount rules not enforced\n", prof->name); - - prof->policy.count += count; - - return ret; -} - -static int post_process_dbus_ents(Profile *prof) -{ - int ret = TRUE; - int count = 0; - - if (prof->dbus_ents && kernel_supports_dbus) { - struct dbus_entry *entry; - - list_for_each(prof->dbus_ents, entry) { - if (!process_dbus_entry(prof->policy.rules, entry)) - ret = FALSE; - count++; - } - } else if (prof->dbus_ents && !kernel_supports_dbus) - pwarn("profile %s dbus rules not enforced\n", prof->name); - - prof->policy.count += count; - return ret; -} - -int post_process_policydb_ents(Profile *prof) -{ - if (!post_process_mnt_ents(prof)) - return FALSE; - if (!post_process_dbus_ents(prof)) - return FALSE; - return TRUE; } --- 2.9-test.orig/parser/parser_variable.c +++ 2.9-test/parser/parser_variable.c @@ -15,6 +15,7 @@ * along with this program; if not, contact Novell, Inc. */ +#include #include #include #include @@ -213,13 +214,15 @@ } /* doesn't handle variables in options atm */ -static int expand_entry_variables(char **name, void *entry) +int expand_entry_variables(char **name) { struct set_value *valuelist; struct var_string *split_var; int ret; - if (!entry) /* can happen when entry is optional */ + assert(name); + + if (!*name) /* can happen when entry is optional */ return 0; while ((split_var = split_out_var(*name))) { @@ -251,7 +254,7 @@ struct cod_entry *entry; list_for_each(entry_list, entry) { - error = expand_entry_variables(&entry->name, entry); + error = expand_entry_variables(&entry->name); if (error) return error; } @@ -259,69 +262,24 @@ return 0; } -/* does not currently support expansion of vars in options */ -static int process_variables_in_mnt_entries(struct mnt_entry *entry_list) +static int process_variables_in_rules(Profile &prof) { - int error = 0; - struct mnt_entry *entry; - - list_for_each(entry_list, entry) { - error = expand_entry_variables(&entry->mnt_point, entry); + for(RuleList::iterator i = prof.rule_ents.begin(); i != prof.rule_ents.end(); i++) { + int error = (*i)->expand_variables(); if (error) return error; - error = expand_entry_variables(&entry->device, entry); - if (error) - return error; - error = expand_entry_variables(&entry->trans, entry); - if (error) - return error; - } return 0; } -static int process_dbus_variables(struct dbus_entry *entry_list) -{ - int error = 0; - struct dbus_entry *entry; - - list_for_each(entry_list, entry) { - error = expand_entry_variables(&entry->bus, entry); - if (error) - return error; - error = expand_entry_variables(&entry->name, entry); - if (error) - return error; - error = expand_entry_variables(&entry->peer_label, entry); - if (error) - return error; - error = expand_entry_variables(&entry->path, entry); - if (error) - return error; - error = expand_entry_variables(&entry->interface, entry); - if (error) - return error; - error = expand_entry_variables(&entry->member, entry); - if (error) - return error; - - } - - return 0; -} int process_profile_variables(Profile *prof) { int error = 0; - - error = process_variables_in_entries(prof->entries); - - if (!error) - error = process_variables_in_mnt_entries(prof->mnt_ents); - - if (!error) - error = process_dbus_variables(prof->dbus_ents); + error = process_variables_in_entries(prof->entries); + if (!error) + error = process_variables_in_rules(*prof); return error; } --- 2.9-test.orig/parser/parser_yacc.y +++ 2.9-test/parser/parser_yacc.y @@ -72,11 +72,11 @@ struct cod_entry *do_file_rule(char *ns, char *id, int mode, char *link_id, char *nt); -struct mnt_entry *do_mnt_rule(struct cond_entry *src_conds, char *src, - struct cond_entry *dst_conds, char *dst, - int mode); -struct mnt_entry *do_pivot_rule(struct cond_entry *old, char *root, - char *transition); +mnt_rule *do_mnt_rule(struct cond_entry *src_conds, char *src, + struct cond_entry *dst_conds, char *dst, + int mode); +mnt_rule *do_pivot_rule(struct cond_entry *old, char *root, + char *transition); void add_local_entry(Profile *prof); @@ -162,6 +162,12 @@ /* debug flag values */ %token TOK_FLAGS +%code requires { + #include "profile.h" + #include "mount.h" + #include "dbus.h" +} + %union { char *id; char *flag_id; @@ -170,8 +176,9 @@ Profile *prof; struct cod_net_entry *net_entry; struct cod_entry *user_entry; - struct mnt_entry *mnt_entry; - struct dbus_entry *dbus_entry; + + mnt_rule *mnt_entry; + dbus_rule *dbus_entry; flagvals flags; int fmode; @@ -281,7 +288,7 @@ prof->flags.complain = 1; post_process_file_entries(prof); - post_process_mnt_entries(prof); + post_process_rule_entries(prof); PDEBUG("%s: flags='%s%s'\n", $2, prof->flags.complain ? "complain, " : "", @@ -667,8 +674,8 @@ } else if ($2.audit) { $3->audit = $3->allow; } - $3->next = $1->mnt_ents; - $1->mnt_ents = $3; + + $1->rule_ents.push_back($3); $$ = $1; } @@ -684,8 +691,7 @@ } else if ($2.audit) { $3->audit = $3->mode; } - $3->next = $1->dbus_ents; - $1->dbus_ents = $3; + $1->rule_ents.push_back($3); $$ = $1; } @@ -1196,9 +1202,9 @@ dbus_rule: TOK_DBUS opt_dbus_perm opt_conds opt_cond_list TOK_END_OF_RULE { - struct dbus_entry *ent; + dbus_rule *ent; - ent = new_dbus_entry($2, $3, $4); + ent = new dbus_rule($2, $3, $4); if (!ent) { yyerror(_("Memory allocation error.")); } @@ -1366,12 +1372,10 @@ return error; } -struct mnt_entry *do_mnt_rule(struct cond_entry *src_conds, char *src, - struct cond_entry *dst_conds, char *dst, - int mode) +mnt_rule *do_mnt_rule(struct cond_entry *src_conds, char *src, + struct cond_entry *dst_conds, char *dst, + int mode) { - struct mnt_entry *ent; - if (verify_mnt_conds(src_conds, MNT_SRC_OPT) != 0) yyerror(_("bad mount rule")); @@ -1382,7 +1386,7 @@ if (dst_conds) yyerror(_("mount point conditions not currently supported")); - ent = new_mnt_entry(src_conds, src, dst_conds, dst, mode); + mnt_rule *ent = new mnt_rule(src_conds, src, dst_conds, dst, mode); if (!ent) { yyerror(_("Memory allocation error.")); } @@ -1390,10 +1394,8 @@ return ent; } -struct mnt_entry *do_pivot_rule(struct cond_entry *old, char *root, - char *transition) +mnt_rule *do_pivot_rule(struct cond_entry *old, char *root, char *transition) { - struct mnt_entry *ent = NULL; char *device = NULL; if (old) { if (strcmp(old->name, "oldroot") != 0) @@ -1405,8 +1407,7 @@ free_cond_entry(old); } - ent = new_mnt_entry(NULL, device, NULL, root, - AA_MAY_PIVOTROOT); + mnt_rule *ent = new mnt_rule(NULL, device, NULL, root, AA_MAY_PIVOTROOT); ent->trans = transition; return ent; --- 2.9-test.orig/parser/profile.cc +++ 2.9-test/parser/profile.cc @@ -13,6 +13,7 @@ */ #include "profile.h" +#include "rule.h" #include #include @@ -62,8 +63,9 @@ { hat_table.clear(); free_cod_entries(entries); - free_mnt_entries(mnt_ents); - free_dbus_entries(dbus_ents); + + for (RuleList::iterator i = rule_ents.begin(); i != rule_ents.end(); i++) + delete *i; if (dfa.rules) aare_delete_ruleset(dfa.rules); if (dfa.dfa) --- 2.9-test.orig/parser/profile.h +++ 2.9-test/parser/profile.h @@ -17,6 +17,7 @@ #include #include "parser.h" +#include "rule.h" class Profile; @@ -153,8 +154,7 @@ char *exec_table[AA_EXEC_COUNT]; struct cod_entry *entries; - struct mnt_entry *mnt_ents; - struct dbus_entry *dbus_ents; + RuleList rule_ents; ProfileList hat_table; @@ -179,9 +179,6 @@ std::fill(exec_table, exec_table + AA_EXEC_COUNT, (char *)NULL); entries = NULL; - mnt_ents = NULL; - dbus_ents = NULL; - }; virtual ~Profile(); --- /dev/null +++ 2.9-test/parser/rule.c @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2014 + * 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 "rule.h" + +std::ostream &operator<<(std::ostream &os, rule_t &rule) +{ + return rule.dump(os); +}; --- /dev/null +++ 2.9-test/parser/rule.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2014 + * 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. + */ +#ifndef __AA_RULE_H +#define __AA_RULE_H + +#include +#include + +#include "policydb.h" + +class Profile; + +#define RULE_NOT_SUPPORTED 0 +#define RULE_ERROR -1 +#define RULE_OK 1 + +class rule_t { +public: + int aa_class; + + rule_t(void): aa_class(AA_CLASS_UNKNOWN) { }; + virtual ~rule_t() { }; + + //virtual bool operator<(rule_t const &rhs)const = 0; + virtual std::ostream &dump(std::ostream &os) = 0; + virtual int expand_variables(void) = 0; + virtual int gen_policy_re(Profile &prof) = 0; + virtual void post_process(Profile &prof) = 0; +}; + +std::ostream &operator<<(std::ostream &os, rule_t &rule); + +typedef std::list RuleList; + +#endif /* __AA_RULE_H */ + -- AppArmor mailing list AppArmor@lists.ubuntu.com Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/apparmor debian/patches/ubuntu-manpage-updates.patch0000664000000000000000000000654112315045675016251 0ustar Author: Jamie Strandboge Description: Adjust apparmor(5) to describe policy load on Ubuntu Bug-Ubuntu: https://launchpad.net/bugs/974089 Forward: no (Ubuntu specific) --- parser/apparmor.pod | 44 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 3 deletions(-) Index: b/parser/apparmor.pod =================================================================== --- a/parser/apparmor.pod +++ b/parser/apparmor.pod @@ -3,7 +3,7 @@ # 2008, 2009 # NOVELL (All rights reserved) # -# Copyright (c) 2010 +# Copyright (c) 2010, 2011, 2012 # Canonical Ltd. (All rights reserved) # # Copyright (c) 2013 @@ -19,7 +19,7 @@ # 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. +# along with this program; if not, contact Canonical Ltd. # ---------------------------------------------------------------------- @@ -37,7 +37,8 @@ AppArmor confinement is provided via I loaded into the kernel via apparmor_parser(8), typically through the F -SysV initscript, which is used like this: +SysV initscript (on Ubuntu, also see UBUNTU POLICY LOAD, below), which is used +like this: # /etc/init.d/apparmor start # /etc/init.d/apparmor stop @@ -95,6 +96,41 @@ iopl(2) ptrace(2) reboot(2) setdomainname(2) sethostname(2) swapoff(2) swapon(2) sysctl(2) +=head1 UBUNTU POLICY LOAD + +Ubuntu systems use Upstart instead of a traditional SysV init system. Because +Upstart is an event-driven init system and understanding that policy must be +loaded before execution, Ubuntu loads policy in two stages: first via upstart +jobs for binaries that are started in early boot, and then via a SysV +initscript that starts in S37 for all remaining policy. When developing +policy it is important to know how your application is started and if policy +load should be handled specially. + +In general, nothing extra has to be done for applications without an initscript +or with an initscript that starts after AppArmor's second stage initscript. + +If the confined application has an Upstart job, adjust the job to call +F with the filename of the policy file +(relative to F). For example: + + pre-start script + /lib/init/apparmor-profile-load usr.bin.foo + end script + +If the confined application does not have an Upstart job but it starts before +AppArmor's second stage initscript, then add a symlink from the policy file in +F to F. For +example: + + # cd /etc/apparmor/init/network-interface-security/ + # ln -s /etc/apparmor.d/usr.bin.foo . + +The network-interface-security Upstart job will load all the symlinked policy +files in F before any network +interfaces come up. Because network interfaces come up very early in the boot +process, this will help ensure that AppArmor policy is loaded before the +confined application starts. + =head1 ERRORS When a confined process tries to access a file it does not have permission @@ -146,6 +182,8 @@ =item F +=item F + =item F =item F debian/patches/dnsmasq-libvirtd-signal-ptrace.patch0000664000000000000000000000133612317207360017656 0ustar Author: Jamie Strandboge Subject: dnsmasq profile updates for signals and ptrace from libvirtd Index: ipc-fixes-and-improvements/profiles/apparmor.d/usr.sbin.dnsmasq =================================================================== --- ipc-fixes-and-improvements.orig/profiles/apparmor.d/usr.sbin.dnsmasq 2014-03-27 11:03:09.893804000 -0500 +++ ipc-fixes-and-improvements/profiles/apparmor.d/usr.sbin.dnsmasq 2014-04-03 02:32:55.321315465 -0500 @@ -25,6 +25,9 @@ capability net_raw, # for DHCP server ping checks network inet raw, + signal (receive) peer=/usr/sbin/libvirtd, + ptrace (readby) peer=/usr/sbin/libvirtd, + /etc/dnsmasq.conf r, /etc/dnsmasq.d/ r, /etc/dnsmasq.d/* r, debian/patches/label-class.patch0000664000000000000000000000177212315045675014041 0ustar Author: John Johansen Forwarded: Yes Subject: add label class to the policydb The label class is used to lookup object permissions based off of label alone when the labeling is not path dependent. Some rules will not generate label entries, some will generate only label entries and some will generate both label and path entries. This is left to the particular rule encoding. Signed-off-by: John Johansen --- parser/policydb.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) --- 2.9-test.orig/parser/policydb.h +++ 2.9-test/parser/policydb.h @@ -32,8 +32,9 @@ #define AA_CLASS_NS_DOMAIN 8 #define AA_CLASS_PTRACE 9 -#define AA_CLASS_ENV 16 +#define AA_CLASS_LABEL 16 +/* defined in libapparmor's apparmor.h #define AA_CLASS_DBUS 32 */ #define AA_CLASS_X 33 #endif /* __AA_POLICYDB_H */ -- AppArmor mailing list AppArmor@lists.ubuntu.com Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/apparmor debian/patches/fix-network.patch0000664000000000000000000000254212315045675014130 0ustar Author: John Johansen Forwarded: Yes Subject: fix: network detection The features file patch broke detection of network support. Signed-off-by: John Johansen --- parser/parser_common.c | 2 +- parser/parser_main.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) --- 2.9-test.orig/parser/parser_common.c +++ 2.9-test/parser/parser_common.c @@ -25,7 +25,7 @@ int perms_create = 0; /* perms contain create flag */ int net_af_max_override = -1; /* use kernel to determine af_max */ int kernel_load = 1; -int kernel_supports_network = 1; /* kernel supports network rules */ +int kernel_supports_network = 0; /* kernel supports network rules */ int kernel_supports_mount = 0; /* kernel supports mount rules */ int kernel_supports_dbus = 0; /* kernel supports dbus rules */ int conf_verbose = 0; --- 2.9-test.orig/parser/parser_main.c +++ 2.9-test/parser/parser_main.c @@ -814,11 +814,11 @@ if (strstr(match_string, " perms=c")) perms_create = 1; free(match_string); + kernel_supports_network = 1; goto out; } no_match: perms_create = 1; - kernel_supports_network = 0; out: if (ms) -- AppArmor mailing list AppArmor@lists.ubuntu.com Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/apparmor debian/patches/etc-writable.patch0000664000000000000000000000466412315045675014244 0ustar Description: Allow reading time configuration from /etc/writable, as we have it on the phone. Author: Martin Pitt Forwarded: No, that's an Ubuntu specific hack Bug-Ubuntu: https://launchpad.net/bugs/1227520 --- profiles/apparmor.d/abstractions/base | 1 + profiles/apparmor.d/abstractions/ubuntu-browsers.d/java | 2 ++ profiles/apparmor/profiles/extras/usr.lib.firefox.firefox | 1 + profiles/apparmor/profiles/extras/usr.sbin.sshd | 1 + 4 files changed, 5 insertions(+) Index: b/profiles/apparmor.d/abstractions/base =================================================================== --- a/profiles/apparmor.d/abstractions/base +++ b/profiles/apparmor.d/abstractions/base @@ -26,6 +26,7 @@ /etc/locale/** r, /etc/locale.alias r, /etc/localtime r, + /etc/writable/localtime r, /usr/share/locale-langpack/** r, /usr/share/locale/** r, /usr/share/**/locale/** r, Index: b/profiles/apparmor.d/abstractions/ubuntu-browsers.d/java =================================================================== --- a/profiles/apparmor.d/abstractions/ubuntu-browsers.d/java +++ b/profiles/apparmor.d/abstractions/ubuntu-browsers.d/java @@ -36,6 +36,7 @@ /etc/lsb-release r, /etc/ssl/certs/java/* r, /etc/timezone r, + /etc/writable/timezone r, @{PROC}/@{pid}/ r, @{PROC}/@{pid}/fd/ r, @@ -80,6 +81,7 @@ /etc/lsb-release r, /etc/ssl/certs/java/* r, /etc/timezone r, + /etc/writable/timezone r, @{PROC}/@{pid}/ r, @{PROC}/@{pid}/fd/ r, Index: b/profiles/apparmor/profiles/extras/usr.lib.firefox.firefox =================================================================== --- a/profiles/apparmor/profiles/extras/usr.lib.firefox.firefox +++ b/profiles/apparmor/profiles/extras/usr.lib.firefox.firefox @@ -38,6 +38,7 @@ /tmp/.X[0-9]*-lock r, /etc/timezone r, + /etc/writable/timezone r, /etc/wildmidi/wildmidi.cfg r, # firefox specific Index: b/profiles/apparmor/profiles/extras/usr.sbin.sshd =================================================================== --- a/profiles/apparmor/profiles/extras/usr.sbin.sshd +++ b/profiles/apparmor/profiles/extras/usr.sbin.sshd @@ -172,6 +172,7 @@ /dev/ptmx rw, /etc/default/passwd r, /etc/localtime r, + /etc/writable/localtime r, /etc/login.defs r, /etc/motd r, /{,var/}run/motd{,.new} rw, debian/patches/test-signal-rules.patch0000664000000000000000000001015212316301477015225 0ustar Author: John Johansen Origin: https://lists.ubuntu.com/archives/apparmor/2014-March/005559.html Origin: https://lists.ubuntu.com/archives/apparmor/2014-March/005585.html Subject: Update test scripts for signal rules Update mkprofile.pl to generate signal rules and update test scripts to grant signal permissions when needed. Signed-off-by: John Johansen Acked-by: Tyler Hicks --- tests/regression/apparmor/exec.sh | 6 +++--- tests/regression/apparmor/mkprofile.pl | 18 ++++++++++++++++++ tests/regression/apparmor/regex.sh | 12 ++++++------ 3 files changed, 27 insertions(+), 9 deletions(-) Index: ipc-fixes-and-improvements/tests/regression/apparmor/exec.sh =================================================================== --- ipc-fixes-and-improvements.orig/tests/regression/apparmor/exec.sh 2014-03-28 16:20:26.054274933 -0500 +++ ipc-fixes-and-improvements/tests/regression/apparmor/exec.sh 2014-03-28 16:20:26.046274933 -0500 @@ -43,19 +43,19 @@ runchecktest "EXEC with px" pass $file # FAIL TEST - px/no profile -genprofile $file:$ok_px_perm +genprofile $file:$ok_px_perm signal:ALL runchecktest "EXEC with px - no profile" fail $file # NOLINK PERMTEST -genprofile $file:$badperm +genprofile $file:$badperm signal:ALL runchecktest "EXEC no x" fail $file # MMAP exec -genprofile $file:$bad_mx_perm +genprofile $file:$bad_mx_perm signal:ALL runchecktest "EXEC mmap x" fail $file Index: ipc-fixes-and-improvements/tests/regression/apparmor/mkprofile.pl =================================================================== --- ipc-fixes-and-improvements.orig/tests/regression/apparmor/mkprofile.pl 2014-03-28 16:20:26.054274933 -0500 +++ ipc-fixes-and-improvements/tests/regression/apparmor/mkprofile.pl 2014-03-28 16:20:26.046274933 -0500 @@ -174,6 +174,22 @@ sub gen_cap($) { } } +sub gen_signal($) { + my $rule = shift; + my @rules = split (/:/, $rule); + if (@rules == 2) { + if ($rules[1] =~ /^ALL$/) { + push (@{$output_rules{$hat}}, " signal,\n"); + } else { + push (@{$output_rules{$hat}}, " signal $rules[1],\n"); + } + } elsif (@rules == 3) { + push (@{$output_rules{$hat}}, " signal $rules[1] $rules[2],\n"); + } else { + (!$nowarn) && print STDERR "Warning: invalid signal description '$rule', ignored\n"; + } +} + sub gen_mount($) { my $rule = shift; my @rules = split (/:/, $rule); @@ -332,6 +348,8 @@ sub gen_from_args() { gen_network($rule); } elsif ($rule =~ /^cap:/) { gen_cap($rule); + } elsif ($rule =~ /^signal:/) { + gen_signal($rule); } elsif ($rule =~ /^mount:/) { gen_mount($rule); } elsif ($rule =~ /^remount:/) { Index: ipc-fixes-and-improvements/tests/regression/apparmor/regex.sh =================================================================== --- ipc-fixes-and-improvements.orig/tests/regression/apparmor/regex.sh 2014-03-28 16:20:26.054274933 -0500 +++ ipc-fixes-and-improvements/tests/regression/apparmor/regex.sh 2014-03-28 16:20:26.046274933 -0500 @@ -148,25 +148,25 @@ genprofile /bin/t\?ue:$okperm runchecktest "QUESTION MARK (exec)" pass $file # FAIL TEST - looking for * -genprofile /sbin/\*:$okperm +genprofile /sbin/\*:$okperm signal:ALL runchecktest "SINGLE TAILGLOB (exec, fail)" fail $file # FAIL TEST - looking for ** -genprofile /sbi\*\*:$okperm +genprofile /sbi\*\*:$okperm signal:ALL runchecktest "DOUBLE TAILGLOB (exec, fail)" fail $file # FAIL TEST - looking for { , } -genprofile /bin/\{flase,false\}:$okperm +genprofile /bin/\{flase,false\}:$okperm signal:ALL runchecktest "CURLY BRACES (exec, fail)" fail $file # FAIL TEST - looking for [] -genprofile /bin/\[aef\]rue:$okperm +genprofile /bin/\[aef\]rue:$okperm signal:ALL runchecktest "SQUARE BRACES 1 (exec, fail)" fail $file # FAIL TEST - looking for [] -genprofile /bin/\[u-x\]rue:$okperm +genprofile /bin/\[u-x\]rue:$okperm signal:ALL runchecktest "SQUARE BRACES 2 (exec, fail)" fail $file # FAIL TEST - looking for ? -genprofile /bin/b\?ue:$okperm +genprofile /bin/b\?ue:$okperm signal:ALL runchecktest "QUESTION MARK (exec, fail)" fail $file debian/patches/python-utils-ptrace-support.patch0000664000000000000000000003244412317337270017321 0ustar Author: Tyler Hicks Origin: https://lists.ubuntu.com/archives/apparmor/2014-April/005604.html Bug-Ubuntu: https://bugs.launchpad.net/bugs/1300317 Subject: utils: Basic support for ptrace rules This patch does bare bones parsing of ptrace rules and stores the raw strings for writing them out later. It is meant to be a simple change to prevent aa.py from emitting a traceback when encountering ptrace rules. Signed-off-by: Tyler Hicks Index: ipc-fixes-and-improvements/utils/apparmor/aa.py =================================================================== --- ipc-fixes-and-improvements.orig/utils/apparmor/aa.py 2014-04-03 12:58:12.548545550 -0500 +++ ipc-fixes-and-improvements/utils/apparmor/aa.py 2014-04-03 12:58:12.544545550 -0500 @@ -2625,6 +2625,7 @@ RE_NETWORK_FAMILY = re.compile('\s+(\S+) RE_PROFILE_DBUS = re.compile('^\s*(audit\s+)?(allow\s+|deny\s+)?(dbus[^#]*\s*,)\s*(#.*)?$') RE_PROFILE_MOUNT = re.compile('^\s*(audit\s+)?(allow\s+|deny\s+)?((mount|remount|umount)[^#]*\s*,)\s*(#.*)?$') RE_PROFILE_SIGNAL = re.compile('^\s*(audit\s+)?(allow\s+|deny\s+)?((signal)[^#]*\s*,)\s*(#.*)?$') +RE_PROFILE_PTRACE = re.compile('^\s*(audit\s+)?(allow\s+|deny\s+)?((ptrace)[^#]*\s*,)\s*(#.*)?$') # match anything that's not " or #, or matching quotes with anything except quotes inside __re_no_or_quoted_hash = '([^#"]|"[^"]*")*' @@ -2704,6 +2705,7 @@ def parse_profile_data(data, file, do_in profile_data[profile][hat]['allow']['dbus'] = list() profile_data[profile][hat]['allow']['mount'] = list() profile_data[profile][hat]['allow']['signal'] = list() + profile_data[profile][hat]['allow']['ptrace'] = list() # Save the initial comment if initial_comment: profile_data[profile][hat]['initial_comment'] = initial_comment @@ -3086,6 +3088,28 @@ def parse_profile_data(data, file, do_in signal_rules.append(signal_rule) profile_data[profile][hat][allow]['signal'] = signal_rules + elif RE_PROFILE_PTRACE.search(line): + matches = RE_PROFILE_PTRACE.search(line).groups() + + if not profile: + raise AppArmorException(_('Syntax Error: Unexpected ptrace entry found in file: %s line: %s') % (file, lineno + 1)) + + audit = False + if matches[0]: + audit = True + allow = 'allow' + if matches[1] and matches[1].strip() == 'deny': + allow = 'deny' + ptrace = matches[2].strip() + + ptrace_rule = parse_ptrace_rule(ptrace) + ptrace_rule.audit = audit + ptrace_rule.deny = (allow == 'deny') + + ptrace_rules = profile_data[profile][hat][allow].get('ptrace', list()) + ptrace_rules.append(ptrace_rule) + profile_data[profile][hat][allow]['ptrace'] = ptrace_rules + elif RE_PROFILE_CHANGE_HAT.search(line): matches = RE_PROFILE_CHANGE_HAT.search(line).groups() @@ -3188,6 +3212,10 @@ def parse_signal_rule(line): # XXX Do real parsing here return aarules.Raw_Signal_Rule(line) +def parse_ptrace_rule(line): + # XXX Do real parsing here + return aarules.Raw_Ptrace_Rule(line) + def separate_vars(vs): """Returns a list of all the values for a variable""" data = [] @@ -3435,6 +3463,24 @@ def write_signal(prof_data, depth): data += write_signal_rules(prof_data, depth, 'allow') return data +def write_ptrace_rules(prof_data, depth, allow): + pre = ' ' * depth + data = [] + + # no ptrace rules, so return + if not prof_data[allow].get('ptrace', False): + return data + + for ptrace_rule in prof_data[allow]['ptrace']: + data.append('%s%s' % (pre, ptrace_rule.serialize())) + data.append('') + return data + +def write_ptrace(prof_data, depth): + data = write_ptrace_rules(prof_data, depth, 'deny') + data += write_ptrace_rules(prof_data, depth, 'allow') + return data + def write_link_rules(prof_data, depth, allow): pre = ' ' * depth data = [] @@ -3542,6 +3588,7 @@ def write_rules(prof_data, depth): data += write_dbus(prof_data, depth) data += write_mount(prof_data, depth) data += write_signal(prof_data, depth) + data += write_ptrace(prof_data, depth) data += write_links(prof_data, depth) data += write_paths(prof_data, depth) data += write_change_profile(prof_data, depth) @@ -3692,6 +3739,7 @@ def serialize_profile_from_old_profile(p 'dbus': write_dbus, 'mount': write_mount, 'signal': write_signal, + 'ptrace': write_ptrace, 'link': write_links, 'path': write_paths, 'change_profile': write_change_profile, @@ -3785,6 +3833,7 @@ def serialize_profile_from_old_profile(p data += write_dbus(write_prof_data[name], depth) data += write_mount(write_prof_data[name], depth) data += write_signal(write_prof_data[name], depth) + data += write_ptrace(write_prof_data[name], depth) data += write_links(write_prof_data[name], depth) data += write_paths(write_prof_data[name], depth) data += write_change_profile(write_prof_data[name], depth) Index: ipc-fixes-and-improvements/utils/apparmor/rules.py =================================================================== --- ipc-fixes-and-improvements.orig/utils/apparmor/rules.py 2014-04-03 12:58:12.548545550 -0500 +++ ipc-fixes-and-improvements/utils/apparmor/rules.py 2014-04-03 12:58:12.544545550 -0500 @@ -79,3 +79,15 @@ class Raw_Signal_Rule(object): return "%s%s%s" % ('audit ' if self.audit else '', 'deny ' if self.deny else '', self.rule) + +class Raw_Ptrace_Rule(object): + audit = False + deny = False + + def __init__(self, rule): + self.rule = rule + + def serialize(self): + return "%s%s%s" % ('audit ' if self.audit else '', + 'deny ' if self.deny else '', + self.rule) Index: ipc-fixes-and-improvements/utils/test/test-ptrace_parse.py =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ ipc-fixes-and-improvements/utils/test/test-ptrace_parse.py 2014-04-03 12:58:12.544545550 -0500 @@ -0,0 +1,54 @@ +#! /usr/bin/env python +# ------------------------------------------------------------------ +# +# Copyright (C) 2014 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. +# +# ------------------------------------------------------------------ + +import apparmor.aa as aa +import unittest + +class AAParsePtraceTest(unittest.TestCase): + + def _test_parse_ptrace_rule(self, rule): + ptrace = aa.parse_ptrace_rule(rule) + print(ptrace.serialize()) + self.assertEqual(rule, ptrace.serialize(), + 'ptrace object returned "%s", expected "%s"' % (ptrace.serialize(), rule)) + + def test_parse_plain_ptrace_rule(self): + self._test_parse_ptrace_rule('ptrace,') + + def test_parse_readby_ptrace_rule(self): + self._test_parse_ptrace_rule('ptrace (readby),') + + def test_parse_trace_ptrace_rule(self): + self._test_parse_ptrace_rule('ptrace (trace),') + + def test_parse_trace_read_ptrace_rule(self): + self._test_parse_ptrace_rule('ptrace (trace read),') + + def test_parse_r_ptrace_rule(self): + self._test_parse_ptrace_rule('ptrace r,') + + def test_parse_w_ptrace_rule(self): + self._test_parse_ptrace_rule('ptrace w,') + + def test_parse_rw_ptrace_rule(self): + self._test_parse_ptrace_rule('ptrace rw,') + + def test_parse_peer_1_ptrace_rule(self): + self._test_parse_ptrace_rule('ptrace read peer=foo,') + + def test_parse_peer_2_ptrace_rule(self): + self._test_parse_ptrace_rule('ptrace (trace read) peer=/usr/bin/bar,') + + def test_parse_peer_3_ptrace_rule(self): + self._test_parse_ptrace_rule('ptrace wr peer=/sbin/baz,') + +if __name__ == '__main__': + unittest.main() Index: ipc-fixes-and-improvements/utils/test/test-regex_matches.py =================================================================== --- ipc-fixes-and-improvements.orig/utils/test/test-regex_matches.py 2014-04-03 12:58:12.548545550 -0500 +++ ipc-fixes-and-improvements/utils/test/test-regex_matches.py 2014-04-03 12:58:12.544545550 -0500 @@ -48,6 +48,11 @@ regex_has_comma_testcases = [ ('signal (send, receive)%s', 'embedded parens signal 01'), ('signal (send, receive) set=(hup, quit)%s', 'embedded parens signal 02'), + ('ptrace%s', 'bare ptrace'), + ('ptrace trace%s', 'simple ptrace'), + ('ptrace (tracedby, readby)%s', 'embedded parens ptrace 01'), + ('ptrace (trace) peer=/usr/bin/foo%s', 'embedded parens ptrace 02'), + # the following fail due to inadequacies in the regex # ('dbus (r, w, %s', 'incomplete dbus action'), # ('member="{Hello,AddMatch,RemoveMatch, %s', 'incomplete {} regex'), # also invalid policy @@ -106,6 +111,8 @@ regex_split_comment_testcases = [ ('file /tmp/foo rw, # read-write', ('file /tmp/foo rw, ', '# read-write')), ('signal, # comment', ('signal, ', '# comment')), ('signal receive set=(usr1 usr2) peer=foo,', False), + ('ptrace, # comment', ('ptrace, ', '# comment')), + ('ptrace (trace read) peer=/usr/bin/foo,', False), ] def setup_split_comment_testcases(): @@ -321,6 +328,77 @@ class AARegexSignal(unittest.TestCase): self.assertEqual(parsed, rule, 'Expected signal rule "%s", got "%s"' % (rule, parsed)) +class AARegexPtrace(unittest.TestCase): + '''Tests for RE_PROFILE_PTRACE''' + + def test_bare_ptrace_01(self): + '''test ' ptrace,' ''' + + rule = 'ptrace,' + line = ' %s' % rule + result = aa.RE_PROFILE_PTRACE.search(line) + self.assertTrue(result, 'Couldn\'t find ptrace rule in "%s"' % line) + parsed = result.groups()[2].strip() + self.assertEqual(parsed, rule, 'Expected ptrace rule "%s", got "%s"' + % (rule, parsed)) + + def test_bare_ptrace_02(self): + '''test ' audit ptrace,' ''' + + rule = 'ptrace,' + line = ' audit %s' % rule + result = aa.RE_PROFILE_PTRACE.search(line) + self.assertTrue(result, 'Couldn\'t find ptrace rule in "%s"' % line) + self.assertTrue(result.groups()[0], 'Couldn\'t find audit modifier in "%s"' % line) + parsed = result.groups()[2].strip() + self.assertEqual(parsed, rule, 'Expected ptrace rule "%s", got "%s"' + % (rule, parsed)) + + def test_simple_ptrace_01(self): + '''test ' ptrace trace,' ''' + + rule = 'ptrace trace,' + line = ' %s' % rule + result = aa.RE_PROFILE_PTRACE.search(line) + self.assertTrue(result, 'Couldn\'t find ptrace rule in "%s"' % line) + parsed = result.groups()[2].strip() + self.assertEqual(parsed, rule, 'Expected ptrace rule "%s", got "%s"' + % (rule, parsed)) + + def test_simple_ptrace_02(self): + '''test ' ptrace (tracedby, readby),' ''' + + rule = 'ptrace (tracedby, readby),' + line = ' %s' % rule + result = aa.RE_PROFILE_PTRACE.search(line) + self.assertTrue(result, 'Couldn\'t find ptrace rule in "%s"' % line) + parsed = result.groups()[2].strip() + self.assertEqual(parsed, rule, 'Expected ptrace rule "%s", got "%s"' + % (rule, parsed)) + + def test_simple_ptrace_03(self): + '''test ' audit ptrace (read),' ''' + + rule = 'ptrace (read),' + line = ' audit %s' % rule + result = aa.RE_PROFILE_PTRACE.search(line) + self.assertTrue(result, 'Couldn\'t find ptrace rule in "%s"' % line) + self.assertTrue(result.groups()[0], 'Couldn\'t find audit modifier in "%s"' % line) + parsed = result.groups()[2].strip() + self.assertEqual(parsed, rule, 'Expected ptrace rule "%s", got "%s"' + % (rule, parsed)) + + def test_peer_ptrace_01(self): + '''test ' ptrace trace peer=/usr/sbin/daemon,' ''' + + rule = 'ptrace trace peer=/usr/sbin/daemon,' + line = ' %s' % rule + result = aa.RE_PROFILE_PTRACE.search(line) + self.assertTrue(result, 'Couldn\'t find ptrace rule in "%s"' % line) + parsed = result.groups()[2].strip() + self.assertEqual(parsed, rule, 'Expected ptrace rule "%s", got "%s"' + % (rule, parsed)) + if __name__ == '__main__': verbosity = 2 @@ -333,6 +411,7 @@ if __name__ == '__main__': test_suite.addTest(unittest.TestLoader().loadTestsFromTestCase(AARegexPath)) test_suite.addTest(unittest.TestLoader().loadTestsFromTestCase(AARegexFile)) test_suite.addTest(unittest.TestLoader().loadTestsFromTestCase(AARegexSignal)) + test_suite.addTest(unittest.TestLoader().loadTestsFromTestCase(AARegexPtrace)) result = unittest.TextTestRunner(verbosity=verbosity).run(test_suite) if not result.wasSuccessful(): exit(1) debian/patches/symtab-tests-and-seenlist-bug.patch0000664000000000000000000001745012315367605017455 0ustar Author: Steve Beattie Origin: https://lists.ubuntu.com/archives/apparmor/2014-March/005574.html Subject: parser: refactor symtab unit tests, expand coverage, fix seenlist bug This patch: - refactors the parser_symtab.c unit tests a bit in preparation for the patch to add an implicit autofilled @{profile_name} variable - expands coverage of the unit tests such that all code paths that don't result in an exit() or are due to memory allocation errors are exercised (this doesn't mean the tests are complete; the __expand_variable() could use more tests for correctness). - it fixes a bug where variables were not being removed from the seenlist when a problem was detected in __expand_variable(). Signed-off-by: Steve Beattie --- parser/parser_symtab.c | 209 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 182 insertions(+), 27 deletions(-) Index: b/parser/parser_symtab.c =================================================================== --- a/parser/parser_symtab.c +++ b/parser/parser_symtab.c @@ -446,8 +446,9 @@ next: } symbol->expanded = expanded; - pop_seen_var(symbol->var_name); + out: + pop_seen_var(symbol->var_name); free_var_string(split); return retval; } @@ -545,12 +546,11 @@ void free_symtabs(void) #include "unit_test.h" -int main(void) +int test_compare_symtab(void) { int rc = 0; int retval; - struct set_value *retptr; - struct symtab *a, *b; + struct symtab *a, *b, *c; a = new_symtab_entry("blah"); b = new_symtab_entry("suck"); @@ -565,6 +565,181 @@ int main(void) retval = compare_symtabs(b, a); MY_TEST(retval != 0, "comparison 3"); + retval = compare_symtabs(b, b); + MY_TEST(retval == 0, "comparison 4"); + + c = new_symtab_entry("blah"); + retval = compare_symtabs(a, c); + MY_TEST(retval == 0, "comparison 5"); + + free_symtab(a); + free_symtab(b); + free_symtab(c); + + return rc; +} + +int test_seenlist(void) +{ + int rc = 0; + + MY_TEST(!is_seen("oogabooga"), "lookup unseen variable"); + + push_seen_var("oogabooga"); + MY_TEST(is_seen("oogabooga"), "lookup seen variable 1"); + MY_TEST(!is_seen("not_seen"), "lookup unseen variable 2"); + + push_seen_var("heebiejeebie"); + MY_TEST(is_seen("oogabooga"), "lookup seen variable 2"); + MY_TEST(is_seen("heebiejeebie"), "lookup seen variable 3"); + MY_TEST(!is_seen("not_seen"), "lookup unseen variable 3"); + + pop_seen_var("oogabooga"); + MY_TEST(!is_seen("oogabooga"), "lookup unseen variable 4"); + MY_TEST(is_seen("heebiejeebie"), "lookup seen variable 4"); + MY_TEST(!is_seen("not_seen"), "lookup unseen variable 5"); + + pop_seen_var("heebiejeebie"); + MY_TEST(!is_seen("heebiejeebie"), "lookup unseen variable 6"); + + //pop_seen_var("not_seen"); /* triggers assert */ + + return rc; +} + +int test_add_set_to_boolean(void) +{ + int rc = 0; + int retval; + + /* test adding a set value to a boolean variable */ + retval = add_boolean_var("not_a_set_variable", 1); + MY_TEST(retval == 0, "new boolean variable 3"); + retval = add_set_value("not_a_set_variable", "a set value"); + MY_TEST(retval != 0, "add set value to boolean"); + + free_symtabs(); + + return rc; +} + +int test_expand_bool_within_set(void) +{ + int rc = 0; + int retval; + struct symtab *retsym; + + /* test expanding a boolean var within a set variable */ + retval = add_boolean_var("not_a_set_variable", 1); + MY_TEST(retval == 0, "new boolean variable 4"); + retval = new_set_var("set_variable", "set_value@{not_a_set_variable}"); + MY_TEST(retval == 0, "add set value with embedded boolean"); + retsym = lookup_existing_symbol("set_variable"); + MY_TEST(retsym != NULL, "get set variable w/boolean"); + retval = __expand_variable(retsym); + MY_TEST(retval != 0, "expand set variable with embedded boolean"); + + free_symtabs(); + + return rc; +} + +int test_expand_recursive_set_vars(void) +{ + int rc = 0; + int retval; + struct symtab *retsym; + + /* test expanding a recursive var within a set variable */ + retval = new_set_var("recursive_1", "set_value@{recursive_2}"); + MY_TEST(retval == 0, "new recursive set variable 1"); + retval = new_set_var("recursive_2", "set_value@{recursive_3}"); + MY_TEST(retval == 0, "new recursive set variable 2"); + retval = new_set_var("recursive_3", "set_value@{recursive_1}"); + MY_TEST(retval == 0, "new recursive set variable 3"); + retsym = lookup_existing_symbol("recursive_1"); + MY_TEST(retsym != NULL, "get recursive set variable"); + retval = __expand_variable(retsym); + MY_TEST(retval != 0, "expand recursive set variable"); + + free_symtabs(); + + return rc; +} + +int test_expand_undefined_set_var(void) +{ + int rc = 0; + int retval; + struct symtab *retsym; + + /* test expanding an undefined var within a set variable */ + retval = new_set_var("defined_var", "set_value@{undefined_var}"); + MY_TEST(retval == 0, "new undefined test set variable"); + retsym = lookup_existing_symbol("defined_var"); + MY_TEST(retsym != NULL, "get undefined test set variable"); + retval = __expand_variable(retsym); + MY_TEST(retval != 0, "expand undefined set variable"); + + free_symtabs(); + + return rc; +} + +int test_expand_set_var_during_dump(void) +{ + int rc = 0; + int retval; + struct symtab *retsym; + + /* test expanding an defined var within a set variable during var dump*/ + retval = new_set_var("set_var_1", "set_value@{set_var_2}"); + MY_TEST(retval == 0, "new dump expansion set variable 1"); + retval = new_set_var("set_var_2", "some other set_value"); + MY_TEST(retval == 0, "new dump expansion set variable 2"); + retsym = lookup_existing_symbol("set_var_1"); + MY_TEST(retsym != NULL, "get dump expansion set variable 1"); + __dump_symtab_entry(retsym, 0); + __dump_symtab_entry(retsym, 1); + __dump_symtab_entry(retsym, 0); + + free_symtabs(); + + return rc; +} + +int main(void) +{ + int rc = 0; + int retval; + struct set_value *retptr; + + rc = test_compare_symtab(); + + retval = test_seenlist(); + if (rc == 0) + rc = retval; + + retval = test_add_set_to_boolean(); + if (rc == 0) + rc = retval; + + retval = test_expand_bool_within_set(); + if (rc == 0) + rc = retval; + + retval = test_expand_recursive_set_vars(); + if (rc == 0) + rc = retval; + + retval = test_expand_undefined_set_var(); + if (rc == 0) + rc = retval; + + retval = test_expand_set_var_during_dump(); + if (rc == 0) + rc = retval; + retval = new_set_var("test", "test value"); MY_TEST(retval == 0, "new set variable 1"); @@ -619,35 +794,13 @@ int main(void) retptr = get_set_var("abuse"); MY_TEST(retptr == NULL, "get set variable that's declared a boolean"); + /* test walking set values */ retptr = get_set_var("monopuff"); MY_TEST(retptr != NULL, "get set variable 1"); - retval = strcmp(get_next_set_value(&retptr), "Mockingbird"); MY_TEST(retval == 0, "get set value 1"); - MY_TEST(get_next_set_value(&retptr) == NULL, "get no more set values 1"); - MY_TEST(!is_seen("oogabooga"), "lookup unseen variable"); - - push_seen_var("oogabooga"); - MY_TEST(is_seen("oogabooga"), "lookup seen variable 1"); - MY_TEST(!is_seen("not_seen"), "lookup unseen variable 2"); - - push_seen_var("heebiejeebie"); - MY_TEST(is_seen("oogabooga"), "lookup seen variable 2"); - MY_TEST(is_seen("heebiejeebie"), "lookup seen variable 3"); - MY_TEST(!is_seen("not_seen"), "lookup unseen variable 3"); - - pop_seen_var("oogabooga"); - MY_TEST(!is_seen("oogabooga"), "lookup unseen variable 4"); - MY_TEST(is_seen("heebiejeebie"), "lookup seen variable 4"); - MY_TEST(!is_seen("not_seen"), "lookup unseen variable 5"); - - pop_seen_var("heebiejeebie"); - MY_TEST(!is_seen("heebiejeebie"), "lookup unseen variable 6"); - - //pop_seen_var("not_seen"); /* triggers assert */ - retval = new_set_var("eek", "Mocking@{monopuff}bir@{stereopuff}d@{stereopuff}"); MY_TEST(retval == 0, "new set variable 4"); @@ -656,6 +809,8 @@ int main(void) dump_symtab(); dump_expanded_symtab(); + free_symtabs(); + return rc; } #endif /* UNIT_TEST */ debian/patches/parse-mode.patch0000664000000000000000000001102612315045675013704 0ustar Author: John Johansen Forwarded: Yes Subject: make the parse_sub_mode code more generic Make it more generic so that it can be shared with signals. Signed-off-by: John Johansen --- parser/dbus.c | 71 ------------------------------------------------ parser/parser.h | 1 parser/parser_misc.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+), 70 deletions(-) --- 2.9-test.orig/parser/dbus.c +++ 2.9-test/parser/dbus.c @@ -32,79 +32,10 @@ #define _(s) gettext(s) -static int parse_dbus_sub_mode(const char *str_mode, int *result, int fail, const char *mode_desc __unused) -{ - int mode = 0; - const char *p; - - PDEBUG("Parsing DBus mode: %s\n", str_mode); - - if (!str_mode) - return 0; - - p = str_mode; - while (*p) { - char current = *p; - char lower; - -reeval: - switch (current) { - case COD_READ_CHAR: - PDEBUG("Parsing DBus mode: found %s READ\n", mode_desc); - mode |= AA_DBUS_RECEIVE; - break; - - case COD_WRITE_CHAR: - PDEBUG("Parsing DBus mode: found %s WRITE\n", - mode_desc); - mode |= AA_DBUS_SEND; - break; - - /* error cases */ - - default: - lower = tolower(current); - switch (lower) { - case COD_READ_CHAR: - case COD_WRITE_CHAR: - PDEBUG("Parsing DBus mode: found invalid upper case char %c\n", - current); - warn_uppercase(); - current = lower; - goto reeval; - break; - default: - if (fail) - yyerror(_("Internal: unexpected DBus mode character '%c' in input"), - current); - else - return 0; - break; - } - break; - } - p++; - } - - PDEBUG("Parsed DBus mode: %s 0x%x\n", str_mode, mode); - - *result = mode; - return 1; -} int parse_dbus_mode(const char *str_mode, int *mode, int fail) { - *mode = 0; - if (!parse_dbus_sub_mode(str_mode, mode, fail, "")) - return 0; - if (*mode & ~AA_VALID_DBUS_PERMS) { - if (fail) - yyerror(_("Internal error generated invalid DBus perm 0x%x\n"), - mode); - else - return 0; - } - return 1; + return parse_X_mode("DBus", AA_VALID_DBUS_PERMS, str_mode, mode, fail); } static void move_conditional_value(char **dst_ptr, struct cond_entry *cond_ent) --- 2.9-test.orig/parser/parser.h +++ 2.9-test/parser/parser.h @@ -331,6 +331,7 @@ extern int get_rlimit(const char *name); extern char *process_var(const char *var); extern int parse_mode(const char *mode); +extern int parse_X_mode(const char *X, int valid, const char *str_mode, int *mode, int fail); extern struct cod_entry *new_entry(char *ns, char *id, int mode, char *link_id); extern struct aa_network_entry *new_network_ent(unsigned int family, unsigned int type, --- 2.9-test.orig/parser/parser_misc.c +++ 2.9-test/parser/parser_misc.c @@ -792,6 +792,81 @@ return mode; } +static int parse_X_sub_mode(const char *X, const char *str_mode, int *result, int fail, const char *mode_desc __unused) +{ + int mode = 0; + const char *p; + + PDEBUG("Parsing X mode: %s\n", X, str_mode); + + if (!str_mode) + return 0; + + p = str_mode; + while (*p) { + char current = *p; + char lower; + +reeval: + switch (current) { + case COD_READ_CHAR: + PDEBUG("Parsing %s mode: found %s READ\n", X, mode_desc); + mode |= AA_DBUS_RECEIVE; + break; + + case COD_WRITE_CHAR: + PDEBUG("Parsing %s mode: found %s WRITE\n", X, + mode_desc); + mode |= AA_DBUS_SEND; + break; + + /* error cases */ + + default: + lower = tolower(current); + switch (lower) { + case COD_READ_CHAR: + case COD_WRITE_CHAR: + PDEBUG("Parsing %s mode: found invalid upper case char %c\n", + X, current); + warn_uppercase(); + current = lower; + goto reeval; + break; + default: + if (fail) + yyerror(_("Internal: unexpected %s mode character '%c' in input"), + X, current); + else + return 0; + break; + } + break; + } + p++; + } + + PDEBUG("Parsed %s mode: %s 0x%x\n", X, str_mode, mode); + + *result = mode; + return 1; +} + +int parse_X_mode(const char *X, int valid, const char *str_mode, int *mode, int fail) +{ + *mode = 0; + if (!parse_X_sub_mode(X, str_mode, mode, fail, "")) + return 0; + if (*mode & ~valid) { + if (fail) + yyerror(_("Internal error generated invalid %s perm 0x%x\n"), + X, mode); + else + return 0; + } + return 1; +} + struct cod_entry *new_entry(char *ns, char *id, int mode, char *link_id) { struct cod_entry *entry = NULL; -- AppArmor mailing list AppArmor@lists.ubuntu.com Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/apparmor debian/patches/test-ptrace-rules.patch0000664000000000000000000012456712315363773015254 0ustar Author: John Johansen Origin: https://lists.ubuntu.com/archives/apparmor/2014-March/005560.html Subject: Update test scripts for ptrace rules. Update mkprofile.pl to generate ptrace rules and update test scripts to test ptrace mediation. Signed-off-by: John Johansen --- tests/regression/apparmor/capabilities.sh | 23 +- tests/regression/apparmor/mkprofile.pl | 18 ++ tests/regression/apparmor/ptrace.sh | 144 +---------- tests/regression/apparmor/ptrace_v5.inc | 138 +++++++++++ tests/regression/apparmor/ptrace_v6.inc | 400 ++++++++++++++++++++++++++++++ 5 files changed, 582 insertions(+), 141 deletions(-) create mode 100644 tests/regression/apparmor/ptrace_v5.inc create mode 100644 tests/regression/apparmor/ptrace_v6.inc diff --git a/tests/regression/apparmor/capabilities.sh b/tests/regression/apparmor/capabilities.sh index 4eb7068..1b50445 100644 --- a/tests/regression/apparmor/capabilities.sh +++ b/tests/regression/apparmor/capabilities.sh @@ -64,6 +64,7 @@ net_raw_net_raw=TRUE # we completely disable ptrace(), but it's not clear if we should allow it # when the sys_ptrace cap is specified. +# NOTE: we handle special casing of v6 ptrace not needing ptrace cap inline syscall_ptrace_sys_ptrace=TRUE # if a test case requires arguments, add them here. @@ -77,7 +78,7 @@ syscall_ptrace_args=sub # if a testcase requires extra subdomain rules, add them here syscall_chroot_extra_entries="/:r ${tmpdir}/:r" -syscall_ptrace_extra_entries="hat:sub" +syscall_ptrace_extra_entries="ptrace:ALL hat:sub ptrace:ALL" net_raw_extra_entries="network:" testwrapper=changehat_wrapper @@ -96,7 +97,13 @@ for TEST in ${TESTS} ; do # no capabilities allowed genprofile ${my_entries} - runchecktest "${TEST} -- no caps" fail ${my_arg} + if [ "${TEST}" == "syscall_ptrace" -a "$(have_features ptrace)" == "true" ] ; then + # ptrace between profiles confining tasks of same pid is controlled by the ptrace rule + # capability + ptrace rule needed between pids + runchecktest "${TEST} -- no caps" pass ${my_arg} + else + runchecktest "${TEST} -- no caps" fail ${my_arg} + fi # all capabilities allowed genprofile cap:ALL ${my_entries} @@ -106,6 +113,8 @@ for TEST in ${TESTS} ; do for cap in ${CAPABILITIES} ; do if [ "X$(eval echo \${${TEST}_${cap}})" == "XTRUE" ] ; then expected_result=pass + elif [ "${TEST}" == "syscall_ptrace" -a "$(have_features ptrace)" == "true" ]; then + expected_result=pass else expected_result=fail fi @@ -117,7 +126,13 @@ for TEST in ${TESTS} ; do # a subprofile. settest ${testwrapper} genprofile hat:$bin/${TEST} addimage:${bin}/${TEST} ${my_entries} - runchecktest "${TEST} changehat -- no caps" fail $bin/${TEST} ${my_arg} + if [ "${TEST}" == "syscall_ptrace" -a "$(have_features ptrace)" == "true" ] ; then + # ptrace between profiles confining tasks of same pid is controlled by the ptrace rule + # capability + ptrace rule needed between pids + runchecktest "${TEST} changehat -- no caps" pass $bin/${TEST} ${my_arg} + else + runchecktest "${TEST} changehat -- no caps" fail $bin/${TEST} ${my_arg} + fi # all capabilities allowed genprofile hat:$bin/${TEST} addimage:${bin}/${TEST} cap:ALL ${my_entries} @@ -126,6 +141,8 @@ for TEST in ${TESTS} ; do for cap in ${CAPABILITIES} ; do if [ "X$(eval echo \${${TEST}_${cap}})" == "XTRUE" ] ; then expected_result=pass + elif [ "${TEST}" == "syscall_ptrace" -a "$(have_features ptrace)" == "true" ]; then + expected_result=pass else expected_result=fail fi diff --git a/tests/regression/apparmor/mkprofile.pl b/tests/regression/apparmor/mkprofile.pl index fb9ae1b..9572d0f 100755 --- a/tests/regression/apparmor/mkprofile.pl +++ b/tests/regression/apparmor/mkprofile.pl @@ -174,6 +174,22 @@ sub gen_cap($) { } } +sub gen_ptrace($) { + my $rule = shift; + my @rules = split (/:/, $rule); + if (@rules == 2) { + if ($rules[1] =~ /^ALL$/) { + push (@{$output_rules{$hat}}, " ptrace,\n"); + } else { + push (@{$output_rules{$hat}}, " ptrace $rules[1],\n"); + } + } elsif (@rules == 3) { + push (@{$output_rules{$hat}}, " ptrace $rules[1] $rules[2],\n"); + } else { + (!$nowarn) && print STDERR "Warning: invalid ptrace description '$rule', ignored\n"; + } +} + sub gen_signal($) { my $rule = shift; my @rules = split (/:/, $rule); @@ -348,6 +364,8 @@ sub gen_from_args() { gen_network($rule); } elsif ($rule =~ /^cap:/) { gen_cap($rule); + } elsif ($rule =~ /^ptrace:/) { + gen_ptrace($rule); } elsif ($rule =~ /^signal:/) { gen_signal($rule); } elsif ($rule =~ /^mount:/) { diff --git a/tests/regression/apparmor/ptrace.sh b/tests/regression/apparmor/ptrace.sh index 00d24c7..9ad851d 100755 --- a/tests/regression/apparmor/ptrace.sh +++ b/tests/regression/apparmor/ptrace.sh @@ -40,7 +40,7 @@ runchecktest "test 1 -h prog" pass -h -n 100 $helper /bin/true runchecktest "test 1 -hc prog" pass -h -c -n 100 $helper /bin/true # test that unconfined can ptrace before profile attaches -genprofile image=/bin/true +genprofile image=/bin/true signal:ALL runchecktest "test 2" pass -n 100 /bin/true runchecktest "test 2 -c" pass -c -n 100 /bin/true runchecktest "test 2 -h" pass -h -n 100 $helper @@ -48,141 +48,9 @@ runchecktest "test 2 -hc" pass -h -c -n 100 $helper runchecktest "test 2 -h prog" pass -h -n 100 $helper /bin/true runchecktest "test 2 -hc prog" pass -h -c -n 100 $helper /bin/true -#unconfined tracing confined helper -#confined helper asking unconfined process to ptrace it -genprofile image=$helper -runchecktest "test 3 -h" pass -h -n 100 $helper -runchecktest "test 3 -hc " pass -h -c -n 100 $helper -# can't exec /bin/true so fail -runchecktest "test 3 -h prog" fail -h -n 100 $helper /bin/true -runchecktest "test 3 -hc prog" fail -h -c -n 100 $helper /bin/true -# lack of 'r' perm is currently not working -genprofile image=$helper $helper:ix -runchecktest "test 4 -h" pass -h -n 100 $helper -runchecktest "test 4 -hc " pass -h -c -n 100 $helper -# can't exec /bin/true so fail -runchecktest "test 4 -h prog" fail -h -n 100 $helper /bin/true -runchecktest "test 4 -hc prog" fail -h -c -n 100 $helper /bin/true - -genprofile image=$helper $helper:rix -runchecktest "test 5 -h" pass -h -n 100 $helper -runchecktest "test 5 -hc " pass -h -c -n 100 $helper -# can't exec /bin/true so fail -runchecktest "test 5 -h prog" fail -h -n 100 $helper /bin/true -runchecktest "test 5 -hc prog" fail -h -c -n 100 $helper /bin/true - -genprofile image=$helper $helper:ix /bin/true:rix -runchecktest "test 6 -h" pass -h -n 100 $helper -runchecktest "test 6 -hc " pass -h -c -n 100 $helper -runchecktest "test 6 -h prog" pass -h -n 100 $helper /bin/true -runchecktest "test 6 -hc prog" pass -h -c -n 100 $helper /bin/true - -#traced child can ptrace_me to unconfined have unconfined trace them -genprofile image=/bin/true -runchecktest "test 7" pass -n 100 /bin/true -# pass - ptrace_attach is done in unconfined helper -runchecktest "test 7 -c " pass -c -n 100 /bin/true -runchecktest "test 7 -h" pass -h -n 100 $helper -# pass - ptrace_attach is done in unconfined helper -runchecktest "test 7 -hc " pass -h -c -n 100 $helper -runchecktest "test 7 -h prog" pass -h -n 100 $helper /bin/true -runchecktest "test 7 -hc prog" pass -h -c -n 100 $helper /bin/true - -genprofile image=$helper $helper:ix /bin/true:rix -runchecktest "test 7a" pass -n 100 /bin/true -# pass - ptrace_attach is allowed from confined process to unconfined -runchecktest "test 7a -c " pass -c -n 100 /bin/true -runchecktest "test 7a -h" pass -h -n 100 $helper -# pass - ptrace_attach is allowed from confined process to unconfined -runchecktest "test 7a -hc " pass -h -c -n 100 $helper -runchecktest "test 7a -h prog" pass -h -n 100 $helper /bin/true -runchecktest "test 7a -hc prog" pass -h -c -n 100 $helper /bin/true - -#traced helper from unconfined -genprofile image=$helper $helper:ix /bin/true:rpx -- image=/bin/true -runchecktest "test 8" pass -n 100 /bin/true -# pass - ptrace_attach is done before exec -runchecktest "test 8 -c " pass -c -n 100 /bin/true -runchecktest "test 8 -h" pass -h -n 100 $helper -runchecktest "test 8 -hc " pass -h -c -n 100 $helper -# pass - can px if tracer can ptrace target -runchecktest "test 8 -h prog" pass -h -n 100 $helper /bin/true -runchecktest "test 8 -hc prog" pass -h -c -n 100 $helper /bin/true - -#traced helper from unconfined -genprofile image=$helper $helper:ix /bin/true:rux -- image=/bin/true -runchecktest "test 9" pass -n 100 /bin/true -# pass - ptrace_attach is done before exec -runchecktest "test 9 -c " pass -c -n 100 /bin/true -runchecktest "test 9 -h" pass -h -n 100 $helper -runchecktest "test 9 -hc " pass -h -c -n 100 $helper -# pass - can ux if tracer can ptrace target -runchecktest "test 9 -h prog" pass -h -n 100 $helper /bin/true -runchecktest "test 9 -hc prog" pass -h -c -n 100 $helper /bin/true - -genprofile -# fail due to no exec permission -runchecktest "test 10" fail -n 100 /bin/true -runchecktest "test 10 -c" fail -c -n 100 /bin/true -runchecktest "test 10 -h" fail -h -n 100 $helper -runchecktest "test 10 -hc" fail -h -c -n 100 $helper -runchecktest "test 10 -h prog" fail -h -n 100 $helper /bin/true -runchecktest "test 10 -hc prog" fail -h -c -n 100 $helper /bin/true - -genprofile /bin/true:ix $helper:ix -# fail due to missing r permission -#runchecktest "test 11" fail -n 100 /bin/true -#runchecktest "test 11 -c" fail -c -n 100 /bin/true -#runchecktest "test 11 -h" fail -h -n 100 $helper -#runchecktest "test 11 -hc" fail -h -c -n 100 $helper -#runchecktest "test 11 -h prog" fail -h -n 100 $helper /bin/true -#runchecktest "test 11 -hc prog" fail -h -c -n 100 $helper /bin/true - -# pass allowed to ix self -genprofile /bin/true:rix $helper:rix -runchecktest "test 12" pass -n 100 /bin/true -runchecktest "test 12 -c" pass -c -n 100 /bin/true -runchecktest "test 12 -h" pass -h -n 100 $helper -runchecktest "test 12 -hc" pass -h -c -n 100 $helper -runchecktest "test 12 -h prog" pass -h -n 100 $helper /bin/true -runchecktest "test 12 -hc prog" pass -h -c -n 100 $helper /bin/true - -#ptraced confined app can't px - fails to unset profile -genprofile image=$helper $helper:rix /bin/true:rpx -runchecktest "test 13 -h prog" fail -h -n 100 $helper /bin/true -runchecktest "test 13 -hc prog" fail -h -c -n 100 $helper /bin/true - - -#ptraced confined app can ux - if the tracer is unconfined -# -genprofile image=$helper $helper:rix /bin/true:rux -runchecktest "test 14a -h prog" pass -h -n 100 $helper /bin/true -runchecktest "test 14a -hc prog" pass -h -c -n 100 $helper /bin/true -#ptraced confined app can't ux - if the tracer can't trace unconfined -genprofile $helper:rpx -- image=$helper $helper:rix /bin/true:rux -runchecktest "test 14b -h prog" fail -h -n 100 $helper /bin/true -runchecktest "test 14b -hc prog" fail -h -c -n 100 $helper /bin/true - -#confined app can't ptrace an unconfined app -genprofile $helper:rux -runchecktest "test 15 -h" fail -h -n 100 $helper -runchecktest "test 15 -h prog" fail -h -n 100 $helper /bin/true -#an unconfined app can't ask a confined app to trace it -runchecktest "test 15 -hc" fail -h -c -n 100 $helper -runchecktest "test 15 -hc prog" fail -h -c -n 100 $helper /bin/true - -#confined app can't ptrace an app confined by a different profile -genprofile $helper:rpx -- image=$helper -runchecktest "test 15 -h" fail -h -n 100 $helper -runchecktest "test 15 -h prog" fail -h -n 100 $helper /bin/true -#a confined app can't ask another confined app with a different profile to -#trace it -runchecktest "test 15 -hc" fail -h -c -n 100 $helper -runchecktest "test 15 -hc prog" fail -h -c -n 100 $helper /bin/true - - - - -# need to do a confined process trying to attach to an unconfined -# need attaching, and ptrace_me of different confinement +if [ "$(have_features ptrace)" == "true" ] ; then + . $bin/ptrace_v6.inc +else + . $bin/ptrace_v5.inc +fi diff --git a/tests/regression/apparmor/ptrace_v5.inc b/tests/regression/apparmor/ptrace_v5.inc new file mode 100644 index 0000000..428410a --- /dev/null +++ b/tests/regression/apparmor/ptrace_v5.inc @@ -0,0 +1,138 @@ +#unconfined tracing confined helper +#confined helper asking unconfined process to ptrace it +genprofile image=$helper +runchecktest "test 3 -h" pass -h -n 100 $helper +runchecktest "test 3 -hc " pass -h -c -n 100 $helper +# can't exec /bin/true so fail +runchecktest "test 3 -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 3 -hc prog" fail -h -c -n 100 $helper /bin/true + +# lack of 'r' perm is currently not working +genprofile image=$helper $helper:ix +runchecktest "test 4 -h" pass -h -n 100 $helper +runchecktest "test 4 -hc " pass -h -c -n 100 $helper +# can't exec /bin/true so fail +runchecktest "test 4 -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 4 -hc prog" fail -h -c -n 100 $helper /bin/true + +genprofile image=$helper $helper:rix +runchecktest "test 5 -h" pass -h -n 100 $helper +runchecktest "test 5 -hc " pass -h -c -n 100 $helper +# can't exec /bin/true so fail +runchecktest "test 5 -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 5 -hc prog" fail -h -c -n 100 $helper /bin/true + +genprofile image=$helper $helper:ix /bin/true:rix +runchecktest "test 6 -h" pass -h -n 100 $helper +runchecktest "test 6 -hc " pass -h -c -n 100 $helper +runchecktest "test 6 -h prog" pass -h -n 100 $helper /bin/true +runchecktest "test 6 -hc prog" pass -h -c -n 100 $helper /bin/true + +#traced child can ptrace_me to unconfined have unconfined trace them +genprofile image=/bin/true +runchecktest "test 7" pass -n 100 /bin/true +# pass - ptrace_attach is done in unconfined helper +runchecktest "test 7 -c " pass -c -n 100 /bin/true +runchecktest "test 7 -h" pass -h -n 100 $helper +# pass - ptrace_attach is done in unconfined helper +runchecktest "test 7 -hc " pass -h -c -n 100 $helper +runchecktest "test 7 -h prog" pass -h -n 100 $helper /bin/true +runchecktest "test 7 -hc prog" pass -h -c -n 100 $helper /bin/true + +genprofile image=$helper $helper:ix /bin/true:rix +runchecktest "test 7a" pass -n 100 /bin/true +# pass - ptrace_attach is allowed from confined process to unconfined +runchecktest "test 7a -c " pass -c -n 100 /bin/true +runchecktest "test 7a -h" pass -h -n 100 $helper +# pass - ptrace_attach is allowed from confined process to unconfined +runchecktest "test 7a -hc " pass -h -c -n 100 $helper +runchecktest "test 7a -h prog" pass -h -n 100 $helper /bin/true +runchecktest "test 7a -hc prog" pass -h -c -n 100 $helper /bin/true + +#traced helper from unconfined +genprofile image=$helper $helper:ix /bin/true:rpx -- image=/bin/true +runchecktest "test 8" pass -n 100 /bin/true +# pass - ptrace_attach is done before exec +runchecktest "test 8 -c " pass -c -n 100 /bin/true +runchecktest "test 8 -h" pass -h -n 100 $helper +runchecktest "test 8 -hc " pass -h -c -n 100 $helper +# pass - can px if tracer can ptrace target +runchecktest "test 8 -h prog" pass -h -n 100 $helper /bin/true +runchecktest "test 8 -hc prog" pass -h -c -n 100 $helper /bin/true + +#traced helper from unconfined +genprofile image=$helper $helper:ix /bin/true:rux -- image=/bin/true +runchecktest "test 9" pass -n 100 /bin/true +# pass - ptrace_attach is done before exec +runchecktest "test 9 -c " pass -c -n 100 /bin/true +runchecktest "test 9 -h" pass -h -n 100 $helper +runchecktest "test 9 -hc " pass -h -c -n 100 $helper +# pass - can ux if tracer can ptrace target +runchecktest "test 9 -h prog" pass -h -n 100 $helper /bin/true +runchecktest "test 9 -hc prog" pass -h -c -n 100 $helper /bin/true + +genprofile +# fail due to no exec permission +runchecktest "test 10" fail -n 100 /bin/true +runchecktest "test 10 -c" fail -c -n 100 /bin/true +runchecktest "test 10 -h" fail -h -n 100 $helper +runchecktest "test 10 -hc" fail -h -c -n 100 $helper +runchecktest "test 10 -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 10 -hc prog" fail -h -c -n 100 $helper /bin/true + +genprofile /bin/true:ix $helper:ix +# fail due to missing r permission +#runchecktest "test 11" fail -n 100 /bin/true +#runchecktest "test 11 -c" fail -c -n 100 /bin/true +#runchecktest "test 11 -h" fail -h -n 100 $helper +#runchecktest "test 11 -hc" fail -h -c -n 100 $helper +#runchecktest "test 11 -h prog" fail -h -n 100 $helper /bin/true +#runchecktest "test 11 -hc prog" fail -h -c -n 100 $helper /bin/true + +# pass allowed to ix self +genprofile /bin/true:rix $helper:rix +runchecktest "test 12" pass -n 100 /bin/true +runchecktest "test 12 -c" pass -c -n 100 /bin/true +runchecktest "test 12 -h" pass -h -n 100 $helper +runchecktest "test 12 -hc" pass -h -c -n 100 $helper +runchecktest "test 12 -h prog" pass -h -n 100 $helper /bin/true +runchecktest "test 12 -hc prog" pass -h -c -n 100 $helper /bin/true + +#ptraced confined app can't px - fails to unset profile +genprofile image=$helper $helper:rix /bin/true:rpx +runchecktest "test 13 -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 13 -hc prog" fail -h -c -n 100 $helper /bin/true + + +#ptraced confined app can ux - if the tracer is unconfined +# +genprofile image=$helper $helper:rix /bin/true:rux +runchecktest "test 14a -h prog" pass -h -n 100 $helper /bin/true +runchecktest "test 14a -hc prog" pass -h -c -n 100 $helper /bin/true +#ptraced confined app can't ux - if the tracer can't trace unconfined +genprofile $helper:rpx -- image=$helper $helper:rix /bin/true:rux +runchecktest "test 14b -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 14b -hc prog" fail -h -c -n 100 $helper /bin/true + +#confined app can't ptrace an unconfined app +genprofile $helper:rux +runchecktest "test 15 -h" fail -h -n 100 $helper +runchecktest "test 15 -h prog" fail -h -n 100 $helper /bin/true +#an unconfined app can't ask a confined app to trace it +runchecktest "test 15 -hc" fail -h -c -n 100 $helper +runchecktest "test 15 -hc prog" fail -h -c -n 100 $helper /bin/true + +#confined app can't ptrace an app confined by a different profile +genprofile $helper:rpx -- image=$helper +runchecktest "test 15 -h" fail -h -n 100 $helper +runchecktest "test 15 -h prog" fail -h -n 100 $helper /bin/true +#a confined app can't ask another confined app with a different profile to +#trace it +runchecktest "test 15 -hc" fail -h -c -n 100 $helper +runchecktest "test 15 -hc prog" fail -h -c -n 100 $helper /bin/true + + + + +# need to do a confined process trying to attach to an unconfined +# need attaching, and ptrace_me of different confinement diff --git a/tests/regression/apparmor/ptrace_v6.inc b/tests/regression/apparmor/ptrace_v6.inc new file mode 100644 index 0000000..f4c2088 --- /dev/null +++ b/tests/regression/apparmor/ptrace_v6.inc @@ -0,0 +1,400 @@ +## v5 ptrace tests except with failures where appropriate. Testing that capability ptrace +## does not grant ptrace perms + +## Note: ptrace tests need signal permissions to function correctly +## signal permissions are not actually needed by all tests to function but +## we grant signal perms to all to be consistent + +echo " using ptrace v6 tests ..." + +################################################################################ +# v5 ptrace tests without ptrace rules +################################################################################ + +#unconfined tracing confined helper +#confined helper asking unconfined process to ptrace it +genprofile image=$helper signal:ALL + +runchecktest "test 3 -h" pass -h -n 100 $helper +runchecktest "test 3 -hc " pass -h -c -n 100 $helper +# can't exec /bin/true so fail +runchecktest "test 3 -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 3 -hc prog" fail -h -c -n 100 $helper /bin/true + +# lack of 'r' perm is currently not working +genprofile image=$helper $helper:ix signal:ALL +runchecktest "test 4 -h" pass -h -n 100 $helper +runchecktest "test 4 -hc " pass -h -c -n 100 $helper +# can't exec /bin/true so fail +runchecktest "test 4 -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 4 -hc prog" fail -h -c -n 100 $helper /bin/true + +genprofile image=$helper $helper:rix signal:ALL +runchecktest "test 5 -h" pass -h -n 100 $helper +runchecktest "test 5 -hc " pass -h -c -n 100 $helper +# can't exec /bin/true so fail +runchecktest "test 5 -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 5 -hc prog" fail -h -c -n 100 $helper /bin/true + +genprofile image=$helper $helper:ix /bin/true:rix signal:ALL +runchecktest "test 6 -h" pass -h -n 100 $helper +runchecktest "test 6 -hc " pass -h -c -n 100 $helper +runchecktest "test 6 -h prog" pass -h -n 100 $helper /bin/true +runchecktest "test 6 -hc prog" pass -h -c -n 100 $helper /bin/true + +#traced child can ptrace_me to unconfined have unconfined trace them +genprofile image=/bin/true signal:ALL +runchecktest "test 7" pass -n 100 /bin/true +# pass - ptrace_attach is done in unconfined helper +runchecktest "test 7 -c " pass -c -n 100 /bin/true +runchecktest "test 7 -h" pass -h -n 100 $helper +# pass - ptrace_attach is done in unconfined helper +runchecktest "test 7 -hc " pass -h -c -n 100 $helper +runchecktest "test 7 -h prog" pass -h -n 100 $helper /bin/true +runchecktest "test 7 -hc prog" pass -h -c -n 100 $helper /bin/true + +genprofile image=$helper $helper:ix /bin/true:rix signal:ALL +runchecktest "test 7a" pass -n 100 /bin/true +# pass - ptrace_attach is allowed from confined process to unconfined +runchecktest "test 7a -c " pass -c -n 100 /bin/true +runchecktest "test 7a -h" pass -h -n 100 $helper +# pass - ptrace_attach is allowed from confined process to unconfined +runchecktest "test 7a -hc " pass -h -c -n 100 $helper +runchecktest "test 7a -h prog" pass -h -n 100 $helper /bin/true +runchecktest "test 7a -hc prog" pass -h -c -n 100 $helper /bin/true + +#traced helper from unconfined +genprofile image=$helper $helper:ix /bin/true:rpx signal:ALL -- image=/bin/true signal:ALL +runchecktest "test 8" pass -n 100 /bin/true +# pass - ptrace_attach is done before exec +runchecktest "test 8 -c " pass -c -n 100 /bin/true +runchecktest "test 8 -h" pass -h -n 100 $helper +runchecktest "test 8 -hc " pass -h -c -n 100 $helper +# pass - can px if tracer can ptrace target +runchecktest "test 8 -h prog" pass -h -n 100 $helper /bin/true +runchecktest "test 8 -hc prog" pass -h -c -n 100 $helper /bin/true + +#traced helper from unconfined +genprofile image=$helper $helper:ix /bin/true:rux signal:ALL -- image=/bin/true signal:ALL +runchecktest "test 9" pass -n 100 /bin/true +# pass - ptrace_attach is done before exec +runchecktest "test 9 -c " pass -c -n 100 /bin/true +runchecktest "test 9 -h" pass -h -n 100 $helper +runchecktest "test 9 -hc " pass -h -c -n 100 $helper +# pass - can ux if tracer can ptrace target +runchecktest "test 9 -h prog" pass -h -n 100 $helper /bin/true +runchecktest "test 9 -hc prog" pass -h -c -n 100 $helper /bin/true + +genprofile signal:ALL +# fail due to no exec permission +runchecktest "test 10" fail -n 100 /bin/true +runchecktest "test 10 -c" fail -c -n 100 /bin/true +runchecktest "test 10 -h" fail -h -n 100 $helper +runchecktest "test 10 -hc" fail -h -c -n 100 $helper +runchecktest "test 10 -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 10 -hc prog" fail -h -c -n 100 $helper /bin/true + +genprofile /bin/true:ix $helper:ix signal:ALL +# fail due to missing r permission +#runchecktest "test 11" fail -n 100 /bin/true +#runchecktest "test 11 -c" fail -c -n 100 /bin/true +#runchecktest "test 11 -h" fail -h -n 100 $helper +#runchecktest "test 11 -hc" fail -h -c -n 100 $helper +#runchecktest "test 11 -h prog" fail -h -n 100 $helper /bin/true +#runchecktest "test 11 -hc prog" fail -h -c -n 100 $helper /bin/true + +# fail was pass in v5 allowed to ix self +genprofile /bin/true:rix $helper:rix signal:ALL +runchecktest "test 12" fail -n 100 /bin/true +runchecktest "test 12 -c" fail -c -n 100 /bin/true +runchecktest "test 12 -h" fail -h -n 100 $helper +runchecktest "test 12 -hc" fail -h -c -n 100 $helper +runchecktest "test 12 -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 12 -hc prog" fail -h -c -n 100 $helper /bin/true + +#ptraced confined app traced by unconfined can px +genprofile image=$helper $helper:rix /bin/true:rpx signal:ALL -- image=/bin/true /bin/true:rix +runchecktest "test 13u -h prog" pass -h -n 100 $helper /bin/true +runchecktest "test 13u -hc prog" pass -h -c -n 100 $helper /bin/true + +#ptraced confined app traced by profile without ptrace on targeted can't px +genprofile /bin/true:rpx signal:ALL -- image=/bin/true /bin/true:rix +runchecktest "test 13 -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 13 -hc prog" fail -h -c -n 100 $helper /bin/true + + +#ptraced confined app can ux - if the tracer is unconfined +# +genprofile image=$helper $helper:rix /bin/true:rux signal:ALL +runchecktest "test 14a -h prog" pass -h -n 100 $helper /bin/true +runchecktest "test 14a -hc prog" pass -h -c -n 100 $helper /bin/true +#ptraced confined app can't ux - if the tracer can't trace unconfined +genprofile $helper:rpx signal:ALL -- image=$helper $helper:rix /bin/true:rux signal:ALL +runchecktest "test 14b -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 14b -hc prog" fail -h -c -n 100 $helper /bin/true + +#confined app can't ptrace an unconfined app +genprofile $helper:rux signal:ALL +runchecktest "test 15 -h" fail -h -n 100 $helper +runchecktest "test 15 -h prog" fail -h -n 100 $helper /bin/true +#an unconfined app can't ask a confined app to trace it +runchecktest "test 15 -hc" fail -h -c -n 100 $helper +runchecktest "test 15 -hc prog" fail -h -c -n 100 $helper /bin/true + +#confined app can't ptrace an app confined by a different profile +genprofile $helper:rpx signal:ALL -- image=$helper signal:ALL +runchecktest "test 15 -h" fail -h -n 100 $helper +runchecktest "test 15 -h prog" fail -h -n 100 $helper /bin/true +#a confined app can't ask another confined app with a different profile to +#trace it +runchecktest "test 15 -hc" fail -h -c -n 100 $helper +runchecktest "test 15 -hc prog" fail -h -c -n 100 $helper /bin/true + +################### cap:sys_ptrace doesn't change results from above ########################## +# fail was pass in v5 allowed to ix self +genprofile /bin/true:rix $helper:rix signal:ALL cap:sys_ptrace +runchecktest "test 12c" fail -n 100 /bin/true +runchecktest "test 12c -c" fail -c -n 100 /bin/true +runchecktest "test 12c -h" fail -h -n 100 $helper +runchecktest "test 12c -hc" fail -h -c -n 100 $helper +runchecktest "test 12c -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 12c -hc prog" fail -h -c -n 100 $helper /bin/true + +#ptraced confined app traced by unconfined can px +genprofile image=$helper $helper:rix /bin/true:rpx signal:ALL cap:sys_ptrace -- image=/bin/true /bin/true:rix cap:sys_ptrace +runchecktest "test 13cu -h prog" pass -h -n 100 $helper /bin/true +runchecktest "test 13cu -hc prog" pass -h -c -n 100 $helper /bin/true + +#ptraced confined app traced by profile without ptrace on targeted can't px +genprofile /bin/true:rpx signal:ALL cap:sys_ptrace -- image=/bin/true /bin/true:rix cap:sys_ptrace +runchecktest "test 13c -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 13c -hc prog" fail -h -c -n 100 $helper /bin/true + + +#ptraced confined app can ux - if the tracer is unconfined +# +genprofile image=$helper $helper:rix /bin/true:rux signal:ALL cap:sys_ptrace +runchecktest "test 14ca -h prog" pass -h -n 100 $helper /bin/true +runchecktest "test 14ca -hc prog" pass -h -c -n 100 $helper /bin/true +#ptraced confined app can't ux - if the tracer can't trace unconfined +genprofile $helper:rpx signal:ALL -- image=$helper $helper:rix /bin/true:rux signal:ALL +runchecktest "test 14cb -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 14cb -hc prog" fail -h -c -n 100 $helper /bin/true + +#confined app can't ptrace an unconfined app +genprofile $helper:rux signal:ALL cap:sys_ptrace +runchecktest "test 15c -h" fail -h -n 100 $helper +runchecktest "test 15c -h prog" fail -h -n 100 $helper /bin/true +#an unconfined app can't ask a confined app to trace it +runchecktest "test 15c -hc" fail -h -c -n 100 $helper +runchecktest "test 15c -hc prog" fail -h -c -n 100 $helper /bin/true + +#confined app can't ptrace an app confined by a different profile +genprofile $helper:rpx signal:ALL cap:sys_ptrace -- image=$helper signal:ALL cap:sys_ptrace +runchecktest "test 15c -h" fail -h -n 100 $helper +runchecktest "test 15c -h prog" fail -h -n 100 $helper /bin/true +#a confined app can't ask another confined app with a different profile to +#trace it +runchecktest "test 15c -hc" fail -h -c -n 100 $helper +runchecktest "test 15c -hc prog" fail -h -c -n 100 $helper /bin/true + + +################################################################################ +# v5 ptrace tests with ptrace rules +################################################################################ + +##### Now do tests with ptrace rules in profiles ####### +# pass in v5 allowed to ix self +genprofile /bin/true:rix $helper:rix signal:ALL ptrace:ALL +runchecktest "test 12p" pass -n 100 /bin/true +runchecktest "test 12p -c" pass -c -n 100 /bin/true +runchecktest "test 12p -h" pass -h -n 100 $helper +runchecktest "test 12p -hc" pass -h -c -n 100 $helper +runchecktest "test 12p -h prog" pass -h -n 100 $helper /bin/true +runchecktest "test 12p -hc prog" pass -h -c -n 100 $helper /bin/true +genprofile /bin/true:rix $helper:rix signal:ALL ptrace:$test +runchecktest "test 12p1" pass -n 100 /bin/true +runchecktest "test 12p1 -c" pass -c -n 100 /bin/true +runchecktest "test 12p1 -h" pass -h -n 100 $helper +runchecktest "test 12p1 -hc" pass -h -c -n 100 $helper +runchecktest "test 12p1 -h prog" pass -h -n 100 $helper /bin/true +runchecktest "test 12p1 -hc prog" pass -h -c -n 100 $helper /bin/true +genprofile /bin/true:rix $helper:rix signal:ALL ptrace:notaprofile +runchecktest "test 12p2" fail -n 100 /bin/true +runchecktest "test 12p2 -c" fail -c -n 100 /bin/true +runchecktest "test 12p2 -h" fail -h -n 100 $helper +runchecktest "test 12p2 -hc" fail -h -c -n 100 $helper +runchecktest "test 12p2 -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 12p2 -hc prog" fail -h -c -n 100 $helper /bin/true + + +#ptraced confined app traced by profile can px +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:/bin/true -- image=/bin/true /bin/true:rix +runchecktest "test 13p1 -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 13p2 -hc prog" fail -h -c -n 100 $helper /bin/true +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:/bin/true -- image=/bin/true /bin/true:rix ptrace:tracedby +runchecktest "test 13p3 -h prog" pass -h -n 100 $helper /bin/true +runchecktest "test 13p4 -hc prog" pass -h -c -n 100 $helper /bin/true +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:/bin/true -- image=/bin/true /bin/true:rix ptrace:tracedby:$test +runchecktest "test 13p5 -h prog" pass -h -n 100 $helper /bin/true +runchecktest "test 13p6 -hc prog" pass -h -c -n 100 $helper /bin/true +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:/bin/true -- image=/bin/true /bin/true:rix ptrace:tracedby:notaprofile +runchecktest "test 13p7 -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 13p8 -hc prog" fail -h -c -n 100 $helper /bin/true +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:/bin/true -- image=/bin/true /bin/true:rix ptrace:trace +runchecktest "test 13p9 -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 13pa -hc prog" fail -h -c -n 100 $helper /bin/true +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:/bin/true -- image=/bin/true /bin/true:rix ptrace:trace:$test +runchecktest "test 13pb -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 13pc -hc prog" fail -h -c -n 100 $helper /bin/true +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:/bin/true -- image=/bin/true /bin/true:rix ptrace:trace:notaprofile +runchecktest "test 13pd -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 13pe -hc prog" fail -h -c -n 100 $helper /bin/true + + +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:trace:/bin/true -- image=/bin/true /bin/true:rix +runchecktest "test 13p11 -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 13p21 -hc prog" fail -h -c -n 100 $helper /bin/true +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:trace:/bin/true -- image=/bin/true /bin/true:rix ptrace:tracedby +runchecktest "test 13p31 -h prog" pass -h -n 100 $helper /bin/true +runchecktest "test 13p41 -hc prog" pass -h -c -n 100 $helper /bin/true +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:trace:/bin/true -- image=/bin/true /bin/true:rix ptrace:tracedby:$test +runchecktest "test 13p51 -h prog" pass -h -n 100 $helper /bin/true +runchecktest "test 13p61 -hc prog" pass -h -c -n 100 $helper /bin/true +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:trace:/bin/true -- image=/bin/true /bin/true:rix ptrace:tracedby:notaprofile +runchecktest "test 13p71 -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 13p81 -hc prog" fail -h -c -n 100 $helper /bin/true +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:trace:/bin/true -- image=/bin/true /bin/true:rix ptrace:trace +runchecktest "test 13p91 -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 13pa1 -hc prog" fail -h -c -n 100 $helper /bin/true +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:trace:/bin/true -- image=/bin/true /bin/true:rix ptrace:trace:$test +runchecktest "test 13pb1 -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 13pc1 -hc prog" fail -h -c -n 100 $helper /bin/true +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:trace:/bin/true -- image=/bin/true /bin/true:rix ptrace:trace:notaprofile +runchecktest "test 13pd1 -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 13pe1 -hc prog" fail -h -c -n 100 $helper /bin/true + + +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:ALL -- image=/bin/true /bin/true:rix +runchecktest "test 13p12 -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 13p22 -hc prog" fail -h -c -n 100 $helper /bin/true +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:ALL -- image=/bin/true /bin/true:rix ptrace:tracedby +runchecktest "test 13p32 -h prog" pass -h -n 100 $helper /bin/true +runchecktest "test 13p42 -hc prog" pass -h -c -n 100 $helper /bin/true +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:ALL -- image=/bin/true /bin/true:rix ptrace:tracedby:$test +runchecktest "test 13p52 -h prog" pass -h -n 100 $helper /bin/true +runchecktest "test 13p62 -hc prog" pass -h -c -n 100 $helper /bin/true +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:ALL -- image=/bin/true /bin/true:rix ptrace:tracedby:notaprofile +runchecktest "test 13p72 -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 13p82 -hc prog" fail -h -c -n 100 $helper /bin/true +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:ALL -- image=/bin/true /bin/true:rix ptrace:trace +runchecktest "test 13p92 -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 13pa2 -hc prog" fail -h -c -n 100 $helper /bin/true +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:ALL -- image=/bin/true /bin/true:rix ptrace:trace:$test +runchecktest "test 13pb2 -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 13pc2 -hc prog" fail -h -c -n 100 $helper /bin/true +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:ALL -- image=/bin/true /bin/true:rix ptrace:trace:notaprofile +runchecktest "test 13pd2 -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 13pe2 -hc prog" fail -h -c -n 100 $helper /bin/true + +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:tracedby -- image=/bin/true /bin/true:rix +runchecktest "test 13p13 -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 13p23 -hc prog" fail -h -c -n 100 $helper /bin/true +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:tracedby -- image=/bin/true /bin/true:rix ptrace:tracedby +runchecktest "test 13p33 -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 13p43 -hc prog" fail -h -c -n 100 $helper /bin/true +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:tracedby -- image=/bin/true /bin/true:rix ptrace:tracedby:$test +runchecktest "test 13p53 -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 13p63 -hc prog" fail -h -c -n 100 $helper /bin/true +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:tracedby -- image=/bin/true /bin/true:rix ptrace:tracedby:notaprofile +runchecktest "test 13p73 -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 13p83 -hc prog" fail -h -c -n 100 $helper /bin/true +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:tracedby -- image=/bin/true /bin/true:rix ptrace:trace +runchecktest "test 13p93 -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 13pa3 -hc prog" fail -h -c -n 100 $helper /bin/true +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:tracedby -- image=/bin/true /bin/true:rix ptrace:trace:$test +runchecktest "test 13pb3 -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 13pc3 -hc prog" fail -h -c -n 100 $helper /bin/true +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:tracedby -- image=/bin/true /bin/true:rix ptrace:trace:notaprofile +runchecktest "test 13pd3 -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 13pe3 -hc prog" fail -h -c -n 100 $helper /bin/true + +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:tracedby:notaprofile -- image=/bin/true /bin/true:rix +runchecktest "test 13p14 -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 13p24 -hc prog" fail -h -c -n 100 $helper /bin/true +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:tracedby:notaprofile -- image=/bin/true /bin/true:rix ptrace:tracedby +runchecktest "test 13p34 -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 13p44 -hc prog" fail -h -c -n 100 $helper /bin/true +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:tracedby:notaprofile -- image=/bin/true /bin/true:rix ptrace:tracedby:$test +runchecktest "test 13p54 -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 13p64 -hc prog" fail -h -c -n 100 $helper /bin/true +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:tracedby:notaprofile -- image=/bin/true /bin/true:rix ptrace:tracedby:notaprofile +runchecktest "test 13p74 -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 13p84 -hc prog" fail -h -c -n 100 $helper /bin/true +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:tracedby:notaprofile -- image=/bin/true /bin/true:rix ptrace:trace +runchecktest "test 13p94 -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 13pa4 -hc prog" fail -h -c -n 100 $helper /bin/true +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:tracedby:notaprofile -- image=/bin/true /bin/true:rix ptrace:trace:$test +runchecktest "test 13pb4 -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 13pc4 -hc prog" fail -h -c -n 100 $helper /bin/true +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:tracedby:notaprofile -- image=/bin/true /bin/true:rix ptrace:trace:notaprofile +runchecktest "test 13pd4 -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 13pe4 -hc prog" fail -h -c -n 100 $helper /bin/true + +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:notaprofile -- image=/bin/true /bin/true:rix +runchecktest "test 13p15 -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 13p25 -hc prog" fail -h -c -n 100 $helper /bin/true +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:notaprofile -- image=/bin/true /bin/true:rix ptrace:tracedby +runchecktest "test 13p35 -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 13p45 -hc prog" fail -h -c -n 100 $helper /bin/true +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:notaprofile -- image=/bin/true /bin/true:rix ptrace:tracedby:$test +runchecktest "test 13p55 -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 13p65 -hc prog" fail -h -c -n 100 $helper /bin/true +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:notaprofile -- image=/bin/true /bin/true:rix ptrace:tracedby:notaprofile +runchecktest "test 13p75 -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 13p85 -hc prog" fail -h -c -n 100 $helper /bin/true +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:notaprofile -- image=/bin/true /bin/true:rix ptrace:trace +runchecktest "test 13p95 -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 13pa5 -hc prog" fail -h -c -n 100 $helper /bin/true +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:notaprofile -- image=/bin/true /bin/true:rix ptrace:trace:$test +runchecktest "test 13pb5 -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 13pc5 -hc prog" fail -h -c -n 100 $helper /bin/true +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:notaprofile -- image=/bin/true /bin/true:rix ptrace:trace:notaprofile +runchecktest "test 13pd5 -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 13pe5 -hc prog" fail -h -c -n 100 $helper /bin/true + + +### todo Variations of below tests + + +#ptraced confined app can ux - if the tracer is unconfined +# +genprofile image=$helper $helper:rix /bin/true:rux signal:ALL +runchecktest "test 14pa -h prog" pass -h -n 100 $helper /bin/true +runchecktest "test 14pa -hc prog" pass -h -c -n 100 $helper /bin/true +#ptraced confined app can't ux - if the tracer can't trace unconfined +genprofile $helper:rpx signal:ALL -- image=$helper $helper:rix /bin/true:rux signal:ALL +runchecktest "test 14pb -h prog" fail -h -n 100 $helper /bin/true +runchecktest "test 14pb -hc prog" fail -h -c -n 100 $helper /bin/true + +#confined app can't ptrace an unconfined app +genprofile $helper:rux signal:ALL +runchecktest "test 15p -h" fail -h -n 100 $helper +runchecktest "test 15p -h prog" fail -h -n 100 $helper /bin/true +#an unconfined app can't ask a confined app to trace it +runchecktest "test 15p -hc" fail -h -c -n 100 $helper +runchecktest "test 15p -hc prog" fail -h -c -n 100 $helper /bin/true + +#confined app can't ptrace an app confined by a different profile +genprofile $helper:rpx signal:ALL -- image=$helper signal:ALL +runchecktest "test 15p -h" fail -h -n 100 $helper +runchecktest "test 15p -h prog" fail -h -n 100 $helper /bin/true +#a confined app can't ask another confined app with a different profile to +#trace it +runchecktest "test 15p -hc" fail -h -c -n 100 $helper +runchecktest "test 15p -hc prog" fail -h -c -n 100 $helper /bin/true + + +## TODO: ptrace read tests +## TODO: ptrace + change_profile +## TODO: ptrace + change_hat -- 1.9.1 debian/patches/mediate-signals.patch0000664000000000000000000004610312315357464014724 0ustar Author: John Johansen Origin: https://lists.ubuntu.com/archives/apparmor/2014-March/005557.html Subject: Add the ability to mediate signals. Add signal rules and make sure the parser encodes support for them if the supported feature set reports supporting them. The current format of the signal rule is [audit] [deny] signal [] [] , signal_perm := 'send'|'receive'|'r'|'w'|'rw' signal_perms := | '(' ([,])* ')' signal := ("hup"|"int"|"quit"|"ill"|"trap"|"abrt"|"bus"|"fpe"|"kill"| "usr1"|"segv"|"usr2"|"pipe"|"alrm"|"term"|"tkflt"|"chld"| "cont"|"stop"|"stp"|"ttin"|"ttou"|"urg"|"xcpu"|"xfsz"|"vtalrm"| "prof"|"winch"|"io"|"pwr"|"sys"|"emt"|"exists") signal_set := set= | '(' ([,])* ')' it does not currently follow the peer=() format, and there is some question as to whether it should or not. Input welcome. --- parser/Makefile | 8 - parser/parser.h | 5 parser/parser_common.c | 1 parser/parser_lex.l | 22 ++- parser/parser_main.c | 2 parser/parser_misc.c | 1 parser/parser_regex.c | 7 - parser/parser_yacc.y | 68 ++++++++++ parser/policydb.h | 1 parser/signal.c | 315 +++++++++++++++++++++++++++++++++++++++++++++++++ parser/signal.h | 58 +++++++++ 11 files changed, 476 insertions(+), 12 deletions(-) --- 2.9-test.orig/parser/Makefile +++ 2.9-test/parser/Makefile @@ -79,9 +79,10 @@ SRCS = parser_common.c parser_include.c parser_interface.c parser_lex.c \ parser_main.c parser_misc.c parser_merge.c parser_symtab.c \ parser_yacc.c parser_regex.c parser_variable.c parser_policy.c \ - parser_alias.c mount.c dbus.c lib.c profile.cc rule.c common_optarg.c + parser_alias.c mount.c dbus.c lib.c profile.cc rule.c common_optarg.c \ + signal.c HDRS = parser.h parser_include.h immunix.h mount.h dbus.h lib.h profile.h \ - rule.h common_optarg.h + rule.h common_optarg.h signal.h TOOLS = apparmor_parser OBJECTS = $(SRCS:.c=.o) @@ -244,6 +245,9 @@ dbus.o: dbus.c dbus.h parser.h immunix.h parser_yacc.h rule.h $(APPARMOR_H) $(CXX) $(EXTRA_CFLAGS) -c -o $@ $< +signal.o: signal.c signal.h parser.h immunix.h parser_yacc.h rule.h $(APPARMOR_H) + $(CXX) $(EXTRA_CFLAGS) -c -o $@ $< + profile.o: profile.cc profile.h parser.h $(CXX) $(EXTRA_CFLAGS) -c -o $@ $< --- 2.9-test.orig/parser/parser.h +++ 2.9-test/parser/parser.h @@ -298,6 +298,7 @@ extern int kernel_supports_diff_encode; extern int kernel_supports_mount; extern int kernel_supports_dbus; +extern int kernel_supports_signal; extern int conf_verbose; extern int conf_quiet; extern int names_only; @@ -330,7 +331,9 @@ extern const char *basedir; /* parser_regex.c */ -extern const char *default_match_pattern; +#define default_match_pattern "[^\\000]*" +#define anyone_match_pattern "[^\\000]+" + extern pattern_t convert_aaregex_to_pcre(const char *aare, int anchor, std::string& pcre, int *first_re_pos); extern int build_list_val_expr(std::string& buffer, struct value_list *list); --- 2.9-test.orig/parser/parser_common.c +++ 2.9-test/parser/parser_common.c @@ -71,6 +71,7 @@ int kernel_supports_mount = 0; /* kernel supports mount rules */ int kernel_supports_dbus = 0; /* kernel supports dbus rules */ int kernel_supports_diff_encode = 0; /* kernel supports diff_encode */ +int kernel_supports_signal = 0; /* kernel supports signal rules */ int conf_verbose = 0; int conf_quiet = 0; int names_only = 0; --- 2.9-test.orig/parser/parser_lex.l +++ 2.9-test/parser/parser_lex.l @@ -253,6 +253,7 @@ %x RLIMIT_MODE %x MOUNT_MODE %x DBUS_MODE +%x SIGNAL_MODE %x CHANGE_PROFILE_MODE %x INCLUDE @@ -267,7 +268,7 @@ } %} -{ +{ {WS}+ { DUMP_PREPROCESS; /* Ignoring whitespace */ } } @@ -293,7 +294,7 @@ yyterminate(); } -{ +{ {VARIABLE_NAME}/{WS}*= { /* we match to the = in the lexer so that we can switch scanner * state. By the time the parser see the = it may be too late @@ -462,12 +463,15 @@ } { + bind { RETURN_TOKEN(TOK_BIND); } + eavesdrop { RETURN_TOKEN(TOK_EAVESDROP); } +} + +{ send { RETURN_TOKEN(TOK_SEND); } receive { RETURN_TOKEN(TOK_RECEIVE); } - bind { RETURN_TOKEN(TOK_BIND); } read { RETURN_TOKEN(TOK_READ); } write { RETURN_TOKEN(TOK_WRITE); } - eavesdrop { RETURN_TOKEN(TOK_EAVESDROP); } {OPEN_PAREN} { PUSH_AND_RETURN(LIST_VAL_MODE, TOK_OPENPAREN); } @@ -477,7 +481,7 @@ } } -{ +{ {ARROW} { RETURN_TOKEN(TOK_ARROW); } ({IDS_NOEQ}|{PATHNAME}|{QUOTED_ID}) { @@ -566,13 +570,16 @@ case TOK_DBUS: state = DBUS_MODE; break; + case TOK_SIGNAL: + state = SIGNAL_MODE; + break; default: /* nothing */ break; } PUSH_AND_RETURN(state, token); } -{ +{ {END_OF_RULE} { if (YY_START != INITIAL) POP(); @@ -585,7 +592,7 @@ } } -{ +{ [^\n] { DUMP_PREPROCESS; /* Something we didn't expect */ @@ -612,6 +619,7 @@ STATE_TABLE_ENT(RLIMIT_MODE), STATE_TABLE_ENT(MOUNT_MODE), STATE_TABLE_ENT(DBUS_MODE), + STATE_TABLE_ENT(SIGNAL_MODE), STATE_TABLE_ENT(CHANGE_PROFILE_MODE), STATE_TABLE_ENT(INCLUDE), }; --- 2.9-test.orig/parser/parser_main.c +++ 2.9-test/parser/parser_main.c @@ -695,6 +695,8 @@ kernel_supports_mount = 1; if (strstr(features_string, "dbus")) kernel_supports_dbus = 1; + if (strstr(features_string, "signal")) + kernel_supports_signal = 1; if (strstr(features_string, "diff_encode")) kernel_supports_diff_encode = 1; else if (dfaflags & DFA_CONTROL_DIFF_ENCODE) --- 2.9-test.orig/parser/parser_misc.c +++ 2.9-test/parser/parser_misc.c @@ -142,6 +142,7 @@ {"pivot_root", TOK_PIVOTROOT}, {"in", TOK_IN}, {"dbus", TOK_DBUS}, + {"signal", TOK_SIGNAL}, {"send", TOK_SEND}, {"receive", TOK_RECEIVE}, {"bind", TOK_BIND}, --- 2.9-test.orig/parser/parser_regex.c +++ 2.9-test/parser/parser_regex.c @@ -43,8 +43,6 @@ e_parse_error, }; -/* match any char except \000 0 or more times */ -const char *default_match_pattern = "[^\\000]*"; /* Filters out multiple slashes (except if the first two are slashes, * that's a distinct namespace in linux) and trailing slashes. @@ -675,6 +673,7 @@ static const char *mediates_file = CLASS_STR(AA_CLASS_FILE); static const char *mediates_mount = CLASS_STR(AA_CLASS_MOUNT); static const char *mediates_dbus = CLASS_STR(AA_CLASS_DBUS); +static const char *mediates_signal = CLASS_STR(AA_CLASS_SIGNAL); int process_profile_policydb(Profile *prof) { @@ -701,6 +700,10 @@ if (kernel_supports_dbus && !prof->policy.rules->add_rule(mediates_dbus, 0, AA_MAY_READ, 0, dfaflags)) goto out; + if (kernel_supports_signal && + !prof->policy.rules->add_rule(mediates_signal, 0, AA_MAY_READ, 0, dfaflags)) + goto out; + if (prof->policy.rules->rule_count > 0) { prof->policy.dfa = prof->policy.rules->create_dfa(&prof->policy.size, dfaflags); delete prof->policy.rules; --- 2.9-test.orig/parser/parser_yacc.y +++ 2.9-test/parser/parser_yacc.y @@ -28,6 +28,8 @@ #include #include #include + +#include #define _(s) gettext(s) /* #define DEBUG */ @@ -128,6 +130,7 @@ %token TOK_PIVOTROOT %token TOK_IN %token TOK_DBUS +%token TOK_SIGNAL %token TOK_SEND %token TOK_RECEIVE %token TOK_BIND @@ -166,6 +169,7 @@ #include "profile.h" #include "mount.h" #include "dbus.h" + #include "signal.h" } %union { @@ -179,6 +183,7 @@ mnt_rule *mnt_entry; dbus_rule *dbus_entry; + signal_rule *signal_entry; flagvals flags; int fmode; @@ -241,6 +246,10 @@ %type dbus_perms %type opt_dbus_perm %type dbus_rule +%type signal_perm +%type signal_perms +%type opt_signal_perm +%type signal_rule %type opt_named_transition %type opt_unsafe %type opt_file @@ -698,6 +707,22 @@ $$ = $1; } +rules: rules opt_prefix signal_rule + { + if ($2.owner) + yyerror(_("owner prefix not allowed on signal rules")); + if ($2.deny && $2.audit) { + $3->deny = 1; + } else if ($2.deny) { + $3->deny = 1; + $3->audit = $3->mode; + } else if ($2.audit) { + $3->audit = $3->mode; + } + $1->rule_ents.push_back($3); + $$ = $1; + } + rules: rules change_profile { PDEBUG("matched: rules change_profile\n"); @@ -1214,6 +1239,49 @@ $$ = ent; } +signal_perm: TOK_VALUE + { + if (strcmp($1, "send") == 0 || strcmp($1, "write") == 0) + $$ = AA_MAY_SEND; + else if (strcmp($1, "receive") == 0 || strcmp($1, "read") == 0) + $$ = AA_MAY_RECEIVE; + else if ($1) { + parse_signal_mode($1, &$$, 1); + } else + $$ = 0; + + if ($1) + free($1); + } + | TOK_SEND { $$ = AA_MAY_SEND; } + | TOK_RECEIVE { $$ = AA_MAY_RECEIVE; } + | TOK_READ { $$ = AA_MAY_RECEIVE; } + | TOK_WRITE { $$ = AA_MAY_SEND; } + | TOK_MODE + { + parse_signal_mode($1, &$$, 1); + free($1); + } + +signal_perms: { /* nothing */ $$ = 0; } + | signal_perms signal_perm { $$ = $1 | $2; } + | signal_perms TOK_COMMA signal_perm { $$ = $1 | $3; } + +opt_signal_perm: { /* nothing */ $$ = 0; } + | signal_perm { $$ = $1; } + | TOK_OPENPAREN signal_perms TOK_CLOSEPAREN { $$ = $2; } + +signal_rule: TOK_SIGNAL opt_signal_perm opt_conds TOK_END_OF_RULE + { + signal_rule *ent = new signal_rule($2, $3, NULL); + $$ = ent; + } + | TOK_SIGNAL opt_signal_perm opt_conds TOK_ID TOK_END_OF_RULE + { + signal_rule *ent = new signal_rule($2, $3, $4); + $$ = ent; + } + hat_start: TOK_CARET {} | TOK_HAT {} --- 2.9-test.orig/parser/policydb.h +++ 2.9-test/parser/policydb.h @@ -31,6 +31,7 @@ #define AA_CLASS_MOUNT 7 #define AA_CLASS_NS_DOMAIN 8 #define AA_CLASS_PTRACE 9 +#define AA_CLASS_SIGNAL 10 #define AA_CLASS_LABEL 16 --- /dev/null +++ 2.9-test/parser/signal.c @@ -0,0 +1,315 @@ +/* + * Copyright (c) 2014 + * 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 +#include +#include + +#include +#include +#include +#include +#include + +#include "parser.h" +#include "profile.h" +#include "parser_yacc.h" +#include "signal.h" + +#define MAXMAPPED_SIG 35 +#define MINRT_SIG 128 /* base of RT sigs */ +#define MAXRT_SIG 32 /* Max RT above MINRT_SIG */ + +/* Signal names mapped to and internal ordering */ +static struct signal_map { const char *name; int num; } signal_map[] = { + {"hup", 1}, + {"int", 2}, + {"quit", 3}, + {"ill", 4}, + {"trap", 5}, + {"abrt", 6}, + {"bus", 7}, + {"fpe", 8}, + {"kill", 9}, + {"usr1", 10}, + {"segv", 11}, + {"usr2", 12}, + {"pipe", 13}, + {"alrm", 14}, + {"term", 15}, + {"stkflt", 16}, + {"chld", 17}, + {"cont", 18}, + {"stop", 19}, + {"stp", 20}, + {"ttin", 21}, + {"ttou", 22}, + {"urg", 23}, + {"xcpu", 24}, + {"xfsz", 25}, + {"vtalrm", 26}, + {"prof", 27}, + {"winch", 28}, + {"io", 29}, + {"pwr", 30}, + {"sys", 31}, + {"emt", 32}, + {"exists", 35}, + + /* terminate */ + {NULL, 0} +}; + +/* this table is ordered post sig_map[sig] mapping */ +static const char *const sig_names[MAXMAPPED_SIG + 1] = { + "unknown", + "hup", + "int", + "quit", + "ill", + "trap", + "abrt", + "bus", + "fpe", + "kill", + "usr1", + "segv", + "usr2", + "pipe", + "alrm", + "term", + "stkflt", + "chld", + "cont", + "stop", + "stp", + "ttin", + "ttou", + "urg", + "xcpu", + "xfsz", + "vtalrm", + "prof", + "winch", + "io", + "pwr", + "sys", + "emt", + "lost", + "unused", + + "exists", /* always last existance test mapped to MAXMAPPED_SIG */ +}; + + +int parse_signal_mode(const char *str_mode, int *mode, int fail) +{ + return parse_X_mode("signal", AA_VALID_SIGNAL_PERMS, str_mode, mode, fail); +} + +static int find_signal_mapping(const char *sig) +{ + if (strncmp("rtmin+", sig, 6) == 0) { + char *end; + unsigned long n = strtoul(sig + 6, &end, 10); + if (end == sig || n > MAXRT_SIG) + return -1; + return MINRT_SIG + n; + } else { + for (int i = 0; signal_map[i].name; i++) { + if (strcmp(sig, signal_map[i].name) == 0) + return signal_map[i].num; + } + } + return -1; +} + +void signal_rule::extract_sigs(struct value_list **list) +{ + struct value_list *entry, *tmp, *prev = NULL; + list_for_each_safe(*list, entry, tmp) { + int i = find_signal_mapping(entry->value); + if (i != -1) { + signals.insert(i); + list_remove_at(*list, prev, entry); + free_value_list(entry); + } else { + yyerror("unknown signal \"%s\"\n", entry->value); + prev = entry; + } + } +} + +void signal_rule::move_conditionals(struct cond_entry *conds) +{ + struct cond_entry *cond_ent; + + list_for_each(conds, cond_ent) { + /* for now disallow keyword 'in' (list) */ + if (!cond_ent->eq) + yyerror("keyword \"in\" is not allowed in signal rules\n"); + if (strcmp(cond_ent->name, "set") == 0) { + extract_sigs(&cond_ent->vals); + } else { + yyerror("invalid signal rule conditional \"%s\"\n", + cond_ent->name); + } + } +} + +signal_rule::signal_rule(int mode_p, struct cond_entry *conds, + char *peer): + signals(), peer_label(peer), audit(0), deny(0) +{ + if (mode_p) { + mode = mode_p; + if (mode & ~AA_VALID_SIGNAL_PERMS) + yyerror("mode contains invalid permission for signals\n"); + } else { + mode = AA_VALID_SIGNAL_PERMS; + } + + move_conditionals(conds); + + free_cond_list(conds); +} + +ostream &signal_rule::dump(ostream &os) +{ + if (audit) + os << "audit "; + if (deny) + os << "deny "; + + os << "signal"; + + if (mode != AA_VALID_SIGNAL_PERMS) { + os << " ("; + + if (mode & AA_MAY_SEND) + os << "send "; + if (mode & AA_MAY_RECEIVE) + os << "receive "; + os << ")"; + } + + if (!signals.empty()) { + os << " set=("; + for (Signals::iterator i = signals.begin(); i != signals.end(); + i++) { + if (i != signals.begin()) + os << ", "; + if (*i < MINRT_SIG) + os << sig_names[*i]; + else + os << "rtmin+" << (*i - MINRT_SIG); + } + os << ")"; + } + + if (peer_label) + os << " " << peer_label; + + os << ",\n"; + + return os; +} + +int signal_rule::expand_variables(void) +{ + return expand_entry_variables(&peer_label); +} + +/* do we want to warn once/profile or just once per compile?? */ +static void warn_once(const char *name) +{ + static const char *warned_name = NULL; + + if (warned_name != name) { + cerr << "Warning from profile " << name << " ("; + if (current_filename) + cerr << current_filename; + else + cerr << "stdin"; + cerr << ") signal rules not enforced\n"; + warned_name = name; + } +} + +int signal_rule::gen_policy_re(Profile &prof) +{ + std::ostringstream buffer; + std::string buf; + + pattern_t ptype; + int pos; + + /* Currently do not generate the rules if the kernel doesn't support + * it. We may want to switch this so that a compile could be + * used for full support on kernels that don't support the feature + */ + if (!kernel_supports_signal) { + warn_once(prof.name); + return RULE_NOT_SUPPORTED; + } + + if (signals.size() == 0) { + /* not conditional on signal set, so will generate a label + * rule as well + */ + buffer << "(" << "\\x" << std::setfill('0') << std::setw(2) << std::hex << AA_CLASS_LABEL << "\\x" << AA_CLASS_SIGNAL << "|"; + } + + buffer << "\\x" << std::setfill('0') << std::setw(2) << std::hex << AA_CLASS_SIGNAL; + + if (signals.size()) { + buffer << "["; + for (Signals::iterator i = signals.begin(); i != signals.end(); i++) { + buffer << "\\x" << std::setfill('0') << std::setw(2) << std::hex << *i; + } + buffer << "]"; + } else { + /* match any char */ + buffer << "."; + } + + if (signals.size() == 0) { + /* close alternation */ + buffer << ")"; + } + if (peer_label) { + ptype = convert_aaregex_to_pcre(peer_label, 0, buf, &pos); + if (ptype == ePatternInvalid) + goto fail; + buffer << buf; + } else { + buffer << anyone_match_pattern; + } + + buf = buffer.str(); + if (mode & (AA_MAY_SEND | AA_MAY_RECEIVE)) { + if (!prof.policy.rules->add_rule(buf.c_str(), deny, mode, audit, + dfaflags)) + goto fail; + } + + return RULE_OK; + +fail: + return RULE_ERROR; +} --- /dev/null +++ 2.9-test/parser/signal.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2014 + * 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. + */ + +#ifndef __AA_SIGNAL_H +#define __AA_SIGNAL_H + +#include "parser.h" +#include "rule.h" +#include "profile.h" + + +#define AA_MAY_SEND (1 << 1) +#define AA_MAY_RECEIVE (1 << 2) +#define AA_VALID_SIGNAL_PERMS (AA_MAY_SEND | AA_MAY_RECEIVE) + + +typedef set Signals; + +int parse_signal_mode(const char *str_mode, int *mode, int fail); + +class signal_rule: public rule_t { + void extract_sigs(struct value_list **list); + void move_conditionals(struct cond_entry *conds); +public: + Signals signals; + char *peer_label; + int mode; + int audit; + int deny; + + signal_rule(int mode, struct cond_entry *conds, char *peer); + virtual ~signal_rule() { + signals.clear(); + free(peer_label); + }; + + virtual ostream &dump(ostream &os); + virtual int expand_variables(void); + virtual int gen_policy_re(Profile &prof); + virtual void post_process(Profile &prof __unused) { }; +}; + +#endif /* __AA_SIGNAL_H */ debian/patches/update-chromium-browser.patch0000664000000000000000000000555312317275370016443 0ustar Author: Jamie Strandboge Description: Update chromium-browser profile Updates for newer chromium-browser and AppArmor ptrace mediation. --- a/profiles/apparmor.d/usr.bin.chromium-browser 2014-04-03 09:36:59.192597849 -0500 +++ b/profiles/apparmor.d/usr.bin.chromium-browser 2014-04-03 09:45:16.255516274 -0500 @@ -40,6 +40,7 @@ owner @{PROC}/[0-9]*/stat r, @{PROC}/[0-9]*/statm r, owner @{PROC}/[0-9]*/status r, + owner @{PROC}/[0-9]*/oom_{,score_}adj w, # Newer chromium needs these now /etc/udev/udev.conf r, @@ -80,6 +81,9 @@ # Noisy deny /usr/lib/chromium-browser/** w, + # Allow ptracing ourselves + ptrace (trace) peer=@{profile_name}, + # Make browsing directories work / r, /**/ r, @@ -95,6 +99,10 @@ owner @{HOME}/Downloads/ r, owner @{HOME}/Downloads/* rw, + # For migration + owner @{HOME}/.mozilla/firefox/profiles.ini r, + owner @{HOME}/.mozilla/firefox/*/prefs.js r, + # Helpers /usr/bin/xdg-open ixr, /usr/bin/gnome-open ixr, @@ -126,6 +134,7 @@ /bin/ps Uxr, /usr/lib/chromium-browser/xdg-settings Cxr -> xdgsettings, /usr/bin/xdg-settings Cxr -> xdgsettings, + /usr/bin/lsb_release Cxr -> lsb_release, # GSettings owner /{,var/}run/user/*/dconf/ rw, @@ -163,12 +172,30 @@ owner @{HOME}/.local/share/applications/mimeapps.list* rw, } + profile lsb_release { + #include + #include + /usr/bin/lsb_release r, + /bin/dash ixr, + /usr/bin/dpkg-query ixr, + /usr/include/python2.[4567]/pyconfig.h r, + /etc/lsb-release r, + /etc/debian_version r, + /var/lib/dpkg/** r, + + /usr/local/lib/python3.[0-4]/dist-packages/ r, + /usr/bin/ r, + /usr/bin/python3.[0-4] r, + } + + # Site-specific additions and overrides. See local/README for details. #include profile chromium_browser_sandbox { # Be fanatical since it is setuid root and don't use an abstraction /lib/libgcc_s.so* mr, + /lib/@{multiarch}/libgcc_s.so* mr, /lib{,32,64}/libm-*.so* mr, /lib/@{multiarch}/libm-*.so* mr, /lib{,32,64}/libpthread-*.so* mr, @@ -183,6 +210,7 @@ /lib/tls/*/{cmov,nosegneg}/libpthread-*.so* mr, /lib/tls/*/{cmov,nosegneg}/libc-*.so* mr, /usr/lib/libstdc++.so* mr, + /usr/lib/@{multiarch}/libstdc++.so* mr, /etc/ld.so.cache r, # Required for dropping into PID namespace. Keep in mind that until the @@ -198,14 +226,14 @@ capability dac_override, capability sys_chroot, - # *Sigh* capability sys_ptrace, + ptrace (read, readby), @{PROC}/ r, @{PROC}/[0-9]*/ r, @{PROC}/[0-9]*/fd/ r, - @{PROC}/[0-9]*/oom_adj w, - @{PROC}/[0-9]*/oom_score_adj w, + owner @{PROC}/[0-9]*/oom_adj w, + owner @{PROC}/[0-9]*/oom_score_adj w, @{PROC}/[0-9]*/status r, @{PROC}/[0-9]*/task/[0-9]*/stat r, debian/patches/change-signal-syntax.patch0000664000000000000000000001646012315361313015671 0ustar Author: John Johansen Origin: https://lists.ubuntu.com/archives/apparmor/2014-March/005563.html Subject: change syntax to specify a signals target from signal /foo, to signal peer=/foo, Signed-off-by: John Johansen --- parser/dbus.c | 22 ++++++---------------- parser/parser.h | 8 ++++++++ parser/parser_lex.l | 18 ++++++++++-------- parser/parser_misc.c | 11 +++++++++++ parser/parser_yacc.y | 25 ++++++++++++++----------- parser/signal.c | 7 ++++--- parser/signal.h | 2 +- 7 files changed, 54 insertions(+), 39 deletions(-) --- 2.9-test.orig/parser/dbus.c +++ 2.9-test/parser/dbus.c @@ -38,16 +38,6 @@ return parse_X_mode("DBus", AA_VALID_DBUS_PERMS, str_mode, mode, fail); } -static void move_conditional_value(char **dst_ptr, struct cond_entry *cond_ent) -{ - if (*dst_ptr) - yyerror("dbus conditional \"%s\" can only be specified once\n", - cond_ent->name); - - *dst_ptr = cond_ent->vals->value; - cond_ent->vals->value = NULL; -} - void dbus_rule::move_conditionals(struct cond_entry *conds) { struct cond_entry *cond_ent; @@ -61,17 +51,17 @@ cond_ent->name); if (strcmp(cond_ent->name, "bus") == 0) { - move_conditional_value(&bus, cond_ent); + move_conditional_value("dbus", &bus, cond_ent); } else if (strcmp(cond_ent->name, "name") == 0) { - move_conditional_value(&name, cond_ent); + move_conditional_value("dbus", &name, cond_ent); } else if (strcmp(cond_ent->name, "label") == 0) { - move_conditional_value(&peer_label, cond_ent); + move_conditional_value("dbus", &peer_label, cond_ent); } else if (strcmp(cond_ent->name, "path") == 0) { - move_conditional_value(&path, cond_ent); + move_conditional_value("dbus", &path, cond_ent); } else if (strcmp(cond_ent->name, "interface") == 0) { - move_conditional_value(&interface, cond_ent); + move_conditional_value("dbus", &interface, cond_ent); } else if (strcmp(cond_ent->name, "member") == 0) { - move_conditional_value(&member, cond_ent); + move_conditional_value("dbus", &member, cond_ent); } else { yyerror("invalid dbus conditional \"%s\"\n", cond_ent->name); --- 2.9-test.orig/parser/parser.h +++ 2.9-test/parser/parser.h @@ -78,6 +78,12 @@ struct cond_entry *next; }; +struct cond_entry_list { + char *name; + + struct cond_entry *list; +}; + struct cod_entry { char *ns; char *name; @@ -362,6 +368,8 @@ extern void free_value_list(struct value_list *list); extern void print_value_list(struct value_list *list); extern struct cond_entry *new_cond_entry(char *name, int eq, struct value_list *list); +extern void move_conditional_value(const char *rulename, char **dst_ptr, + struct cond_entry *cond_ent); extern void free_cond_entry(struct cond_entry *ent); extern void free_cond_list(struct cond_entry *ents); extern void print_cond_entry(struct cond_entry *ent); --- 2.9-test.orig/parser/parser_lex.l +++ 2.9-test/parser/parser_lex.l @@ -295,19 +295,21 @@ } { + {VARIABLE_NAME}/{WS}*={WS}*\( { + /* we match to the = in the lexer so that we can switch scanner + * state. By the time the parser see the = it may be too late + * as bison may have requested the next token from the scanner + */ + yylval.id = processid(yytext, yyleng); + PUSH_AND_RETURN(EXTCONDLIST_MODE, TOK_CONDLISTID); + } {VARIABLE_NAME}/{WS}*= { /* we match to the = in the lexer so that we can switch scanner * state. By the time the parser see the = it may be too late * as bison may have requested the next token from the scanner */ - int token = get_keyword_token(yytext); - - if (token == TOK_PEER) { - PUSH_AND_RETURN(EXTCONDLIST_MODE, TOK_CONDLISTID); - } else { - yylval.id = processid(yytext, yyleng); - PUSH_AND_RETURN(EXTCOND_MODE, TOK_CONDID); - } + yylval.id = processid(yytext, yyleng); + PUSH_AND_RETURN(EXTCOND_MODE, TOK_CONDID); } {VARIABLE_NAME}/{WS}+in{WS}*\( { /* we match to 'in' in the lexer so that we can switch scanner --- 2.9-test.orig/parser/parser_misc.c +++ 2.9-test/parser/parser_misc.c @@ -1205,6 +1205,17 @@ } } +void move_conditional_value(const char *rulename, char **dst_ptr, + struct cond_entry *cond_ent) +{ + if (*dst_ptr) + yyerror("%s conditional \"%s\" can only be specified once\n", + rulename, cond_ent->name); + + *dst_ptr = cond_ent->vals->value; + cond_ent->vals->value = NULL; +} + struct cond_entry *new_cond_entry(char *name, int eq, struct value_list *list) { struct cond_entry *ent = (struct cond_entry *) calloc(1, sizeof(struct cond_entry)); --- 2.9-test.orig/parser/parser_yacc.y +++ 2.9-test/parser/parser_yacc.y @@ -166,6 +166,7 @@ %token TOK_FLAGS %code requires { + #include "parser.h" #include "profile.h" #include "mount.h" #include "dbus.h" @@ -194,6 +195,7 @@ char *var_val; struct value_list *val_list; struct cond_entry *cond_entry; + struct cond_entry_list cond_entry_list; int boolean; struct named_transition transition; struct prefixes prefix; @@ -219,8 +221,8 @@ %type mnt_rule %type opt_conds %type cond -%type cond_list -%type opt_cond_list +%type cond_list +%type opt_cond_list %type flags %type flagvals %type flagval @@ -1145,10 +1147,11 @@ cond_list: TOK_CONDLISTID TOK_EQUALS TOK_OPENPAREN opt_conds TOK_CLOSEPAREN { - $$ = $4; + $$.name = $1; + $$.list = $4; } -opt_cond_list: { /* nothing */ $$ = NULL; } +opt_cond_list: { /* nothing */ $$ = { NULL, NULL }; } | cond_list { $$ = $1; } mnt_rule: TOK_MOUNT opt_conds opt_id TOK_END_OF_RULE @@ -1232,7 +1235,12 @@ { dbus_rule *ent; - ent = new dbus_rule($2, $3, $4); + if ($4.name) { + if (strcmp($4.name, "peer") != 0) + yyerror(_("dbus rule: invalid conditional group %s=()"), $4.name); + free($4.name); + } + ent = new dbus_rule($2, $3, $4.list); if (!ent) { yyerror(_("Memory allocation error.")); } @@ -1273,12 +1281,7 @@ signal_rule: TOK_SIGNAL opt_signal_perm opt_conds TOK_END_OF_RULE { - signal_rule *ent = new signal_rule($2, $3, NULL); - $$ = ent; - } - | TOK_SIGNAL opt_signal_perm opt_conds TOK_ID TOK_END_OF_RULE - { - signal_rule *ent = new signal_rule($2, $3, $4); + signal_rule *ent = new signal_rule($2, $3); $$ = ent; } --- 2.9-test.orig/parser/signal.c +++ 2.9-test/parser/signal.c @@ -165,6 +165,8 @@ yyerror("keyword \"in\" is not allowed in signal rules\n"); if (strcmp(cond_ent->name, "set") == 0) { extract_sigs(&cond_ent->vals); + } else if (strcmp(cond_ent->name, "peer") == 0) { + move_conditional_value("signal", &peer_label, cond_ent); } else { yyerror("invalid signal rule conditional \"%s\"\n", cond_ent->name); @@ -172,9 +174,8 @@ } } -signal_rule::signal_rule(int mode_p, struct cond_entry *conds, - char *peer): - signals(), peer_label(peer), audit(0), deny(0) +signal_rule::signal_rule(int mode_p, struct cond_entry *conds): + signals(), peer_label(NULL), audit(0), deny(0) { if (mode_p) { mode = mode_p; --- 2.9-test.orig/parser/signal.h +++ 2.9-test/parser/signal.h @@ -43,7 +43,7 @@ int audit; int deny; - signal_rule(int mode, struct cond_entry *conds, char *peer); + signal_rule(int mode, struct cond_entry *conds); virtual ~signal_rule() { signals.clear(); free(peer_label); debian/patches/fix-names-treated-as-condlistid.patch0000664000000000000000000000200012315371464017706 0ustar Author: John Johansen Origin: backport, https://lists.ubuntu.com/archives/apparmor/2014-March/005579.html Subject: fix: the what names can treated as a condlistid The match {VARIABLE_NAME}/{WS}*={WS}*\( is too broad causing mount and dbus rules to fail for sets of values eg. mount options=(ro bind) Instead of doing a broad match, for now lets lock it down to just peer=(...) being the only cond that can cause entry into CONDLISTID Signed-off-by: John Johansen --- parser/parser_lex.l | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) --- 2.9-test.orig/parser/parser_lex.l +++ 2.9-test/parser/parser_lex.l @@ -302,7 +302,7 @@ } { - {VARIABLE_NAME}/{WS}*={WS}*\( { + peer/{WS}*={WS}*\( { /* we match to the = in the lexer so that we can switch scanner * state. By the time the parser see the = it may be too late * as bison may have requested the next token from the scanner debian/patches/update-tests-for-new-semantics.patch0000664000000000000000000006510412316027251017626 0ustar Author: John Johansen Origin: https://lists.ubuntu.com/archives/apparmor/2014-March/005581.html Subject: Update test scripts for new signal and ptrace semantics The previous test patches where done with the hardcoded bypass for unconfined. This semantic was changed so that a confined app can now block unconfined processes from tracing or sending signals to it. --- Index: ipc-fixes-and-improvements/tests/regression/apparmor/dbus.inc =================================================================== --- ipc-fixes-and-improvements.orig/tests/regression/apparmor/dbus.inc 2014-03-30 09:48:03.720238309 -0500 +++ ipc-fixes-and-improvements/tests/regression/apparmor/dbus.inc 2014-03-30 09:48:03.708238308 -0500 @@ -14,6 +14,7 @@ ${__dbus_var_decl} $test { @{gen $test} $@ + signal receive peer=unconfined, } EOF unset __dbus_var_decl Index: ipc-fixes-and-improvements/tests/regression/apparmor/exec_qual.sh =================================================================== --- ipc-fixes-and-improvements.orig/tests/regression/apparmor/exec_qual.sh 2014-03-30 09:48:03.720238309 -0500 +++ ipc-fixes-and-improvements/tests/regression/apparmor/exec_qual.sh 2014-03-30 09:48:03.708238308 -0500 @@ -72,28 +72,28 @@ local_runchecktest() # child profile grants access # expected behaviour: child should be able to access resource -genprofile $test2:px $file:$fileperm -- image=$test2 $file:$fileperm +genprofile $test2:px $file:$fileperm signal:receive:peer=unconfined -- image=$test2 $file:$fileperm signal:receive local_runchecktest "enforce px case1" pass $test2 $test2 $file # case 2: parent profile grants access (should be irrelevant) # child profile disallows access # expected behaviour: child should be unable to access resource -genprofile $test2:px $file:$fileperm -- image=$test2 +genprofile $test2:px $file:$fileperm signal:receive:peer=unconfined -- image=$test2 signal:receive local_runchecktest "enforce px case2" fail $test2 $test2 $file # case 3: parent profile disallows access (should be irrelevant) # child profile allows access # expected behaviour: child should be able to access resource -genprofile $test2:px -- image=$test2 $file:$fileperm +genprofile $test2:px signal:receive:peer=unconfined -- image=$test2 $file:$fileperm signal:receive local_runchecktest "enforce px case3" pass $test2 $test2 $file # case 4: parent profile grants access (should be irrelevant) # missing child profile # expected behaviour: exec of child fails -genprofile $test2:px $file:$fileperm +genprofile $test2:px $file:$fileperm signal:receive:peer=unconfined local_runchecktest "enforce px case4" fail "n/a" $test2 $file # confined parent, exec child with 'ix' @@ -101,41 +101,41 @@ local_runchecktest "enforce px case4" fa # child profile grants access (should be irrelevant) # expected behaviour: child should be able to access resource -genprofile $test2:rix $file:$fileperm -- image=$test2 $file:$fileperm +genprofile $test2:rix $file:$fileperm signal:receive:peer=unconfined -- image=$test2 $file:$fileperm signal:receive local_runchecktest "enforce ix case1" pass $test1 $test2 $file # case 2: parent profile grants access # child profile disallows access (should be irrelevant) # expected behaviour: child should be able to access resource -genprofile $test2:rix $file:$fileperm -- image=$test2 +genprofile $test2:rix $file:$fileperm signal:receive:peer=unconfined -- image=$test2 signal:receive local_runchecktest "enforce ix case2" pass $test1 $test2 $file # case 3: parent profile disallows access # child profile allows access (should be irrelevant) # expected behaviour: child should be unable to access resource -genprofile $test2:rix -- image=$test2 $file:$fileperm +genprofile $test2:rix signal:receive:peer=unconfined -- image=$test2 $file:$fileperm signal:receive local_runchecktest "enforce ix case3" fail $test1 $test2 $file # case 4: parent profile grants access # missing child profile (irrelvant) # expected behaviour: child should be able to access resource -genprofile $test2:rix $file:$fileperm +genprofile $test2:rix $file:$fileperm signal:receive:peer=unconfined local_runchecktest "enforce ix case4" pass $test1 $test2 $file # confined parent, exec child with 'ux' # case 1: parent profile grants access (should be irrelevant) # expected behaviour, child should be able to access resource -genprofile $test2:ux $file:$fileperm +genprofile $test2:ux $file:$fileperm signal:receive:peer=unconfined local_runchecktest "enforce ux case1" pass "unconfined" $test2 $file # case 2: parent profile denies access (should be irrelevant) # expected behaviour, child should be able to access resource -genprofile $test2:ux +genprofile $test2:ux signal:receive:peer=unconfined local_runchecktest "enforce ux case1" pass "unconfined" $test2 $file # confined parent, exec child with conflicting exec qualifiers @@ -144,20 +144,20 @@ local_runchecktest "enforce ux case1" pa # case 1: # expected behaviour: exec of child passes -genprofile $test2:px $test2_rex1:ix -- image=$test2 $file:$fileperm +genprofile $test2:px $test2_rex1:ix signal:receive:peer=unconfined -- image=$test2 $file:$fileperm signal:receive local_runchecktest "enforce conflicting exec qual" pass $test2 $test2 $file # unconfined parent # case 1: child profile exists, child profile grants access # expected behaviour: child should be able to access resource -genprofile image=$test2 $file:$fileperm +genprofile image=$test2 $file:$fileperm signal:receive:peer=unconfined local_runchecktest "enforce unconfined case1" pass $test2 $test2 $file # case 2: child profile exists, child profile denies access # expected behaviour: child should be unable to access resource -genprofile image=$test2 +genprofile image=$test2 signal:receive:peer=unconfined local_runchecktest "enforce unconfined case2" fail $test2 $test2 $file # case 3: no child profile exists, unconfined Index: ipc-fixes-and-improvements/tests/regression/apparmor/mmap.sh =================================================================== --- ipc-fixes-and-improvements.orig/tests/regression/apparmor/mmap.sh 2014-03-30 09:48:03.720238309 -0500 +++ ipc-fixes-and-improvements/tests/regression/apparmor/mmap.sh 2014-03-30 09:48:03.708238308 -0500 @@ -29,7 +29,7 @@ badperm=r # PASS TEST (pt 1) -genprofile $file:$okperm +genprofile $file:$okperm signal:receive:peer=unconfined runtestbg "READ/WRITE pass1" pass $file @@ -47,13 +47,13 @@ rm -f $file # FAILURE TEST (pt 1) -genprofile $file:$okperm +genprofile $file:$okperm signal:receive:peer=unconfined runtestbg "READ/WRITE pass2" pass $file sleep 2 -genprofile $file:$badperm +genprofile $file:$badperm signal:receive:peer=unconfined # FAILURE TEST (pt 2) Index: ipc-fixes-and-improvements/tests/regression/apparmor/ptrace_v6.inc =================================================================== --- ipc-fixes-and-improvements.orig/tests/regression/apparmor/ptrace_v6.inc 2014-03-30 09:48:03.720238309 -0500 +++ ipc-fixes-and-improvements/tests/regression/apparmor/ptrace_v6.inc 2014-03-30 09:48:03.712238309 -0500 @@ -13,7 +13,7 @@ echo " using ptrace v6 tests ..." #unconfined tracing confined helper #confined helper asking unconfined process to ptrace it -genprofile image=$helper signal:ALL +genprofile image=$helper signal:ALL ptrace:tracedby:peer=unconfined runchecktest "test 3 -h" pass -h -n 100 $helper runchecktest "test 3 -hc " pass -h -c -n 100 $helper @@ -212,14 +212,14 @@ runchecktest "test 12p -h" pass -h -n 10 runchecktest "test 12p -hc" pass -h -c -n 100 $helper runchecktest "test 12p -h prog" pass -h -n 100 $helper /bin/true runchecktest "test 12p -hc prog" pass -h -c -n 100 $helper /bin/true -genprofile /bin/true:rix $helper:rix signal:ALL ptrace:$test +genprofile /bin/true:rix $helper:rix signal:ALL ptrace:peer=$test runchecktest "test 12p1" pass -n 100 /bin/true runchecktest "test 12p1 -c" pass -c -n 100 /bin/true runchecktest "test 12p1 -h" pass -h -n 100 $helper runchecktest "test 12p1 -hc" pass -h -c -n 100 $helper runchecktest "test 12p1 -h prog" pass -h -n 100 $helper /bin/true runchecktest "test 12p1 -hc prog" pass -h -c -n 100 $helper /bin/true -genprofile /bin/true:rix $helper:rix signal:ALL ptrace:notaprofile +genprofile /bin/true:rix $helper:rix signal:ALL ptrace:peer=notaprofile runchecktest "test 12p2" fail -n 100 /bin/true runchecktest "test 12p2 -c" fail -c -n 100 /bin/true runchecktest "test 12p2 -h" fail -h -n 100 $helper @@ -229,137 +229,137 @@ runchecktest "test 12p2 -hc prog" fail - #ptraced confined app traced by profile can px -genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:/bin/true -- image=/bin/true /bin/true:rix +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:peer=/bin/true -- image=/bin/true /bin/true:rix runchecktest "test 13p1 -h prog" fail -h -n 100 $helper /bin/true runchecktest "test 13p2 -hc prog" fail -h -c -n 100 $helper /bin/true -genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:/bin/true -- image=/bin/true /bin/true:rix ptrace:tracedby +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:peer=/bin/true -- image=/bin/true /bin/true:rix ptrace:tracedby runchecktest "test 13p3 -h prog" pass -h -n 100 $helper /bin/true runchecktest "test 13p4 -hc prog" pass -h -c -n 100 $helper /bin/true -genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:/bin/true -- image=/bin/true /bin/true:rix ptrace:tracedby:$test +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:peer=/bin/true -- image=/bin/true /bin/true:rix ptrace:tracedby:peer=$test runchecktest "test 13p5 -h prog" pass -h -n 100 $helper /bin/true runchecktest "test 13p6 -hc prog" pass -h -c -n 100 $helper /bin/true -genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:/bin/true -- image=/bin/true /bin/true:rix ptrace:tracedby:notaprofile +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:peer=/bin/true -- image=/bin/true /bin/true:rix ptrace:tracedby:peer=notaprofile runchecktest "test 13p7 -h prog" fail -h -n 100 $helper /bin/true runchecktest "test 13p8 -hc prog" fail -h -c -n 100 $helper /bin/true -genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:/bin/true -- image=/bin/true /bin/true:rix ptrace:trace +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:peer=/bin/true -- image=/bin/true /bin/true:rix ptrace:trace runchecktest "test 13p9 -h prog" fail -h -n 100 $helper /bin/true runchecktest "test 13pa -hc prog" fail -h -c -n 100 $helper /bin/true -genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:/bin/true -- image=/bin/true /bin/true:rix ptrace:trace:$test +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:peer=/bin/true -- image=/bin/true /bin/true:rix ptrace:trace:peer=$test runchecktest "test 13pb -h prog" fail -h -n 100 $helper /bin/true runchecktest "test 13pc -hc prog" fail -h -c -n 100 $helper /bin/true -genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:/bin/true -- image=/bin/true /bin/true:rix ptrace:trace:notaprofile +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:peer=/bin/true -- image=/bin/true /bin/true:rix ptrace:trace:peer=notaprofile runchecktest "test 13pd -h prog" fail -h -n 100 $helper /bin/true runchecktest "test 13pe -hc prog" fail -h -c -n 100 $helper /bin/true -genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:trace:/bin/true -- image=/bin/true /bin/true:rix +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:trace:peer=/bin/true -- image=/bin/true /bin/true:rix runchecktest "test 13p11 -h prog" fail -h -n 100 $helper /bin/true runchecktest "test 13p21 -hc prog" fail -h -c -n 100 $helper /bin/true -genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:trace:/bin/true -- image=/bin/true /bin/true:rix ptrace:tracedby +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:trace:peer=/bin/true -- image=/bin/true /bin/true:rix ptrace:tracedby runchecktest "test 13p31 -h prog" pass -h -n 100 $helper /bin/true runchecktest "test 13p41 -hc prog" pass -h -c -n 100 $helper /bin/true -genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:trace:/bin/true -- image=/bin/true /bin/true:rix ptrace:tracedby:$test +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:trace:peer=/bin/true -- image=/bin/true /bin/true:rix ptrace:tracedby:peer=$test runchecktest "test 13p51 -h prog" pass -h -n 100 $helper /bin/true runchecktest "test 13p61 -hc prog" pass -h -c -n 100 $helper /bin/true -genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:trace:/bin/true -- image=/bin/true /bin/true:rix ptrace:tracedby:notaprofile +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:trace:peer=/bin/true -- image=/bin/true /bin/true:rix ptrace:tracedby:peer=notaprofile runchecktest "test 13p71 -h prog" fail -h -n 100 $helper /bin/true runchecktest "test 13p81 -hc prog" fail -h -c -n 100 $helper /bin/true -genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:trace:/bin/true -- image=/bin/true /bin/true:rix ptrace:trace +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:trace:peer=/bin/true -- image=/bin/true /bin/true:rix ptrace:trace runchecktest "test 13p91 -h prog" fail -h -n 100 $helper /bin/true runchecktest "test 13pa1 -hc prog" fail -h -c -n 100 $helper /bin/true -genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:trace:/bin/true -- image=/bin/true /bin/true:rix ptrace:trace:$test +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:trace:peer=/bin/true -- image=/bin/true /bin/true:rix ptrace:trace:peer=$test runchecktest "test 13pb1 -h prog" fail -h -n 100 $helper /bin/true runchecktest "test 13pc1 -hc prog" fail -h -c -n 100 $helper /bin/true -genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:trace:/bin/true -- image=/bin/true /bin/true:rix ptrace:trace:notaprofile +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:trace:peer=/bin/true -- image=/bin/true /bin/true:rix ptrace:trace:peer=notaprofile runchecktest "test 13pd1 -h prog" fail -h -n 100 $helper /bin/true runchecktest "test 13pe1 -hc prog" fail -h -c -n 100 $helper /bin/true -genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:ALL -- image=/bin/true /bin/true:rix +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:ALL -- image=/bin/true /bin/true:rix runchecktest "test 13p12 -h prog" fail -h -n 100 $helper /bin/true runchecktest "test 13p22 -hc prog" fail -h -c -n 100 $helper /bin/true -genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:ALL -- image=/bin/true /bin/true:rix ptrace:tracedby +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:ALL -- image=/bin/true /bin/true:rix ptrace:tracedby runchecktest "test 13p32 -h prog" pass -h -n 100 $helper /bin/true runchecktest "test 13p42 -hc prog" pass -h -c -n 100 $helper /bin/true -genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:ALL -- image=/bin/true /bin/true:rix ptrace:tracedby:$test +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:ALL -- image=/bin/true /bin/true:rix ptrace:tracedby:peer=$test runchecktest "test 13p52 -h prog" pass -h -n 100 $helper /bin/true runchecktest "test 13p62 -hc prog" pass -h -c -n 100 $helper /bin/true -genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:ALL -- image=/bin/true /bin/true:rix ptrace:tracedby:notaprofile +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:ALL -- image=/bin/true /bin/true:rix ptrace:tracedby:peer=notaprofile runchecktest "test 13p72 -h prog" fail -h -n 100 $helper /bin/true runchecktest "test 13p82 -hc prog" fail -h -c -n 100 $helper /bin/true -genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:ALL -- image=/bin/true /bin/true:rix ptrace:trace +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:ALL -- image=/bin/true /bin/true:rix ptrace:trace runchecktest "test 13p92 -h prog" fail -h -n 100 $helper /bin/true runchecktest "test 13pa2 -hc prog" fail -h -c -n 100 $helper /bin/true -genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:ALL -- image=/bin/true /bin/true:rix ptrace:trace:$test +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:ALL -- image=/bin/true /bin/true:rix ptrace:trace:peer=$test runchecktest "test 13pb2 -h prog" fail -h -n 100 $helper /bin/true runchecktest "test 13pc2 -hc prog" fail -h -c -n 100 $helper /bin/true -genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:ALL -- image=/bin/true /bin/true:rix ptrace:trace:notaprofile +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:ALL -- image=/bin/true /bin/true:rix ptrace:trace:peer=notaprofile runchecktest "test 13pd2 -h prog" fail -h -n 100 $helper /bin/true runchecktest "test 13pe2 -hc prog" fail -h -c -n 100 $helper /bin/true -genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:tracedby -- image=/bin/true /bin/true:rix +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:tracedby -- image=/bin/true /bin/true:rix runchecktest "test 13p13 -h prog" fail -h -n 100 $helper /bin/true runchecktest "test 13p23 -hc prog" fail -h -c -n 100 $helper /bin/true -genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:tracedby -- image=/bin/true /bin/true:rix ptrace:tracedby +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:tracedby -- image=/bin/true /bin/true:rix ptrace:tracedby runchecktest "test 13p33 -h prog" fail -h -n 100 $helper /bin/true runchecktest "test 13p43 -hc prog" fail -h -c -n 100 $helper /bin/true -genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:tracedby -- image=/bin/true /bin/true:rix ptrace:tracedby:$test +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:tracedby -- image=/bin/true /bin/true:rix ptrace:tracedby:peer=$test runchecktest "test 13p53 -h prog" fail -h -n 100 $helper /bin/true runchecktest "test 13p63 -hc prog" fail -h -c -n 100 $helper /bin/true -genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:tracedby -- image=/bin/true /bin/true:rix ptrace:tracedby:notaprofile +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:tracedby -- image=/bin/true /bin/true:rix ptrace:tracedby:peer=notaprofile runchecktest "test 13p73 -h prog" fail -h -n 100 $helper /bin/true runchecktest "test 13p83 -hc prog" fail -h -c -n 100 $helper /bin/true -genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:tracedby -- image=/bin/true /bin/true:rix ptrace:trace +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:tracedby -- image=/bin/true /bin/true:rix ptrace:trace runchecktest "test 13p93 -h prog" fail -h -n 100 $helper /bin/true runchecktest "test 13pa3 -hc prog" fail -h -c -n 100 $helper /bin/true -genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:tracedby -- image=/bin/true /bin/true:rix ptrace:trace:$test +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:tracedby -- image=/bin/true /bin/true:rix ptrace:trace:peer=$test runchecktest "test 13pb3 -h prog" fail -h -n 100 $helper /bin/true runchecktest "test 13pc3 -hc prog" fail -h -c -n 100 $helper /bin/true -genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:tracedby -- image=/bin/true /bin/true:rix ptrace:trace:notaprofile +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:tracedby -- image=/bin/true /bin/true:rix ptrace:trace:peer=notaprofile runchecktest "test 13pd3 -h prog" fail -h -n 100 $helper /bin/true runchecktest "test 13pe3 -hc prog" fail -h -c -n 100 $helper /bin/true -genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:tracedby:notaprofile -- image=/bin/true /bin/true:rix +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:tracedby:peer=notaprofile -- image=/bin/true /bin/true:rix runchecktest "test 13p14 -h prog" fail -h -n 100 $helper /bin/true runchecktest "test 13p24 -hc prog" fail -h -c -n 100 $helper /bin/true -genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:tracedby:notaprofile -- image=/bin/true /bin/true:rix ptrace:tracedby +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:tracedby:peer=notaprofile -- image=/bin/true /bin/true:rix ptrace:tracedby runchecktest "test 13p34 -h prog" fail -h -n 100 $helper /bin/true runchecktest "test 13p44 -hc prog" fail -h -c -n 100 $helper /bin/true -genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:tracedby:notaprofile -- image=/bin/true /bin/true:rix ptrace:tracedby:$test +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:tracedby:peer=notaprofile -- image=/bin/true /bin/true:rix ptrace:tracedby:peer=$test runchecktest "test 13p54 -h prog" fail -h -n 100 $helper /bin/true runchecktest "test 13p64 -hc prog" fail -h -c -n 100 $helper /bin/true -genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:tracedby:notaprofile -- image=/bin/true /bin/true:rix ptrace:tracedby:notaprofile +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:tracedby:peer=notaprofile -- image=/bin/true /bin/true:rix ptrace:tracedby:peer=notaprofile runchecktest "test 13p74 -h prog" fail -h -n 100 $helper /bin/true runchecktest "test 13p84 -hc prog" fail -h -c -n 100 $helper /bin/true -genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:tracedby:notaprofile -- image=/bin/true /bin/true:rix ptrace:trace +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:tracedby:peer=notaprofile -- image=/bin/true /bin/true:rix ptrace:trace runchecktest "test 13p94 -h prog" fail -h -n 100 $helper /bin/true runchecktest "test 13pa4 -hc prog" fail -h -c -n 100 $helper /bin/true -genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:tracedby:notaprofile -- image=/bin/true /bin/true:rix ptrace:trace:$test +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:tracedby:peer=notaprofile -- image=/bin/true /bin/true:rix ptrace:trace:peer=$test runchecktest "test 13pb4 -h prog" fail -h -n 100 $helper /bin/true runchecktest "test 13pc4 -hc prog" fail -h -c -n 100 $helper /bin/true -genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:tracedby:notaprofile -- image=/bin/true /bin/true:rix ptrace:trace:notaprofile +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:tracedby:peer=notaprofile -- image=/bin/true /bin/true:rix ptrace:trace:peer=notaprofile runchecktest "test 13pd4 -h prog" fail -h -n 100 $helper /bin/true runchecktest "test 13pe4 -hc prog" fail -h -c -n 100 $helper /bin/true -genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:notaprofile -- image=/bin/true /bin/true:rix +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:peer=notaprofile -- image=/bin/true /bin/true:rix runchecktest "test 13p15 -h prog" fail -h -n 100 $helper /bin/true runchecktest "test 13p25 -hc prog" fail -h -c -n 100 $helper /bin/true -genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:notaprofile -- image=/bin/true /bin/true:rix ptrace:tracedby +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:peer=notaprofile -- image=/bin/true /bin/true:rix ptrace:tracedby runchecktest "test 13p35 -h prog" fail -h -n 100 $helper /bin/true runchecktest "test 13p45 -hc prog" fail -h -c -n 100 $helper /bin/true -genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:notaprofile -- image=/bin/true /bin/true:rix ptrace:tracedby:$test +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:peer=notaprofile -- image=/bin/true /bin/true:rix ptrace:tracedby:peer=$test runchecktest "test 13p55 -h prog" fail -h -n 100 $helper /bin/true runchecktest "test 13p65 -hc prog" fail -h -c -n 100 $helper /bin/true -genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:notaprofile -- image=/bin/true /bin/true:rix ptrace:tracedby:notaprofile +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:peer=notaprofile -- image=/bin/true /bin/true:rix ptrace:tracedby:peer=notaprofile runchecktest "test 13p75 -h prog" fail -h -n 100 $helper /bin/true runchecktest "test 13p85 -hc prog" fail -h -c -n 100 $helper /bin/true -genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:notaprofile -- image=/bin/true /bin/true:rix ptrace:trace +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:peer=notaprofile -- image=/bin/true /bin/true:rix ptrace:trace runchecktest "test 13p95 -h prog" fail -h -n 100 $helper /bin/true runchecktest "test 13pa5 -hc prog" fail -h -c -n 100 $helper /bin/true -genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:notaprofile -- image=/bin/true /bin/true:rix ptrace:trace:$test +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:peer=notaprofile -- image=/bin/true /bin/true:rix ptrace:trace:peer=$test runchecktest "test 13pb5 -h prog" fail -h -n 100 $helper /bin/true runchecktest "test 13pc5 -hc prog" fail -h -c -n 100 $helper /bin/true -genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:$test ptrace:notaprofile -- image=/bin/true /bin/true:rix ptrace:trace:notaprofile +genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:peer=notaprofile -- image=/bin/true /bin/true:rix ptrace:trace:peer=notaprofile runchecktest "test 13pd5 -h prog" fail -h -n 100 $helper /bin/true runchecktest "test 13pe5 -hc prog" fail -h -c -n 100 $helper /bin/true Index: ipc-fixes-and-improvements/tests/regression/apparmor/pwrite.sh =================================================================== --- ipc-fixes-and-improvements.orig/tests/regression/apparmor/pwrite.sh 2014-03-30 09:48:03.720238309 -0500 +++ ipc-fixes-and-improvements/tests/regression/apparmor/pwrite.sh 2014-03-30 09:48:03.712238309 -0500 @@ -23,7 +23,7 @@ badreadperm=w # PASS TEST (pass 1) -genprofile $file:$okperm +genprofile $file:$okperm signal:receive:peer=unconfined runtestbg "PREAD/PWRITE with rw" pass $file Index: ipc-fixes-and-improvements/tests/regression/apparmor/rw.sh =================================================================== --- ipc-fixes-and-improvements.orig/tests/regression/apparmor/rw.sh 2014-03-30 09:48:03.720238309 -0500 +++ ipc-fixes-and-improvements/tests/regression/apparmor/rw.sh 2014-03-30 09:48:03.712238309 -0500 @@ -29,7 +29,7 @@ badperm=r # PASS TEST (pt 1) -genprofile $file:$okperm +genprofile $file:$okperm signal:receive:peer=unconfined runtestbg "READ/WRITE pass" pass $file debian/patches/mediate-ptrace.patch0000664000000000000000000003544612315363452014544 0ustar Author: John Johansen Origin: https://lists.ubuntu.com/archives/apparmor/2014-March/005564.html Subject: Add the ability to specify ptrace rules ptrace rules currently take the form of ptrace [] [], ptrace_perm := read|trace|readby|tracedby ptrace_perms := ptrace_perm | '(' ptrace_perm+ ')' After having used the cross check (permission needed in both profiles) I am not sure it is correct for ptrace. Signed-off-by: John Johansen --- parser/Makefile | 7 +- parser/parser.h | 1 parser/parser_common.c | 1 parser/parser_lex.l | 25 ++++++- parser/parser_main.c | 2 parser/parser_misc.c | 3 parser/parser_regex.c | 4 + parser/parser_yacc.y | 73 ++++++++++++++++++++++ parser/ptrace.c | 159 +++++++++++++++++++++++++++++++++++++++++++++++++ parser/ptrace.h | 52 ++++++++++++++++ 10 files changed, 320 insertions(+), 7 deletions(-) --- 2.9-test.orig/parser/Makefile +++ 2.9-test/parser/Makefile @@ -80,9 +80,9 @@ parser_main.c parser_misc.c parser_merge.c parser_symtab.c \ parser_yacc.c parser_regex.c parser_variable.c parser_policy.c \ parser_alias.c mount.c dbus.c lib.c profile.cc rule.c common_optarg.c \ - signal.c + signal.c ptrace.c HDRS = parser.h parser_include.h immunix.h mount.h dbus.h lib.h profile.h \ - rule.h common_optarg.h signal.h + rule.h common_optarg.h signal.h ptrace.h TOOLS = apparmor_parser OBJECTS = $(SRCS:.c=.o) @@ -248,6 +248,9 @@ signal.o: signal.c signal.h parser.h immunix.h parser_yacc.h rule.h $(APPARMOR_H) $(CXX) $(EXTRA_CFLAGS) -c -o $@ $< +ptrace.o: ptrace.c ptrace.h parser.h immunix.h parser_yacc.h rule.h $(APPARMOR_H) + $(CXX) $(EXTRA_CFLAGS) -c -o $@ $< + profile.o: profile.cc profile.h parser.h $(CXX) $(EXTRA_CFLAGS) -c -o $@ $< --- 2.9-test.orig/parser/parser.h +++ 2.9-test/parser/parser.h @@ -305,6 +305,7 @@ extern int kernel_supports_mount; extern int kernel_supports_dbus; extern int kernel_supports_signal; +extern int kernel_supports_ptrace; extern int conf_verbose; extern int conf_quiet; extern int names_only; --- 2.9-test.orig/parser/parser_common.c +++ 2.9-test/parser/parser_common.c @@ -72,6 +72,7 @@ int kernel_supports_dbus = 0; /* kernel supports dbus rules */ int kernel_supports_diff_encode = 0; /* kernel supports diff_encode */ int kernel_supports_signal = 0; /* kernel supports signal rules */ +int kernel_supports_ptrace = 0; /* kernel supports ptrace rules */ int conf_verbose = 0; int conf_quiet = 0; int names_only = 0; --- 2.9-test.orig/parser/parser_lex.l +++ 2.9-test/parser/parser_lex.l @@ -254,6 +254,7 @@ %x MOUNT_MODE %x DBUS_MODE %x SIGNAL_MODE +%x PTRACE_MODE %x CHANGE_PROFILE_MODE %x INCLUDE @@ -268,7 +269,7 @@ } %} -{ +{ {WS}+ { DUMP_PREPROCESS; /* Ignoring whitespace */ } } @@ -294,7 +295,7 @@ yyterminate(); } -{ +{ {VARIABLE_NAME}/{WS}*={WS}*\( { /* we match to the = in the lexer so that we can switch scanner * state. By the time the parser see the = it may be too late @@ -472,6 +473,15 @@ { send { RETURN_TOKEN(TOK_SEND); } receive { RETURN_TOKEN(TOK_RECEIVE); } +} + +{ + trace { RETURN_TOKEN(TOK_TRACE); } + readby { RETURN_TOKEN(TOK_READBY); } + tracedby { RETURN_TOKEN(TOK_TRACEDBY); } +} + +{ read { RETURN_TOKEN(TOK_READ); } write { RETURN_TOKEN(TOK_WRITE); } {OPEN_PAREN} { @@ -483,9 +493,11 @@ } } -{ +{ {ARROW} { RETURN_TOKEN(TOK_ARROW); } +} +{ ({IDS_NOEQ}|{PATHNAME}|{QUOTED_ID}) { yylval.id = processid(yytext, yyleng); RETURN_TOKEN(TOK_ID); @@ -575,13 +587,15 @@ case TOK_SIGNAL: state = SIGNAL_MODE; break; + case TOK_PTRACE: + state = PTRACE_MODE; default: /* nothing */ break; } PUSH_AND_RETURN(state, token); } -{ +{ {END_OF_RULE} { if (YY_START != INITIAL) POP(); @@ -594,7 +608,7 @@ } } -{ +{ [^\n] { DUMP_PREPROCESS; /* Something we didn't expect */ @@ -622,6 +636,7 @@ STATE_TABLE_ENT(MOUNT_MODE), STATE_TABLE_ENT(DBUS_MODE), STATE_TABLE_ENT(SIGNAL_MODE), + STATE_TABLE_ENT(PTRACE_MODE), STATE_TABLE_ENT(CHANGE_PROFILE_MODE), STATE_TABLE_ENT(INCLUDE), }; --- 2.9-test.orig/parser/parser_main.c +++ 2.9-test/parser/parser_main.c @@ -697,6 +697,8 @@ kernel_supports_dbus = 1; if (strstr(features_string, "signal")) kernel_supports_signal = 1; + if (strstr(features_string, "ptrace {")) + kernel_supports_ptrace = 1; if (strstr(features_string, "diff_encode")) kernel_supports_diff_encode = 1; else if (dfaflags & DFA_CONTROL_DIFF_ENCODE) --- 2.9-test.orig/parser/parser_misc.c +++ 2.9-test/parser/parser_misc.c @@ -150,6 +150,9 @@ {"write", TOK_WRITE}, {"eavesdrop", TOK_EAVESDROP}, {"peer", TOK_PEER}, + {"trace", TOK_TRACE}, + {"tracedby", TOK_TRACEDBY}, + {"readby", TOK_READBY}, /* terminate */ {NULL, 0} --- 2.9-test.orig/parser/parser_regex.c +++ 2.9-test/parser/parser_regex.c @@ -674,6 +674,7 @@ static const char *mediates_mount = CLASS_STR(AA_CLASS_MOUNT); static const char *mediates_dbus = CLASS_STR(AA_CLASS_DBUS); static const char *mediates_signal = CLASS_STR(AA_CLASS_SIGNAL); +static const char *mediates_ptrace = CLASS_STR(AA_CLASS_PTRACE); int process_profile_policydb(Profile *prof) { @@ -703,6 +704,9 @@ if (kernel_supports_signal && !prof->policy.rules->add_rule(mediates_signal, 0, AA_MAY_READ, 0, dfaflags)) goto out; + if (kernel_supports_ptrace && + !prof->policy.rules->add_rule(mediates_ptrace, 0, AA_MAY_READ, 0, dfaflags)) + goto out; if (prof->policy.rules->rule_count > 0) { prof->policy.dfa = prof->policy.rules->create_dfa(&prof->policy.size, dfaflags); --- 2.9-test.orig/parser/parser_yacc.y +++ 2.9-test/parser/parser_yacc.y @@ -138,6 +138,9 @@ %token TOK_WRITE %token TOK_EAVESDROP %token TOK_PEER +%token TOK_TRACE +%token TOK_TRACEDBY +%token TOK_READBY /* rlimits */ %token TOK_RLIMIT @@ -171,6 +174,7 @@ #include "mount.h" #include "dbus.h" #include "signal.h" + #include "ptrace.h" } %union { @@ -185,6 +189,7 @@ mnt_rule *mnt_entry; dbus_rule *dbus_entry; signal_rule *signal_entry; + ptrace_rule *ptrace_entry; flagvals flags; int fmode; @@ -252,6 +257,10 @@ %type signal_perms %type opt_signal_perm %type signal_rule +%type ptrace_perm +%type ptrace_perms +%type opt_ptrace_perm +%type ptrace_rule %type opt_named_transition %type opt_unsafe %type opt_file @@ -725,6 +734,22 @@ $$ = $1; } +rules: rules opt_prefix ptrace_rule + { + if ($2.owner) + yyerror(_("owner prefix not allowed on ptrace rules")); + if ($2.deny && $2.audit) { + $3->deny = 1; + } else if ($2.deny) { + $3->deny = 1; + $3->audit = $3->mode; + } else if ($2.audit) { + $3->audit = $3->mode; + } + $1->rule_ents.push_back($3); + $$ = $1; + } + rules: rules change_profile { PDEBUG("matched: rules change_profile\n"); @@ -1285,6 +1310,54 @@ $$ = ent; } +ptrace_perm: TOK_VALUE + { + if (strcmp($1, "trace") == 0 || strcmp($1, "write") == 0) + $$ = AA_MAY_TRACE; + else if (strcmp($1, "read") == 0) + $$ = AA_MAY_READ; + else if (strcmp($1, "tracedby") == 0) + $$ = AA_MAY_TRACEDBY; + else if (strcmp($1, "readby") == 0) + $$ = AA_MAY_READBY; + else if ($1) + parse_ptrace_mode($1, &$$, 1); + else + $$ = 0; + + if ($1) + free($1); + } + | TOK_TRACE { $$ = AA_MAY_TRACE; } + | TOK_TRACEDBY { $$ = AA_MAY_TRACEDBY; } + | TOK_READ { $$ = AA_MAY_READ; } + | TOK_WRITE { $$ = AA_MAY_TRACE; } + | TOK_READBY { $$ = AA_MAY_READBY; } + | TOK_MODE + { + parse_ptrace_mode($1, &$$, 1); + free($1); + } + +ptrace_perms: { /* nothing */ $$ = 0; } + | ptrace_perms ptrace_perm { $$ = $1 | $2; } + | ptrace_perms TOK_COMMA ptrace_perm { $$ = $1 | $3; } + +opt_ptrace_perm: { /* nothing */ $$ = 0; } + | ptrace_perm { $$ = $1; } + | TOK_OPENPAREN ptrace_perms TOK_CLOSEPAREN { $$ = $2; } + +ptrace_rule: TOK_PTRACE opt_ptrace_perm opt_conds TOK_END_OF_RULE + { + ptrace_rule *ent = new ptrace_rule($2, $3, NULL); + $$ = ent; + } + | TOK_PTRACE opt_ptrace_perm opt_conds TOK_ID TOK_END_OF_RULE + { + ptrace_rule *ent = new ptrace_rule($2, $3, $4); + $$ = ent; + } + hat_start: TOK_CARET {} | TOK_HAT {} --- /dev/null +++ 2.9-test/parser/ptrace.c @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2014 + * 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 "parser.h" +#include "profile.h" +#include "ptrace.h" + +#include +#include +#include +#include + +int parse_ptrace_mode(const char *str_mode, int *mode, int fail) +{ + return parse_X_mode("ptrace", AA_VALID_PTRACE_PERMS, str_mode, mode, fail); +} + +void ptrace_rule::move_conditionals(struct cond_entry *conds) +{ + struct cond_entry *cond_ent; + + list_for_each(conds, cond_ent) { + /* for now disallow keyword 'in' (list) */ + if (!cond_ent->eq) + yyerror("keyword \"in\" is not allowed in ptrace rules\n"); + + /* no valid conditionals atm */ + yyerror("invalid ptrace rule conditional \"%s\"\n", + cond_ent->name); + } +} + +ptrace_rule::ptrace_rule(int mode_p, struct cond_entry *conds, char *peer): + peer_label(peer), audit(0), deny(0) +{ + if (mode_p) { + if (mode_p & ~AA_VALID_PTRACE_PERMS) + yyerror("mode contains invalid permissions for ptrace\n"); + mode = mode_p; + } else { + mode = AA_VALID_PTRACE_PERMS; + } + + move_conditionals(conds); + free_cond_list(conds); +} + +ostream &ptrace_rule::dump(ostream &os) +{ + if (audit) + os << "audit "; + if (deny) + os << "deny "; + + os << "ptrace"; + + if (mode != AA_VALID_PTRACE_PERMS) { + os << " ("; + + if (mode & AA_MAY_READ) + os << "read "; + if (mode & AA_MAY_READBY) + os << "readby "; + if (mode & AA_MAY_TRACE) + os << "trace "; + if (mode & AA_MAY_TRACEDBY) + os << "tracedby "; + os << ")"; + } + + if (peer_label) + os << " " << peer_label; + + os << ",\n"; + + return os; +} + + +int ptrace_rule::expand_variables(void) +{ + return expand_entry_variables(&peer_label); +} + +/* do we want to warn once/profile or just once per compile?? */ +static void warn_once(const char *name) +{ + static const char *warned_name = NULL; + + if (warned_name != name) { + cerr << "Warning from profile " << name << " ("; + if (current_filename) + cerr << current_filename; + else + cerr << "stdin"; + cerr << ") ptrace rules not enforced\n"; + warned_name = name; + } +} + +int ptrace_rule::gen_policy_re(Profile &prof) +{ + std::ostringstream buffer; + std::string buf; + + pattern_t ptype; + int pos; + + /* ?? do we want to generate the rules in the policy so that it + * the compile could be used on another kernel unchanged?? + * Current caching doesn't support this but in the future maybe + */ + if (!kernel_supports_ptrace) { + warn_once(prof.name); + return RULE_NOT_SUPPORTED; + } + + /* always generate a label and ptrace entry */ + buffer << "(" << "\\x" << std::setfill('0') << std::setw(2) << std::hex << AA_CLASS_LABEL << "|)"; + + buffer << "\\x" << std::setfill('0') << std::setw(2) << std::hex << AA_CLASS_PTRACE; + + if (peer_label) { + ptype = convert_aaregex_to_pcre(peer_label, 0, buf, &pos); + if (ptype == ePatternInvalid) + goto fail; + buffer << buf; + } else { + buffer << anyone_match_pattern; + } + + buf = buffer.str(); + if (mode & AA_VALID_PTRACE_PERMS) { + if (!prof.policy.rules->add_rule(buf.c_str(), deny, mode, audit, + dfaflags)) + goto fail; + } + + return RULE_OK; + +fail: + return RULE_ERROR; +} + --- /dev/null +++ 2.9-test/parser/ptrace.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2014 + * 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. + */ +#ifndef __AA_PTRACE_H +#define __AA_PTRACE_H + +#include "immunix.h" +#include "parser.h" + +#define AA_MAY_TRACE AA_MAY_WRITE +#define AA_MAY_READBY 0x10 /* MAY_CREATE in new encoding */ +#define AA_MAY_TRACEDBY AA_MAY_APPEND +#define AA_VALID_PTRACE_PERMS (AA_MAY_READ | AA_MAY_TRACE | AA_MAY_READBY | \ + AA_MAY_TRACEDBY) + +int parse_ptrace_mode(const char *str_mode, int *mode, int fail); + +class ptrace_rule: public rule_t { + void move_conditionals(struct cond_entry *conds); +public: + char *peer_label; + int mode; + int audit; + int deny; + + ptrace_rule(int mode, struct cond_entry *conds, char *peer); + virtual ~ptrace_rule() + { + free(peer_label); + }; + + virtual ostream &dump(ostream &os); + virtual int expand_variables(void); + virtual int gen_policy_re(Profile &prof); + virtual void post_process(Profile &prof __unused) { }; +}; + +#endif /* __AA_PTRACE_H */ debian/patches/add-profile-name-variable.patch0000664000000000000000000002716312315367757016560 0ustar Author: Steve Beattie Origin: https://lists.ubuntu.com/archives/apparmor/2014-March/005575.html Subject: parser: add implicit set variable @{profile_name} to profile symbol table This patch adds the creation of an implicit set variable @{profile_name} for use within policy. It expands to: - a given profile name if specified; e.g. for 'profile flappy_bird /some/pattern/match* { [...] }' @{profile_name} would expand to 'flappy_bird' - if no given name, the match pattern; e.g. for '/usr/bin/doge_bird { [...] }' @{profile_name} would expand to '/usr/bin/doge_bird' - hats and child profiles will include the fully qualified name; e.g. the 'doge' hat in the /usr/bin/flappy_bird profile would cause @{profile_name} to expand to '/usr/bin/flappy_bird//doge' within the 'doge' hat, and '/usr/bin/flappy_bird' outside of it in the profile. There are some parsing tests added, but more tests are needed to verify that expansion occurs properly (I've verified manually using parser dumps of the added tests, but automated checks are needed). [A side question is whether a @{profile_hatname} or @{profile_childname} implicit variable that doesn't include the fully qualified path would be useful for writing template profiles for multiple nearly identical hats.] Signed-off-by: Steve Beattie --- parser/parser.h | 4 parser/parser_symtab.c | 63 ++++++++++++++ parser/parser_variable.c | 17 +++ parser/profile.h | 24 ++++- parser/tst/simple_tests/vars/vars_auto_profile_name_01.sd | 9 ++ parser/tst/simple_tests/vars/vars_auto_profile_name_02.sd | 9 ++ parser/tst/simple_tests/vars/vars_auto_profile_name_03.sd | 9 ++ parser/tst/simple_tests/vars/vars_auto_profile_name_04.sd | 18 ++++ parser/tst/simple_tests/vars/vars_auto_profile_name_05.sd | 40 ++++++++ parser/tst/simple_tests/vars/vars_auto_profile_name_06.sd | 19 ++++ parser/tst/simple_tests/vars/vars_auto_profile_name_07.sd | 22 ++++ 11 files changed, 226 insertions(+), 8 deletions(-) Index: ipc-fixes-and-improvements/parser/parser_symtab.c =================================================================== --- ipc-fixes-and-improvements.orig/parser/parser_symtab.c 2014-03-28 16:55:38.998325150 -0500 +++ ipc-fixes-and-improvements/parser/parser_symtab.c 2014-03-28 16:55:38.978325150 -0500 @@ -330,6 +330,50 @@ char *get_next_set_value(struct set_valu return ret; } +/* delete_symbol + * removes an individual variable from the symbol table. We don't + * support this in the language, but for special variables that change + * between profiles, we need this. + */ +int delete_set_var(const char *var_name) +{ + int rc = 0; + struct symtab **result, *n, *var; + + n = new_symtab_entry(var_name); + if (!n) { + rc = ENOMEM; + goto out; + } + + result = (struct symtab **) tfind(n, &my_symtab, (comparison_fn_t) &compare_symtabs); + if (!result) { + /* XXX Warning? */ + goto out; + } + + var = (*result); + + result = (struct symtab **) tdelete(n, &my_symtab, (comparison_fn_t) &compare_symtabs); + if (!result) { + PERROR("ASSERT: delete_set_var: tfind found var %s but tdelete failed to delete it\n", + var_name); + exit(1); + } + + if (var->type != sd_set) { + PERROR("ASSERT: delete_set_var: deleting %s but is a boolean variable\n", + var_name); + exit(1); + } + + free_symtab(var); + +out: + free_symtab(n); + return rc; +} + static void *seenlist = NULL; static int is_seen(const char *var) @@ -708,6 +752,21 @@ int test_expand_set_var_during_dump(void return rc; } +int test_delete_set_var(void) +{ + int rc = 0; + int retval; + + retval = new_set_var("deleteme", "delete this variable"); + MY_TEST(retval == 0, "new delete set variable"); + retval = delete_set_var("deleteme"); + MY_TEST(retval == 0, "delete set variable"); + + free_symtabs(); + + return rc; +} + int main(void) { int rc = 0; @@ -740,6 +799,10 @@ int main(void) if (rc == 0) rc = retval; + retval = test_delete_set_var(); + if (rc == 0) + rc = retval; + retval = new_set_var("test", "test value"); MY_TEST(retval == 0, "new set variable 1"); Index: ipc-fixes-and-improvements/parser/parser.h =================================================================== --- ipc-fixes-and-improvements.orig/parser/parser.h 2014-03-28 16:55:38.998325150 -0500 +++ ipc-fixes-and-improvements/parser/parser.h 2014-03-28 16:55:38.982325150 -0500 @@ -290,6 +290,9 @@ do { \ version; \ }) +/* The parser fills this variable in automatically */ +#define PROFILE_NAME_VARIABLE "profile_name" + /* from parser_common.c */ extern uint32_t policy_version; extern uint32_t parser_abi_version; @@ -412,6 +415,7 @@ extern int new_set_var(const char *var, extern int add_set_value(const char *var, const char *value); extern struct set_value *get_set_var(const char *var); extern char *get_next_set_value(struct set_value **context); +extern int delete_set_var(const char *var_name); extern void dump_symtab(void); extern void dump_expanded_symtab(void); void free_symtabs(void); Index: ipc-fixes-and-improvements/parser/parser_variable.c =================================================================== --- ipc-fixes-and-improvements.orig/parser/parser_variable.c 2014-03-28 16:55:38.998325150 -0500 +++ ipc-fixes-and-improvements/parser/parser_variable.c 2014-03-28 16:55:38.982325150 -0500 @@ -276,11 +276,22 @@ static int process_variables_in_rules(Pr int process_profile_variables(Profile *prof) { - int error = 0; - error = process_variables_in_entries(prof->entries); - if (!error) + int error = 0, rc; + std::string *buf = prof->get_name(true); + + error = new_set_var(PROFILE_NAME_VARIABLE, buf->c_str()); + delete buf; + + if (!error) + error = process_variables_in_entries(prof->entries); + + if (!error) error = process_variables_in_rules(*prof); + rc = delete_set_var(PROFILE_NAME_VARIABLE); + if (!error) + error = rc; + return error; } Index: ipc-fixes-and-improvements/parser/tst/simple_tests/vars/vars_auto_profile_name_01.sd =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ ipc-fixes-and-improvements/parser/tst/simple_tests/vars/vars_auto_profile_name_01.sd 2014-03-28 16:55:38.982325150 -0500 @@ -0,0 +1,9 @@ +#=DESCRIPTION reference auto profile_name variable in rules +#=EXRESULT PASS + +/a/test/profile { + /a/test/profile rix, + + /var/run/@{profile_name} rwk, + +} Index: ipc-fixes-and-improvements/parser/tst/simple_tests/vars/vars_auto_profile_name_02.sd =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ ipc-fixes-and-improvements/parser/tst/simple_tests/vars/vars_auto_profile_name_02.sd 2014-03-28 16:55:38.982325150 -0500 @@ -0,0 +1,9 @@ +#=DESCRIPTION reference auto profile_name variable in rules +#=EXRESULT PASS + +profile /a/test/profile { + /a/test/profile rix, + + /var/@{profile_name}/tmp rwk, + +} Index: ipc-fixes-and-improvements/parser/tst/simple_tests/vars/vars_auto_profile_name_03.sd =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ ipc-fixes-and-improvements/parser/tst/simple_tests/vars/vars_auto_profile_name_03.sd 2014-03-28 16:55:38.986325150 -0500 @@ -0,0 +1,9 @@ +#=DESCRIPTION reference auto profile_name variable in rules +#=EXRESULT PASS + +profile this_is_a_test /a/test/profile { + /a/test/profile rix, + + /run/@{profile_name}/tmp rwk, + +} Index: ipc-fixes-and-improvements/parser/tst/simple_tests/vars/vars_auto_profile_name_04.sd =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ ipc-fixes-and-improvements/parser/tst/simple_tests/vars/vars_auto_profile_name_04.sd 2014-03-28 16:55:38.986325150 -0500 @@ -0,0 +1,18 @@ +#=DESCRIPTION reference auto profile_name variable in rules w/hats +#=EXRESULT PASS + +/test/profile { + /test/profile rix, + + /run/@{profile_name}/tmp rwk, + + ^spork { + owner /tmp/* r, + /spork/@{profile_name}/** rw, + } + + ^spelunkk { + owner /tmp/* r, + /spelunk/@{profile_name}/** rw, + } +} Index: ipc-fixes-and-improvements/parser/profile.h =================================================================== --- ipc-fixes-and-improvements.orig/parser/profile.h 2014-03-28 16:55:38.998325150 -0500 +++ ipc-fixes-and-improvements/parser/profile.h 2014-03-28 16:55:38.986325150 -0500 @@ -15,6 +15,8 @@ #define __AA_PROFILE_H #include +#include +#include #include "parser.h" #include "rule.h" @@ -225,13 +227,25 @@ public: hat_table.dump(); } - void dump_name(bool fqp) + std::string* get_name(bool fqp) { + std::string *buf; if (fqp && parent) { - parent->dump_name(fqp); - printf("//%s", name); - } else - printf("%s", name); + buf = parent->get_name(fqp); + buf->append("//"); + buf->append(name); + } else { + return new std::string(name); + } + + return buf; + } + + void dump_name(bool fqp) + { + std::string *buf = get_name(fqp);; + cout << *buf; + delete buf; } }; Index: ipc-fixes-and-improvements/parser/tst/simple_tests/vars/vars_auto_profile_name_05.sd =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ ipc-fixes-and-improvements/parser/tst/simple_tests/vars/vars_auto_profile_name_05.sd 2014-03-28 16:55:38.986325150 -0500 @@ -0,0 +1,40 @@ +#=DESCRIPTION reference auto profile_name variable in rules w/hats +#=EXRESULT PASS + +profile idf3s2A6GX8vrk /simple/profile { + /test/profile rix, + + /run/@{profile_name}/tmp rwk, + + ^spork { + owner /tmp/* r, + /spork/@{profile_name}/** rw, + } + + ^spelunkk { + owner /tmp/* r, + /spelunk/@{profile_name}/** rw, + } +} + +profile LzdZb9bKTMN6y /not/simple/profile { + /test/profile rix, + + /run/@{profile_name}/tmp rwk, + + ^spork { + owner /tmp/* r, + /run/@{profile_name}/** rw, + } + + ^spelunkk { + owner /tmp/* r, + /run/@{profile_name}/** rw, + } + + ^spry { + owner /tmp/* r, + /run/@{profile_name}/** rw, + } + +} Index: ipc-fixes-and-improvements/parser/tst/simple_tests/vars/vars_auto_profile_name_06.sd =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ ipc-fixes-and-improvements/parser/tst/simple_tests/vars/vars_auto_profile_name_06.sd 2014-03-28 16:55:38.986325150 -0500 @@ -0,0 +1,19 @@ +#=DESCRIPTION reference auto profile_name variable in rules w/Cx profiles +#=EXRESULT PASS + +profile top_profile /test/profile { + /test/profile rix, + + /run/@{profile_name}/tmp rwk, + /bin/spork Cx -> spork, + + profile spork { + owner /tmp/* r, + /run/@{profile_name}/** rw, + } + + profile spelunkk { + owner /tmp/* r, + /run/@{profile_name}/** rw, + } +} Index: ipc-fixes-and-improvements/parser/tst/simple_tests/vars/vars_auto_profile_name_07.sd =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ ipc-fixes-and-improvements/parser/tst/simple_tests/vars/vars_auto_profile_name_07.sd 2014-03-28 16:55:38.986325150 -0500 @@ -0,0 +1,22 @@ +#=DESCRIPTION ensure profile_name expansion after subprofiles works +#=EXRESULT PASS + +profile top_profile /test/profile { + /test/profile rix, + + /first/path/@{profile_name}/tmp rwk, + /bin/spork Cx -> spork, + + profile spork { + owner /tmp/* r, + /run/@{profile_name}/** rw, + } + + hat spelunkk { + owner /tmp/* r, + /run/@{profile_name}/** rw, + } + + # Does this expand properly? + /second/path/@{profile_name}/tmp rk, +} debian/patches/policy_mediates.patch0000664000000000000000000000412012315045675015017 0ustar Author: John Johansen Forwarded: Yes Subject: Add stub rules to indicate compilation support for given features. Policy enforcement needs to be able to support older userspaces and compilers that don't know about new features. The absence of a feature in the policydb indicates that feature mediation is not present for it. We add stub rules, that provide a none 0 start state for features that are supported at compile time. This can be used by the kernel to indicate that it should enforce a given feature. This does not indicate the feature is allowed, in an abscence of other rules for the feature the feature will be denied. Note: this will break the minimize tests when run with kernels that support mount or dbus rules. A patch to specify these features to the parser is needed to fix this. Signed-off-by: John Johansen --- parser/parser_regex.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) --- 2.9-test.orig/parser/parser_regex.c +++ 2.9-test/parser/parser_regex.c @@ -673,6 +673,12 @@ return TRUE; } +#define MAKE_STR(X) #X +#define CLASS_STR(X) "\\d" MAKE_STR(X) + +static const char *mediates_mount = CLASS_STR(AA_CLASS_MOUNT); +static const char *mediates_dbus = CLASS_STR(AA_CLASS_DBUS); + int process_profile_policydb(Profile *prof) { int error = -1; @@ -684,6 +690,20 @@ if (!post_process_policydb_ents(prof)) goto out; + /* insert entries to show indicate what compiler/policy expects + * to be supported + */ + + if (kernel_supports_mount) { + if (!aare_add_rule(prof->policy.rules, mediates_mount, 0, AA_MAY_READ, 0, dfaflags)) + goto out; + prof->policy.count++; + } + if (kernel_supports_dbus) { + if (!aare_add_rule(prof->policy.rules, mediates_dbus, 0, AA_MAY_READ, 0, dfaflags)) + goto out; + prof->policy.count++; + } if (prof->policy.count > 0) { prof->policy.dfa = aare_create_dfa(prof->policy.rules, &prof->policy.size, -- AppArmor mailing list AppArmor@lists.ubuntu.com Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/apparmor debian/patches/add-mediation-unix.patch0000664000000000000000000001054612315045675015336 0ustar Author: John Johansen Forwarded: Yes Subject: Add tag indicating file policy is mediated. Tag start of entries in the policydb as being mediated. This makes the start state for any class being mediated be none 0. The kernel can detect this to determine whether the parser expected mediation for the class. This is just a way of encoding what features expect mediation within the policydb it self so that a separate table isn't needed. This is also used to indicate the new unix semantics for mediation of unix domain sockets on connect should be applied. Note: this does cause a fail open on situation on Ubuntu Saucy, which did not properly indicate support. That is if a kernel using this patch is installed on an Ubuntu Saucy system, unix domain socket mediation on connect won't happen, instead the older behavior will be applied. This won't cause policy failures as it is less strict than what Ubuntu Saucy applies. This is necessary so that AppArmor can properly function on older userspaces without a compile time configuration on the kernel to determine behavior. A kernel expecting this behavior will function correctly with all old userspaces expect it will not enforce connect time mediation on Ubuntu Saucy. However Ubuntu does not support Trusty (or newer) kernels as backports to Saucy, so this does not break them. Signed-off-by: John Johansen --- parser/parser.h | 2 ++ parser/parser_common.c | 2 ++ parser/parser_interface.c | 3 +-- parser/parser_main.c | 4 ++++ parser/parser_regex.c | 5 +++++ 5 files changed, 14 insertions(+), 2 deletions(-) --- 2.9-test.orig/parser/parser.h +++ 2.9-test/parser/parser.h @@ -257,7 +257,9 @@ extern int perms_create; extern int net_af_max_override; extern int kernel_load; +extern int kernel_policy_version; extern int kernel_supports_network; +extern int kernel_supports_policydb; extern int kernel_supports_mount; extern int kernel_supports_dbus; extern int conf_verbose; --- 2.9-test.orig/parser/parser_common.c +++ 2.9-test/parser/parser_common.c @@ -25,7 +25,9 @@ int perms_create = 0; /* perms contain create flag */ int net_af_max_override = -1; /* use kernel to determine af_max */ int kernel_load = 1; +int kernel_policy_version = 5; /* default to base version */ int kernel_supports_network = 0; /* kernel supports network rules */ +int kernel_supports_policydb = 0; /* kernel supports new policydb */ int kernel_supports_mount = 0; /* kernel supports mount rules */ int kernel_supports_dbus = 0; /* kernel supports dbus rules */ int conf_verbose = 0; --- 2.9-test.orig/parser/parser_interface.c +++ 2.9-test/parser/parser_interface.c @@ -61,7 +61,6 @@ #define SD_CODE_SIZE (sizeof(u8)) #define SD_STR_LEN (sizeof(u16)) -#define SUBDOMAIN_INTERFACE_DFA_VERSION 5 int __sd_serialize_profile(int option, Profile *prof); @@ -683,7 +682,7 @@ { int version; - version = SUBDOMAIN_INTERFACE_DFA_VERSION; + version = kernel_policy_version; if (!sd_write_name(p, "version")) return 0; --- 2.9-test.orig/parser/parser_main.c +++ 2.9-test/parser/parser_main.c @@ -838,6 +838,10 @@ perms_create = 1; /* TODO: make this real parsing and config setting */ + if (strstr(features_string, "file {")) /* pre policydb is file= */ + kernel_supports_policydb = 1; + if (strstr(features_string, "v6")) + kernel_policy_version = 6; if (strstr(features_string, "network")) kernel_supports_network = 1; if (strstr(features_string, "mount")) --- 2.9-test.orig/parser/parser_regex.c +++ 2.9-test/parser/parser_regex.c @@ -672,6 +672,7 @@ #define MAKE_STR(X) #X #define CLASS_STR(X) "\\d" MAKE_STR(X) +static const char *mediates_file = CLASS_STR(AA_CLASS_FILE); static const char *mediates_mount = CLASS_STR(AA_CLASS_MOUNT); static const char *mediates_dbus = CLASS_STR(AA_CLASS_DBUS); @@ -690,6 +691,10 @@ * to be supported */ + /* note: this activates unix domain sockets mediation on connect */ + if (kernel_policy_version > 5 && + !prof->policy.rules->add_rule(mediates_file, 0, AA_MAY_READ, 0, dfaflags)) + goto out; if (kernel_supports_mount && !prof->policy.rules->add_rule(mediates_mount, 0, AA_MAY_READ, 0, dfaflags)) goto out; -- AppArmor mailing list AppArmor@lists.ubuntu.com Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/apparmor debian/patches/python-utils-file-support.patch0000664000000000000000000003741412317347533016767 0ustar Author: Tyler Hicks Forwarded: https://lists.ubuntu.com/archives/apparmor/2014-April/005600.html Bug-Ubuntu: https://bugs.launchpad.net/bugs/1295346 Subject: utils: Basic support for file prefix in path rules Add the ability to read and write path rules containing the file prefix. This also includes bare "file," rules. The ALL global is updated to include a preceding NUL char to eliminate possibilities of a real file path colliding with the ALL global. Signed-off-by: Tyler Hicks Index: ipc-fixes-and-improvements/utils/apparmor/aa.py =================================================================== --- ipc-fixes-and-improvements.orig/utils/apparmor/aa.py 2014-04-03 12:56:40.592547437 -0500 +++ ipc-fixes-and-improvements/utils/apparmor/aa.py 2014-04-03 12:56:40.584547437 -0500 @@ -79,7 +79,7 @@ seen_events = 0 # was our user_globs = [] # The key for representing bare rules such as "capability," or "file," -ALL = '_ALL' +ALL = '\0ALL' ## Variables used under logprof ### Were our @@ -2615,6 +2615,7 @@ RE_PROFILE_VARIABLE = re.compile('^\s*(@ RE_PROFILE_CONDITIONAL = re.compile('^\s*if\s+(not\s+)?(\$\{?\w*\}?)\s*\{\s*(#.*)?$') RE_PROFILE_CONDITIONAL_VARIABLE = re.compile('^\s*if\s+(not\s+)?defined\s+(@\{?\w+\}?)\s*\{\s*(#.*)?$') RE_PROFILE_CONDITIONAL_BOOLEAN = re.compile('^\s*if\s+(not\s+)?defined\s+(\$\{?\w+\}?)\s*\{\s*(#.*)?$') +RE_PROFILE_FILE_ENTRY = re.compile('^\s*(audit\s+)?(allow\s+|deny\s+)?(owner\s+)?file(?:\s+([\"@/].*?)\s+(\S+)(\s+->\s*(.*?))?)?\s*,\s*(#.*)?$') RE_PROFILE_PATH_ENTRY = re.compile('^\s*(audit\s+)?(allow\s+|deny\s+)?(owner\s+)?([\"@/].*?)\s+(\S+)(\s+->\s*(.*?))?\s*,\s*(#.*)?$') RE_PROFILE_NETWORK = re.compile('^\s*(audit\s+)?(allow\s+|deny\s+)?network(.*)\s*(#.*)?$') RE_PROFILE_CHANGE_HAT = re.compile('^\s*\^(\"??.+?\"??)\s*,\s*(#.*)?$') @@ -2896,6 +2897,69 @@ def parse_profile_data(data, file, do_in else: profile_data[profile][hat][allow]['path'][path]['audit'] = set() + elif RE_PROFILE_FILE_ENTRY.search(line): + matches = RE_PROFILE_FILE_ENTRY.search(line).groups() + + if not profile: + raise AppArmorException(_('Syntax Error: Unexpected file entry found in file: %s line: %s') % (file, lineno + 1)) + + audit = False + if matches[0]: + audit = True + + allow = 'allow' + if matches[1] and matches[1].strip() == 'deny': + allow = 'deny' + + user = False + if matches[2]: + user = True + + path = None + if matches[3]: + path = matches[3].strip() + + mode = None + if matches[4]: + mode = matches[4] + + nt_name = None + if matches[6]: + nt_name = matches[6].strip() + + if not path and not mode and not nt_name: + path = ALL + elif (path and not mode) or (nt_name and (not path or not mode)): + raise AppArmorException(_('Syntax Error: Invalid file entry found in file: %s line: %s') % (file, lineno + 1)) + + p_re = convert_regexp(path) + try: + re.compile(p_re) + except: + raise AppArmorException(_('Syntax Error: Invalid Regex %s in file: %s line: %s') % (path, file, lineno + 1)) + + tmpmode = set() + if mode: + if not validate_profile_mode(mode, allow, nt_name): + raise AppArmorException(_('Invalid mode %s in file: %s line: %s') % (mode, file, lineno + 1)) + + if user: + tmpmode = str_to_mode('%s::' % mode) + else: + tmpmode = str_to_mode(mode) + + profile_data[profile][hat][allow]['path'][path]['mode'] = profile_data[profile][hat][allow]['path'][path].get('mode', set()) | tmpmode + + profile_data[profile][hat][allow]['path'][path]['file_prefix'] = True + + if nt_name: + profile_data[profile][hat][allow]['path'][path]['to'] = nt_name + + if audit: + profile_data[profile][hat][allow]['path'][path]['audit'] = profile_data[profile][hat][allow]['path'][path].get('audit', set()) | tmpmode + else: + profile_data[profile][hat][allow]['path'][path]['audit'] = set() + elif re_match_include(line): # Include files include_name = re_match_include(line) @@ -3359,13 +3423,19 @@ def write_path_rules(prof_data, depth, a if prof_data[allow].get('path', False): for path in sorted(prof_data[allow]['path'].keys()): + filestr = '' + if prof_data[allow]['path'][path].get('file_prefix', False): + filestr = 'file ' mode = prof_data[allow]['path'][path]['mode'] audit = prof_data[allow]['path'][path]['audit'] tail = '' if prof_data[allow]['path'][path].get('to', False): tail = ' -> %s' % prof_data[allow]['path'][path]['to'] - user, other = split_mode(mode) - user_audit, other_audit = split_mode(audit) + user = None + other = None + if mode or audit: + user, other = split_mode(mode) + user_audit, other_audit = split_mode(audit) while user or other: ownerstr = '' @@ -3393,13 +3463,19 @@ def write_path_rules(prof_data, depth, a if tmpmode & tmpaudit: modestr = mode_to_str(tmpmode & tmpaudit) path = quote_if_needed(path) - data.append('%saudit %s%s%s %s%s,' % (pre, allowstr, ownerstr, path, modestr, tail)) + data.append('%saudit %s%s%s%s %s%s,' % (pre, allowstr, ownerstr, filestr, path, modestr, tail)) tmpmode = tmpmode - tmpaudit if tmpmode: modestr = mode_to_str(tmpmode) path = quote_if_needed(path) - data.append('%s%s%s%s %s%s,' % (pre, allowstr, ownerstr, path, modestr, tail)) + data.append('%s%s%s%s%s %s%s,' % (pre, allowstr, ownerstr, filestr, path, modestr, tail)) + + if filestr and path == ALL: + auditstr = '' + if audit == 0: + auditstr = 'audit ' + data.append('%s%s%s%s%s,' % (pre, auditstr, allowstr, filestr, tail)) data.append('') return data @@ -3954,6 +4030,71 @@ def serialize_profile_from_old_profile(p if correct: if not segments['path'] and True in segments.values(): + for segs in list(filter(lambda x: segments[x], segments.keys())): + depth = len(line) - len(line.lstrip()) + data += write_methods[segs](write_prof_data[name], int(depth / 2)) + segments[segs] = False + if write_prof_data[name]['allow'].get(segs, False): + write_prof_data[name]['allow'].pop(segs) + if write_prof_data[name]['deny'].get(segs, False): + write_prof_data[name]['deny'].pop(segs) + segments['path'] = True + write_prof_data[hat][allow]['path'].pop(path) + data.append(line) + else: + #To-Do + pass + + elif RE_PROFILE_FILE_ENTRY.search(line): + matches = RE_PROFILE_FILE_ENTRY.search(line).groups() + audit = False + if matches[0]: + audit = True + allow = 'allow' + if matches[1] and matches[1].split() == 'deny': + allow = 'deny' + + user = False + if matches[2]: + user = True + + path = None + if matches[3]: + path = matches[3].strip() + + mode = None + if matches[4]: + mode = matches[4].strip() + + nt_name = None + if matches[6]: + nt_name = matches[6].strip() + + if not path and not mode and not nt_name: + path = ALL + elif (path and not mode) or (nt_name and (not path or not mode)): + correct = False + + tmpmode = set() + if mode: + if user: + tmpmode = str_to_mode('%s::' % mode) + else: + tmpmode = str_to_mode(mode) + + if not write_prof_data[hat][allow]['path'][path].get('mode', set()) & tmpmode: + if path != ALL: + correct = False + + if nt_name and not write_prof_data[hat][allow]['path'][path].get('to', False) == nt_name: + correct = False + + if audit and not write_prof_data[hat][allow]['path'][path].get('audit', set()) & tmpmode: + if path != ALL: + correct = False + + if correct: + if not segments['path'] and True in segments.values(): for segs in list(filter(lambda x: segments[x], segments.keys())): depth = len(line) - len(line.lstrip()) data += write_methods[segs](write_prof_data[name], int(depth / 2)) Index: ipc-fixes-and-improvements/utils/test/test-regex_matches.py =================================================================== --- ipc-fixes-and-improvements.orig/utils/test/test-regex_matches.py 2014-04-03 12:56:40.592547437 -0500 +++ ipc-fixes-and-improvements/utils/test/test-regex_matches.py 2014-04-03 12:56:40.584547437 -0500 @@ -96,6 +96,9 @@ regex_split_comment_testcases = [ ('dbus send member=no_comment, ', False), ('audit "/tmp/foo, # bar" rw', False), ('audit "/tmp/foo, # bar" rw # comment', ('audit "/tmp/foo, # bar" rw ', '# comment')), + ('file,', False), + ('file, # bare', ('file, ', '# bare')), + ('file /tmp/foo rw, # read-write', ('file /tmp/foo rw, ', '# read-write')), ] def setup_split_comment_testcases(): @@ -110,6 +113,125 @@ def setup_split_comment_testcases(): stub_test.__doc__ = "test '%s'" % (test_string) setattr(AARegexSplitComment, 'test_split_comment_%d' % (i), stub_test) +class AARegexPath(unittest.TestCase): + '''Tests for RE_PROFILE_PATH_ENTRY''' + + def test_simple_path_01(self): + '''test ' /tmp/foo r,' ''' + + line = ' /tmp/foo r,' + result = aa.RE_PROFILE_PATH_ENTRY.search(line) + self.assertTrue(result, 'Couldn\'t find file rule in "%s"' % line) + mode = result.groups()[4].strip() + self.assertEqual(mode, 'r', 'Expected mode "r", got "%s"' % (mode)) + + def test_simple_path_02(self): + '''test ' audit /tmp/foo rw,' ''' + + line = ' audit /tmp/foo rw,' + result = aa.RE_PROFILE_PATH_ENTRY.search(line) + self.assertTrue(result, 'Couldn\'t find file rule in "%s"' % line) + audit = result.groups()[0].strip() + self.assertEqual(audit, 'audit', 'Couldn\t find audit modifier') + mode = result.groups()[4].strip() + self.assertEqual(mode, 'rw', 'Expected mode "rw", got "%s"' % (mode)) + + def test_simple_path_03(self): + '''test ' audit deny /tmp/foo rw,' ''' + + line = ' audit deny /tmp/foo rw,' + result = aa.RE_PROFILE_PATH_ENTRY.search(line) + self.assertTrue(result, 'Couldn\'t find file rule in "%s"' % line) + audit = result.groups()[0].strip() + self.assertEqual(audit, 'audit', 'Couldn\t find audit modifier') + deny = result.groups()[1].strip() + self.assertEqual(deny, 'deny', 'Couldn\t find deny modifier') + mode = result.groups()[4].strip() + self.assertEqual(mode, 'rw', 'Expected mode "rw", got "%s"' % (mode)) + + def test_simple_bad_path_01(self): + '''test ' file,' ''' + + line = ' file,' + result = aa.RE_PROFILE_PATH_ENTRY.search(line) + self.assertFalse(result, 'RE_PROFILE_PATH_ENTRY unexpectedly matched "%s"' % line) + + def test_simple_bad_path_02(self): + '''test ' file /tmp/foo rw,' ''' + + line = ' file /tmp/foo rw,' + result = aa.RE_PROFILE_PATH_ENTRY.search(line) + self.assertFalse(result, 'RE_PROFILE_PATH_ENTRY unexpectedly matched "%s"' % line) + +class AARegexFile(unittest.TestCase): + '''Tests for RE_PROFILE_FILE_ENTRY''' + + def _assertEqualStrings(self, str1, str2): + self.assertEqual(str1, str2, 'Expected %s, got "%s"' % (str1, str2)) + + def test_simple_file_01(self): + '''test ' file /tmp/foo rw,' ''' + + path = '/tmp/foo' + mode = 'rw' + line = ' file %s %s,' % (path, mode) + result = aa.RE_PROFILE_FILE_ENTRY.search(line) + self.assertTrue(result, 'Couldn\'t find file rule in "%s"' % line) + self._assertEqualStrings(path, result.groups()[3].strip()) + self._assertEqualStrings(mode, result.groups()[4].strip()) + + def test_simple_file_02(self): + '''test ' file,' ''' + + line = ' file,' + result = aa.RE_PROFILE_FILE_ENTRY.search(line) + self.assertTrue(result, 'Couldn\'t find file rule in "%s"' % line) + path = result.groups()[3] + self.assertEqual(path, None, 'Unexpected path, got "%s"' % path) + mode = result.groups()[4] + self.assertEqual(mode, None, 'Unexpected mode, got "%s"' % (mode)) + + def test_simple_file_03(self): + '''test ' audit file,' ''' + + line = ' audit file,' + result = aa.RE_PROFILE_FILE_ENTRY.search(line) + self.assertTrue(result, 'Couldn\'t find file rule in "%s"' % line) + audit = result.groups()[0].strip() + self.assertEqual(audit, 'audit', 'Couldn\t find audit modifier') + path = result.groups()[3] + self.assertEqual(path, None, 'Unexpected path, got "%s"' % path) + mode = result.groups()[4] + self.assertEqual(mode, None, 'Unexpected mode, got "%s"' % (mode)) + + def test_simple_bad_file_01(self): + '''test ' dbus,' ''' + + line = ' dbus,' + result = aa.RE_PROFILE_FILE_ENTRY.search(line) + self.assertFalse(result, 'RE_PROFILE_FILE_ENTRY unexpectedly matched "%s"' % line) + + def test_simple_bad_file_02(self): + '''test ' /tmp/foo rw,' ''' + + line = ' /tmp/foo rw,' + result = aa.RE_PROFILE_FILE_ENTRY.search(line) + self.assertFalse(result, 'RE_PROFILE_FILE_ENTRY unexpectedly matched "%s"' % line) + + def test_simple_bad_file_03(self): + '''test ' file /tmp/foo,' ''' + + line = ' file /tmp/foo,' + result = aa.RE_PROFILE_FILE_ENTRY.search(line) + self.assertFalse(result, 'RE_PROFILE_FILE_ENTRY unexpectedly matched "%s"' % line) + + def test_simple_bad_file_04(self): + '''test ' file r,' ''' + + line = ' file r,' + result = aa.RE_PROFILE_FILE_ENTRY.search(line) + self.assertFalse(result, 'RE_PROFILE_FILE_ENTRY unexpectedly matched "%s"' % line) + if __name__ == '__main__': verbosity = 2 @@ -119,6 +241,8 @@ if __name__ == '__main__': test_suite = unittest.TestSuite() test_suite.addTest(unittest.TestLoader().loadTestsFromTestCase(AARegexHasComma)) test_suite.addTest(unittest.TestLoader().loadTestsFromTestCase(AARegexSplitComment)) + test_suite.addTest(unittest.TestLoader().loadTestsFromTestCase(AARegexPath)) + test_suite.addTest(unittest.TestLoader().loadTestsFromTestCase(AARegexFile)) result = unittest.TextTestRunner(verbosity=verbosity).run(test_suite) if not result.wasSuccessful(): exit(1) debian/patches/parser_version.patch0000664000000000000000000002337212315045675014720 0ustar Author: John Johansen Forwarded: Yes Subject: Add the ability to separate policy_version from kernel and parser abi This will allow for the parser to invalidate its caches separate of whether the kernel policy version has changed. This can be desirable if a parser bug is discovered, a new version the parser is shipped and we need to force cache files to be regenerated. Policy current stores a 32 bit version number in the header binary policy. For newer policy (> v5 kernel abi) split this number into 3 separate fields policy_version, parser_abi, kernel_abi. If binary policy with a split version number is loaded to an older kernel it will be correctly rejected as unsupported as those kernels will see it as a none v5 version. For kernels that only support v5 policy on the kernel abi version is written. The rules for policy versioning should be policy_version: Set by text policy language version. Parsers that don't understand a specified version may fail, or drop rules they are unaware of. parser_abi_version: gets bumped when a userspace bug is discovered that requires policy be recompiled. The policy version could be reset for each new kernel version but since the parser needs to support multiple kernel versions tracking this is extra work and should be avoided. kernel_abi_version: gets bumped when semantic changes need to be applied. Eg unix domain sockets being mediated at connect. the kernel abi version does not encapsulate all supported features. As kernels could have different sets of patches supplied. Basic feature support is determined by the policy_mediates() encoding in the policydb. As such comparing cache features to kernel features is still needed to determine if cached policy is best matched to the kernel. Signed-off-by: John Johansen --- parser/parser.h | 40 +++++++++++++++++++++++++++++++++++++++- parser/parser_common.c | 42 +++++++++++++++++++++++++++++++++++++++++- parser/parser_interface.c | 18 +++--------------- parser/parser_main.c | 40 +++++++++++++++++++++++++++++++++++++--- parser/parser_regex.c | 2 +- parser/parser_yacc.y | 5 ++++- 6 files changed, 125 insertions(+), 22 deletions(-) --- 2.9-test.orig/parser/parser.h +++ 2.9-test/parser/parser.h @@ -253,11 +253,49 @@ goto fail_target; \ } while (0) + +#define u8 unsigned char +#define u16 uint16_t +#define u32 uint32_t +#define u64 uint64_t +#if __BYTE_ORDER == __BIG_ENDIAN +# define cpu_to_le16(x) ((u16)(bswap_16 ((u16) x))) +# define cpu_to_le32(x) ((u32)(bswap_32 ((u32) x))) +# define cpu_to_le64(x) ((u64)(bswap_64 ((u64) x))) +#else +# define cpu_to_le16(x) ((u16)(x)) +# define cpu_to_le32(x) ((u32)(x)) +# define cpu_to_le64(x) ((u64)(x)) +#endif + +/* The encoding for kernal abi > 5 is + * 28-31: reserved + * 20-27: policy version + * 12-19: policy abi version + * 11: force complain flag + * 10: reserved + * 0-9: kernel abi version + */ +#define ENCODE_VERSION(C, P, PABI, KABI) \ +({ \ + u32 version = (KABI) & 0x3ff; \ + if ((KABI) > 5) { \ + version |= (C) ? 1 << 11 : 0; \ + version |= ((PABI) & 0xff) << 12; \ + version |= ((P) & 0xff) << 20; \ + } \ + version; \ +}) + /* from parser_common.c */ +extern uint32_t policy_version; +extern uint32_t parser_abi_version; +extern uint32_t kernel_abi_version; + +extern int force_complain; extern int perms_create; extern int net_af_max_override; extern int kernel_load; -extern int kernel_policy_version; extern int kernel_supports_network; extern int kernel_supports_policydb; extern int kernel_supports_mount; --- 2.9-test.orig/parser/parser_common.c +++ 2.9-test/parser/parser_common.c @@ -22,10 +22,50 @@ #define _(s) gettext(s) #include "parser.h" +/* Policy versioning is determined by a combination of 3 values: + * policy_version: version of txt policy + * parser_abi_version: version of abi revision of policy generated by parser + * kernel_abi_version: version of abi revision for the kernel + * + * The version info is stored in a single 32 bit version field in the + * header portion of each binary policy file. + * + * policy_version: + * a gross revision number indicating what features and semantics are + * expected by the text policy. This does not necessarily map directly + * to a feature set as a kernel may not have all the supported features + * patched/builtin. + * + * policy_version is not supported by kernels that only support v5 + * kernel abi, so it will not be written when creating policy for + * those kernels. + * + * kernel_abi_version: + * should be set to the highest version supported by both the parser and + * the kernel. + * This allows new kernels to detect old userspaces, and new parsers + * to support old kernels and policies semantics. + * + * parser_abi_version: + * should be bumped when a compiler error or some other event happens + * and policy cache needs to be forced to be recomputed, when the + * policy_version or kernel version has not changed. + * + * parser_abi_version is not supported by kernels that only support + * v5 kernel abi so it will not be written when creating policy for those + * kernels. + * + * Default values set to v5 kernel abi before the different versioning + * numbers where supported. + */ +uint32_t policy_version = 2; +uint32_t parser_abi_version = 0; +uint32_t kernel_abi_version = 5; + +int force_complain = 0; int perms_create = 0; /* perms contain create flag */ int net_af_max_override = -1; /* use kernel to determine af_max */ int kernel_load = 1; -int kernel_policy_version = 5; /* default to base version */ int kernel_supports_network = 0; /* kernel supports network rules */ int kernel_supports_policydb = 0; /* kernel supports new policydb */ int kernel_supports_mount = 0; /* kernel supports mount rules */ --- 2.9-test.orig/parser/parser_interface.c +++ 2.9-test/parser/parser_interface.c @@ -40,23 +40,10 @@ #include #define _(s) gettext(s) -#define u8 unsigned char -#define u16 uint16_t -#define u32 uint32_t -#define u64 uint64_t #define BUFFERINC 65536 //#define BUFFERINC 16 -#if __BYTE_ORDER == __BIG_ENDIAN -# define cpu_to_le16(x) ((u16)(bswap_16 ((u16) x))) -# define cpu_to_le32(x) ((u32)(bswap_32 ((u32) x))) -# define cpu_to_le64(x) ((u64)(bswap_64 ((u64) x))) -#else -# define cpu_to_le16(x) ((u16)(x)) -# define cpu_to_le32(x) ((u32)(x)) -# define cpu_to_le64(x) ((u64)(x)) -#endif #define SD_CODE_SIZE (sizeof(u8)) #define SD_STR_LEN (sizeof(u16)) @@ -680,9 +667,10 @@ int sd_serialize_top_profile(sd_serialize *p, Profile *profile) { - int version; + uint32_t version; - version = kernel_policy_version; + version = ENCODE_VERSION(force_complain, policy_version, + parser_abi_version, kernel_abi_version); if (!sd_write_name(p, "version")) return 0; --- 2.9-test.orig/parser/parser_main.c +++ 2.9-test/parser/parser_main.c @@ -84,7 +84,6 @@ char *cacheloc = NULL; /* per-profile settings */ -int force_complain = 0; static int load_features(const char *name); @@ -841,7 +840,7 @@ if (strstr(features_string, "file {")) /* pre policydb is file= */ kernel_supports_policydb = 1; if (strstr(features_string, "v6")) - kernel_policy_version = 6; + kernel_abi_version = 6; if (strstr(features_string, "network")) kernel_supports_network = 1; if (strstr(features_string, "mount")) @@ -941,6 +940,40 @@ return rc; } +#if __BYTE_ORDER == __BIG_ENDIAN +# define le16_to_cpu(x) ((uint16_t)(bswap_16 (*(uint16_t *) x))) +#else +# define le16_to_cpu(x) (*(uint16_t *)(x)) +#endif + +const char header_string[] = "\004\010\000version\000\002"; +#define HEADER_STRING_SIZE 12 +static bool valid_cached_file_version(const char *cachename) +{ + char buffer[16]; + FILE *f; + if (!(f = fopen(cachename, "r"))) { + PERROR(_("Error: Could not read cache file '%s', skipping...\n"), cachename); + return false; + } + size_t res = fread(buffer, 1, 16, f); + fclose(f); + if (res < 16) + return false; + + /* 12 byte header that is always the same and then 4 byte version # */ + if (memcmp(buffer, header_string, HEADER_STRING_SIZE) != 0) + return false; + + uint32_t version = cpu_to_le32(ENCODE_VERSION(force_complain, + policy_version, + parser_abi_version, + kernel_abi_version)); + if (memcmp(buffer + 12, &version, 4) != 0) + return false; + + return true; +} /* returns true if time is more recent than mru_tstamp */ #define mru_t_cmp(a) \ @@ -1045,7 +1078,8 @@ /* Load a binary cache if it exists and is newest */ if (!skip_read_cache && stat(cachename, &stat_bin) == 0 && - stat_bin.st_size > 0 && (mru_t_cmp(stat_bin.st_mtim))) { + stat_bin.st_size > 0 && (mru_t_cmp(stat_bin.st_mtim)) && + valid_cached_file_version(cachename)) { if (show_cache) PERROR("Cache hit: %s\n", cachename); retval = process_binary(option, cachename); --- 2.9-test.orig/parser/parser_regex.c +++ 2.9-test/parser/parser_regex.c @@ -692,7 +692,7 @@ */ /* note: this activates unix domain sockets mediation on connect */ - if (kernel_policy_version > 5 && + if (kernel_abi_version > 5 && !prof->policy.rules->add_rule(mediates_file, 0, AA_MAY_READ, 0, dfaflags)) goto out; if (kernel_supports_mount && --- 2.9-test.orig/parser/parser_yacc.y +++ 2.9-test/parser/parser_yacc.y @@ -284,7 +284,10 @@ */ yyerror(_("Profile attachment must begin with a '/'.")); prof->flags = $3; - if (force_complain) + if (force_complain && kernel_abi_version == 5) + /* newer abis encode force complain as part of the + * header + */ prof->flags.complain = 1; post_process_file_entries(prof); -- AppArmor mailing list AppArmor@lists.ubuntu.com Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/apparmor debian/patches/add-debian-integration-to-lighttpd.patch0000664000000000000000000000175612315045675020407 0ustar Author: https://launchpad.net/~teka101 Description: Add entries for lighttpd to work in a Debian/Ubuntu install Forwarded: no (Debian/Ubuntu specific) Ubuntu-Bug: https://bugs.launchpad.net/ubuntu/+source/apparmor/+bug/582814 Index: apparmor-2.8.95~2385/profiles/apparmor/profiles/extras/usr.sbin.lighttpd =================================================================== --- apparmor-2.8.95~2385.orig/profiles/apparmor/profiles/extras/usr.sbin.lighttpd 2014-02-27 08:16:21.463928153 -0600 +++ apparmor-2.8.95~2385/profiles/apparmor/profiles/extras/usr.sbin.lighttpd 2014-02-27 08:16:46.088256332 -0600 @@ -52,5 +52,15 @@ /bin/bash mix, /bin/zsh mix, /bin/cat mix, + + # Debian/Ubuntu integration in default installation + #include + /etc/mime.types r, + /usr/share/lighttpd/ r, + /usr/share/lighttpd/*.pl rmix, + /etc/lighttpd/conf-available/ r, + /etc/lighttpd/conf-available/*.conf r, + /etc/lighttpd/conf-enabled/ r, + /etc/lighttpd/conf-enabled/*.conf r, } debian/patches/series0000664000000000000000000000273312317332414012041 0ustar add-chromium-browser.patch add-debian-integration-to-lighttpd.patch ubuntu-manpage-updates.patch libapparmor-layout-deb.patch libapparmor-mention-dbus-method-in-getcon-man.patch etc-writable.patch aa-utils_are_bilingual.patch convert-to-rules.patch list-fns.patch parse-mode.patch add-decimal-interp.patch policy_mediates.patch fix-failpath.patch feature_file.patch fix-network.patch aare-to-class.patch add-mediation-unix.patch parser_version.patch caching.patch label-class.patch fix-lexer-debug.patch use-diff-encode.patch fix-serialize.patch fix-ppc-endian-ftbfs.patch opt_arg.patch tests-cond-dbus.patch initialize-mount-flags.patch fix-typo-in-dbus_write.patch limited-mount-rule-support.patch bare-capability-rule-support.patch check-config-for-sysctl.patch increase-swap-size.patch test-v6-policy.patch test-mount-mediation.patch mediate-signals.patch change-signal-syntax.patch mediate-ptrace.patch change-ptrace-syntax.patch test-signal-rules.patch test-ptrace-rules.patch update-tests-for-new-semantics.patch fix-garbage-in-preprocessor-output.patch fix-double-comma-in-preprocessor-output.patch symtab-tests-and-seenlist-bug.patch add-profile-name-variable.patch fix-names-treated-as-condlistid.patch update-base-abstraction-for-signals-and-ptrace.patch manpage-signal-ptrace.patch dnsmasq-libvirtd-signal-ptrace.patch update-chromium-browser.patch python-utils-file-support.patch python-utils-signal-support.patch python-utils-ptrace-support.patch python-utils-pivot_root-support.patch debian/patches/opt_arg.patch0000664000000000000000000003707412315045675013316 0ustar Author: John Johansen Forwarded: Yes Subject: Split flag handling into a separate file Signed-off-by: John Johansen Acked-by: Seth Arnold Acked-by: Steve Beattie ---- --- parser/Makefile | 9 ++ parser/common_optarg.c | 170 +++++++++++++++++++++++++++++++++++++++++++++++++ parser/common_optarg.h | 47 +++++++++++++ parser/parser.h | 1 parser/parser_main.c | 157 --------------------------------------------- 5 files changed, 227 insertions(+), 157 deletions(-) Index: b/parser/Makefile =================================================================== --- a/parser/Makefile +++ b/parser/Makefile @@ -79,8 +79,9 @@ SRCS = parser_common.c parser_include.c parser_interface.c parser_lex.c \ parser_main.c parser_misc.c parser_merge.c parser_symtab.c \ parser_yacc.c parser_regex.c parser_variable.c parser_policy.c \ - parser_alias.c mount.c dbus.c lib.c profile.cc rule.c -HDRS = parser.h parser_include.h immunix.h mount.h dbus.h lib.h profile.h rule.h + parser_alias.c mount.c dbus.c lib.c profile.cc rule.c common_optarg.c +HDRS = parser.h parser_include.h immunix.h mount.h dbus.h lib.h profile.h \ + rule.h common_optarg.h TOOLS = apparmor_parser OBJECTS = $(SRCS:.c=.o) @@ -116,6 +117,7 @@ TEST_OBJECTS = $(filter-out \ parser_lex.o \ parser_yacc.o \ + common_optarg.o \ parser_main.o, ${OBJECTS}) \ $(AAREOBJECTS) TEST_LDFLAGS = $(AARE_LDFLAGS) @@ -233,6 +235,9 @@ mount.o: mount.c mount.h parser.h immunix.h rule.h $(CXX) $(EXTRA_CFLAGS) -c -o $@ $< +common_optarg.o: common_optarg.c common_optarg.h parser.h libapparmor_re/apparmor_re.h + $(CXX) $(EXTRA_CFLAGS) -c -o $@ $< + lib.o: lib.c lib.h parser.h $(CXX) $(EXTRA_CFLAGS) -c -o $@ $< Index: b/parser/common_optarg.c =================================================================== --- /dev/null +++ b/parser/common_optarg.c @@ -0,0 +1,170 @@ +/* + * Copyright (c) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * NOVELL (All rights reserved) + * + * Copyright (c) 2010 - 2013 + * 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 +#include +#include +#include + +#include "common_optarg.h" +#include "parser.h" + +optflag_table_t dumpflag_table[] = { + { 1, "rule-exprs", "Dump rule to expr tree conversions", + DFA_DUMP_RULE_EXPR }, + { 1, "expr-stats", "Dump stats on expr tree", DFA_DUMP_TREE_STATS }, + { 1, "expr-tree", "Dump expression tree", DFA_DUMP_TREE }, + { 1, "expr-simplified", "Dump simplified expression tree", + DFA_DUMP_SIMPLE_TREE }, + { 1, "stats", "Dump all compile stats", + DFA_DUMP_TREE_STATS | DFA_DUMP_STATS | DFA_DUMP_TRANS_STATS | + DFA_DUMP_EQUIV_STATS | DFA_DUMP_DIFF_STATS }, + { 1, "progress", "Dump progress for all compile phases", + DFA_DUMP_PROGRESS | DFA_DUMP_STATS | DFA_DUMP_TRANS_PROGRESS | + DFA_DUMP_TRANS_STATS | DFA_DUMP_DIFF_PROGRESS | DFA_DUMP_DIFF_STATS }, + { 1, "dfa-progress", "Dump dfa creation as in progress", + DFA_DUMP_PROGRESS | DFA_DUMP_STATS }, + { 1, "dfa-stats", "Dump dfa creation stats", DFA_DUMP_STATS }, + { 1, "dfa-states", "Dump dfa state diagram", DFA_DUMP_STATES }, + { 1, "dfa-graph", "Dump dfa dot (graphviz) graph", DFA_DUMP_GRAPH }, + { 1, "dfa-minimize", "Dump dfa minimization", DFA_DUMP_MINIMIZE }, + { 1, "dfa-unreachable", "Dump dfa unreachable states", + DFA_DUMP_UNREACHABLE }, + { 1, "dfa-node-map", "Dump expr node set to state mapping", + DFA_DUMP_NODE_TO_DFA }, + { 1, "dfa-uniq-perms", "Dump unique perms", + DFA_DUMP_UNIQ_PERMS }, + { 1, "dfa-minimize-uniq-perms", "Dump unique perms post minimization", + DFA_DUMP_MIN_UNIQ_PERMS }, + { 1, "dfa-minimize-partitions", "Dump dfa minimization partitions", + DFA_DUMP_MIN_PARTS }, + { 1, "compress-progress", "Dump progress of compression", + DFA_DUMP_TRANS_PROGRESS | DFA_DUMP_TRANS_STATS }, + { 1, "compress-stats", "Dump stats on compression", + DFA_DUMP_TRANS_STATS }, + { 1, "compressed-dfa", "Dump compressed dfa", DFA_DUMP_TRANS_TABLE }, + { 1, "equiv-stats", "Dump equivance class stats", + DFA_DUMP_EQUIV_STATS }, + { 1, "equiv", "Dump equivance class", DFA_DUMP_EQUIV }, + { 1, "diff-encode", "Dump differential encoding", + DFA_DUMP_DIFF_ENCODE }, + { 1, "diff-stats", "Dump differential encoding stats", + DFA_DUMP_DIFF_STATS }, + { 1, "diff-progress", "Dump progress of differential encoding", + DFA_DUMP_DIFF_PROGRESS | DFA_DUMP_DIFF_STATS }, + { 0, NULL, NULL, 0 }, +}; + +optflag_table_t optflag_table[] = { + { 2, "0", "no optimizations", + DFA_CONTROL_TREE_NORMAL | DFA_CONTROL_TREE_SIMPLE | + DFA_CONTROL_MINIMIZE | DFA_CONTROL_REMOVE_UNREACHABLE | + DFA_CONTROL_DIFF_ENCODE + }, + { 1, "equiv", "use equivalent classes", DFA_CONTROL_EQUIV }, + { 1, "expr-normalize", "expression tree normalization", + DFA_CONTROL_TREE_NORMAL }, + { 1, "expr-simplify", "expression tree simplification", + DFA_CONTROL_TREE_SIMPLE }, + { 0, "expr-left-simplify", "left simplification first", + DFA_CONTROL_TREE_LEFT }, + { 2, "expr-right-simplify", "right simplification first", + DFA_CONTROL_TREE_LEFT }, + { 1, "minimize", "dfa state minimization", DFA_CONTROL_MINIMIZE }, + { 1, "filter-deny", "filter out deny information from final dfa", + DFA_CONTROL_FILTER_DENY }, + { 1, "remove-unreachable", "dfa unreachable state removal", + DFA_CONTROL_REMOVE_UNREACHABLE }, + { 0, "compress-small", + "do slower dfa transition table compression", + DFA_CONTROL_TRANS_HIGH }, + { 2, "compress-fast", "do faster dfa transition table compression", + DFA_CONTROL_TRANS_HIGH }, + { 1, "diff-encode", "Differentially encode transitions", + DFA_CONTROL_DIFF_ENCODE }, + { 0, NULL, NULL, 0 }, +}; + +void print_flag_table(optflag_table_t *table) +{ + int i; + unsigned int longest = 0; + for (i = 0; table[i].option; i++) { + if (strlen(table[i].option) > longest) + longest = strlen(table[i].option); + } + + for (i = 0; table[i].option; i++) { + printf("%5s%-*s \t%s\n", (table[i].control & 1) ? "[no-]" : "", + longest, table[i].option, table[i].desc); + } +} + +int handle_flag_table(optflag_table_t *table, const char *optarg, + dfaflags_t *flags) +{ + const char *arg = optarg; + int i, invert = 0; + + if (strncmp(optarg, "no-", 3) == 0) { + arg = optarg + 3; + invert = 1; + } + + for (i = 0; table[i].option; i++) { + if (strcmp(table[i].option, arg) == 0) { + /* check if leading no- was specified but is not + * supported by the option */ + if (invert && !(table[i].control & 1)) + return 0; + if (table[i].control & 2) + invert |= 1; + if (invert) + *flags &= ~table[i].flags; + else + *flags |= table[i].flags; + return 1; + } + } + return 0; +} + +void display_dump(const char *command) +{ + display_version(); + printf("\n%s: --dump [Option]\n\n" + "Options:\n" + "--------\n" + " variables \tDump variables\n" + " expanded-variables\t Dump variables after expansion\n" + ,command); + print_flag_table(dumpflag_table); +} + +void display_optimize(const char *command) +{ + display_version(); + printf("\n%s: -O [Option]\n\n" + "Options:\n" + "--------\n" + ,command); + print_flag_table(optflag_table); +} Index: b/parser/common_optarg.h =================================================================== --- /dev/null +++ b/parser/common_optarg.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * NOVELL (All rights reserved) + * + * Copyright (c) 2010 - 2013 + * 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. + */ +#ifndef __AA_COMMON_OPTARG_H +#define __AA_COMMON_OPTARG_H + +#include "libapparmor_re/apparmor_re.h" + +/* + * flag: 1 - allow no- inversion + * flag: 2 - flags specified should be masked off + */ +typedef struct { + int control; + const char *option; + const char *desc; + dfaflags_t flags; +} optflag_table_t; + +extern optflag_table_t dumpflag_table[]; +extern optflag_table_t optflag_table[]; + +void print_flag_table(optflag_table_t *table); +int handle_flag_table(optflag_table_t *table, const char *optarg, + dfaflags_t *flags); +void display_dump(const char *command); +void display_optimize(const char *command); + +#endif /* __AA_COMMON_OPTARG_H */ + Index: b/parser/parser.h =================================================================== --- a/parser/parser.h +++ b/parser/parser.h @@ -317,6 +317,7 @@ extern int force_complain; extern struct timespec mru_tstamp; extern void update_mru_tstamp(FILE *file); +extern void display_version(void); /* provided by parser_lex.l (cannot be used in tst builds) */ extern FILE *yyin; Index: b/parser/parser_main.c =================================================================== --- a/parser/parser_main.c +++ b/parser/parser_main.c @@ -47,6 +47,7 @@ #include "parser.h" #include "parser_version.h" #include "parser_include.h" +#include "common_optarg.h" #include "libapparmor_re/apparmor_re.h" #define MODULE_NAME "apparmor" @@ -131,7 +132,7 @@ static int debug = 0; -static void display_version(void) +void display_version(void) { printf("%s version " PARSER_VERSION "\n%s\n", parser_title, parser_copyright); @@ -178,160 +179,6 @@ ,command); } -/* - * flag: 1 - allow no- inversion - * flag: 2 - flags specified should be masked off - */ -typedef struct { - int control; - const char *option; - const char *desc; - dfaflags_t flags; -} optflag_table_t; - -optflag_table_t dumpflag_table[] = { - { 1, "rule-exprs", "Dump rule to expr tree conversions", - DFA_DUMP_RULE_EXPR }, - { 1, "expr-stats", "Dump stats on expr tree", DFA_DUMP_TREE_STATS }, - { 1, "expr-tree", "Dump expression tree", DFA_DUMP_TREE }, - { 1, "expr-simplified", "Dump simplified expression tree", - DFA_DUMP_SIMPLE_TREE }, - { 1, "stats", "Dump all compile stats", - DFA_DUMP_TREE_STATS | DFA_DUMP_STATS | DFA_DUMP_TRANS_STATS | - DFA_DUMP_EQUIV_STATS | DFA_DUMP_DIFF_STATS }, - { 1, "progress", "Dump progress for all compile phases", - DFA_DUMP_PROGRESS | DFA_DUMP_STATS | DFA_DUMP_TRANS_PROGRESS | - DFA_DUMP_TRANS_STATS | DFA_DUMP_DIFF_PROGRESS | DFA_DUMP_DIFF_STATS }, - { 1, "dfa-progress", "Dump dfa creation as in progress", - DFA_DUMP_PROGRESS | DFA_DUMP_STATS }, - { 1, "dfa-stats", "Dump dfa creation stats", DFA_DUMP_STATS }, - { 1, "dfa-states", "Dump dfa state diagram", DFA_DUMP_STATES }, - { 1, "dfa-graph", "Dump dfa dot (graphviz) graph", DFA_DUMP_GRAPH }, - { 1, "dfa-minimize", "Dump dfa minimization", DFA_DUMP_MINIMIZE }, - { 1, "dfa-unreachable", "Dump dfa unreachable states", - DFA_DUMP_UNREACHABLE }, - { 1, "dfa-node-map", "Dump expr node set to state mapping", - DFA_DUMP_NODE_TO_DFA }, - { 1, "dfa-uniq-perms", "Dump unique perms", - DFA_DUMP_UNIQ_PERMS }, - { 1, "dfa-minimize-uniq-perms", "Dump unique perms post minimization", - DFA_DUMP_MIN_UNIQ_PERMS }, - { 1, "dfa-minimize-partitions", "Dump dfa minimization partitions", - DFA_DUMP_MIN_PARTS }, - { 1, "compress-progress", "Dump progress of compression", - DFA_DUMP_TRANS_PROGRESS | DFA_DUMP_TRANS_STATS }, - { 1, "compress-stats", "Dump stats on compression", - DFA_DUMP_TRANS_STATS }, - { 1, "compressed-dfa", "Dump compressed dfa", DFA_DUMP_TRANS_TABLE }, - { 1, "equiv-stats", "Dump equivance class stats", - DFA_DUMP_EQUIV_STATS }, - { 1, "equiv", "Dump equivance class", DFA_DUMP_EQUIV }, - { 1, "diff-encode", "Dump differential encoding", - DFA_DUMP_DIFF_ENCODE }, - { 1, "diff-stats", "Dump differential encoding stats", - DFA_DUMP_DIFF_STATS }, - { 1, "diff-progress", "Dump progress of differential encoding", - DFA_DUMP_DIFF_PROGRESS | DFA_DUMP_DIFF_STATS }, - { 0, NULL, NULL, 0 }, -}; - -optflag_table_t optflag_table[] = { - { 2, "0", "no optimizations", - DFA_CONTROL_TREE_NORMAL | DFA_CONTROL_TREE_SIMPLE | - DFA_CONTROL_MINIMIZE | DFA_CONTROL_REMOVE_UNREACHABLE | - DFA_CONTROL_DIFF_ENCODE - }, - { 1, "equiv", "use equivalent classes", DFA_CONTROL_EQUIV }, - { 1, "expr-normalize", "expression tree normalization", - DFA_CONTROL_TREE_NORMAL }, - { 1, "expr-simplify", "expression tree simplification", - DFA_CONTROL_TREE_SIMPLE }, - { 0, "expr-left-simplify", "left simplification first", - DFA_CONTROL_TREE_LEFT }, - { 2, "expr-right-simplify", "right simplification first", - DFA_CONTROL_TREE_LEFT }, - { 1, "minimize", "dfa state minimization", DFA_CONTROL_MINIMIZE }, - { 1, "filter-deny", "filter out deny information from final dfa", - DFA_CONTROL_FILTER_DENY }, - { 1, "remove-unreachable", "dfa unreachable state removal", - DFA_CONTROL_REMOVE_UNREACHABLE }, - { 0, "compress-small", - "do slower dfa transition table compression", - DFA_CONTROL_TRANS_HIGH }, - { 2, "compress-fast", "do faster dfa transition table compression", - DFA_CONTROL_TRANS_HIGH }, - { 1, "diff-encode", "Differentially encode transitions", - DFA_CONTROL_DIFF_ENCODE }, - { 0, NULL, NULL, 0 }, -}; - -static void print_flag_table(optflag_table_t *table) -{ - int i; - unsigned int longest = 0; - for (i = 0; table[i].option; i++) { - if (strlen(table[i].option) > longest) - longest = strlen(table[i].option); - } - - for (i = 0; table[i].option; i++) { - printf("%5s%-*s \t%s\n", (table[i].control & 1) ? "[no-]" : "", - longest, table[i].option, table[i].desc); - } -} - -static int handle_flag_table(optflag_table_t *table, const char *optarg, - dfaflags_t *flags) -{ - const char *arg = optarg; - int i, invert = 0; - - if (strncmp(optarg, "no-", 3) == 0) { - arg = optarg + 3; - invert = 1; - } - - for (i = 0; table[i].option; i++) { - if (strcmp(table[i].option, arg) == 0) { - /* check if leading no- was specified but is not - * supported by the option */ - if (invert && !(table[i].control & 1)) - return 0; - if (table[i].control & 2) - invert |= 1; - if (invert) - *flags &= ~table[i].flags; - else - *flags |= table[i].flags; - return 1; - } - } - - return 0; -} - -static void display_dump(const char *command) -{ - display_version(); - printf("\n%s: --dump [Option]\n\n" - "Options:\n" - "--------\n" - " none specified \tDump variables\n" - " variables \tDump variables\n" - ,command); - print_flag_table(dumpflag_table); -} - -static void display_optimize(const char *command) -{ - display_version(); - printf("\n%s: -O [Option]\n\n" - "Options:\n" - "--------\n" - ,command); - print_flag_table(optflag_table); -} - /* Treat conf file like options passed on command line */ debian/patches/tests-cond-dbus.patch0000664000000000000000000000431712315045675014673 0ustar Author: John Johansen Forwarded: Yes Subject: Make dbus tests be conditionally run based on pkg-config [I removed the extra ')' from the first hunk -- seth.arnold] The addition of the dbus tests requires dbus dev libraries be installed to run the test suite. This is not always desirable or even possible. So make building and running the dbus tests conditional on the pkg-config info from those libs. If they are not present output a message about skipping the tests. This patch contains the review fix from sbeattie Signed-off-by: John Johansen --- tests/regression/apparmor/Makefile | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) --- 2.9-test.orig/tests/regression/apparmor/Makefile +++ 2.9-test/tests/regression/apparmor/Makefile @@ -66,9 +66,6 @@ chown.c \ clone.c \ coredump.c \ - dbus_eavesdrop.c \ - dbus_message.c \ - dbus_service.c \ deleted.c \ environ.c \ env_check.c \ @@ -125,6 +122,17 @@ SRC+=syscall_ioperm.c syscall_iopl.c endif +#only do dbus if proper libs are installl +ifneq (,$(shell pkg-config --exists dbus-1 && echo TRUE)) +SRC+=dbus_eavesdrop.c dbus_message.c dbus_service.c +else +$(warning ${nl}\ +************************************************************************${nl}\ +No dbus pkg-config skipping dbus_eavesdrop dbus_message dbus_services tests ...${nl}\ +Install libdbus-1-dev or equivalent package to build and run these tests${nl}\ +************************************************************************${nl}) +endif + EXEC=$(SRC:%.c=%) TESTS=access \ @@ -138,9 +146,6 @@ chdir \ clone \ coredump \ - dbus_eavesdrop \ - dbus_message \ - dbus_service \ deleted \ environ \ exec \ @@ -179,6 +184,11 @@ xattrs\ longpath +#only do dbus if proper libs are installl +ifneq (,$(shell pkg-config --exists dbus-1 && echo TRUE)) +TESTS+=dbus_eavesdrop dbus_message dbus_service +endif + # Tests that can crash the kernel should be placed here RISKY_TESTS= -- AppArmor mailing list AppArmor@lists.ubuntu.com Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/apparmor debian/patches/feature_file.patch0000664000000000000000000004552212315045675014312 0ustar Author: John Johansen Forwarded: Yes Subject: Hack rework of the feature/match file support This is not the cleanup this code needs, but a quick hack to add the -M flag so we can specify a feature file (or directory) to use for the compile. It mostly just moves around existing code and adds the -M option, though it does introduce a few changes. While I didn't do it in this patch I propose we drop support for the match file without create support. This is several years old now and would clean things up a lot. Note: that the manually input -m or -M drop support for it already I just can't see a good way to support a single input stream indicating the result/existance of two separate files. This needs more work but is needed to support tests and the policy_mediates frame work depends on the policydb getting generated with the special stub rules to indicate whether policy was compiled expecting a certain feature. But this can break the current tests, at least once a bug in the policy rule counting is fixed in a follow on patch. Signed-off-by: John Johansen --- parser/parser_main.c | 198 +++++++++++++------------- parser/tst/features_files/features.dbus | 34 ++++ parser/tst/features_files/features.mount | 34 ++++ parser/tst/features_files/features.mount+dbus | 37 ++++ parser/tst/features_files/features.nopolicydb | 31 ++++ parser/tst/minimize.sh | 16 +- 6 files changed, 247 insertions(+), 103 deletions(-) --- 2.9-test.orig/parser/parser_main.c +++ 2.9-test/parser/parser_main.c @@ -53,8 +53,8 @@ #define OLD_MODULE_NAME "subdomain" #define PROC_MODULES "/proc/modules" #define DEFAULT_APPARMORFS "/sys/kernel/security/" MODULE_NAME -#define MATCH_STRING "/sys/kernel/security/" MODULE_NAME "/matching" -#define FLAGS_FILE "/sys/kernel/security/" MODULE_NAME "/features" +#define MATCH_FILE "/sys/kernel/security/" MODULE_NAME "/matching" +#define FEATURES_FILE "/sys/kernel/security/" MODULE_NAME "/features" #define MOUNTED_FS "/proc/mounts" #define AADFA "pattern=aadfa" @@ -79,16 +79,17 @@ int skip_mode_force = 0; struct timespec mru_tstamp; -#define FLAGS_STRING_SIZE 8192 -char *match_string = NULL; -char *flags_string = NULL; +#define FEATURES_STRING_SIZE 8192 +char *features_string = NULL; char *cacheloc = NULL; /* per-profile settings */ int force_complain = 0; +static int load_features(const char *name); + /* Make sure to update BOTH the short and long_options */ -static const char *short_options = "adf:h::rRVvI:b:BCD:NSm:qQn:XKTWkL:O:po:"; +static const char *short_options = "adf:h::rRVvI:b:BCD:NSm:M:qQn:XKTWkL:O:po:"; struct option long_options[] = { {"add", 0, 0, 'a'}, {"binary", 0, 0, 'B'}, @@ -106,6 +107,7 @@ {"stdout", 0, 0, 'S'}, {"ofile", 1, 0, 'o'}, {"match-string", 1, 0, 'm'}, + {"features-file", 1, 0, 'M'}, {"quiet", 0, 0, 'q'}, {"skip-kernel-load", 0, 0, 'Q'}, {"verbose", 0, 0, 'v'}, @@ -153,7 +155,8 @@ "-b n, --base n Set base dir and cwd\n" "-I n, --Include n Add n to the search path\n" "-f n, --subdomainfs n Set location of apparmor filesystem\n" - "-m n, --match-string n Use only match features n\n" + "-m n, --match-string n Use only features n\n" + "-M n, --features-file n Use only features in file n\n" "-n n, --namespace n Set Namespace for the profile\n" "-X, --readimpliesX Map profile read permissions to mr\n" "-k, --show-cache Report cache hit/miss details\n" @@ -520,7 +523,14 @@ } break; case 'm': - match_string = strdup(optarg); + features_string = strdup(optarg); + break; + case 'M': + if (load_features(optarg) == -1) { + fprintf(stderr, "Failed to load features from '%s'\n", + optarg); + exit(1); + } break; case 'q': conf_verbose = 0; @@ -733,104 +743,107 @@ struct features_struct fst = { buffer, size, pos }; if (dirat_for_each(NULL, filename, &fst, features_dir_cb)) { - PDEBUG("Failed evaluating .features\n"); + PDEBUG("Failed evaluating %s\n", filename); exit(1); } return fst.pos; } -/* match_string == NULL --> no match_string available - match_string != NULL --> either a matching string specified on the - command line, or the kernel supplied a match string */ -static void get_match_string(void) { +static char *load_features_file(const char *name) { + char *buffer; + FILE *f = NULL; + size_t size; - FILE *ms = NULL; - struct stat stat_file; + f = fopen(name, "r"); + if (!f) + return NULL; - /* has process_args() already assigned a match string? */ - if (match_string) - goto out; + buffer = (char *) malloc(FEATURES_STRING_SIZE); + if (!buffer) + goto fail; - if (stat(FLAGS_FILE, &stat_file) == -1) - goto out; + size = fread(buffer, 1, FEATURES_STRING_SIZE - 1, f); + if (!size || ferror(f)) + goto fail; + buffer[size] = 0; - if (S_ISDIR(stat_file.st_mode)) { - /* if we have a features directory default to */ - perms_create = 1; + fclose(f); + return buffer; - flags_string = (char *) malloc(FLAGS_STRING_SIZE); - handle_features_dir(FLAGS_FILE, &flags_string, FLAGS_STRING_SIZE, flags_string); - if (strstr(flags_string, "network")) - kernel_supports_network = 1; - else - kernel_supports_network = 0; - if (strstr(flags_string, "mount")) - kernel_supports_mount = 1; - if (strstr(flags_string, "dbus")) - kernel_supports_dbus = 1; - return; - } +fail: + int save = errno; + free(buffer); + if (f) + fclose(f); + errno = save; + return NULL; +} - ms = fopen(MATCH_STRING, "r"); - if (!ms) - goto out; +static int load_features(const char *name) +{ + struct stat stat_file; - match_string = (char *) malloc(1000); - if (!match_string) { - goto out; - } + if (stat(name, &stat_file) == -1) + return -1; - if (!fgets(match_string, 1000, ms)) { - free(match_string); - match_string = NULL; + if (S_ISDIR(stat_file.st_mode)) { + /* if we have a features directory default to */ + features_string = (char *) malloc(FEATURES_STRING_SIZE); + handle_features_dir(name, &features_string, FEATURES_STRING_SIZE, features_string); + } else { + features_string = load_features_file(name); + if (!features_string) + return -1; } -out: - if (match_string) { + return 0; +} + +static void set_features_by_match_file(void) +{ + FILE *ms = fopen(MATCH_FILE, "r"); + if (ms) { + char *match_string = (char *) malloc(1000); + if (!match_string) + goto no_match; + if (!fgets(match_string, 1000, ms)) { + free(match_string); + goto no_match; + } if (strstr(match_string, " perms=c")) perms_create = 1; - } else { - perms_create = 1; - kernel_supports_network = 0; + free(match_string); + goto out; } +no_match: + perms_create = 1; + kernel_supports_network = 0; +out: if (ms) fclose(ms); - return; } -static void get_flags_string(char **flags, const char *flags_file) { - char *pos; - FILE *f = NULL; - size_t size; - - /* abort if missing or already set */ - if (!flags || *flags) - return; - - f = fopen(flags_file, "r"); - if (!f) - return; +static void set_supported_features(void) { - *flags = (char *) malloc(FLAGS_STRING_SIZE); - if (!*flags) - goto fail; - - size = fread(*flags, 1, FLAGS_STRING_SIZE - 1, f); - if (!size || ferror(f)) - goto fail; - (*flags)[size] = 0; + /* has process_args() already assigned a match string? */ + if (!features_string) { + if (load_features(FEATURES_FILE) == -1) { + set_features_by_match_file(); + return; + } + } - fclose(f); - return; + perms_create = 1; -fail: - free(*flags); - *flags = NULL; - if (f) - fclose(f); - return; + /* TODO: make this real parsing and config setting */ + if (strstr(features_string, "network")) + kernel_supports_network = 1; + if (strstr(features_string, "mount")) + kernel_supports_mount = 1; + if (strstr(features_string, "dbus")) + kernel_supports_dbus = 1; } int process_binary(int option, const char *profilename) @@ -1211,28 +1224,23 @@ char *cache_flags = NULL; /* Get the match string to determine type of regex support needed */ - get_match_string(); - /* Get kernel features string */ - get_flags_string(&flags_string, FLAGS_FILE); + set_supported_features(); + /* Gracefully handle AppArmor kernel without compatibility patch */ - if (!flags_string) { + if (!features_string) { PERROR("Cache read/write disabled: %s interface file missing. " "(Kernel needs AppArmor 2.4 compatibility patch.)\n", - FLAGS_FILE); + FEATURES_FILE); write_cache = 0; skip_read_cache = 1; return; - } else if (strstr(flags_string, "network")) - kernel_supports_network = 1; - else - kernel_supports_network = 0; - + } /* * Deal with cache directory versioning: * - If cache/.features is missing, create it if --write-cache. - * - If cache/.features exists, and does not match flags_string, + * - If cache/.features exists, and does not match features_string, * force cache reading/writing off. */ if (asprintf(&cache_features_path, "%s/.features", cacheloc) == -1) { @@ -1240,16 +1248,16 @@ exit(1); } - get_flags_string(&cache_flags, cache_features_path); + cache_flags = load_features_file(cache_features_path); if (cache_flags) { - if (strcmp(flags_string, cache_flags) != 0) { + if (strcmp(features_string, cache_flags) != 0) { if (write_cache && cond_clear_cache) { if (create_cache(cacheloc, cache_features_path, - flags_string)) + features_string)) skip_read_cache = 1; } else { if (show_cache) - PERROR("Cache read/write disabled: %s does not match %s\n", FLAGS_FILE, cache_features_path); + PERROR("Cache read/write disabled: %s does not match %s\n", FEATURES_FILE, cache_features_path); write_cache = 0; skip_read_cache = 1; } @@ -1257,7 +1265,7 @@ free(cache_flags); cache_flags = NULL; } else if (write_cache) { - create_cache(cacheloc, cache_features_path, flags_string); + create_cache(cacheloc, cache_features_path, features_string); } free(cache_features_path); --- /dev/null +++ 2.9-test/parser/tst/features_files/features.dbus @@ -0,0 +1,34 @@ +dbus {mask {acquire send receive +} +} +caps {mask {chown dac_override dac_read_search fowner fsetid kill setgid setuid setpcap linux_immutable net_bind_service net_broadcast net_admin net_raw ipc_lock ipc_owner sys_module sys_rawio sys_chroot sys_ptrace sys_pacct sys_admin sys_boot sys_nice sys_resource sys_time sys_tty_config mknod lease audit_write audit_control setfcap mac_override mac_admin syslog wake_alarm block_suspend +} +} +rlimit {mask {cpu fsize data stack core rss nproc nofile memlock as locks sigpending msgqueue nice rtprio rttime +} +} +capability {0xffffff +} +namespaces {pivot_root {yes +} +profile {yes +} +} +network {af_mask {unspec unix local inet ax25 ipx appletalk netrom bridge atmpvc x25 inet6 rose netbeui security key netlink packet ash econet atmsvc rds sna irda pppox wanpipe llc ib can tipc bluetooth iucv rxrpc isdn phonet ieee802154 caif alg nfc vsock max +} +} +file {mask {create read write exec append mmap_exec link lock +} +} +domain {change_profile {yes +} +change_onexec {yes +} +change_hatv {yes +} +change_hat {yes +} +} +policy {set_load {yes +} +} --- /dev/null +++ 2.9-test/parser/tst/features_files/features.mount @@ -0,0 +1,34 @@ +caps {mask {chown dac_override dac_read_search fowner fsetid kill setgid setuid setpcap linux_immutable net_bind_service net_broadcast net_admin net_raw ipc_lock ipc_owner sys_module sys_rawio sys_chroot sys_ptrace sys_pacct sys_admin sys_boot sys_nice sys_resource sys_time sys_tty_config mknod lease audit_write audit_control setfcap mac_override mac_admin syslog wake_alarm block_suspend +} +} +rlimit {mask {cpu fsize data stack core rss nproc nofile memlock as locks sigpending msgqueue nice rtprio rttime +} +} +capability {0xffffff +} +namespaces {pivot_root {yes +} +profile {yes +} +} +mount {mask {mount umount +} +} +network {af_mask {unspec unix local inet ax25 ipx appletalk netrom bridge atmpvc x25 inet6 rose netbeui security key netlink packet ash econet atmsvc rds sna irda pppox wanpipe llc ib can tipc bluetooth iucv rxrpc isdn phonet ieee802154 caif alg nfc vsock max +} +} +file {mask {create read write exec append mmap_exec link lock +} +} +domain {change_profile {yes +} +change_onexec {yes +} +change_hatv {yes +} +change_hat {yes +} +} +policy {set_load {yes +} +} --- /dev/null +++ 2.9-test/parser/tst/features_files/features.mount+dbus @@ -0,0 +1,37 @@ +dbus {mask {acquire send receive +} +} +caps {mask {chown dac_override dac_read_search fowner fsetid kill setgid setuid setpcap linux_immutable net_bind_service net_broadcast net_admin net_raw ipc_lock ipc_owner sys_module sys_rawio sys_chroot sys_ptrace sys_pacct sys_admin sys_boot sys_nice sys_resource sys_time sys_tty_config mknod lease audit_write audit_control setfcap mac_override mac_admin syslog wake_alarm block_suspend +} +} +rlimit {mask {cpu fsize data stack core rss nproc nofile memlock as locks sigpending msgqueue nice rtprio rttime +} +} +capability {0xffffff +} +namespaces {pivot_root {yes +} +profile {yes +} +} +mount {mask {mount umount +} +} +network {af_mask {unspec unix local inet ax25 ipx appletalk netrom bridge atmpvc x25 inet6 rose netbeui security key netlink packet ash econet atmsvc rds sna irda pppox wanpipe llc ib can tipc bluetooth iucv rxrpc isdn phonet ieee802154 caif alg nfc vsock max +} +} +file {mask {create read write exec append mmap_exec link lock +} +} +domain {change_profile {yes +} +change_onexec {yes +} +change_hatv {yes +} +change_hat {yes +} +} +policy {set_load {yes +} +} --- /dev/null +++ 2.9-test/parser/tst/features_files/features.nopolicydb @@ -0,0 +1,31 @@ +caps {mask {chown dac_override dac_read_search fowner fsetid kill setgid setuid setpcap linux_immutable net_bind_service net_broadcast net_admin net_raw ipc_lock ipc_owner sys_module sys_rawio sys_chroot sys_ptrace sys_pacct sys_admin sys_boot sys_nice sys_resource sys_time sys_tty_config mknod lease audit_write audit_control setfcap mac_override mac_admin syslog wake_alarm block_suspend +} +} +rlimit {mask {cpu fsize data stack core rss nproc nofile memlock as locks sigpending msgqueue nice rtprio rttime +} +} +capability {0xffffff +} +namespaces {pivot_root {yes +} +profile {yes +} +} +network {af_mask {unspec unix local inet ax25 ipx appletalk netrom bridge atmpvc x25 inet6 rose netbeui security key netlink packet ash econet atmsvc rds sna irda pppox wanpipe llc ib can tipc bluetooth iucv rxrpc isdn phonet ieee802154 caif alg nfc vsock max +} +} +file {mask {create read write exec append mmap_exec link lock +} +} +domain {change_profile {yes +} +change_onexec {yes +} +change_hatv {yes +} +change_hat {yes +} +} +policy {set_load {yes +} +} --- 2.9-test.orig/parser/tst/minimize.sh +++ 2.9-test/parser/tst/minimize.sh @@ -78,7 +78,7 @@ # {a} (0x 40030/0/0/0) echo -n "Minimize profiles basic perms " -if [ `echo "/t { /a r, /b w, /c a, /d l, /e k, /f m, /** w, }" | ${APPARMOR_PARSER} -QT -O minimize -D dfa-states 2>&1 | grep -v '<==' | grep '^{.*} (.*)$' | wc -l` -ne 6 ] ; then +if [ `echo "/t { /a r, /b w, /c a, /d l, /e k, /f m, /** w, }" | ${APPARMOR_PARSER} -M features_files/features.nopolicydb -QT -O minimize -D dfa-states 2>&1 | grep -v '<==' | grep '^{.*} (.*)$' | wc -l` -ne 6 ] ; then echo "failed" exit 1; fi @@ -93,7 +93,7 @@ # {9} (0x 12804a/0/2800a/0) # {c} (0x 40030/0/0/0) echo -n "Minimize profiles audit perms " -if [ `echo "/t { /a r, /b w, /c a, /d l, /e k, /f m, audit /** w, }" | ${APPARMOR_PARSER} -QT -O minimize -D dfa-states 2>&1 | grep -v '<==' | grep '^{.*} (.*)$' | wc -l` -ne 6 ] ; then +if [ `echo "/t { /a r, /b w, /c a, /d l, /e k, /f m, audit /** w, }" | ${APPARMOR_PARSER} -M features_files/features.nopolicydb -QT -O minimize -D dfa-states 2>&1 | grep -v '<==' | grep '^{.*} (.*)$' | wc -l` -ne 6 ] ; then echo "failed" exit 1; fi @@ -112,7 +112,7 @@ # {c} (0x 40030/0/0/0) echo -n "Minimize profiles deny perms " -if [ `echo "/t { /a r, /b w, /c a, /d l, /e k, /f m, deny /** w, }" | ${APPARMOR_PARSER} -QT -O minimize -D dfa-states 2>&1 | grep -v '<==' | grep '^{.*} (.*)$' | wc -l` -ne 6 ] ; then +if [ `echo "/t { /a r, /b w, /c a, /d l, /e k, /f m, deny /** w, }" | ${APPARMOR_PARSER} -M features_files/features.nopolicydb -QT -O minimize -D dfa-states 2>&1 | grep -v '<==' | grep '^{.*} (.*)$' | wc -l` -ne 6 ] ; then echo "failed" exit 1; fi @@ -130,7 +130,7 @@ # {c} (0x 40030/0/0/0) echo -n "Minimize profiles audit deny perms " -if [ `echo "/t { /a r, /b w, /c a, /d l, /e k, /f m, audit deny /** w, }" | ${APPARMOR_PARSER} -QT -O minimize -D dfa-states 2>&1 | grep -v '<==' | grep '^{.*} (.*)$' | wc -l` -ne 5 ] ; then +if [ `echo "/t { /a r, /b w, /c a, /d l, /e k, /f m, audit deny /** w, }" | ${APPARMOR_PARSER} -M features_files/features.nopolicydb -QT -O minimize -D dfa-states 2>&1 | grep -v '<==' | grep '^{.*} (.*)$' | wc -l` -ne 5 ] ; then echo "failed" exit 1; fi @@ -162,7 +162,7 @@ # echo -n "Minimize profiles xtrans " -if [ `echo "/t { /b px, /* Pixr, /a Cx -> foo, }" | ${APPARMOR_PARSER} -QT -O minimize -D dfa-states 2>&1 | grep -v '<==' | grep '^{.*} (.*)$' | wc -l` -ne 3 ] ; then +if [ `echo "/t { /b px, /* Pixr, /a Cx -> foo, }" | ${APPARMOR_PARSER} -M features_files/features.nopolicydb -QT -O minimize -D dfa-states 2>&1 | grep -v '<==' | grep '^{.*} (.*)$' | wc -l` -ne 3 ] ; then echo "failed" exit 1; fi @@ -170,7 +170,7 @@ # same test as above + audit echo -n "Minimize profiles audit xtrans " -if [ `echo "/t { /b px, audit /* Pixr, /a Cx -> foo, }" | ${APPARMOR_PARSER} -QT -O minimize -D dfa-states 2>&1 | grep -v '<==' | grep '^{.*} (.*)$' | wc -l` -ne 3 ] ; then +if [ `echo "/t { /b px, audit /* Pixr, /a Cx -> foo, }" | ${APPARMOR_PARSER} -M features_files/features.nopolicydb -QT -O minimize -D dfa-states 2>&1 | grep -v '<==' | grep '^{.*} (.*)$' | wc -l` -ne 3 ] ; then echo "failed" exit 1; fi @@ -183,7 +183,7 @@ # {3} (0x 0/fe17f85/0/14005) echo -n "Minimize profiles deny xtrans " -if [ `echo "/t { /b px, deny /* xr, /a Cx -> foo, }" | ${APPARMOR_PARSER} -QT -O minimize -D dfa-states 2>&1 | grep -v '<==' | grep '^{.*} (.*)$' | wc -l` -ne 1 ] ; then +if [ `echo "/t { /b px, deny /* xr, /a Cx -> foo, }" | ${APPARMOR_PARSER} -M features_files/features.nopolicydb -QT -O minimize -D dfa-states 2>&1 | grep -v '<==' | grep '^{.*} (.*)$' | wc -l` -ne 1 ] ; then echo "failed" exit 1; fi @@ -195,7 +195,7 @@ # {3} (0x 0/fe17f85/0/0) echo -n "Minimize profiles audit deny xtrans " -if [ `echo "/t { /b px, audit deny /* xr, /a Cx -> foo, }" | ${APPARMOR_PARSER} -QT -O minimize -D dfa-states 2>&1 | grep -v '<==' | grep '^{.*} (.*)$' | wc -l` -ne 0 ] ; then +if [ `echo "/t { /b px, audit deny /* xr, /a Cx -> foo, }" | ${APPARMOR_PARSER} -M features_files/features.nopolicydb -QT -O minimize -D dfa-states 2>&1 | grep -v '<==' | grep '^{.*} (.*)$' | wc -l` -ne 0 ] ; then echo "failed" exit 1; fi -- AppArmor mailing list AppArmor@lists.ubuntu.com Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/apparmor debian/patches/check-config-for-sysctl.patch0000664000000000000000000002233012315312536016264 0ustar Description: regression sysctl: skip if sysctl not available . Some kernels have CONFIG_SYSCALL_SYSCTL disabled, which is something to be encouraged. This patch separates out the two different kind of sysctl tests (syscall based and /proc/sys based) into separate shell functions, and then checks to see that the test environment supports each before invoking each shell function, issuing a warning (but not failing the tests) if not available. . Signed-off-by: Steve Beattie Acked-by: John Johansen Origin: commit, revision id: sbeattie@ubuntu.com-20140320182310-dxmze74scskktd6h Author: Steve Beattie Last-Update: 2014-03-20 X-Bzr-Revision-Id: sbeattie@ubuntu.com-20140320182310-dxmze74scskktd6h === modified file 'tests/regression/apparmor/syscall_sysctl.sh' --- old/tests/regression/apparmor/syscall_sysctl.sh 2010-12-20 20:29:10 +0000 +++ new/tests/regression/apparmor/syscall_sysctl.sh 2014-03-20 18:23:10 +0000 @@ -25,119 +25,140 @@ ## ## C. SYSCTL ## + +test_syscall_sysctl() +{ + settest syscall_sysctl + + runchecktest "SYSCTL (no confinement read only)" pass ro + + runchecktest "SYSCTL (no confinement rw)" pass + + genprofile $sysctlgood:r + runchecktest "SYSCTL (confinement/good r w/ r perm)" pass ro + + genprofile $sysctlgood:r + runchecktest "SYSCTL (confinement/good rw w/ r perm)" fail + + genprofile $sysctlgood:w + runchecktest "SYSCTL (confinement/good r w/ w perm)" fail ro + + genprofile $sysctlgood:w + runchecktest "SYSCTL (confinement/good rw w/ w perm)" fail + + genprofile $sysctlgood:rw + runchecktest "SYSCTL (confinement/good r w/ rw perm)" pass ro + + genprofile $sysctlgood:rw + runchecktest "SYSCTL (confinement/good rw w/ rw perm)" pass + + genprofile $sysctlbad:r + runchecktest "SYSCTL (confinement/bad r w/ r perm)" fail ro + + genprofile $sysctlbad:r + runchecktest "SYSCTL (confinement/bad rw w/ r perm)" fail ro + + genprofile $sysctlbad:w + runchecktest "SYSCTL (confinement/bad r w/ w perm)" fail ro + + genprofile $sysctlbad:w + runchecktest "SYSCTL (confinement/bad rw w/ w perm)" fail + + genprofile $sysctlbad:rw + runchecktest "SYSCTL (confinement/bad r w/ rw perm)" fail ro + + genprofile $sysctlbad:rw + runchecktest "SYSCTL (confinement/bad rw w/ rw perm)" fail +} + +test_sysctl_proc() +{ + settest sysctl_proc + + #unconfined + runchecktest "SYSCTL /proc (read no confinement)" pass $sysctlgood r + value=`cat $sysctlgood` + runchecktest "SYSCTL /proc (write no confinement)" pass $sysctlgood w $value + runchecktest "SYSCTL /proc (rw no confinement)" pass $sysctlgood rw + + #test with profile giving access to sysctlgood + genprofile $sysctlgood:r + runchecktest "SYSCTL /proc (confinement/good r w/ r perm)" pass $sysctlgood r + + genprofile $sysctlgood:w + runchecktest "SYSCTL /proc (confinement/good r w/ w perm)" fail $sysctlgood r + + genprofile $sysctlgood:rw + runchecktest "SYSCTL /proc (confinement/good r w/ rw perm)" pass $sysctlgood r + + genprofile $sysctlgood:r + value=`cat $sysctlgood` + runchecktest "SYSCTL /proc (confinement/good w w/ r perm)" fail $sysctlgood w $value + + genprofile $sysctlgood:w + value=`cat $sysctlgood` + runchecktest "SYSCTL /proc (confinement/good w w/ w perm)" pass $sysctlgood w $value + + genprofile $sysctlgood:rw + value=`cat $sysctlgood` + runchecktest "SYSCTL /proc (confinement/good w w/ rw perm)" pass $sysctlgood w $value + + genprofile $sysctlgood:r + runchecktest "SYSCTL /proc (confinement/good rw w/ r perm)" fail $sysctlgood rw + + genprofile $sysctlgood:w + runchecktest "SYSCTL /proc (confinement/good rw w/ w perm)" fail $sysctlgood rw + + genprofile $sysctlgood:rw + runchecktest "SYSCTL /proc (confinement/good rw w/ rw perm)" pass $sysctlgood rw + + #test with profile giving access to sysctlbad but access to sysctlgood + genprofile $sysctlbad:r + runchecktest "SYSCTL /proc (confinement/bad r w/ r perm)" fail $sysctlgood r + + genprofile $sysctlbad:w + runchecktest "SYSCTL /proc (confinement/bad r w/ w perm)" fail $sysctlgood r + + genprofile $sysctlbad:rw + runchecktest "SYSCTL /proc (confinement/bad r w/ rw perm)" fail $sysctlgood r + + genprofile $sysctlbad:r + value=`cat $sysctlgood` + runchecktest "SYSCTL /proc (confinement/bad w w/ r perm)" fail $sysctlgood w $value + + genprofile $sysctlbad:w + value=`cat $sysctlgood` + runchecktest "SYSCTL /proc (confinement/bad w w/ w perm)" fail $sysctlgood w $value + + genprofile $sysctlbad:rw + value=`cat $sysctlgood` + runchecktest "SYSCTL /proc (confinement/bad w w/ rw perm)" fail $sysctlgood w $value + + genprofile $sysctlbad:r + runchecktest "SYSCTL /proc (confinement/bad rw w/ r perm)" fail $sysctlgood rw + + genprofile $sysctlbad:w + runchecktest "SYSCTL /proc (confinement/bad rw w/ w perm)" fail $sysctlgood rw + + genprofile $sysctlbad:rw + runchecktest "SYSCTL /proc (confinement/bad rw w/ rw perm)" fail $sysctlgood rw +} + + +# check if the kernel supports CONFIG_SYSCTL_SYSCALL +# generally we want to encourage kernels to disable it, but if it's +# enabled we want to test against it settest syscall_sysctl - -runchecktest "SYSCTL (no confinement read only)" pass ro - -runchecktest "SYSCTL (no confinement rw)" pass - -genprofile $sysctlgood:r -runchecktest "SYSCTL (confinement/good r w/ r perm)" pass ro - -genprofile $sysctlgood:r -runchecktest "SYSCTL (confinement/good rw w/ r perm)" fail - -genprofile $sysctlgood:w -runchecktest "SYSCTL (confinement/good r w/ w perm)" fail ro - -genprofile $sysctlgood:w -runchecktest "SYSCTL (confinement/good rw w/ w perm)" fail - -genprofile $sysctlgood:rw -runchecktest "SYSCTL (confinement/good r w/ rw perm)" pass ro - -genprofile $sysctlgood:rw -runchecktest "SYSCTL (confinement/good rw w/ rw perm)" pass - -genprofile $sysctlbad:r -runchecktest "SYSCTL (confinement/bad r w/ r perm)" fail ro - -genprofile $sysctlbad:r -runchecktest "SYSCTL (confinement/bad rw w/ r perm)" fail ro - -genprofile $sysctlbad:w -runchecktest "SYSCTL (confinement/bad r w/ w perm)" fail ro - -genprofile $sysctlbad:w -runchecktest "SYSCTL (confinement/bad rw w/ w perm)" fail - -genprofile $sysctlbad:rw -runchecktest "SYSCTL (confinement/bad r w/ rw perm)" fail ro - -genprofile $sysctlbad:rw -runchecktest "SYSCTL (confinement/bad rw w/ rw perm)" fail +res=$(${test} ro) +if [ $? -ne 0 -a $res == "FAIL: sysctl read failed - Function not implemented" ] ; then + echo " WARNING: syscall sysctl not implemented, skipping tests ..." +else + test_syscall_sysctl +fi # now test /proc/sys/ paths - -settest sysctl_proc - -#unconfined -runchecktest "SYSCTL /proc (read no confinement)" pass $sysctlgood r -value=`cat $sysctlgood` -runchecktest "SYSCTL /proc (write no confinement)" pass $sysctlgood w $value -runchecktest "SYSCTL /proc (rw no confinement)" pass $sysctlgood rw - -#test with profile giving access to sysctlgood -genprofile $sysctlgood:r -runchecktest "SYSCTL /proc (confinement/good r w/ r perm)" pass $sysctlgood r - -genprofile $sysctlgood:w -runchecktest "SYSCTL /proc (confinement/good r w/ w perm)" fail $sysctlgood r - -genprofile $sysctlgood:rw -runchecktest "SYSCTL /proc (confinement/good r w/ rw perm)" pass $sysctlgood r - -genprofile $sysctlgood:r -value=`cat $sysctlgood` -runchecktest "SYSCTL /proc (confinement/good w w/ r perm)" fail $sysctlgood w $value - -genprofile $sysctlgood:w -value=`cat $sysctlgood` -runchecktest "SYSCTL /proc (confinement/good w w/ w perm)" pass $sysctlgood w $value - -genprofile $sysctlgood:rw -value=`cat $sysctlgood` -runchecktest "SYSCTL /proc (confinement/good w w/ rw perm)" pass $sysctlgood w $value - -genprofile $sysctlgood:r -runchecktest "SYSCTL /proc (confinement/good rw w/ r perm)" fail $sysctlgood rw - -genprofile $sysctlgood:w -runchecktest "SYSCTL /proc (confinement/good rw w/ w perm)" fail $sysctlgood rw - -genprofile $sysctlgood:rw -runchecktest "SYSCTL /proc (confinement/good rw w/ rw perm)" pass $sysctlgood rw - -#test with profile giving access to sysctlbad but access to sysctlgood -genprofile $sysctlbad:r -runchecktest "SYSCTL /proc (confinement/bad r w/ r perm)" fail $sysctlgood r - -genprofile $sysctlbad:w -runchecktest "SYSCTL /proc (confinement/bad r w/ w perm)" fail $sysctlgood r - -genprofile $sysctlbad:rw -runchecktest "SYSCTL /proc (confinement/bad r w/ rw perm)" fail $sysctlgood r - -genprofile $sysctlbad:r -value=`cat $sysctlgood` -runchecktest "SYSCTL /proc (confinement/bad w w/ r perm)" fail $sysctlgood w $value - -genprofile $sysctlbad:w -value=`cat $sysctlgood` -runchecktest "SYSCTL /proc (confinement/bad w w/ w perm)" fail $sysctlgood w $value - -genprofile $sysctlbad:rw -value=`cat $sysctlgood` -runchecktest "SYSCTL /proc (confinement/bad w w/ rw perm)" fail $sysctlgood w $value - -genprofile $sysctlbad:r -runchecktest "SYSCTL /proc (confinement/bad rw w/ r perm)" fail $sysctlgood rw - -genprofile $sysctlbad:w -runchecktest "SYSCTL /proc (confinement/bad rw w/ w perm)" fail $sysctlgood rw - -genprofile $sysctlbad:rw -runchecktest "SYSCTL /proc (confinement/bad rw w/ rw perm)" fail $sysctlgood rw - - - +if [ ! -f "${sysctlgood}" ] ; then + echo " WARNING: proc sysctl path not found, /proc not mounted? Skipping tests ..." +else + test_sysctl_proc +fi debian/patches/caching.patch0000664000000000000000000000367712315045675013261 0ustar Author: John Johansen Forwarded: Yes Subject: Dont use the parser time stamp to determine if policy is newer. Using the parser timestamp was a work around to force recompilation of policy that was built with a buggy parser. There are better ways to handle this so remove checking of the parser timestamp. Signed-off-by: John Johansen --- parser/parser_main.c | 7 ------- parser/tst/caching.py | 6 +++--- 2 files changed, 3 insertions(+), 10 deletions(-) --- 2.9-test.orig/parser/parser_main.c +++ 2.9-test/parser/parser_main.c @@ -996,7 +996,6 @@ char * cachename = NULL; char * cachetemp = NULL; const char *basename = NULL; - FILE *cmd; /* per-profile states */ force_complain = opt_force_complain; @@ -1044,12 +1043,6 @@ update_mru_tstamp(yyin); } - cmd = fopen("/proc/self/exe", "r"); - if (cmd) { - update_mru_tstamp(cmd); - fclose(cmd); - } - retval = yyparse(); if (retval != 0) goto out; --- 2.9-test.orig/parser/tst/caching.py +++ 2.9-test/parser/tst/caching.py @@ -328,8 +328,8 @@ cmd.extend(['-v', '-r', self.profile]) self.run_cmd_check(cmd, expected_string='Replacement succeeded for') - def test_parser_newer_skips_cache(self): - '''test cache is skipped if parser is newer''' + def test_parser_newer_uses_cache(self): + '''test cache is not skipped if parser is newer''' self._generate_cache_file() time.sleep(config.timeout) @@ -342,7 +342,7 @@ cmd = list(self.cmd_prefix) cmd[0] = new_parser cmd.extend(['-v', '-r', self.profile]) - self.run_cmd_check(cmd, expected_string='Replacement succeeded for') + self.run_cmd_check(cmd, expected_string='Cached reload succeeded for') def _purge_cache_test(self, location): -- AppArmor mailing list AppArmor@lists.ubuntu.com Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/apparmor debian/patches/bare-capability-rule-support.patch0000664000000000000000000000751312315312536017356 0ustar Description: utils: Basic support for bare capability rules . Bug: https://bugs.launchpad.net/bugs/1294819 . This patch as minimal support for bare capability rules ("capability,"). It prevents aa.py from emitting a traceback when encountering such a rule. . It only adds the ability to parse and write the bare rule. It doesn't attempt to be clever when deleting duplicate rules, such as realizing that "capability audit_control," can be deleted if "capability," is also present. . Signed-off-by: Tyler Hicks Acked-by: Steve Beattie Acked-by: Christian Boltz Origin: commit, revision id: tyhicks@canonical.com-20140320192724-z0kqjl8kzx4khx57 Author: Tyler Hicks Bug: https://launchpad.net/bugs/1294819 Last-Update: 2014-03-20 X-Bzr-Revision-Id: tyhicks@canonical.com-20140320192724-z0kqjl8kzx4khx57 === modified file 'utils/apparmor/aa.py' --- old/utils/apparmor/aa.py 2014-03-20 19:25:42 +0000 +++ new/utils/apparmor/aa.py 2014-03-20 19:27:24 +0000 @@ -78,6 +78,9 @@ # To store the globs entered by users so they can be provided again user_globs = [] +# The key for representing bare rules such as "capability," or "file," +ALL = '_ALL' + ## Variables used under logprof ### Were our t = hasher() # dict() @@ -2104,6 +2107,9 @@ deleted = [] if profilecaps and inccaps: for capname in profilecaps.keys(): + # XXX The presence of a bare capability rule ("capability,") should + # cause more specific capability rules + # ("capability audit_control,") to be deleted if inccaps[capname].get('set', False) == 1: deleted.append(capname) for capname in deleted: @@ -2599,7 +2605,7 @@ ## Profile parsing regex RE_PROFILE_START = re.compile('^\s*(("??/.+?"??)|(profile\s+("??.+?"??)))\s+((flags=)?\((.+)\)\s+)?\{\s*(#.*)?$') RE_PROFILE_END = re.compile('^\s*\}\s*(#.*)?$') -RE_PROFILE_CAP = re.compile('^\s*(audit\s+)?(allow\s+|deny\s+)?capability\s+(\S+)\s*,\s*(#.*)?$') +RE_PROFILE_CAP = re.compile('^\s*(audit\s+)?(allow\s+|deny\s+)?capability(\s+\S+)?\s*,\s*(#.*)?$') RE_PROFILE_LINK = re.compile('^\s*(audit\s+)?(allow\s+|deny\s+)?link\s+(((subset)|(<=))\s+)?([\"\@\/].*?"??)\s+->\s*([\"\@\/].*?"??)\s*,\s*(#.*)?$') RE_PROFILE_CHANGE_PROFILE = re.compile('^\s*change_profile\s+->\s*("??.+?"??),(#.*)?$') RE_PROFILE_ALIAS = re.compile('^\s*alias\s+("??.+?"??)\s+->\s*("??.+?"??)\s*,(#.*)?$') @@ -2733,7 +2739,9 @@ if matches[1] and matches[1].strip() == 'deny': allow = 'deny' - capability = matches[2] + capability = ALL + if matches[2]: + capability = matches[2].strip() profile_data[profile][hat][allow]['capability'][capability]['set'] = True profile_data[profile][hat][allow]['capability'][capability]['audit'] = audit @@ -3236,7 +3244,10 @@ if prof_data[allow]['capability'][cap].get('audit', False): audit = 'audit ' if prof_data[allow]['capability'][cap].get('set', False): - data.append('%s%s%scapability %s,' % (pre, audit, allowstr, cap)) + if cap == ALL: + data.append('%s%s%scapability,' % (pre, audit, allowstr)) + else: + data.append('%s%s%scapability %s,' % (pre, audit, allowstr, cap)) data.append('') return data @@ -3698,7 +3709,9 @@ if matches[1] and matches[1].strip() == 'deny': allow = 'deny' - capability = matches[2] + capability = ALL + if matches[2]: + capability = matches[2].strip() if not write_prof_data[hat][allow]['capability'][capability].get('set', False): correct = False debian/patches/libapparmor-layout-deb.patch0000664000000000000000000000273412315045675016231 0ustar Author: Jamie Strandboge Description: always install python modules in the proper location when creating deb files Forwarded: no (Debian/Ubuntu specific) --- libraries/libapparmor/swig/python/Makefile.am | 2 +- utils/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) Index: b/libraries/libapparmor/swig/python/Makefile.am =================================================================== --- a/libraries/libapparmor/swig/python/Makefile.am +++ b/libraries/libapparmor/swig/python/Makefile.am @@ -15,7 +15,7 @@ all-local: libapparmor_wrap.c setup.py $(PYTHON) setup.py build install-exec-local: - $(PYTHON) setup.py install --root="/$(DESTDIR)" --prefix="$(prefix)" + $(PYTHON) setup.py install --root="/$(DESTDIR)" --prefix="$(prefix)" --install-layout=deb clean-local: if test -x "$(PYTHON)"; then $(PYTHON) setup.py clean; fi Index: b/utils/Makefile =================================================================== --- a/utils/Makefile +++ b/utils/Makefile @@ -59,7 +59,7 @@ install: ${MANPAGES} ${HTMLMANPAGES} $(MAKE) install_manpages DESTDIR=${DESTDIR} $(MAKE) -C vim install DESTDIR=${DESTDIR} ln -sf aa-status.8 ${DESTDIR}/${MANDIR}/man8/apparmor_status.8 - ${PYTHON} ${PYSETUP} install --prefix=${PYPREFIX} --root=${DESTDIR} --version=${VERSION} + ${PYTHON} ${PYSETUP} install --prefix=${PYPREFIX} --root=${DESTDIR} --install-layout=deb --version=${VERSION} .PHONY: clean ifndef VERBOSE debian/patches/fix-lexer-debug.patch0000664000000000000000000000437312315045675014646 0ustar Author: John Johansen Forwarded: Yes Subject: A few fixes/improvements to the lexer debug output Signed-off-by: John Johansen --- parser/parser_lex.l | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) --- 2.9-test.orig/parser/parser_lex.l +++ 2.9-test/parser/parser_lex.l @@ -52,7 +52,7 @@ /* #define DEBUG */ #ifdef DEBUG static int yy_top_state(void); -#define PDEBUG(fmt, args...) printf("Lexer (Line %d) (state %s): " fmt, current_lineno, state_names[YY_START].c_str(), ## args) +#define PDEBUG(fmt, args...) fprintf(stderr, "Lexer (Line %d) (state %s): " fmt, current_lineno, state_names[YY_START].c_str(), ## args) #else #define PDEBUG(fmt, args...) /* Do nothing */ #endif @@ -70,7 +70,7 @@ #define RETURN_TOKEN(X) \ do { \ - DUMP_AND_DEBUG("Matched: %s\n", yytext); \ + DUMP_AND_DEBUG("Matched: '%s' Returning(%s)\n", yytext, #X); \ return (X); \ } while (0) @@ -276,12 +276,12 @@ char *filename = strndup(yytext, yyleng - 1); include_filename(filename + 1, *filename == '<'); free(filename); - yy_pop_state(); + POP(); } [^\<\>\" \t\n]+ { /* filename */ include_filename(yytext, 0); - yy_pop_state(); + POP(); } } @@ -425,7 +425,7 @@ \r?\n { DUMP_PREPROCESS; current_lineno++; - yy_pop_state(); + POP(); } } @@ -469,8 +469,7 @@ write { RETURN_TOKEN(TOK_WRITE); } eavesdrop { RETURN_TOKEN(TOK_EAVESDROP); } {OPEN_PAREN} { - yy_push_state(LIST_VAL_MODE); - RETURN_TOKEN(TOK_OPENPAREN); + PUSH_AND_RETURN(LIST_VAL_MODE, TOK_OPENPAREN); } (r|w|rw|wr)/([[:space:],]) { yylval.mode = strdup(yytext); @@ -488,8 +487,8 @@ } #include/.*\r?\n { - /* Don't use push here as we don't want #include echoed out. It needs - * to be handled specially + /* Don't use PUSH() macro here as we don't want #include echoed out. + * It needs to be handled specially */ yy_push_state(INCLUDE); } @@ -576,7 +575,7 @@ { {END_OF_RULE} { if (YY_START != INITIAL) - yy_pop_state(); + POP(); RETURN_TOKEN(TOK_END_OF_RULE); } -- AppArmor mailing list AppArmor@lists.ubuntu.com Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/apparmor debian/patches/list-fns.patch0000664000000000000000000000531312315045675013411 0ustar Author: John Johansen Forwarded: Yes Subject: cleanup the list fns and use a little bit. Yes its seems pointless because these will eventually get replaced by stl. But until then Signed-off-by: John Johansen --- parser/dbus.c | 11 ----------- parser/mount.c | 12 ++---------- parser/parser.h | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 21 deletions(-) --- 2.9-test.orig/parser/dbus.c +++ 2.9-test/parser/dbus.c @@ -107,17 +107,6 @@ return 1; } -static int list_len(struct value_list *v) -{ - int len = 0; - struct value_list *tmp; - - list_for_each(v, tmp) - len++; - - return len; -} - static void move_conditional_value(char **dst_ptr, struct cond_entry *cond_ent) { if (*dst_ptr) --- 2.9-test.orig/parser/mount.c +++ 2.9-test/parser/mount.c @@ -350,11 +350,7 @@ if (strcmp(entry->name, "fstype") == 0 || strcmp(entry->name, "vfstype") == 0) { PDEBUG(" extracting fstype\n"); - if (prev) - prev->next = tmp; - if (entry == *conds) - *conds = tmp; - entry->next = NULL; + list_remove_at(*conds, prev, entry); list_append(entry->vals, list); list = entry->vals; entry->vals = NULL; @@ -376,11 +372,7 @@ if ((strcmp(entry->name, "options") == 0 || strcmp(entry->name, "option") == 0) && entry->eq == eq) { - if (prev) - prev->next = tmp; - if (entry == *conds) - *conds = tmp; - entry->next = NULL; + list_remove_at(*conds, prev, entry); PDEBUG(" extracting option %s\n", entry->name); list_append(entry->vals, list); list = entry->vals; --- 2.9-test.orig/parser/parser.h +++ 2.9-test/parser/parser.h @@ -212,6 +212,40 @@ ___tmp->next = (LISTB); \ } while (0) +#define list_len(LIST) \ +({ \ + int len = 0; \ + typeof(LIST) tmp; \ + list_for_each((LIST), tmp) \ + len++; \ + len; \ +}) + +#define list_find_prev(LIST, ENTRY) \ +({ \ + typeof(ENTRY) tmp, prev = NULL; \ + list_for_each((LIST), tmp) { \ + if (tmp == (ENTRY)) \ + break; \ + prev = tmp; \ + } \ + prev; \ +}) + +#define list_remove_at(LIST, PREV, ENTRY) \ + if (PREV) \ + (PREV)->next = (ENTRY)->next; \ + if ((ENTRY) == (LIST)) \ + (LIST) = (ENTRY)->next; \ + (ENTRY)->next = NULL; \ + +#define list_remove(LIST, ENTRY) \ +do { \ + typeof(ENTRY) prev = list_find_prev((LIST), (ENTRY)); \ + list_remove_at((LIST), prev, (ENTRY)); \ +} while (0) + + #define DUP_STRING(orig, new, field, fail_target) \ do { \ (new)->field = ((orig)->field) ? strdup((orig)->field) : NULL; \ -- AppArmor mailing list AppArmor@lists.ubuntu.com Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/apparmor debian/apparmor-docs.doc-base0000664000000000000000000000036112315045675013346 0ustar Document: apparmor Title: AppArmor Technical Documentation Author: Andreas Gruenbacher and Seth Arnold Abstract: Overview of AppArmor technical details Section: System/Security Format: PDF Files: /usr/share/doc/apparmor-docs/techdoc.pdf.gz debian/copyright0000664000000000000000000001214112315045675011132 0ustar Format: http://svn.debian.org/wsvn/dep/web/deps/dep5.mdwn?op=file&rev=166 Upstream-Name: AppArmor Upstream-Contact: apparmor@lists.ubuntu.com Source: https://launchpad.net/apparmor Files: * Copyright: 1998-2007 Novell/SuSE/Immunix 2007-2011 Canonical Ltd. License: GPL-2 Files: changehat/pam_apparmor/* Copyright: 2006 SUSE Linux Products GmbH, Nuernberg, Germany 2002, 2003, 2004 SuSE GmbH Nuernberg, Germany 2002-2006 Novell/SuSE 2010 Canonical Ltd. License: BSD-3-clause or GPL-2+ Files: changehat/mod_apparmor/* libraries/libapparmor/* parser/libapparmor_re/apparmor_re.h Copyright: 1999-2008 Novell 2009-2010 Canonical Ltd. License: LGPL-2.1+ Files: profiles/enabled/sbin.syslog-ng Copyright: 2006 Novell, Christian Boltz License: GPL-2 Files: profiles/apparmor/profiles/extras/usr.bin.mlmmj-make-ml.sh Copyright: 2002-2005 Novell/SUSE License: GPL-2 Files: profiles/extras/usr.bin.passwd Copyright: 2006 Novell, Volker Kuhlmann License: GPL-2 Files: libraries/libapparmor/ltmain.sh Copyright: 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007 2008 Free Software Foundation, Inc. License: GPL-2+ Files: deprecated/management/profile-editor/* Copyright: 2006 Novell Matt Barringer 1998-2003 by Neil Hodgson Robin Dunn License: GPL-2+ Files: deprecated/management/apparmor-dbus/* Copyright: 2006 Novell Matt Barringer License: GPL-2+ Files: deprecated/management/profile-editor/src/wxStyledTextCtrl/StyleContext.* Copyright: 1998-2004 Neil Hodgson License: public-domain This file is in the public domain. Files: deprecated/management/profile-editor/src/wxStyledTextCtrl/RESearch.h Copyright: Neil Hodgson Ozan S. Yigit License: public-domain This file is in the public domain. Files: debian/* Copyright: 2007-2011 Canonical Ltd. License: GPL-2 License: GPL-2 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. . 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. . On Debian systems, the complete text of the GNU General Public License can be found in `/usr/share/common-licenses/GPL-2'. License: GPL-2+ 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; either version 2 of the License, or (at your option) any later version. . 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. . On Debian systems, the complete text of the GNU General Public License can be found in `/usr/share/common-licenses/GPL-2'. License: LGPL-2.1+ This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. . This library 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 Lesser General Public License for more details. . You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA . On Debian systems, the complete text of the GNU General Public License can be found in `/usr/share/common-licenses/LGPL-2.1'. License: BSD-3-clause Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: . 1. Redistributions of source code must retain any existing copyright notice, and this entire permission notice in its entirety, including the disclaimer of warranties. . 2. Redistributions in binary form must reproduce all prior and current copyright notices, this list of conditions, and the following disclaimer in the documentation and/or other materials provided with the distribution. . 3. The name of any author may not be used to endorse or promote products derived from this software without their specific prior written permission. debian/apparmor-utils.manpages0000664000000000000000000000104612315045675013675 0ustar debian/tmp/usr/share/man/man8/aa-complain.8 debian/tmp/usr/share/man/man8/aa-decode.8 debian/tmp/usr/share/man/man8/aa-genprof.8 debian/tmp/usr/share/man/man8/aa-audit.8 debian/tmp/usr/share/man/man8/aa-logprof.8 debian/tmp/usr/share/man/man8/aa-autodep.8 debian/tmp/usr/share/man/man8/aa-unconfined.8 debian/tmp/usr/share/man/man8/aa-enforce.8 debian/tmp/usr/share/man/man8/aa-disable.8 debian/tmp/usr/share/man/man8/aa-cleanprof.8 debian/tmp/usr/share/man/man8/aa-mergeprof.8 debian/tmp/usr/share/man/man5/logprof.conf.5 debian/aa-update-browser.8 debian/libapache2-mod-apparmor.postrm0000664000000000000000000000025112315045675015032 0ustar #!/bin/sh set -e if [ "$1" = "purge" ]; then APP_PROFILE="usr.sbin.apache2" rm -f /etc/apparmor.d/disable/$APP_PROFILE >/dev/null 2>&1 || true fi #DEBHELPER# debian/put-all-profiles-in-complain-mode.sh0000664000000000000000000000102012315045675016052 0ustar #!/bin/sh PROFILE_DIR="./etc/apparmor.d" for f in ${PROFILE_DIR}/* do [ ! -f "$f" ] && continue if egrep -q 'flags=\(.*\) {' "$f"; then # Deal with existing flags, but need to account for multiple # profiles in one file and not all of them having the same # flags. grep -q 'flags=(complain)' "$f" && continue sed -i -e 's/flags=(\(.*\)) {$/flags=(complain,\1) {/' -e 's/ {$/ flags=(complain) {/' -e 's/) flags=(complain) {/) {/' "$f" else # No existing flags sed -i 's/ {$/ flags=(complain) {/' "$f" fi done debian/templates0000664000000000000000000000064612315045675011127 0ustar Template: apparmor/homedirs Type: string _Description: Additional home directory locations: Please enter a space separated list of any additional locations for user home directories. These locations are in addition to those specified in /etc/apparmor.d/tunables/home and must end with a '/'. . Example: if user's directories are stored in /srv/nfs/home and /mnt/homes, you should enter "/srv/nfs/home/ /mnt/homes/". debian/libapparmor1.install0000664000000000000000000000003412315045675013156 0ustar usr/lib/*/libapparmor.so.1* debian/dh-apparmor.manpages0000664000000000000000000000003712315045675013127 0ustar debian/debhelper/dh_apparmor.1