Received: by taz.hyperreal.com (8.6.12/8.6.5) id NAA26393; Fri, 7 Jun 1996 13:54:22 -0700 Received: by taz.hyperreal.com (8.6.12/8.6.5) id NAA26374; Fri, 7 Jun 1996 13:54:19 -0700 Date: Fri, 7 Jun 1996 13:54:19 -0700 From: Chuck Murcko Message-Id: <199606072054.NAA26374@taz.hyperreal.com> To: apache-cvs@hyperreal.com Subject: cvs commit: apache/src mod_include.c Sender: owner-apache-cvs@apache.org Precedence: bulk chuck 96/06/07 13:54:18 Modified: src mod_include.c Log: Reviewed by: The Group Submitted by: Howard Fear I've finally tracked down the persistant core dumps we were experiencing on Linux. Attached is a patch for 1.0.5. I'll do one for 1.1 later tonight. The problem is in mod_include.c. The macro that reads the file fcloses a pfopen'ed file. This results in closing the file twice, once during the fclose and again during the resource cleanup. This apparently sends the linux libc.5.3.x fclose into a SIGSEGV, its not smart enough to realize that the fd has already been closed. This happens for every page served through mod_include. This can be a serious problem for sites that set up the include handler for .html files. Revision Changes Path 1.8 +16 -15 apache/src/mod_include.c Index: mod_include.c =================================================================== RCS file: /export/home/cvs/apache/src/mod_include.c,v retrieving revision 1.7 retrieving revision 1.8 diff -C3 -r1.7 -r1.8 *** mod_include.c 1996/05/29 03:08:15 1.7 --- mod_include.c 1996/06/07 20:54:17 1.8 *************** *** 78,84 **** static void decodehtml(char *s); static char *get_tag(pool *p, FILE *in, char *tag, int tag_len, int dodecode); ! static int get_directive(FILE *in, char *d); /* ------------------------ Environment function -------------------------- */ --- 78,84 ---- static void decodehtml(char *s); static char *get_tag(pool *p, FILE *in, char *tag, int tag_len, int dodecode); ! static int get_directive(FILE *in, char *d, pool *p); /* ------------------------ Environment function -------------------------- */ *************** *** 114,124 **** } } ! #define GET_CHAR(f,c,r) \ { \ int i = getc(f); \ if(feof(f) || ferror(f) || (i == -1)) { \ ! fclose(f); \ return r; \ } \ c = (char)i; \ --- 114,124 ---- } } ! #define GET_CHAR(f,c,r,p) \ { \ int i = getc(f); \ if(feof(f) || ferror(f) || (i == -1)) { \ ! pfclose(p, f); \ return r; \ } \ c = (char)i; \ *************** *** 136,142 **** p=0; while(1) { ! GET_CHAR(in,c,1); if(c == str[p]) { if((++p) == l) return 0; --- 136,142 ---- p=0; while(1) { ! GET_CHAR(in,c,1,r->pool); if(c == str[p]) { if((++p) == l) return 0; *************** *** 253,267 **** n = 0; do { /* skip whitespace */ ! GET_CHAR(in,c,NULL); } while (isspace(c)); /* tags can't start with - */ if(c == '-') { ! GET_CHAR(in,c,NULL); if(c == '-') { do { ! GET_CHAR(in,c,NULL); } while (isspace(c)); if(c == '>') { strcpy(tag,"done"); --- 253,267 ---- n = 0; do { /* skip whitespace */ ! GET_CHAR(in,c,NULL,p); } while (isspace(c)); /* tags can't start with - */ if(c == '-') { ! GET_CHAR(in,c,NULL,p); if(c == '-') { do { ! GET_CHAR(in,c,NULL,p); } while (isspace(c)); if(c == '>') { strcpy(tag,"done"); *************** *** 279,295 **** } if(c == '=' || isspace(c)) break; *(t++) = tolower(c); ! GET_CHAR(in,c,NULL); } *t++ = '\0'; tag_val = t; ! while (isspace(c)) GET_CHAR(in, c, NULL); /* space before = */ if (c != '=') return NULL; do { ! GET_CHAR(in,c,NULL); /* space after = */ } while (isspace(c)); /* we should allow a 'name' as a value */ --- 279,295 ---- } if(c == '=' || isspace(c)) break; *(t++) = tolower(c); ! GET_CHAR(in,c,NULL,p); } *t++ = '\0'; tag_val = t; ! while (isspace(c)) GET_CHAR(in, c, NULL,p); /* space before = */ if (c != '=') return NULL; do { ! GET_CHAR(in,c,NULL,p); /* space after = */ } while (isspace(c)); /* we should allow a 'name' as a value */ *************** *** 297,303 **** if (c != '"' && c != '\'') return NULL; term = c; while(1) { ! GET_CHAR(in,c,NULL); if(++n == tagbuf_len) { t[tagbuf_len - 1] = '\0'; return NULL; --- 297,303 ---- if (c != '"' && c != '\'') return NULL; term = c; while(1) { ! GET_CHAR(in,c,NULL,p); if(++n == tagbuf_len) { t[tagbuf_len - 1] = '\0'; return NULL; *************** *** 310,329 **** return pstrdup (p, tag_val); } static int ! get_directive(FILE *in, char *d) { char c; /* skip initial whitespace */ while(1) { ! GET_CHAR(in,c,1); if(!isspace(c)) break; } /* now get directive */ while(1) { *d++ = tolower(c); ! GET_CHAR(in,c,1); if(isspace(c)) break; } --- 310,330 ---- return pstrdup (p, tag_val); } + /* the pool is required to allow GET_CHAR to call pfclose */ static int ! get_directive(FILE *in, char *d, pool *p) { char c; /* skip initial whitespace */ while(1) { ! GET_CHAR(in,c,1,p); if(!isspace(c)) break; } /* now get directive */ while(1) { *d++ = tolower(c); ! GET_CHAR(in,c,1,p); if(isspace(c)) break; } *************** *** 723,729 **** while(1) { if(!find_string(f,STARTING_SEQUENCE,r)) { ! if(get_directive(f,directive)) return; if(!strcmp(directive,"exec")) { if(noexec) { --- 724,730 ---- while(1) { if(!find_string(f,STARTING_SEQUENCE,r)) { ! if(get_directive(f,directive,r->pool)) return; if(!strcmp(directive,"exec")) { if(noexec) {