Short version
If you have files which can't be accessed by lighttpd 1.4.13's normal user (i.e. are run via suexec), then lighttpd can easily be tricked into trying to open() them, causing a segfault every time. Do this by post-fixing a slash.
Long version
I have a lighttpd 1.4.13 + FastCGI with SuExec?, running on some files which can't be read by the normal lighttpd user.
This all works fine... unless you try to access specially crafted URLs - which cause lighty to crash _every time_.
Here's my (slightly obscured) set-up:
server.name = "1.2.3.4"
server.document-root = "/var/www/html/"
server.indexfiles = ( "index.html", "index.htm", "index.php" )
fastcgi.server = ( ".php" =>
( "localhost" =>
( "socket" => "/tmp/webadmin.socket",
"bin-path" => "/etc/lighttpd/suexec.sh",
"idle-timeout" => 30,
"check-local" => "disable",
"min-procs" => 1,
"max-procs" => 1,
) ) )
I have a file /var/www/html/x.php. Its contents can be anything. For a test case, I used:
<?
phpinfo();
?>
My suexec script is not relevant to the crash, but is completely simple (just execs a shell script that calls php-cgi).
The test file x.php is only accessible by the SuExec? user:
[root@ ~]# ls -l /var/www/html/x.php
-rwxr-x--- 1 suexecuser suexecgroup 19 Apr 12 22:06 /var/www/html/x.php
If I access it as http://1.2.3.4/x.php then all is fine - I get what I'd expect. No problems.
However, if I try http://1.2.3.4/x.php/y (i.e. appending a pseudo-directory), then - boom! segfault! This happens every single time. Not good on a live server... :-(
Here are the last few lines of the strace:
poll([{fd=4, events=POLLIN}, {fd=5, events=POLLIN}, {fd=25, events=POLLIN, revents=POLLIN}], 3, 1000) = 1
read(25, "\27\3\1\2\0\7\273)\315YK:\36j#\345\30\321\316\2623!\357"..., 18437) = 517
read(25, 0x8780820, 18437) = -1 EAGAIN (Resource temporarily unavailable)
stat64("/var/www/html/x.php/y", 0xbffcaa70) = -1 ENOTDIR (Not a directory)
stat64("/var/www/html/x.php/y", 0xbffcab30) = -1 ENOTDIR (Not a directory)
stat64("/var/www/html/x.php", {st_mode=S_IFREG|0750, st_size=19, ...}) = 0
stat64("/var/www/html/x.php", {st_mode=S_IFREG|0750, st_size=19, ...}) = 0
open("/var/www/html/x.php", O_RDONLY|O_LARGEFILE) = -1 EACCES (Permission denied)
--- SIGSEGV (Segmentation fault) @ 0 (0) ---