I’ve been playing around with RedHat’s newly released Enterprise Linux 5. This comes with PHP 5.1.6, which I’ve taken off my test box and replaced with a copy of PHP 4 built from source.
After installing PHP 4, the first time I tried to start up Apache, it failed with this error:
Cannot load modules/libphp4.so into server: modules/libphp4.so: cannot restore segment prot after reloc: Permission denied
This is an error message from SELinux (which is enabled by default on RHEL5). The error has been triggered because the PHP runtime code contains text relocations – a situation where the code inside the .so has to be writable in memory.
(The definitive place to look for information about text relocations and the risk they pose to the security of your server is this page from Ulrich Drepper).
The quick workaround is to run this command on your server:
chcon -t textrel_shlib_t modules/libphp4.so
This command tells SELinux to allow text relocations inside the libphp4.so Apache module. (Use the command “chcon -t usr_t modules/lib4php.so” to reverse the effect, if you need to).
There are a couple of serious downsides to this workaround. The first one is that it disables one of the protections that SELinux provides. It makes your server more vulnerable to security exploits targetted at the PHP runtime itself. The second problem is that your server uses more memory per Apache process, because each Apache process ends up with its own copy of PHP.
One fix is to recompile your copy of PHP 4 using the “–with-pic” configure option. This produces a copy of PHP that doesn’t contain text relocations. In theory (I haven’t tested this yet), it should also be able to handle more concurrent connections on a server before the server runs out of RAM. Using Apache’s ab benchmarking app, my results suggest that PHP 4 w/ “–with-pic” is about 0.7% slower – small enough not to matter for many folks.
There’s a second way to avoid text relocations – don’t compile with “–with-pic”, and use the prelink tool instead. This tool, run from the command-line, works out the text relocations once, and then writes the data back to the binaries and libraries. From my testing, this avoids the SELinux error, and performance-wise it’s about 0.1% faster than PHP w/ text relocations, and about 0.8% faster than PHP 4 w/ “–with-pic”. This approach should also bring the benefits of reduced memory usage too that go with the “–with-pic” approach, but I haven’t done any testing to confirm this.
Which approach is the best – PHP 4 w/ “–with-pic”, or using prelink? The downside of using prelink is that this approach is reported to be unsuitable for Linux installs configured to do address space randomisation. You also have to remember to re-run prelink everytime you upgrade or re-install PHP. Using PHP 4 w/ “–with-pic” avoids these issues.