summaryrefslogtreecommitdiffstats
path: root/meta-security/recipes-security/AppArmor/files/functions
diff options
context:
space:
mode:
Diffstat (limited to 'meta-security/recipes-security/AppArmor/files/functions')
-rw-r--r--meta-security/recipes-security/AppArmor/files/functions271
1 files changed, 271 insertions, 0 deletions
diff --git a/meta-security/recipes-security/AppArmor/files/functions b/meta-security/recipes-security/AppArmor/files/functions
new file mode 100644
index 000000000..cef8cfe7d
--- /dev/null
+++ b/meta-security/recipes-security/AppArmor/files/functions
@@ -0,0 +1,271 @@
+# /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 <kees@ubuntu.com>
+
+PROFILES="/etc/apparmor.d"
+PROFILES_CACHE="$PROFILES/cache"
+PROFILES_VAR="/var/lib/apparmor/profiles"
+PROFILES_SNAPPY="/var/lib/snapd/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() {
+ rc_all="0"
+ for pdir in "$PROFILES" "$PROFILES_VAR" "$PROFILES_SNAPPY" ; do
+ if [ ! -d "$pdir" ]; then
+ continue
+ fi
+ num=`find "$pdir" -type f ! -name '*.md5sums' | wc -l`
+ if [ "$num" = "0" ]; then
+ continue
+ fi
+
+ cache_dir="$PROFILES_CACHE"
+ if [ -d "$PROFILES_CACHE_VAR" ] && [ "$pdir" = "$PROFILES_VAR" ] || [ "$pdir" = "$PROFILES_SNAPPY" ]; then
+ cache_dir="$PROFILES_CACHE_VAR"
+ fi
+ cache_args="--cache-loc=$cache_dir"
+ if [ ! -d "$cache_dir" ]; then
+ cache_args=
+ fi
+
+ # LP: #1383858 - expr tree simplification is too slow for
+ # Touch policy on ARM, so disable it for now
+ cache_extra_args=
+ if [ -d "$PROFILES_CACHE_VAR" ] && [ "$pdir" = "$PROFILES_VAR" ] || [ "$pdir" = "$PROFILES_SNAPPY" ]; then
+ cache_extra_args="-O no-expr-simplify"
+ fi
+
+ # If need to compile everything, then use -n1 with xargs to
+ # take advantage of -P. When cache files are in use, omit -n1
+ # since it is considerably faster on moderately sized profile
+ # sets to give the parser all the profiles to load at once
+ n1_args=
+ num=`find "$cache_dir" -type f ! -name '.features' | wc -l`
+ if [ "$num" = "0" ]; then
+ n1_args="-n1"
+ 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_args -d"\n" -P$(getconf _NPROCESSORS_ONLN) "$PARSER" "$@" $cache_args $cache_extra_args -- || {
+ rc_all="$?"
+ # FIXME: when the parser properly handles broken
+ # profiles (LP: #1377338), remove this if statement.
+ # For now, if the xargs returns with error, just run
+ # through everything with -n1. (This could be broken
+ # out and refactored, but this is temporary so make it
+ # easy to understand and revert)
+ if [ "$rc_all" != "0" ]; then
+ (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 $cache_extra_args -- || {
+ rc_all="$?"
+ }
+ fi
+ }
+ done
+ return $rc_all
+}
+
+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() {
+ clear_cache_system
+ clear_cache_var
+}
+
+clear_cache_system() {
+ find "$PROFILES_CACHE" -maxdepth 1 -type f -print0 | xargs -0 rm -f --
+}
+
+clear_cache_var() {
+ 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
+}
+
+unload_obsolete_profiles() {
+ # Currently we must re-parse all the profiles to get policy names. :(
+ aa_configured=$(mktemp -t aa-XXXXXX)
+ configured_profile_names > "$aa_configured" || true
+ aa_loaded=$(mktemp -t aa-XXXXXX)
+ running_profile_names > "$aa_loaded" || true
+ LC_COLLATE=C comm -2 -3 "$aa_loaded" "$aa_configured" | while read profile ; do
+ unload_profile "$profile"
+ done
+ rm -f "$aa_configured" "$aa_loaded"
+}
+
+# If the system debsum differs from the saved debsum, the new system debsum is
+# saved and non-zero is returned. Returns 0 if the two debsums matched or if
+# the system debsum file does not exist. This can be removed when system image
+# flavors all move to snappy.
+compare_and_save_debsums() {
+ pkg="$1"
+
+ if [ -n $pkg ] && [ -d "$PROFILES_VAR" ]; then
+ sums="/var/lib/dpkg/info/${pkg}.md5sums"
+ # store saved md5sums in /var/lib/apparmor/profiles since
+ # /var/cache/apparmor might be cleared by apparmor
+ saved_sums="${PROFILES_VAR}/.${pkg}.md5sums"
+
+ if [ -f "$sums" ] && \
+ ! diff -q "$sums" "$saved_sums" 2>&1 >/dev/null ; then
+ cp -f "$sums" "$saved_sums"
+ return 1
+ fi
+ fi
+
+ return 0
+}
+
+compare_previous_version() {
+ installed="/usr/share/snappy/security-policy-version"
+ previous="/var/lib/snappy/security-policy-version"
+
+ # When just $previous doesn't exist, assume this is a new system with
+ # no cache and don't do anything special.
+ if [ -f "$installed" ] && [ -f "$previous" ]; then
+ pv=`grep '^apparmor/' "$previous" | cut -d ' ' -f 2`
+ iv=`grep '^apparmor/' "$installed" | cut -d ' ' -f 2`
+ if [ -n "$iv" ] && [ -n "$pv" ] && [ "$iv" != "$pv" ]; then
+ # snappy updates $previous elsewhere, so just return
+ return 1
+ fi
+ fi
+
+ return 0
+}
+
+# Checks to see if the current container is capable of having internal AppArmor
+# profiles that should be loaded. Callers of this function should have already
+# verified that they're running inside of a container environment with
+# something like `systemd-detect-virt --container`.
+#
+# The only known container environments capable of supporting internal policy
+# are LXD and LXC environment.
+#
+# Returns 0 if the container environment is capable of having its own internal
+# policy and non-zero otherwise.
+#
+# IMPORTANT: This function will return 0 in the case of a non-LXD/non-LXC
+# system container technology being nested inside of a LXD/LXC container that
+# utilized an AppArmor namespace and profile stacking. The reason 0 will be
+# returned is because .ns_stacked will be "yes" and .ns_name will still match
+# "lx[dc]-*" since the nested system container technology will not have set up
+# a new AppArmor profile namespace. This will result in the nested system
+# container's boot process to experience failed policy loads but the boot
+# process should continue without any loss of functionality. This is an
+# unsupported configuration that cannot be properly handled by this function.
+is_container_with_internal_policy() {
+ local ns_stacked_path="${AA_SFS}/.ns_stacked"
+ local ns_name_path="${AA_SFS}/.ns_name"
+ local ns_stacked
+ local ns_name
+
+ if ! [ -f "$ns_stacked_path" ] || ! [ -f "$ns_name_path" ]; then
+ return 1
+ fi
+
+ read -r ns_stacked < "$ns_stacked_path"
+ if [ "$ns_stacked" != "yes" ]; then
+ return 1
+ fi
+
+ # LXD and LXC set up AppArmor namespaces starting with "lxd-" and
+ # "lxc-", respectively. Return non-zero for all other namespace
+ # identifiers.
+ read -r ns_name < "$ns_name_path"
+ if [ "${ns_name#lxd-*}" = "$ns_name" ] && \
+ [ "${ns_name#lxc-*}" = "$ns_name" ]; then
+ return 1
+ fi
+
+ return 0
+}
OpenPOWER on IntegriCloud