apache2 does not work with shipped profiles

Bug #1322764 reported by Kees Cook
18
This bug affects 4 people
Affects Status Importance Assigned to Milestone
AppArmor
Fix Released
Medium
Unassigned
apparmor (Ubuntu)
Fix Released
Medium
Unassigned

Bug Description

Apache2 fails dramatically with apparmor module enabled.

$ apt-get install apache2 libapache2-mod-php5 libapache2-mod-apparmor

#bug?
# Processing triggers for ufw (0.34~rc-0ubuntu2) ...
# WARN: Skipping 'ufw-directoryserver': couldn't process

$ service apache2 stop
$ service apache2 start
# All is well

# By default, apache2 is disabled:
$ aa-status | grep apache | wc -l
0

$ ls /etc/apparmor.d/disable | grep apache2 | wc -l
1
$ grep complain /etc/apparmor.d/usr.sbin.apache2
/usr/sbin/apache2 flags=(complain) {
  ^DEFAULT_URI flags=(complain) {
  ^HANDLING_UNTRUSTED_INPUT flags=(complain) {
$ aa-enforce /etc/apparmor.d/usr.sbin.apache2
$ ls /etc/apparmor.d/disable | grep apache2 | wc -l
0
$ grep complain /etc/apparmor.d/usr.sbin.apache2
  ^DEFAULT_URI flags=(complain) {
  ^HANDLING_UNTRUSTED_INPUT flags=(complain) {
#bug: complain not removed on hats when aa-enforce runs
$ aa-status
...
31 profiles are in enforce mode.
...
   /usr/sbin/apache2
...
2 profiles are in complain mode.
   /usr/sbin/apache2//DEFAULT_URI
   /usr/sbin/apache2//HANDLING_UNTRUSTED_INPUT
6 processes are unconfined but have a profile defined.
   /usr/sbin/apache2 (811)
   /usr/sbin/apache2 (814)
...

$ service apache2 stop
 * Stopping web server apache2
$ ps -ef | grep apache2 | wc -l
8
#bug: stop fails, via seemingly impossible signal blocking
# dmesg shows:
# [17967.520600] type=1400 audit(1399577975.916:104): apparmor="DENIED" operation="signal" profile="/usr/sbin/apache2" pid=29013 comm="apache2" requested_mask="send" denied_mask="send" signal=term peer="unconfined"
# How did this happen? The "/usr/sbin/apache2" profile has "base", which includes the signal
# rules for allowing an unconfined process send to it.

# Get back to sanity:
$ apparmor_parser -R /etc/apparmor.d/usr.sbin.apache2
$ service apache2 stop
$ vi /etc/apparmor.d/usr.sbin.apache2 #remove "complain" flags on HATs
$ apparmor_parser -r /etc/apparmor.d/usr.sbin.apache2
$ aa-status
...
33 profiles are in enforce mode.
...
   /usr/sbin/apache2
   /usr/sbin/apache2//DEFAULT_URI
   /usr/sbin/apache2//HANDLING_UNTRUSTED_INPUT
...
$ service apache2 start
$ aa-status
...
13 processes are in enforce mode.
...
   /usr/sbin/apache2 (1152)
   /usr/sbin/apache2 (1153)
...
$ wget http://localhost/
# All is well

$ a2enmod apparmor
$ service apache2 restart
$ aa-status
...
13 processes are in enforce mode.
...
   /usr/sbin/apache2 (1162)
   /usr/sbin/apache2//HANDLING_UNTRUSTED_INPUT (1165)
   /usr/sbin/apache2//HANDLING_UNTRUSTED_INPUT (1166)
...
$ wget http://localhost/
# All is well

$ service apache2 stop
# Apache2 can't shut down
# logs: [Fri May 09 22:34:42.280997 2014] [core:warn] [pid 1162] AH00045: child process 1165 still did not exit, sending a SIGTERM
# dmesg: [140073.881409] type=1400 audit(1399700082.276:328): apparmor="DENIED" operation="signal" profile="/usr/sbin/apache2//HANDLING_UNTRUSTED_INPUT" pid=1162 comm="apache2" requested_mask="receive" denied_mask="receive" signal=term peer="/usr/sbin/apache2"
#bug: signals from apache to hats fail
$ pkill apache2
pkill: killing pid 1382 failed: Permission denied
pkill: killing pid 1383 failed: Permission denied
...
#bug: signals from unconfined to hats fail

# Fix things up...
$ apparmor_parser -R /etc/apparmor.d/usr.sbin.apache2
$ service apache2 stop
$ pkill apache2
$ vi /etc/apparmor.d/usr.sbin.apache2
# add to ^HANDLING_UNTRUSTED_INPUT (instead of adding all of "base"):
# # Allow unconfined processes to send us signals by default
# signal (receive) peer=unconfined,
# # Allow apache to send us signals by default
# signal (receive) peer=/usr/sbin/apache2,
# # Allow us to signal ourselves
# signal peer=@{profile_name},
# add to ^DEFAULT_URI (not in "base"):
# # Allow apache to send us signals by default
# signal (receive) peer=/usr/sbin/apache2,
# add to /usr/sbin/apache2:
# # Send signals to all hats.
# signal (send) peer=/usr/sbin/apache2//*,
# add to /etc/apparmor.d/abstractions/apache2-common (instead of all of "base"):
# # Allow unconfined processes to send us signals by default
# signal (receive) peer=unconfined,
# # Allow apache to send us signals by default
# signal (receive) peer=/usr/sbin/apache2,
# # Allow us to signal ourselves
# signal peer=@{profile_name},
$ apparmor_parser -r /etc/apparmor.d/usr.sbin.apache2
$ service apache2 start
$ aa-status
...
13 processes are in enforce mode.
...
   /usr/sbin/apache2 (1298)
   /usr/sbin/apache2//HANDLING_UNTRUSTED_INPUT (1301)
   /usr/sbin/apache2//HANDLING_UNTRUSTED_INPUT (1302)
...
$ wget http://localhost/
$ service apache2 stop
$ service apache2 start
# All is well

# Create new "site-one" hat via /etc/apparmor.d/local/usr.sbin.apache2:
# ^site-one {
# #include <abstractions/apache2-common>
# }
# Attach it to /etc/apache2/sites-enabled/000-default.conf:
# in VirtualHost...
# <IfModule mod_apparmor.c>
# AADefaultHatName site-one
# </IfModule>
$ apparmor_parser -r /etc/apparmor.d/usr.sbin.apache2
$ service apache2 reload
$ wget http://localhost/
#fails, expected, however, in dmesg:
# [141351.407572] type=1400 audit(1399701359.804:571): apparmor="DENIED" operation="open" profile="/usr/sbin/apache2//site-one" name="/proc/1774/attr/current" pid=1774 comm="apache2" requested_mask="r" denied_mask="r" fsuid=33 ouid=0
#bug: attr/current "r" missing in apache2-common
$ vi /etc/apparmor.d/abstractions/apache2-common
# add 'r" to attr/current
$ apparmor_parser -r /etc/apparmor.d/usr.sbin.apache2
$ wget http://localhost/
#fails, expected. dmesg looks sensible
# All is well

# Add to site-one:
# # Site files.
# /var/www/** r,
# # Logs.
# /var/log/apache2/** w,
$ apparmor_parser -r /etc/apparmor.d/usr.sbin.apache2
$ wget http://localhost/
# All is well

# Notes:
# - HANDLING_UNTRUSTED_INPUT seems insanely open, should be extremely tight.
# DEFAULT_URI should include apache2-common and basics for default site
# instead of full permissions.

Related branches

Revision history for this message
Kees Cook (kees) wrote :
Revision history for this message
Kees Cook (kees) wrote :

The "wordpress" package also needs the mysql abstraction added to its profile...

Revision history for this message
Christian Boltz (cboltz) wrote :

#bug: complain not removed on hats when aa-enforce runs

filed as https://bugs.launchpad.net/apparmor/+bug/1322780 to avoid this gets lost.

tags: added: patch
Steve Beattie (sbeattie)
Changed in apparmor (Ubuntu):
importance: Undecided → Medium
status: New → Triaged
Revision history for this message
Steve Beattie (sbeattie) wrote :

Kees,

Thanks for the report. The mysql abstraction fix already made it into the upstream lp:apparmor tree in commit 2506. I'm reviewing the other changes now.

Changed in apparmor:
milestone: none → 2.9.0
Revision history for this message
Steve Beattie (sbeattie) wrote :

Kees,

I accepted most of the rest of the fixes you proposed in lp:apparmor commit 2533. The exceptions to those I've submitted to the apparmor list at https://lists.ubuntu.com/archives/apparmor/2014-June/005857.html with an attempt to explain why I felt uncomfortable accepting them, but giving you and others the opportunity to override my opinion on them.

Thanks!

Changed in apparmor:
status: New → In Progress
importance: Undecided → Medium
tags: added: aa-policy
Changed in apparmor (Ubuntu):
status: Triaged → Fix Released
Steve Beattie (sbeattie)
Changed in apparmor:
status: In Progress → Fix Committed
Revision history for this message
Steve Beattie (sbeattie) wrote :

Apparmor 2.9.0 has been released; closing.

Changed in apparmor:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.