Bug 12655 - SSI "include virtual" sometimes causing QUERY_STRING variable to be garbage.
Summary: SSI "include virtual" sometimes causing QUERY_STRING variable to be garbage.
Status: CLOSED FIXED
Alias: None
Product: Apache httpd-2
Classification: Unclassified
Component: mod_include (show other bugs)
Version: 2.0-HEAD
Hardware: PC Linux
: P3 major with 4 votes (vote)
Target Milestone: ---
Assignee: Apache HTTPD Bugs Mailing List
URL:
Keywords: PatchAvailable
: 36452 (view as bug list)
Depends on:
Blocks:
 
Reported: 2002-09-15 02:02 UTC by William Drury
Modified: 2005-08-31 23:26 UTC (History)
2 users (show)



Attachments
the patch for QUERY_STRING case (739 bytes, patch)
2005-05-30 18:20 UTC, Deomid Ryabkov
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description William Drury 2002-09-15 02:02:09 UTC
I have run into this problem in both 2.0.39 and 2.0.40.

Using httpd 2.0.40 in Linux Mandrake 8.2, compiled without any external modules
(but with --enable-rewrite), I have set the following things in httpd.conf:

AddHandler cgi-script .sgi
AddOutputFilter INCLUDES .sgi

My intent is to server-parse the output of cgi scripts whose filename ends with
.sgi.  This seems to work, if I print "<!--set VAR=\"FOO\" VALUE=\"bar\" -->\n"
; in the script, it is indeed set, so that code like:

<!--#include virtual="/cgi-bin/foo.sgi?$QUERY_STRING" -->
<!--#if expr="$FOO" -->
Foo is set.
<!--#else -->
Foo is not set.
<!--#endif -->

produces the expected final output "Foo is set.".

However, if I have several "include virtual" statements in the same .shtml file,
there appears to be a problem.  If I add more include virtual statements to this
file, like:

<!--#include virtual="/cgi-bin/foo.sgi?$QUERY_STRING" -->
<!--#include virtual="/somefile.html" -->
<!--#include virtual="/another_existing_file.html" -->
<PRE>
<!--#include virtual="/cgi-bin/printenv?$QUERY_STRING" -->
</PRE>

... printenv will show QUERY_STRING to be an empty string, and
QUERY_STRING_UNESCAPED to be a disturbingly different line of garbage each time.

I'm available to test fixes on my example setup.

William Drury
Comment 1 Joshua Slive 2002-09-15 16:47:27 UTC
This is probably related to bug 12542.
Comment 2 William Drury 2002-09-30 21:36:54 UTC
This behaviour is still occurring in 2.0.42
Comment 3 André Malo 2003-05-17 20:50:19 UTC
It works for me with HEAD. Can you please test the current version with your
setup and confirm?

Thanks!
Comment 4 André Malo 2003-06-01 17:16:55 UTC
No further response. Assuming issue resolved.

Please reopen the bug if this is not the case and you can provide additional
information.

Thanks for using Apache.
Comment 5 Deomid Ryabkov 2005-05-30 18:18:39 UTC
the bug still exists in 2.0.54.

the problem is that during subrequest processing, QUERY_STRING is allocated from
subrequest's own r->pool that gets destroyed later, invalidating the table entry
in the global suprocess_env.

apr_pool_join(r->main->pool, r->pool); which, if i'm correct, is supposed to
take care of subrequest's pool lifetime, is effectively a nop when compiled
without APR_POOL_DEBUG (--enable-pool-debug).

there might be other consequences of assuming extended lifetime of subrequest's
pool, but in regard to QUERY_STRING i have made a small patch that i attach to
this bug.

having investigated this i find the issue obvious enough, but i can arrange a
testcase if requested.
Comment 6 Deomid Ryabkov 2005-05-30 18:20:43 UTC
Created attachment 15216 [details]
the patch for QUERY_STRING case
Comment 7 Joe Orton 2005-05-31 11:45:20 UTC
Hmmm, interesting.  Do you have a simple test case which reliably reproduces the
issue, I can't get the examples above to fail?

But I don't disagree with your analysis, though I'm not convinced your fix is
sufficient.  Are there other places where r->main->subprocess_env will get
populated from r->pool during the subrequest?  I think there are: e.g., 
handle_set().

The apr_pool_join() call isn't supposed to actually do anything for non-debug
builds; it just says "I guarantee that this subpool won't be destroyed before
its parent".  But in fact that guarantee is not really given: the subrequest
r->pool *is* destroyed, when ap_destroy_sub_req is called.

So a possibly more correct fix would be to just remove the call to
ap_destroy_sub_request.  Does that fix your case, also?
Comment 8 Deomid Ryabkov 2005-05-31 15:14:57 UTC
i have even shorter test case.

http://testcase12655.rbc.ru:88/?testQS - non-patched 2.0.54, QS3 should contain
garbage.

http://testcase12655.rbc.ru/?testQS - patched, should be ok.

you can browse the source here:
http://testcase12655.rbc.ru/index.txt
http://testcase12655.rbc.ru/q.txt
http://testcase12655.rbc.ru/empty.txt
(every .shtml has a corresponding .txt symlink)

i don't normally hack apache, so i can't say if there are other places to fix
pool usage in subrequests... i'm glad that i brought your attntion to this issue
so it can be fixed thoroughly :)
Comment 9 Joe Orton 2005-06-14 22:42:32 UTC
Thanks a lot, that was a great help.  I've committed a fix for this to the trunk
and will propose it for backport to 2.0.x.

http://svn.apache.org/viewcvs?rev=179763&view=rev
Comment 10 Joe Orton 2005-08-30 13:53:08 UTC
Now merged for 2.0.55.

http://svn.apache.org/viewcvs?rev=264762&view=rev
Comment 11 André Malo 2005-09-01 07:26:51 UTC
*** Bug 36452 has been marked as a duplicate of this bug. ***