php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #21898 Segfault after Apache internal redirect
Submitted: 2003-01-27 06:21 UTC Modified: 2003-01-28 21:31 UTC
From: mlippmaa at issp dot u-tokyo dot ac dot jp Assigned:
Status: Closed Package: Apache2 related
PHP Version: 4.3.0 OS: RedHat Linux
Private report: No CVE-ID: None
View Add Comment Developer Edit
Anyone can comment on a bug. Have a simpler test case? Does it work for you on a different platform? Let us know!
Just going to say 'Me too!'? Don't clutter the database with that please !
Your email address:
MUST BE VALID
Solve the problem:
13 + 45 = ?
Subscribe to this entry?

 
 [2003-01-27 06:21 UTC] mlippmaa at issp dot u-tokyo dot ac dot jp
Using Apache 2.0.43 internal redirects with PHP4.3.0 
either cause a segfault or expose a part of the original 
PHP script.

I have an authentication module in Apache, which checks 
the user access rghts in the ap_hook_auth_checker hook and
diverts the user to an error document if authentication
fails. The Apache module does this:

r->method = apr_pstrdup(r->pool, "GET");
r->method_number = M_GET;
ap_internal_redirect(url, r);
return OK;

If the url of the error document points to a PHP file, 
the error document is processed immediately, as it should
be, but parts of the source text of the original PHP script
that the user tried to access is also sent before Apache
finishes the request.

What happens is that Apache calls the php_output_filter in
sapi_apache2.c first with a brigade that only contains
the error document's filename. This gets processed normally.
Apache then calls the php_output_filter *again* with a
brigade that contains the filename of the original PHP
script (to which access was denied). The output filter 
looks at the ctx->request_processed flag, which is now set,
and passes the brigade to the next filter. Unfortunately, 
for some reason at this stage the ctx->r->handler field 
has been cleared to NULL, which is probably why some other
filter downstream actually delivers the PHP script source 
as text, appended to the original PHP output. The appended
text is not visible in the browser, but easy enough to see
in a packet dump between the client and the server.

If the error document is a HTML file, the same thing 
happens, except in this case apache makes the second call 
to the php_output_filter with ctx->r->handler = NULL and
ctx->request_processed = 0, which means that the filter 
code reaches the strncp() that checks if this is a
php-source request. Since the handler pointer is NULL, the
strncmp call causes a segmentation fault at this point.

For all I know, this whole problem could be caused by an
incorrect use of the ap_internal_redirect call in Apache,
but it may still be a good idea to check that if the PHP
output filter does get called, that there really is a
non-NULL handler field in ctx->r.

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2003-01-27 17:32 UTC] iliaa@php.net
This bug may be related to bug #17868.
 [2003-01-27 19:47 UTC] mlippmaa at issp dot u-tokyo dot ac dot jp
I just checked this. The problem is indeed related to bug
#17868. If you have an .shtml file with two includes for 
PHP scripts then what happens there is that the first 
include is processed correctly. Apache then does the second
subrequest and calls the php filter again with the second
script name but by this time the ctx->request_processed
flag is set, so the php filter just ignores the request.

This is perhaps not surprising, because after processing the
first included scripts the php filter itself, just after
the php_apache_request_dtor call sets 
ctx->request_processed=1. 

I don't know who else touches this flag, or how it gets 
communicated between the main request and other subrequests
but could it be that the php filter should check more
carefully when to set the request_processed flag?
 [2003-01-27 21:09 UTC] mlippmaa at issp dot u-tokyo dot ac dot jp
As I see it, the cause of bug #17868 is in the php filter.
The same filter (with the same context) gets called several
times if there are several included php scripts in a shtml
file. After the first file is processed, the filter always
sets the request_processed flag and ignores any calls that
follow. This should not be done for subrequests, i.e. if 
you do

if (! f->r->main)
  ctx->request_processed = 1;

then the #17868 bug goes away and you can include many php
scripts in a shtml file.

But all this doesn't help me with the internal redirects.
The problem in my case is that the r->handler (and the
ctx->r->handler) end up NULL after a redirect. In this case
the PHP filter ignores the request (as it should, I
suppose), and some default handler in Apache serves the
php file as plain text. But this doesn't look like a PHP
problem...
 [2003-01-28 21:31 UTC] mlippmaa at issp dot u-tokyo dot ac dot jp
This was indeed Apache problem. The Apache module was doing

ap_internal_redirect(url, r);
return OK;

After digging in the Apache code I changed it to

ap_internal_redirect(url, r);
return DONE;

Doing this, and changing the request_processed flag in the
php filter solved the problem. I also pointed the file type
check strncmp in the php filter to f->r->handler instead of
ctx->r->handler.

So this "bug" can be closed.
 
PHP Copyright © 2001-2022 The PHP Group
All rights reserved.
Last updated: Tue Dec 06 04:05:54 2022 UTC