You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Ed Korthof <ed...@bitmechanic.com> on 1999/05/12 18:34:45 UTC

[PATCH] workaround for stat problem on RedHat 5.1/5.2

Hi --

A JServ user turned some something which appears to be a bug in RedHat's
stat.  It doesn't show up when mod_rewrite isn't enabled, and it only
affects URIs for which there is no matching file. 

On RedHat 5.1/5.2, with a file which doesn't exist, stat returns -1, and
sets errno to ENOENT. Unfortunately, it leaves r->finfo in an inconsistent
state; r->finfo.st_mode appears to contain garbage (an address of some
sort, most likely).  Sometimes it leaves r->finfo.st_mode set to a value
for which all of S_ISDIR(), S_ISLNK(), and S_ISREG() return false; 
sometimes it doesn't (this depends on the text of the program -- if that
changes, the value will change).  If all of those return false, then
check_safe_path (in http_request.c) returns 403, and that's the HTTP
return code. 

This is a problem in general for modules which answer URIs for files which
doesn't exist, and it's a problem for JServ in particular.  We advise
people to configure their Apache so that /servlets/foo is transformed into
a request for the servlet named foo ... where /servlets/ doesn't exist as
a directory.

I'm pretty sure this behavior is a bug in glibc's stat; the following
simple program demonstrates it:

----
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>

void main() {
    char *filename = "missing file";
    struct stat finfo;
    finfo.st_mode = 0;
    fprintf(stderr, "stat returned: %d\n", stat(filename, &finfo));
    fprintf(stderr, "finfo.st_mode = %d\n", finfo.st_mode);
}
----

And sample output on RedHat 5.1:
-----
stat returned: -1
38416
-----


Should mod_rewrite really be copying the URI to r->filename in
hook_uri2file?  Here's the comment which made me wonder:

329  /*
330   * Are we dealing with a file? If not, we can (hopefuly) safely assume we
331   * have a handler that doesn't require one, but for safety's sake, and so
332   * we have something find_types() can get something out of, fake one. But
333   * don't run through the directory entries.
334   */
335 
336  if (r->filename == NULL) {
337      r->filename = ap_pstrdup(r->pool, r->uri);
338      r->finfo.st_mode = 0;   /* Not really a file... */
339      r->per_dir_config = per_dir_defaults;
340
341      return OK;
342  }

Anyway, the following patch does solve the problem I'm seeing; but I'm not
sure it's very reasonable for non-linux servers.  It might make sense to
wrap it in an appropriate preprocessor define ... but I'm not sure which
versions of linux display this problem.

----
--- http_request.c      1999/04/20 23:38:44     1.147
+++ http_request.c      1999/05/12 01:59:42
@@ -267,6 +267,9 @@
         }
 #if defined(ENOENT) && defined(ENOTDIR)
         else if (errno == ENOENT || errno == ENOTDIR) {
+            if (errno == ENOENT)
+                r->finfo.st_mode = 0;
+
             last_cp = cp;
 
             while (--cp > path && *cp != '/')
-----

thanks --

Ed



Re: [PATCH] workaround for stat problem on RedHat 5.1/5.2

Posted by Ben Laurie <be...@algroup.co.uk>.
Ed Korthof wrote:
> 
> Hi --
> 
> A JServ user turned some something which appears to be a bug in RedHat's
> stat.  It doesn't show up when mod_rewrite isn't enabled, and it only
> affects URIs for which there is no matching file.
> 
> On RedHat 5.1/5.2, with a file which doesn't exist, stat returns -1, and
> sets errno to ENOENT. Unfortunately, it leaves r->finfo in an inconsistent
> state; r->finfo.st_mode appears to contain garbage (an address of some
> sort, most likely).  Sometimes it leaves r->finfo.st_mode set to a value
> for which all of S_ISDIR(), S_ISLNK(), and S_ISREG() return false;
> sometimes it doesn't (this depends on the text of the program -- if that
> changes, the value will change).  If all of those return false, then
> check_safe_path (in http_request.c) returns 403, and that's the HTTP
> return code.
> 
> This is a problem in general for modules which answer URIs for files which
> doesn't exist, and it's a problem for JServ in particular.  We advise
> people to configure their Apache so that /servlets/foo is transformed into
> a request for the servlet named foo ... where /servlets/ doesn't exist as
> a directory.
> 
> I'm pretty sure this behavior is a bug in glibc's stat; the following
> simple program demonstrates it:

It isn't a bug in stat: the bug is to continue to use finfo after stat
failed.

Cheers,

Ben.

--
http://www.apache-ssl.org/ben.html

"My grandfather once told me that there are two kinds of people: those
who work and those who take the credit. He told me to try to be in the
first group; there was less competition there."
     - Indira Gandhi

Re: [PATCH] workaround for stat problem on RedHat 5.1/5.2

Posted by Dean Gaudet <dg...@arctic.org>.
Actually I think it's bogus for us to assume anything about the contents
of struct stat after a negative stat return... I'll commit that.

Dean