jim 98/05/09 07:27:27
Modified: . STATUS src CHANGES src/include httpd.h src/main util.c Log: Submitted by: Jim Jagielski Reviewed by: Dean Gaudet, Martin Kraemer, Brian Behlendorf Disallow non-/dev/null device files to be used for ``configuration'' files (this includes htaccess, htpasswd and the mod_mime file). Also, open these using ap_pfopen to better handle timeouts. Revision Changes Path 1.393 +0 -5 apache-1.3/STATUS Index: STATUS =================================================================== RCS file: /export/home/cvs/apache-1.3/STATUS,v retrieving revision 1.392 retrieving revision 1.393 diff -u -r1.392 -r1.393 --- STATUS 1998/05/09 02:28:31 1.392 +++ STATUS 1998/05/09 14:27:22 1.393 @@ -18,11 +18,6 @@ o Jim's looked over the ap_snprintf() stuff (the changes that Dean did to make thread-safe) and they look fine. - * The DoS issue about symlinks to /dev/zero is still present. - A device checker patch had been sent to the list a while ago. - PATCH: <[EMAIL PROTECTED]> - Status: Jim +1, Brian +1, Dean +1 (ASSUMED: the API is intact) - WIN32 1.3 FINAL RELEASE SHOWSTOPPERS: * SECURITY: check if the magic con/aux/nul/etc names do anything 1.838 +6 -0 apache-1.3/src/CHANGES Index: CHANGES =================================================================== RCS file: /export/home/cvs/apache-1.3/src/CHANGES,v retrieving revision 1.837 retrieving revision 1.838 diff -u -r1.837 -r1.838 --- CHANGES 1998/05/09 03:25:40 1.837 +++ CHANGES 1998/05/09 14:27:24 1.838 @@ -1,5 +1,11 @@ Changes with Apache 1.3b7 + *) When opening "configuration" files (like httpd.conf, htaccess + and htpasswd), Apache will not allow them to be non-/dev/null + device files. This closes a DoS hole. At the same time, + we use ap_pfopen to open these files to handle timeouts. + [Jim Jagielski, Martin Kraemer] + *) Apache will now log the reason its httpd children exit if they exit due to an unexpected signal. (It requires a new porting define, SYS_SIGLIST, which if defined should point to a list of text 1.211 +10 -4 apache-1.3/src/include/httpd.h Index: httpd.h =================================================================== RCS file: /export/home/cvs/apache-1.3/src/include/httpd.h,v retrieving revision 1.210 retrieving revision 1.211 diff -u -r1.210 -r1.211 --- httpd.h 1998/05/07 12:24:24 1.210 +++ httpd.h 1998/05/09 14:27:26 1.211 @@ -905,12 +905,18 @@ typedef struct { int (*getch) (void *param); /* a getc()-like function */ void *(*getstr) (void *buf, size_t bufsiz, void *param); /* a fgets()-like function */ - int (*close) (void *param); /* a fclose()-like function */ - void *param; /* the argument passed to getc()/close()/gets() */ + int (*close) (void *param); /* a close hander function */ + void *param; /* the argument passed to getch/getstr/close */ const char *name; /* the filename / description */ unsigned line_number; /* current line number, starting at 1 */ } configfile_t; +/* Common structure that holds the file and pool for ap_pcfg_openfile */ +typedef struct { + struct pool *pool; + FILE *file; +} poolfile_t; + /* Open a configfile_t as FILE, return open configfile_t struct pointer */ API_EXPORT(configfile_t *) ap_pcfg_openfile(pool *p, const char *name); @@ -919,7 +925,7 @@ void *param, int(*getc_func)(void*), void *(*gets_func) (void *buf, size_t bufsiz, void *param), - int(*close_func)(void*)); + int(*close_func)(void *param)); /* Read one line from open configfile_t, strip LF, increase line number */ API_EXPORT(int) ap_cfg_getline(char *buf, size_t bufsize, configfile_t *cfp); @@ -928,7 +934,7 @@ API_EXPORT(int) ap_cfg_getc(configfile_t *cfp); /* Detach from open configfile_t, calling the close handler */ -API_EXPORT(int) ap_cfg_closefile(configfile_t *fp); +API_EXPORT(int) ap_cfg_closefile(configfile_t *cfp); #ifdef NEED_STRERROR char *strerror(int err); 1.115 +41 -25 apache-1.3/src/main/util.c Index: util.c =================================================================== RCS file: /export/home/cvs/apache-1.3/src/main/util.c,v retrieving revision 1.114 retrieving revision 1.115 diff -u -r1.114 -r1.115 --- util.c 1998/05/06 19:47:08 1.114 +++ util.c 1998/05/09 14:27:27 1.115 @@ -698,15 +698,39 @@ return res; } +API_EXPORT(int) ap_cfg_closefile(configfile_t *cfp) +{ +#ifdef DEBUG + ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, NULL, "Done with config file %s", fp->name); +#endif + return (cfp->close == NULL) ? 0 : cfp->close(cfp->param); +} + +static int cfg_close(void *param) +{ + poolfile_t *cfp = (poolfile_t *) param; + return (ap_pfclose(cfp->pool, cfp->file)); +} + +static int cfg_getch(void *param) +{ + poolfile_t *cfp = (poolfile_t *) param; + return (fgetc(cfp->file)); +} +static void *cfg_getstr(void *buf, size_t bufsiz, void *param) +{ + poolfile_t *cfp = (poolfile_t *) param; + return (fgets(buf, bufsiz, cfp->file)); +} + /* Open a configfile_t as FILE, return open configfile_t struct pointer */ API_EXPORT(configfile_t *) ap_pcfg_openfile(pool *p, const char *name) { configfile_t *new_cfg; + poolfile_t *new_pfile; FILE *file; -#ifdef unvoted_DISALLOW_DEVICE_ACCESS struct stat stbuf; -#endif if (name == NULL) { ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, NULL, @@ -714,7 +738,7 @@ return NULL; } - file = fopen(name, "r"); + file = ap_pfopen(p, name, "r"); #ifdef DEBUG ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, NULL, "Opening config file %s (%s)", @@ -723,24 +747,25 @@ if (file == NULL) return NULL; -#ifdef unvoted_DISALLOW_DEVICE_ACCESS if (strcmp(name, "/dev/null") != 0 && fstat(fileno(file), &stbuf) == 0 && !S_ISREG(stbuf.st_mode)) { ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, NULL, "Access to file %s denied by server: not a regular file", name); - fclose(file); + ap_pfclose(p, file); return NULL; } -#endif new_cfg = ap_palloc(p, sizeof(*new_cfg)); - new_cfg->param = file; + new_pfile = ap_palloc(p, sizeof(*new_pfile)); + new_pfile->file = file; + new_pfile->pool = p; + new_cfg->param = new_pfile; new_cfg->name = ap_pstrdup(p, name); - new_cfg->getch = (int (*)(void *)) fgetc; - new_cfg->getstr = (void *(*)(void *, size_t, void *)) fgets; - new_cfg->close = (int (*)(void *)) fclose; + new_cfg->getch = (int (*)(void *)) cfg_getch; + new_cfg->getstr = (void *(*)(void *, size_t, void *)) cfg_getstr; + new_cfg->close = (int (*)(void *)) cfg_close; new_cfg->line_number = 0; return new_cfg; } @@ -749,9 +774,9 @@ /* Allocate a configfile_t handle with user defined functions and params */ API_EXPORT(configfile_t *) ap_pcfg_open_custom(pool *p, const char *descr, void *param, - int(*getch)(void *), + int(*getch)(void *param), void *(*getstr) (void *buf, size_t bufsiz, void *param), - int(*close_func)(void *)) + int(*close_func)(void *param)) { configfile_t *new_cfg = ap_palloc(p, sizeof(*new_cfg)); #ifdef DEBUG @@ -920,15 +945,6 @@ } } -API_EXPORT(int) ap_cfg_closefile(configfile_t *fp) -{ -#ifdef DEBUG - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, NULL, "Done with config file %s", fp->name); -#endif - return (fp->close == NULL) ? 0 : fp->close(fp->param); -} - - /* Retrieve a token, spacing over it and returning a pointer to * the first non-white byte afterwards. Note that these tokens * are delimited by semis and commas; and can also be delimited @@ -1321,13 +1337,13 @@ #ifdef NEED_STRDUP char *strdup(const char *str) { - char *dup; + char *sdup; - if (!(dup = (char *) malloc(strlen(str) + 1))) + if (!(sdup = (char *) malloc(strlen(str) + 1))) return NULL; - dup = strcpy(dup, str); + sdup = strcpy(sdup, str); - return dup; + return sdup; } #endif