Typo in apache2-maintscript-helper causes MPM check to misfire

Bug #1782806 reported by Tim Bishop on 2018-07-20
24
This bug affects 4 people
Affects Status Importance Assigned to Milestone
apache2 (Debian)
Fix Released
Unknown
apache2 (Ubuntu)
High
Andreas Hasenack
Bionic
Undecided
Andreas Hasenack

Bug Description

[Impact]
There are two conditions for this bug to happen, as far as I could figure out:
a) the mpm_prefork module configuration files are named just prefork.{conf,module} instead of, or in addition to, mpm_prefork.{conf,module}
b) this renamed prefork mpm module is enabled manually instead of using a2enmod

These conditions mean that one will have two mpm modules enabled at the same time in /etc/apache2/mod-enabled, something that the a2enmod tool knows how to prevent. But the symlinks can still be created manually. Note that apache2 will fail to (re)start in this situation.

These were the conditions I could figure out via code inspection and from logs from this bug and #1771934, meaning, I could reproduce the same error, including shell code path execution.

It's quite a corner case, but it showed a real bug in the apache apache2-maintscript-helper shell script. It seems to be triggered by a puppetlabs module, but I didn't install or configure puppet to confirm.

One could argue it's a local configuration issue, since non-standard tools were used, but the bug it showed in the apache script is real and I believe it's worth fixing.

Once the two mpm modules (event, from the default install, and prefork, from the manual symlink) are enabled at the same time (see testing instructions for an example on how to do it), the following happens when php is installed:
- php's postinst runs a2query -M to check which mpm is in use
- that call returns "event", so php proceeds to switch the mpm to prefork by calling "apache2_switch_mpm prefork"
- due to the bug, apache2_switch_mpm() will check if "prefork" (and NOT mpm_prefork) is already enabled. In this line, $MPM=prefork, and $mpm is not defined. So this:

    a2query -m "$mpm_$MPM" > /dev/null 2>&1 || a2query_ret=$?

Turns into:

    a2query -m "prefork" > /dev/null 2>&1 || a2query_ret=$?

- because there is a /etc/apache2/mods-enabled/prefork.* symlink (manually created), this returns 0, in which case the function determines there is nothing to do (prefork is already enabled!) and exits 0 without actually switching anything
- but mpm_event is still enabled, and when a2enmod is called to enable php, that correctly complains and fails.

With the fix, the a2query call from apache2_switch_mpm() will correctly determine that mpm_prefork is not enabled, and perform the requested switch.

In the end, prefork will be loaded twice, but apache handles that gracefully and ignores the second load:

[Thu Oct 11 18:33:48.576838 2018] [so:warn] [pid 9923] AH01574: module mpm_prefork_module is already loaded, skipping

[Test Case]

sudo apt update
sudo apt install apache2
sudo cp /etc/apache2/mods-available/{mpm_prefork,prefork}.conf
sudo cp /etc/apache2/mods-available/{mpm_prefork,prefork}.load
sudo ln -s /etc/apache2/mods-{available,enabled}/prefork.load
sudo ln -s /etc/apache2/mods-{available,enabled}/prefork.conf

Installing the php7.2 module now will fail:
sudo apt install libapache2-mod-php7.2

Creating config file /etc/php/7.2/apache2/php.ini with new version
apache2_switch_mpm prefork: No action required
dpkg: error processing package libapache2-mod-php7.2 (--configure):
 installed libapache2-mod-php7.2 package post-installation script subprocess returned error exit status 1
E: Sub-process /usr/bin/dpkg returned an error code (1)

With the package from proposed, the above will work just fine.
If a user is in the failed situation already, a dist-upgrade also fixes the problem.

[Regression Potential]
One has to wonder if there are modules and helpers out there relying on this bug, or what kind of workarounds they might have implemented already for this.

There is an example in the puppetlaps apache2 module where they deliberately disable mpm_event while installing php:

https://github.com/puppetlabs/puppetlabs-apache/blob/3bd70296be093a10713fd2f85676ac08d305e93f/manifests/mpm.pp#L76

[Other Info]
The reproducer steps might be a bit too artificial, but are easy to follow than an actual puppet installation, and I believe they show the problem correctly. Nonetheless, it would be good to see puppet users perform this verification using the actual puppet module that is suspected to trigger the bug.

[Original Description]

The following line appears to have a typo:

a2query -m "$mpm_$MPM" > /dev/null 2>&1 || a2query_ret=$?

It should read:

a2query -m "mpm_$MPM" > /dev/null 2>&1 || a2query_ret=$?

Since $mpm is not defined. Later on there are references to enabling and disabling "mpm_$MPM".

https://salsa.debian.org/apache-team/apache2/blob/master/debian/debhelper/apache2-maintscript-helper#L290

This appears to trip up the Puppet apache module since it creates a prefork module (rather than mpm_prefork), which results in the above query returning a positive response. This is what's happening in bug #1771934.

Fix is obvious and trivial so can hopefully be implemented soon. Appears only to affect bionic since xenial had different code.

Related branches

tags: added: bitesize
Changed in apache2 (Ubuntu):
status: New → Triaged
importance: Undecided → High
Changed in apache2 (Debian):
status: Unknown → New
Changed in apache2 (Debian):
status: New → Fix Released
Changed in apache2 (Ubuntu):
status: Triaged → In Progress
assignee: nobody → Andreas Hasenack (ahasenack)
Andreas Hasenack (ahasenack) wrote :

This is fixed in cosmic.

Changed in apache2 (Ubuntu):
status: In Progress → Fix Released
Launchpad Janitor (janitor) wrote :

Status changed to 'Confirmed' because the bug affects multiple users.

Changed in apache2 (Ubuntu Bionic):
status: New → Confirmed
tags: added: server-next
Changed in apache2 (Ubuntu Bionic):
assignee: nobody → Andreas Hasenack (ahasenack)
status: Confirmed → In Progress
description: updated
description: updated
description: updated
description: updated
description: updated
description: updated

Hello Tim, or anyone else affected,

Accepted apache2 into bionic-proposed. The package will build now and be available at https://launchpad.net/ubuntu/+source/apache2/2.4.29-1ubuntu4.5 in a few hours, and then in the -proposed repository.

Please help us by testing this new package. See https://wiki.ubuntu.com/Testing/EnableProposed for documentation on how to enable and use -proposed. Your feedback will aid us getting this update out to other Ubuntu users.

If this package fixes the bug for you, please add a comment to this bug, mentioning the version of the package you tested and change the tag from verification-needed-bionic to verification-done-bionic. If it does not fix the bug for you, please add a comment stating that, and change the tag to verification-failed-bionic. In either case, without details of your testing we will not be able to proceed.

Further information regarding the verification process can be found at https://wiki.ubuntu.com/QATeam/PerformingSRUVerification . Thank you in advance for helping!

N.B. The updated package will be released to -updates after the bug(s) fixed by this package have been verified and the package has been in -proposed for a minimum of 7 days.

Changed in apache2 (Ubuntu Bionic):
status: In Progress → Fix Committed
tags: added: verification-needed verification-needed-bionic
Andreas Hasenack (ahasenack) wrote :
Download full text (4.0 KiB)

Bionic Verification
===================

First, confirming the bug:
ubuntu@bionic-apache2-1782806:~$ apt-cache policy apache2
apache2:
  Installed: 2.4.29-1ubuntu4.4
  Candidate: 2.4.29-1ubuntu4.4
  Version table:
 *** 2.4.29-1ubuntu4.4 500
        500 http://br.archive.ubuntu.com/ubuntu bionic-updates/main amd64 Packages

# prep
ubuntu@bionic-apache2-1782806:~$ sudo cp /etc/apache2/mods-available/{mpm_prefork,prefork}.conf
ubuntu@bionic-apache2-1782806:~$ sudo cp /etc/apache2/mods-available/{mpm_prefork,prefork}.load
ubuntu@bionic-apache2-1782806:~$ sudo ln -s /etc/apache2/mods-{available,enabled}/prefork.load
ubuntu@bionic-apache2-1782806:~$ sudo ln -s /etc/apache2/mods-{available,enabled}/prefork.conf

# this should fail
ubuntu@bionic-apache2-1782806:~$ sudo apt install libapache2-mod-php7.2 -y
...
Creating config file /etc/php/7.2/apache2/php.ini with new version
apache2_switch_mpm prefork: No action required
dpkg: error processing package libapache2-mod-php7.2 (--configure):
 installed libapache2-mod-php7.2 package post-installation script subprocess returned error exit status 1
Errors were encountered while processing:
 libapache2-mod-php7.2
E: Sub-process /usr/bin/dpkg returned an error code (1)

Bug confirmed.

Confirming fix

a) upgrading from the broken package to the fixed one
Starting with this scenario. Note how the php module package is in a failed state:
ubuntu@bionic-apache2-1782806:~$ dpkg -l|grep apache2
ii apache2 2.4.29-1ubuntu4.4
ii apache2-bin 2.4.29-1ubuntu4.4
ii apache2-data 2.4.29-1ubuntu4.4
ii apache2-utils 2.4.29-1ubuntu4.4
iF libapache2-mod-php7.2 7.2.10-0ubuntu0.18.04.1

ubuntu@bionic-apache2-1782806:~$ sudo apt install apache2 apache2-bin apache2-data apache2-utils

(...)
Setting up apache2 (2.4.29-1ubuntu4.5) ...
info: Switch to mpm prefork for package libapache2-mod-php7.2
Module mpm_event disabled.
Enabling module mpm_prefork.
info: Executing deferred 'a2enmod php7.2' for package libapache2-mod-php7.2
Enabling module php7.2.
W: APT had planned for dpkg to do more than it reported back (20 vs 24).
   Affected packages: libapache2-mod-php7.2:amd64

# php is now ok
ubuntu@bionic-apache2-1782806:~$ dpkg -l|grep libapache2-mod-php
ii libapache2-mod-php7.2 7.2.10-0ubuntu0.18.04.1 amd64 server-side, HTML-embedded scripting language (Apache 2 module)

# apt -f install is clean:
ubuntu@bionic-apache2-1782806:~$ sudo apt -f install
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following package was automatically installed and is no longer required:
  libfreetype6
Use 'sudo apt autoremove' to remove it.
0 upgraded, 0 newly installed, 0 to remove and 49 not upgraded.

b) Starting out with the condition that shows the bug, but with the fixed package from proposed:
ubuntu@bionic-apache2-1782806:~$ apt-cache policy apache2
apache2:
  Installed: 2.4.29-1ubuntu4.5
  Candidate: 2.4.29-1ubuntu4.5
  Version table:
 *** 2.4.29-1ubuntu4.5 500
        500 http://br.archive.ubuntu.com/ubuntu bionic-proposed/main amd64 Packages

# Creating the condition for the...

Read more...

tags: added: verification-done-bionic
removed: verification-needed-bionic
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Duplicates of this bug

Other bug subscribers

Remote bug watches

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