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