Mailing List Archive

cvs commit: apache-1.3/src/main util.c
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: <199805082150.RAA15462@devsys.jaguNET.com>
- 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