2006-04-11 21:52:54 +00:00
#!/bin/sh
# ----------------------------------------------------------------------
2011-02-22 11:14:34 -06:00
# Copyright (c) 1999-2008 NOVELL (All rights reserved)
2012-02-24 04:21:59 -08:00
# Copyright (c) 2009-2012 Canonical Ltd. (All rights reserved)
2006-04-11 21:52:54 +00:00
#
# 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.
# ----------------------------------------------------------------------
2007-04-04 21:56:08 +00:00
# rc.apparmor.functions by Steve Beattie
2006-04-11 21:52:54 +00:00
#
2007-04-04 21:56:08 +00:00
# NOTE: rc.apparmor initscripts that source this file need to implement
2006-04-11 21:52:54 +00:00
# the following set of functions:
2007-04-04 21:56:08 +00:00
# aa_action
2009-11-11 10:51:05 -08:00
# aa_log_action_start
# aa_log_action_end
2007-04-04 21:56:08 +00:00
# aa_log_success_msg
# aa_log_warning_msg
# aa_log_failure_msg
# aa_log_skipped_msg
2009-11-11 10:51:05 -08:00
# aa_log_daemon_msg
# aa_log_end_msg
2006-04-11 21:52:54 +00:00
# Some nice defines that we use
CONFIG_DIR=/etc/apparmor
MODULE=apparmor
OLD_MODULE=subdomain
if [ -f "${CONFIG_DIR}/${MODULE}.conf" ] ; then
APPARMOR_CONF="${CONFIG_DIR}/${MODULE}.conf"
elif [ -f "${CONFIG_DIR}/${OLD_MODULE}.conf" ] ; then
APPARMOR_CONF="${CONFIG_DIR}/${OLD_MODULE}.conf"
elif [ -f "/etc/immunix/subdomain.conf" ] ; then
2007-04-04 21:56:08 +00:00
aa_log_warning_msg "/etc/immunix/subdomain.conf is deprecated, use ${CONFIG_DIR}/subdomain.conf instead"
2006-04-11 21:52:54 +00:00
APPARMOR_CONF="/etc/immunix/subdomain.conf"
elif [ -f "/etc/subdomain.conf" ] ; then
2007-04-04 21:56:08 +00:00
aa_log_warning_msg "/etc/subdomain.conf is deprecated, use ${CONFIG_DIR}/subdomain.conf instead"
2006-04-11 21:52:54 +00:00
APPARMOR_CONF="/etc/subdomain.conf"
else
2007-04-04 21:56:08 +00:00
aa_log_warning_msg "Unable to find config file in ${CONFIG_DIR}, installation problem?"
2006-04-11 21:52:54 +00:00
fi
# Read configuration options from /etc/subdomain.conf, default is to
# warn if subdomain won't load.
SUBDOMAIN_MODULE_PANIC="warn"
SUBDOMAIN_ENABLE_OWLSM="no"
APPARMOR_ENABLE_AAEVENTD="no"
if [ -f "${APPARMOR_CONF}" ] ; then
#parse the conf file to see what we should do
2006-12-12 10:54:44 +00:00
. "${APPARMOR_CONF}"
2006-04-11 21:52:54 +00:00
fi
2009-11-11 10:51:05 -08:00
PARSER=/sbin/apparmor_parser
2006-04-11 21:52:54 +00:00
# SUBDOMAIN_DIR and APPARMOR_DIR might be defined in subdomain.conf|apparmor.conf
2008-11-18 17:33:38 +00:00
if [ -d "${APPARMOR_DIR}" ] ; then
2006-04-11 21:52:54 +00:00
PROFILE_DIR=${APPARMOR_DIR}
elif [ -d "${SUBDOMAIN_DIR}" ] ; then
PROFILE_DIR=${SUBDOMAIN_DIR}
elif [ -d /etc/apparmor.d ] ; then
PROFILE_DIR=/etc/apparmor.d
elif [ -d /etc/subdomain.d ] ; then
PROFILE_DIR=/etc/subdomain.d
fi
ABSTRACTIONS="-I${PROFILE_DIR}"
AA_EV_BIN=/usr/sbin/aa-eventd
AA_EV_PIDFILE=/var/run/aa-eventd.pid
2010-11-03 17:03:52 -07:00
AA_STATUS=/usr/sbin/aa-status
2006-04-11 21:52:54 +00:00
SD_EV_BIN=/usr/sbin/sd-event-dispatch.pl
SD_EV_PIDFILE=/var/run/sd-event-dispatch.init.pid
SD_STATUS=/usr/sbin/subdomain_status
2007-04-04 21:23:42 +00:00
SECURITYFS=/sys/kernel/security
2006-04-11 21:52:54 +00:00
2009-07-24 12:06:17 +00:00
SUBDOMAINFS_MOUNTPOINT=$(grep subdomainfs /etc/fstab | \
sed -e 's|^[[:space:]]*[^[:space:]]\+[[:space:]]\+\(/[^[:space:]]*\)[[:space:]]\+subdomainfs.*$|\1|' 2> /dev/null)
2006-04-11 21:52:54 +00:00
# keep exit status from parser during profile load. 0 is good, 1 is bad
STATUS=0
2008-01-03 22:27:20 +00:00
# Test if the apparmor "module" is present.
is_apparmor_present() {
2009-07-24 12:06:17 +00:00
local modules=$1
shift
while [ $# -gt 0 ] ; do
modules="$modules|$1"
shift
done
# check for subdomainfs version of module
grep -qE "^($modules)[[:space:]]" /proc/modules
2009-11-11 10:51:05 -08:00
2011-08-13 14:13:49 +02:00
[ $? -ne 0 -a -d /sys/module/apparmor ]
2008-01-03 22:27:20 +00:00
return $?
}
2007-08-14 19:19:59 +00:00
# This set of patterns to skip needs to be kept in sync with
2011-01-13 13:58:26 -08:00
# AppArmor.pm::isSkippableFile()
2009-11-11 10:51:05 -08:00
# returns 0 if profile should NOT be skipped
# returns 1 on verbose skip
# returns 2 on silent skip
2007-04-04 20:42:26 +00:00
skip_profile() {
local profile=$1
if [ "${profile%.rpmnew}" != "${profile}" -o \
"${profile%.rpmsave}" != "${profile}" -o \
2009-11-11 10:51:05 -08:00
-e "${PROFILE_DIR}/disable/`basename ${profile}`" -o \
2007-04-04 20:42:26 +00:00
"${profile%\~}" != "${profile}" ] ; then
2009-11-11 10:51:05 -08:00
return 1
fi
2018-10-09 12:39:24 -07:00
# Silently ignore the dpkg, pacman, and xbps files
2009-11-11 10:51:05 -08:00
if [ "${profile%.dpkg-new}" != "${profile}" -o \
"${profile%.dpkg-old}" != "${profile}" -o \
2010-02-16 12:56:04 -08:00
"${profile%.dpkg-dist}" != "${profile}" -o \
2018-03-30 17:46:25 +02:00
"${profile%.dpkg-bak}" != "${profile}" -o \
2018-03-30 18:05:06 +02:00
"${profile%.dpkg-remove}" != "${profile}" -o \
2018-03-30 17:46:25 +02:00
"${profile%.pacsave}" != "${profile}" -o \
"${profile%.pacnew}" != "${profile}" ] ; then
2009-11-11 10:51:05 -08:00
return 2
fi
2018-10-09 12:39:24 -07:00
if echo "${profile}" | egrep -q '^.+\.new-[0-9\.]+_[0-9]+$'; then
2018-10-14 18:10:46 +02:00
return 2
2018-10-09 12:39:24 -07:00
fi
2009-11-11 10:51:05 -08:00
return 0
}
force_complain() {
local profile=$1
# if profile not in complain mode
if ! egrep -q "^/.*[ \t]+flags[ \t]*=[ \t]*\([ \t]*complain[ \t]*\)[ \t]+{" $profile ; then
local link="${PROFILE_DIR}/force-complain/`basename ${profile}`"
if [ -e "$link" ] ; then
aa_log_warning_msg "found $link, forcing complain mode"
return 0
fi
2007-04-04 20:42:26 +00:00
fi
return 1
}
2006-12-12 10:54:44 +00:00
parse_profiles() {
2006-04-11 21:52:54 +00:00
# get parser arg
case "$1" in
load)
PARSER_ARGS="--add"
PARSER_MSG="Loading AppArmor profiles "
;;
reload)
PARSER_ARGS="--replace"
PARSER_MSG="Reloading AppArmor profiles "
;;
*)
2009-11-11 10:51:05 -08:00
aa_log_failure_msg "required 'load' or 'reload'"
2006-04-11 21:52:54 +00:00
exit 1
;;
esac
2011-03-17 10:21:06 -07:00
aa_log_action_start "$PARSER_MSG"
2006-04-11 21:52:54 +00:00
# run the parser on all of the apparmor profiles
if [ ! -f "$PARSER" ]; then
2009-11-11 10:51:05 -08:00
aa_log_failure_msg "AppArmor parser not found"
aa_log_action_end 1
2006-04-11 21:52:54 +00:00
exit 1
fi
if [ ! -d "$PROFILE_DIR" ]; then
2009-11-11 10:51:05 -08:00
aa_log_failure_msg "Profile directory not found"
aa_log_action_end 1
exit 1
2006-04-11 21:52:54 +00:00
fi
2007-03-27 18:38:28 +00:00
if [ -z "$(ls $PROFILE_DIR/)" ]; then
2009-11-11 10:51:05 -08:00
aa_log_failure_msg "No profiles found"
aa_log_action_end 1
2006-08-04 17:16:47 +00:00
return 1
2006-04-11 21:52:54 +00:00
fi
for profile in $PROFILE_DIR/*; do
2009-11-11 10:51:05 -08:00
skip_profile "${profile}"
skip=$?
# Ignore skip status == 2 (silent skip)
if [ "$skip" -eq 1 ] ; then
aa_log_skipped_msg "$profile"
2006-04-11 21:52:54 +00:00
logger -t "AppArmor(init)" -p daemon.warn "Skipping profile $profile"
2009-11-11 10:51:05 -08:00
STATUS=2
2011-08-04 16:20:26 -07:00
continue
2009-11-11 10:51:05 -08:00
elif [ "$skip" -ne 0 ]; then
continue
fi
if [ -f "${profile}" ] ; then
COMPLAIN=""
if force_complain "${profile}" ; then
COMPLAIN="-C"
fi
$PARSER $ABSTRACTIONS $PARSER_ARGS $COMPLAIN "$profile" > /dev/null
2006-04-11 21:52:54 +00:00
if [ $? -ne 0 ]; then
2009-11-11 10:51:05 -08:00
aa_log_failure_msg "$profile failed to load"
2006-04-11 21:52:54 +00:00
STATUS=1
fi
fi
done
2009-11-11 10:51:05 -08:00
if [ $STATUS -eq 2 ]; then
STATUS=0
2006-04-11 21:52:54 +00:00
fi
2009-11-11 10:51:05 -08:00
aa_log_action_end "$STATUS"
return $STATUS
2006-04-11 21:52:54 +00:00
}
2006-12-12 10:54:44 +00:00
profiles_names_list() {
2006-04-11 21:52:54 +00:00
# run the parser on all of the apparmor profiles
if [ ! -f "$PARSER" ]; then
2007-04-04 21:56:08 +00:00
aa_log_failure_msg "- AppArmor parser not found"
2006-04-11 21:52:54 +00:00
exit 1
fi
if [ ! -d "$PROFILE_DIR" ]; then
2007-04-04 21:56:08 +00:00
aa_log_failure_msg "- Profile directory not found"
2006-04-11 21:52:54 +00:00
exit 1
fi
for profile in $PROFILE_DIR/*; do
2009-11-11 10:51:05 -08:00
if skip_profile "${profile}" && [ -f "${profile}" ] ; then
Attached is a patch to make the initscript not fail if /tmp is full
by converting the comm(1) usage on temporary files to an embedded
awk script. On both Ubuntu and OpenSUSE, a version of awk (mawk in
Ubuntu, gawk in OpenSUSE) is either a direct or indirect dependency
on the minimal or base package set, and the original reporter also
mentioned that an awk-based solution would be palatable in a way that
converting to bash, or using perl or python here would not be.
In the embedded awk script, I've tried to avoid gawk or mawk specific
behaviors or extensions; e.g. this is the reason for the call to sort
on the output of the awk script, rather than using gawk's asort(). But
please let me know if you see anything that shouldn't be portable
across awk implementations.
An additional issue that is fixed in both scripts is handling child
profiles (e.g. hats) during reload. If child profiles are filtered
out (via grep -v '//') of the list to consider, then on reloading
a profile where a child profile has been removed or renamed, that
child profile will continue to stick around. However, if the profile
containing child profiles is removed entirely, if the initscript
attempts to unload the child profiles after the parent is removed,
this will fail because they were unloaded when the parent was unloaded.
Thus I removed any filtering of child profiles out, but do a post-awk
reverse sort which guarantees that any child profiles will be removed
before their parent is. I also added the LC_COLLATE=C (based on the
Ubuntu version) to the sort call to ensure a consistent sort order.
To restate, the problem with the existing code is that it creates
temporary files in $TMPDIR (by default /tmp) and if that partition
is full, problems with the reload action ensue. Alternate solutions
include switching the initscript to use bash and its <$() extension
or setting TMPDIR to /dev/shm/. The former is unpalatable to some
(particularly for an initscript), and for the latter, /dev/shm is
only guaranteed to exist on GNU libc based systems (glibc apparently
expects /dev/shm to exist for its POSIX shared memory implementation;
see shm_overview(7)). So to me, awk (sans GNU extensions) looks to
be the least bad option here.
Bug: https://launchpad.net/bugs/775785
2011-08-26 15:55:43 -07:00
LIST_ADD=$($PARSER $ABSTRACTIONS -N "$profile" )
2006-04-11 21:52:54 +00:00
if [ $? -eq 0 ]; then
Attached is a patch to make the initscript not fail if /tmp is full
by converting the comm(1) usage on temporary files to an embedded
awk script. On both Ubuntu and OpenSUSE, a version of awk (mawk in
Ubuntu, gawk in OpenSUSE) is either a direct or indirect dependency
on the minimal or base package set, and the original reporter also
mentioned that an awk-based solution would be palatable in a way that
converting to bash, or using perl or python here would not be.
In the embedded awk script, I've tried to avoid gawk or mawk specific
behaviors or extensions; e.g. this is the reason for the call to sort
on the output of the awk script, rather than using gawk's asort(). But
please let me know if you see anything that shouldn't be portable
across awk implementations.
An additional issue that is fixed in both scripts is handling child
profiles (e.g. hats) during reload. If child profiles are filtered
out (via grep -v '//') of the list to consider, then on reloading
a profile where a child profile has been removed or renamed, that
child profile will continue to stick around. However, if the profile
containing child profiles is removed entirely, if the initscript
attempts to unload the child profiles after the parent is removed,
this will fail because they were unloaded when the parent was unloaded.
Thus I removed any filtering of child profiles out, but do a post-awk
reverse sort which guarantees that any child profiles will be removed
before their parent is. I also added the LC_COLLATE=C (based on the
Ubuntu version) to the sort call to ensure a consistent sort order.
To restate, the problem with the existing code is that it creates
temporary files in $TMPDIR (by default /tmp) and if that partition
is full, problems with the reload action ensue. Alternate solutions
include switching the initscript to use bash and its <$() extension
or setting TMPDIR to /dev/shm/. The former is unpalatable to some
(particularly for an initscript), and for the latter, /dev/shm is
only guaranteed to exist on GNU libc based systems (glibc apparently
expects /dev/shm to exist for its POSIX shared memory implementation;
see shm_overview(7)). So to me, awk (sans GNU extensions) looks to
be the least bad option here.
Bug: https://launchpad.net/bugs/775785
2011-08-26 15:55:43 -07:00
echo "$LIST_ADD"
2006-04-11 21:52:54 +00:00
fi
fi
done
}
2006-12-12 10:54:44 +00:00
failstop_system() {
2006-04-11 21:52:54 +00:00
level=$(runlevel | cut -d" " -f2)
if [ $level -ne "1" ] ; then
2007-04-04 21:56:08 +00:00
aa_log_failure_msg "- could not start AppArmor. Changing to runlevel 1"
2006-04-11 21:52:54 +00:00
telinit 1;
2018-11-02 17:00:33 +01:00
return 255;
2006-04-11 21:52:54 +00:00
fi
2007-04-04 21:56:08 +00:00
aa_log_failure_msg "- could not start AppArmor."
2018-11-02 17:00:33 +01:00
return 255
2006-04-11 21:52:54 +00:00
}
2006-12-12 10:54:44 +00:00
module_panic() {
2006-04-11 21:52:54 +00:00
# the module failed to load, determine what action should be taken
case "$SUBDOMAIN_MODULE_PANIC" in
2007-04-04 21:23:42 +00:00
"warn"|"WARN")
return 1 ;;
2006-04-11 21:52:54 +00:00
"panic"|"PANIC") failstop_system
rc=$?
return $rc ;;
2007-04-04 21:56:08 +00:00
*) aa_log_failure_msg "- invalid AppArmor module fail option"
2018-11-02 17:00:33 +01:00
return 255 ;;
2006-04-11 21:52:54 +00:00
esac
}
2007-04-04 21:23:42 +00:00
is_apparmor_loaded() {
if ! is_securityfs_mounted ; then
mount_securityfs
fi
mount_subdomainfs
if [ -f "${SECURITYFS}/${MODULE}/profiles" ]; then
SFS_MOUNTPOINT="${SECURITYFS}/${MODULE}"
return 0
fi
if [ -f "${SECURITYFS}/${OLD_MODULE}/profiles" ]; then
SFS_MOUNTPOINT="${SECURITYFS}/${OLD_MODULE}"
return 0
fi
2009-07-24 12:06:17 +00:00
if [ -f "${SUBDOMAINFS_MOUNTPOINT}/profiles" ]; then
SFS_MOUNTPOINT=${SUBDOMAINFS_MOUNTPOINT}
return 0
fi
2007-04-04 21:23:42 +00:00
# check for subdomainfs version of module
2009-07-24 12:06:17 +00:00
is_apparmor_present apparmor subdomain
2008-01-03 22:27:20 +00:00
2007-04-04 21:23:42 +00:00
return $?
}
is_securityfs_mounted() {
2011-08-13 14:15:58 +02:00
test -d ${SECURITYFS} -a -d /sys/fs/cgroup/systemd || grep -q securityfs /proc/filesystems && grep -q securityfs /proc/mounts
2007-04-04 21:23:42 +00:00
return $?
}
mount_securityfs() {
if grep -q securityfs /proc/filesystems ; then
2007-04-04 21:56:08 +00:00
aa_action "Mounting securityfs on ${SECURITYFS}" \
2007-04-04 21:23:42 +00:00
mount -t securityfs securityfs "${SECURITYFS}"
return $?
fi
return 0
}
mount_subdomainfs() {
# for backwords compatibility
if grep -q subdomainfs /proc/filesystems && \
! grep -q subdomainfs /proc/mounts && \
[ -n "${SUBDOMAINFS_MOUNTPOINT}" ]; then
2007-04-04 21:56:08 +00:00
aa_action "Mounting subdomainfs on ${SUBDOMAINFS_MOUNTPOINT}" \
2007-04-04 21:23:42 +00:00
mount "${SUBDOMAINFS_MOUNTPOINT}"
return $?
fi
return 0
}
unmount_subdomainfs() {
SUBDOMAINFS=$(grep subdomainfs /proc/mounts | cut -d" " -f2 2> /dev/null)
if [ -n "${SUBDOMAINFS}" ]; then
2007-04-04 21:56:08 +00:00
aa_action "Unmounting subdomainfs" umount ${SUBDOMAINFS}
2007-04-04 21:23:42 +00:00
fi
}
2007-04-04 21:56:08 +00:00
apparmor_start() {
2009-11-11 10:51:05 -08:00
aa_log_daemon_msg "Starting AppArmor"
2018-11-03 07:15:16 -07:00
if ! is_apparmor_present ; then
aa_log_failure_msg "Starting AppArmor - failed, To enable AppArmor, ensure your kernel is configured with CONFIG_SECURITY_APPARMOR=y then add 'security=apparmor apparmor=1' to the kernel command line"
aa_log_end_msg 1
return 1
elif ! is_apparmor_loaded ; then
aa_log_failure_msg "Starting AppArmor - AppArmor control files aren't available under /sys/kernel/security/, please make sure securityfs is mounted."
aa_log_end_msg 1
return 1
2006-04-11 21:52:54 +00:00
fi
if [ ! -w "$SFS_MOUNTPOINT/.load" ] ; then
2007-04-04 21:56:08 +00:00
aa_log_failure_msg "Loading AppArmor profiles - failed, Do you have the correct privileges?"
2009-11-11 10:51:05 -08:00
aa_log_end_msg 1
2006-04-11 21:52:54 +00:00
return 1
fi
configure_owlsm
2008-11-07 12:53:37 +00:00
# if there is anything in the profiles file don't load
2011-08-13 14:13:49 +02:00
if ! read line < "$SFS_MOUNTPOINT/profiles"; then
2006-04-11 21:52:54 +00:00
parse_profiles load
else
2011-08-13 14:13:49 +02:00
aa_log_skipped_msg ": already loaded with profiles."
return 0
2006-04-11 21:52:54 +00:00
fi
2009-11-11 10:51:05 -08:00
aa_log_end_msg 0
return 0
2006-04-11 21:52:54 +00:00
}
2006-12-12 10:54:44 +00:00
remove_profiles() {
2006-04-11 21:52:54 +00:00
# removing profiles as we directly read from subdomainfs
# doesn't work, since we are removing entries which screws up
# our position. Lets hope there are never enough profiles to
# overflow the variable
2007-04-04 21:23:42 +00:00
if ! is_apparmor_loaded ; then
2009-11-11 10:51:05 -08:00
aa_log_failure_msg "AppArmor module is not loaded"
2006-04-11 21:52:54 +00:00
return 1
fi
if [ ! -w "$SFS_MOUNTPOINT/.remove" ] ; then
2009-11-11 10:51:05 -08:00
aa_log_failure_msg "Root privileges not available"
2006-04-11 21:52:54 +00:00
return 1
fi
if [ ! -x "${PARSER}" ] ; then
2009-11-11 10:51:05 -08:00
aa_log_failure_msg "Unable to execute AppArmor parser"
2006-04-11 21:52:54 +00:00
return 1
fi
retval=0
Attached is a patch to make the initscript not fail if /tmp is full
by converting the comm(1) usage on temporary files to an embedded
awk script. On both Ubuntu and OpenSUSE, a version of awk (mawk in
Ubuntu, gawk in OpenSUSE) is either a direct or indirect dependency
on the minimal or base package set, and the original reporter also
mentioned that an awk-based solution would be palatable in a way that
converting to bash, or using perl or python here would not be.
In the embedded awk script, I've tried to avoid gawk or mawk specific
behaviors or extensions; e.g. this is the reason for the call to sort
on the output of the awk script, rather than using gawk's asort(). But
please let me know if you see anything that shouldn't be portable
across awk implementations.
An additional issue that is fixed in both scripts is handling child
profiles (e.g. hats) during reload. If child profiles are filtered
out (via grep -v '//') of the list to consider, then on reloading
a profile where a child profile has been removed or renamed, that
child profile will continue to stick around. However, if the profile
containing child profiles is removed entirely, if the initscript
attempts to unload the child profiles after the parent is removed,
this will fail because they were unloaded when the parent was unloaded.
Thus I removed any filtering of child profiles out, but do a post-awk
reverse sort which guarantees that any child profiles will be removed
before their parent is. I also added the LC_COLLATE=C (based on the
Ubuntu version) to the sort call to ensure a consistent sort order.
To restate, the problem with the existing code is that it creates
temporary files in $TMPDIR (by default /tmp) and if that partition
is full, problems with the reload action ensue. Alternate solutions
include switching the initscript to use bash and its <$() extension
or setting TMPDIR to /dev/shm/. The former is unpalatable to some
(particularly for an initscript), and for the latter, /dev/shm is
only guaranteed to exist on GNU libc based systems (glibc apparently
expects /dev/shm to exist for its POSIX shared memory implementation;
see shm_overview(7)). So to me, awk (sans GNU extensions) looks to
be the least bad option here.
Bug: https://launchpad.net/bugs/775785
2011-08-26 15:55:43 -07:00
# We filter child profiles as removing the parent will remove
# the children
2011-10-12 00:45:11 +02:00
sed -e "s/ (\(enforce\|complain\))$//" "$SFS_MOUNTPOINT/profiles" | \
Attached is a patch to make the initscript not fail if /tmp is full
by converting the comm(1) usage on temporary files to an embedded
awk script. On both Ubuntu and OpenSUSE, a version of awk (mawk in
Ubuntu, gawk in OpenSUSE) is either a direct or indirect dependency
on the minimal or base package set, and the original reporter also
mentioned that an awk-based solution would be palatable in a way that
converting to bash, or using perl or python here would not be.
In the embedded awk script, I've tried to avoid gawk or mawk specific
behaviors or extensions; e.g. this is the reason for the call to sort
on the output of the awk script, rather than using gawk's asort(). But
please let me know if you see anything that shouldn't be portable
across awk implementations.
An additional issue that is fixed in both scripts is handling child
profiles (e.g. hats) during reload. If child profiles are filtered
out (via grep -v '//') of the list to consider, then on reloading
a profile where a child profile has been removed or renamed, that
child profile will continue to stick around. However, if the profile
containing child profiles is removed entirely, if the initscript
attempts to unload the child profiles after the parent is removed,
this will fail because they were unloaded when the parent was unloaded.
Thus I removed any filtering of child profiles out, but do a post-awk
reverse sort which guarantees that any child profiles will be removed
before their parent is. I also added the LC_COLLATE=C (based on the
Ubuntu version) to the sort call to ensure a consistent sort order.
To restate, the problem with the existing code is that it creates
temporary files in $TMPDIR (by default /tmp) and if that partition
is full, problems with the reload action ensue. Alternate solutions
include switching the initscript to use bash and its <$() extension
or setting TMPDIR to /dev/shm/. The former is unpalatable to some
(particularly for an initscript), and for the latter, /dev/shm is
only guaranteed to exist on GNU libc based systems (glibc apparently
expects /dev/shm to exist for its POSIX shared memory implementation;
see shm_overview(7)). So to me, awk (sans GNU extensions) looks to
be the least bad option here.
Bug: https://launchpad.net/bugs/775785
2011-08-26 15:55:43 -07:00
LC_COLLATE=C sort | grep -v // | while read profile ; do
2008-05-29 23:10:27 +00:00
echo -n "$profile" > "$SFS_MOUNTPOINT/.remove"
2006-04-11 21:52:54 +00:00
rc=$?
if [ ${rc} -ne 0 ] ; then
retval=${rc}
fi
done
2007-04-04 21:23:42 +00:00
return ${retval}
2006-04-11 21:52:54 +00:00
}
2007-04-04 21:56:08 +00:00
apparmor_stop() {
2009-11-11 10:51:05 -08:00
aa_log_daemon_msg "Unloading AppArmor profiles "
2006-04-11 21:52:54 +00:00
remove_profiles
2009-11-11 10:51:05 -08:00
rc=$?
2011-03-17 10:21:06 -07:00
aa_log_end_msg $rc
2009-11-11 10:51:05 -08:00
return $rc
2006-04-11 21:52:54 +00:00
}
2007-04-04 21:56:08 +00:00
apparmor_kill() {
2009-11-11 10:51:05 -08:00
aa_log_daemon_msg "Unloading AppArmor modules "
2007-04-04 21:23:42 +00:00
if ! is_apparmor_loaded ; then
2009-11-11 10:51:05 -08:00
aa_log_failure_msg "AppArmor module is not loaded"
2007-04-04 21:23:42 +00:00
return 1
fi
2006-04-11 21:52:54 +00:00
unmount_subdomainfs
2008-01-03 22:27:20 +00:00
if is_apparmor_present apparmor ; then
2006-04-11 21:52:54 +00:00
MODULE=apparmor
2008-01-03 22:27:20 +00:00
elif is_apparmor_present subdomain ; then
2006-04-11 21:52:54 +00:00
MODULE=subdomain
else
2009-11-11 10:51:05 -08:00
aa_log_failure_msg "AppArmor is builtin"
2007-04-04 21:23:42 +00:00
return 1
2006-04-11 21:52:54 +00:00
fi
2009-11-11 10:51:05 -08:00
/sbin/modprobe -qr $MODULE
rc=$?
aa_log_end_msg $rc
return $rc
2006-04-11 21:52:54 +00:00
}
2007-04-04 21:56:08 +00:00
__apparmor_restart() {
2006-04-11 21:52:54 +00:00
if [ ! -w "$SFS_MOUNTPOINT/.load" ] ; then
2007-04-04 21:56:08 +00:00
aa_log_failure_msg "Loading AppArmor profiles - failed, Do you have the correct privileges?"
2006-04-11 21:52:54 +00:00
return 4
fi
2011-09-15 21:23:25 +02:00
aa_log_daemon_msg "Restarting AppArmor"
2006-04-11 21:52:54 +00:00
configure_owlsm
parse_profiles reload
Attached is a patch to make the initscript not fail if /tmp is full
by converting the comm(1) usage on temporary files to an embedded
awk script. On both Ubuntu and OpenSUSE, a version of awk (mawk in
Ubuntu, gawk in OpenSUSE) is either a direct or indirect dependency
on the minimal or base package set, and the original reporter also
mentioned that an awk-based solution would be palatable in a way that
converting to bash, or using perl or python here would not be.
In the embedded awk script, I've tried to avoid gawk or mawk specific
behaviors or extensions; e.g. this is the reason for the call to sort
on the output of the awk script, rather than using gawk's asort(). But
please let me know if you see anything that shouldn't be portable
across awk implementations.
An additional issue that is fixed in both scripts is handling child
profiles (e.g. hats) during reload. If child profiles are filtered
out (via grep -v '//') of the list to consider, then on reloading
a profile where a child profile has been removed or renamed, that
child profile will continue to stick around. However, if the profile
containing child profiles is removed entirely, if the initscript
attempts to unload the child profiles after the parent is removed,
this will fail because they were unloaded when the parent was unloaded.
Thus I removed any filtering of child profiles out, but do a post-awk
reverse sort which guarantees that any child profiles will be removed
before their parent is. I also added the LC_COLLATE=C (based on the
Ubuntu version) to the sort call to ensure a consistent sort order.
To restate, the problem with the existing code is that it creates
temporary files in $TMPDIR (by default /tmp) and if that partition
is full, problems with the reload action ensue. Alternate solutions
include switching the initscript to use bash and its <$() extension
or setting TMPDIR to /dev/shm/. The former is unpalatable to some
(particularly for an initscript), and for the latter, /dev/shm is
only guaranteed to exist on GNU libc based systems (glibc apparently
expects /dev/shm to exist for its POSIX shared memory implementation;
see shm_overview(7)). So to me, awk (sans GNU extensions) looks to
be the least bad option here.
Bug: https://launchpad.net/bugs/775785
2011-08-26 15:55:43 -07:00
2011-09-15 21:23:25 +02:00
rc=$?
aa_log_end_msg $rc
return $rc
2006-04-11 21:52:54 +00:00
}
2007-04-04 21:56:08 +00:00
apparmor_restart() {
2007-04-04 21:23:42 +00:00
if ! is_apparmor_loaded ; then
2007-04-04 21:56:08 +00:00
apparmor_start
2006-04-11 21:52:54 +00:00
rc=$?
return $rc
fi
2007-04-04 21:56:08 +00:00
__apparmor_restart
2007-04-04 21:23:42 +00:00
return $?
2006-04-11 21:52:54 +00:00
}
2007-04-04 21:56:08 +00:00
apparmor_try_restart() {
2007-04-04 21:23:42 +00:00
if ! is_apparmor_loaded ; then
2007-05-24 05:00:34 +00:00
return 0
2006-04-11 21:52:54 +00:00
fi
2007-04-04 21:56:08 +00:00
__apparmor_restart
2007-04-04 21:23:42 +00:00
return $?
2006-04-11 21:52:54 +00:00
}
2006-12-12 10:54:44 +00:00
configure_owlsm () {
2006-04-11 21:52:54 +00:00
if [ "${SUBDOMAIN_ENABLE_OWLSM}" = "yes" -a -f ${SFS_MOUNTPOINT}/control/owlsm ] ; then
2007-04-04 21:56:08 +00:00
# Sigh, the "sh -c" is necessary for the SuSE aa_action
2006-04-11 21:52:54 +00:00
# and it can't be abstracted out as a seperate function, as
# that breaks under RedHat's action, which needs a
# binary to invoke.
2007-04-04 21:56:08 +00:00
aa_action "Enabling OWLSM extension" sh -c "echo -n \"1\" > \"${SFS_MOUNTPOINT}/control/owlsm\""
2006-04-11 21:52:54 +00:00
elif [ -f "${SFS_MOUNTPOINT}/control/owlsm" ] ; then
2007-04-04 21:56:08 +00:00
aa_action "Disabling OWLSM extension" sh -c "echo -n \"0\" > \"${SFS_MOUNTPOINT}/control/owlsm\""
2006-04-11 21:52:54 +00:00
fi
}
2007-04-04 21:56:08 +00:00
apparmor_status () {
2006-04-11 21:52:54 +00:00
if test -x ${AA_STATUS} ; then
${AA_STATUS} --verbose
return $?
fi
if test -x ${SD_STATUS} ; then
${SD_STATUS} --verbose
return $?
fi
2011-11-10 09:43:10 -08:00
if ! is_apparmor_loaded ; then
2006-04-11 21:52:54 +00:00
echo "AppArmor is not loaded."
rc=1
else
2011-11-10 09:43:10 -08:00
echo "AppArmor is enabled."
2006-04-11 21:52:54 +00:00
rc=0
fi
echo "Install the apparmor-utils package to receive more detailed"
echo "status information here (or examine ${SFS_MOUNTPOINT} directly)."
return $rc
}