diff --git a/.gitignore b/.gitignore index 9969f1d..8020585 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/httpd-2.4.6.tar.bz2 +SOURCES/httpd-2.4.12.tar.bz2 diff --git a/.httpd24-httpd.metadata b/.httpd24-httpd.metadata index d335a99..2f41236 100644 --- a/.httpd24-httpd.metadata +++ b/.httpd24-httpd.metadata @@ -1 +1 @@ -16d8ec72535ded65d035122b0d944b0e64eaa2a2 SOURCES/httpd-2.4.6.tar.bz2 +bc4681bfd63accec8d82d3cc440fbc8264ce0f17 SOURCES/httpd-2.4.12.tar.bz2 diff --git a/SOURCES/00-base.conf b/SOURCES/00-base.conf index 31d979f..9ec0adf 100644 --- a/SOURCES/00-base.conf +++ b/SOURCES/00-base.conf @@ -45,6 +45,7 @@ LoadModule mime_module modules/mod_mime.so LoadModule negotiation_module modules/mod_negotiation.so LoadModule remoteip_module modules/mod_remoteip.so LoadModule reqtimeout_module modules/mod_reqtimeout.so +LoadModule request_module modules/mod_request.so LoadModule rewrite_module modules/mod_rewrite.so LoadModule setenvif_module modules/mod_setenvif.so LoadModule slotmem_plain_module modules/mod_slotmem_plain.so @@ -61,17 +62,3 @@ LoadModule userdir_module modules/mod_userdir.so LoadModule version_module modules/mod_version.so LoadModule vhost_alias_module modules/mod_vhost_alias.so -#LoadModule buffer_module modules/mod_buffer.so -#LoadModule watchdog_module modules/mod_watchdog.so -#LoadModule heartbeat_module modules/mod_heartbeat.so -#LoadModule heartmonitor_module modules/mod_heartmonitor.so -#LoadModule usertrack_module modules/mod_usertrack.so -#LoadModule dialup_module modules/mod_dialup.so -#LoadModule charset_lite_module modules/mod_charset_lite.so -#LoadModule log_debug_module modules/mod_log_debug.so -#LoadModule ratelimit_module modules/mod_ratelimit.so -#LoadModule reflector_module modules/mod_reflector.so -#LoadModule request_module modules/mod_request.so -#LoadModule sed_module modules/mod_sed.so -#LoadModule speling_module modules/mod_speling.so - diff --git a/SOURCES/00-optional.conf b/SOURCES/00-optional.conf new file mode 100644 index 0000000..b8c43c6 --- /dev/null +++ b/SOURCES/00-optional.conf @@ -0,0 +1,17 @@ +# +# This file lists modules included with the Apache HTTP Server +# which are not enabled by default. +# + +#LoadModule buffer_module modules/mod_buffer.so +#LoadModule watchdog_module modules/mod_watchdog.so +#LoadModule heartbeat_module modules/mod_heartbeat.so +#LoadModule heartmonitor_module modules/mod_heartmonitor.so +#LoadModule usertrack_module modules/mod_usertrack.so +#LoadModule dialup_module modules/mod_dialup.so +#LoadModule charset_lite_module modules/mod_charset_lite.so +#LoadModule log_debug_module modules/mod_log_debug.so +#LoadModule ratelimit_module modules/mod_ratelimit.so +#LoadModule reflector_module modules/mod_reflector.so +#LoadModule sed_module modules/mod_sed.so +#LoadModule speling_module modules/mod_speling.so diff --git a/SOURCES/httpd-2.4.12-skiplist.patch b/SOURCES/httpd-2.4.12-skiplist.patch new file mode 100644 index 0000000..7339d33 --- /dev/null +++ b/SOURCES/httpd-2.4.12-skiplist.patch @@ -0,0 +1,946 @@ +diff --git a/server/mpm/event/config.m4 b/server/mpm/event/config.m4 +index c891c75..351f1ac 100644 +--- a/server/mpm/event/config.m4 ++++ b/server/mpm/event/config.m4 +@@ -7,8 +7,6 @@ elif test $have_threaded_sig_graceful != yes; then + AC_MSG_RESULT(no - SIG_GRACEFUL cannot be used with a threaded MPM) + elif test $ac_cv_have_threadsafe_pollset != yes; then + AC_MSG_RESULT(no - APR_POLLSET_THREADSAFE is not supported) +-elif test $apr_has_skiplist != yes; then +- AC_MSG_RESULT(no - APR skiplist is not available, need APR 1.5.x or later) + else + AC_MSG_RESULT(yes) + APACHE_MPM_SUPPORTED(event, yes, yes) +diff --git a/server/mpm/event/config3.m4 b/server/mpm/event/config3.m4 +index 8aa1631..fa9b8af 100644 +--- a/server/mpm/event/config3.m4 ++++ b/server/mpm/event/config3.m4 +@@ -2,6 +2,6 @@ dnl ## XXX - Need a more thorough check of the proper flags to use + + APACHE_SUBST(MOD_MPM_EVENT_LDADD) + +-APACHE_MPM_MODULE(event, $enable_mpm_event, event.lo fdqueue.lo,[ ++APACHE_MPM_MODULE(event, $enable_mpm_event, event.lo fdqueue.lo apr_skiplist.lo,[ + AC_CHECK_FUNCS(pthread_kill) + ], , [\$(MOD_MPM_EVENT_LDADD)]) +diff --git a/server/mpm/event/apr_skiplist.c b/server/mpm/event/apr_skiplist.c +new file mode 100644 +index 0000000..effcf60 +--- /dev/null ++++ b/server/mpm/event/apr_skiplist.c +@@ -0,0 +1,650 @@ ++/* Licensed to the Apache Software Foundation (ASF) under one or more ++ * contributor license agreements. See the NOTICE file distributed with ++ * this work for additional information regarding copyright ownership. ++ * The ASF licenses this file to You under the Apache License, Version 2.0 ++ * (the "License"); you may not use this file except in compliance with ++ * the License. You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ */ ++ ++/* ++ * Modified to use APR and APR pools. ++ * TODO: Is malloc() better? Will long running skiplists grow too much? ++ * Keep the skiplist_alloc() and skiplist_free() until we know ++ * Yeah, if using pools it means some bogus cycles for checks ++ * (and an useless function call for skiplist_free) which we ++ * can removed if/when needed. ++ */ ++ ++#include "apr_skiplist.h" ++ ++struct apr_skiplist { ++ apr_skiplist_compare compare; ++ apr_skiplist_compare comparek; ++ int height; ++ int preheight; ++ int size; ++ apr_skiplistnode *top; ++ apr_skiplistnode *bottom; ++ /* These two are needed for appending */ ++ apr_skiplistnode *topend; ++ apr_skiplistnode *bottomend; ++ apr_skiplist *index; ++ apr_array_header_t *memlist; ++ apr_pool_t *pool; ++}; ++ ++struct apr_skiplistnode { ++ void *data; ++ apr_skiplistnode *next; ++ apr_skiplistnode *prev; ++ apr_skiplistnode *down; ++ apr_skiplistnode *up; ++ apr_skiplistnode *previndex; ++ apr_skiplistnode *nextindex; ++ apr_skiplist *sl; ++}; ++ ++#ifndef MIN ++#define MIN(a,b) ((a 31) { /* Num bits in return of rand() */ ++ ph = 0; ++ randseq = (apr_uint32_t) rand(); ++ } ++ ph++; ++ return ((randseq & (1 << (ph - 1))) >> (ph - 1)); ++} ++ ++typedef struct { ++ size_t size; ++ apr_array_header_t *list; ++} memlist_t; ++ ++typedef struct { ++ void *ptr; ++ char inuse; ++} chunk_t; ++ ++APR_DECLARE(void *) apr_skiplist_alloc(apr_skiplist *sl, size_t size) ++{ ++ if (sl->pool) { ++ void *ptr; ++ int found_size = 0; ++ int i; ++ chunk_t *newchunk; ++ memlist_t *memlist = (memlist_t *)sl->memlist->elts; ++ for (i = 0; i < sl->memlist->nelts; i++) { ++ if (memlist->size == size) { ++ int j; ++ chunk_t *chunk = (chunk_t *)memlist->list->elts; ++ found_size = 1; ++ for (j = 0; j < memlist->list->nelts; j++) { ++ if (!chunk->inuse) { ++ chunk->inuse = 1; ++ return chunk->ptr; ++ } ++ chunk++; ++ } ++ break; /* no free of this size; punt */ ++ } ++ memlist++; ++ } ++ /* no free chunks */ ++ ptr = apr_pcalloc(sl->pool, size); ++ if (!ptr) { ++ return ptr; ++ } ++ /* ++ * is this a new sized chunk? If so, we need to create a new ++ * array of them. Otherwise, re-use what we already have. ++ */ ++ if (!found_size) { ++ memlist = apr_array_push(sl->memlist); ++ memlist->size = size; ++ memlist->list = apr_array_make(sl->pool, 20, sizeof(chunk_t)); ++ } ++ newchunk = apr_array_push(memlist->list); ++ newchunk->ptr = ptr; ++ newchunk->inuse = 1; ++ return ptr; ++ } ++ else { ++ return calloc(1, size); ++ } ++} ++ ++APR_DECLARE(void) apr_skiplist_free(apr_skiplist *sl, void *mem) ++{ ++ if (!sl->pool) { ++ free(mem); ++ } ++ else { ++ int i; ++ memlist_t *memlist = (memlist_t *)sl->memlist->elts; ++ for (i = 0; i < sl->memlist->nelts; i++) { ++ int j; ++ chunk_t *chunk = (chunk_t *)memlist->list->elts; ++ for (j = 0; j < memlist->list->nelts; j++) { ++ if (chunk->ptr == mem) { ++ chunk->inuse = 0; ++ return; ++ } ++ chunk++; ++ } ++ memlist++; ++ } ++ } ++} ++ ++static apr_status_t skiplisti_init(apr_skiplist **s, apr_pool_t *p) ++{ ++ apr_skiplist *sl; ++ if (p) { ++ sl = apr_pcalloc(p, sizeof(apr_skiplist)); ++ sl->memlist = apr_array_make(p, 20, sizeof(memlist_t)); ++ } ++ else { ++ sl = calloc(1, sizeof(apr_skiplist)); ++ } ++#if 0 ++ sl->compare = (apr_skiplist_compare) NULL; ++ sl->comparek = (apr_skiplist_compare) NULL; ++ sl->height = 0; ++ sl->preheight = 0; ++ sl->size = 0; ++ sl->top = NULL; ++ sl->bottom = NULL; ++ sl->index = NULL; ++#endif ++ sl->pool = p; ++ *s = sl; ++ return APR_SUCCESS; ++} ++ ++static int indexing_comp(void *a, void *b) ++{ ++ void *ac = (void *) (((apr_skiplist *) a)->compare); ++ void *bc = (void *) (((apr_skiplist *) b)->compare); ++ return ((ac < bc) ? -1 : ((ac > bc) ? 1 : 0)); ++} ++ ++static int indexing_compk(void *ac, void *b) ++{ ++ void *bc = (void *) (((apr_skiplist *) b)->compare); ++ return ((ac < bc) ? -1 : ((ac > bc) ? 1 : 0)); ++} ++ ++APR_DECLARE(apr_status_t) apr_skiplist_init(apr_skiplist **s, apr_pool_t *p) ++{ ++ apr_skiplist *sl; ++ skiplisti_init(s, p); ++ sl = *s; ++ skiplisti_init(&(sl->index), p); ++ apr_skiplist_set_compare(sl->index, indexing_comp, indexing_compk); ++ return APR_SUCCESS; ++} ++ ++APR_DECLARE(void) apr_skiplist_set_compare(apr_skiplist *sl, ++ apr_skiplist_compare comp, ++ apr_skiplist_compare compk) ++{ ++ if (sl->compare && sl->comparek) { ++ apr_skiplist_add_index(sl, comp, compk); ++ } ++ else { ++ sl->compare = comp; ++ sl->comparek = compk; ++ } ++} ++ ++APR_DECLARE(void) apr_skiplist_add_index(apr_skiplist *sl, ++ apr_skiplist_compare comp, ++ apr_skiplist_compare compk) ++{ ++ apr_skiplistnode *m; ++ apr_skiplist *ni; ++ int icount = 0; ++ apr_skiplist_find(sl->index, (void *)comp, &m); ++ if (m) { ++ return; /* Index already there! */ ++ } ++ skiplisti_init(&ni, sl->pool); ++ apr_skiplist_set_compare(ni, comp, compk); ++ /* Build the new index... This can be expensive! */ ++ m = apr_skiplist_insert(sl->index, ni); ++ while (m->prev) { ++ m = m->prev; ++ icount++; ++ } ++ for (m = apr_skiplist_getlist(sl); m; apr_skiplist_next(sl, &m)) { ++ int j = icount - 1; ++ apr_skiplistnode *nsln; ++ nsln = apr_skiplist_insert(ni, m->data); ++ /* skip from main index down list */ ++ while (j > 0) { ++ m = m->nextindex; ++ j--; ++ } ++ /* insert this node in the indexlist after m */ ++ nsln->nextindex = m->nextindex; ++ if (m->nextindex) { ++ m->nextindex->previndex = nsln; ++ } ++ nsln->previndex = m; ++ m->nextindex = nsln; ++ } ++} ++ ++APR_DECLARE(apr_skiplistnode *) apr_skiplist_getlist(apr_skiplist *sl) ++{ ++ if (!sl->bottom) { ++ return NULL; ++ } ++ return sl->bottom->next; ++} ++ ++APR_DECLARE(void *) apr_skiplist_find(apr_skiplist *sl, void *data, apr_skiplistnode **iter) ++{ ++ void *ret; ++ apr_skiplistnode *aiter; ++ if (!sl->compare) { ++ return 0; ++ } ++ if (iter) { ++ ret = apr_skiplist_find_compare(sl, data, iter, sl->compare); ++ } ++ else { ++ ret = apr_skiplist_find_compare(sl, data, &aiter, sl->compare); ++ } ++ return ret; ++} ++ ++static int skiplisti_find_compare(apr_skiplist *sl, void *data, ++ apr_skiplistnode **ret, ++ apr_skiplist_compare comp) ++{ ++ apr_skiplistnode *m = NULL; ++ int count = 0; ++ m = sl->top; ++ while (m) { ++ int compared; ++ compared = (m->next) ? comp(data, m->next->data) : -1; ++ if (compared == 0) { ++ m = m->next; ++ while (m->down) { ++ m = m->down; ++ } ++ *ret = m; ++ return count; ++ } ++ if ((m->next == NULL) || (compared < 0)) { ++ m = m->down; ++ count++; ++ } ++ else { ++ m = m->next; ++ count++; ++ } ++ } ++ *ret = NULL; ++ return count; ++} ++ ++APR_DECLARE(void *) apr_skiplist_find_compare(apr_skiplist *sli, void *data, ++ apr_skiplistnode **iter, ++ apr_skiplist_compare comp) ++{ ++ apr_skiplistnode *m = NULL; ++ apr_skiplist *sl; ++ if (comp == sli->compare || !sli->index) { ++ sl = sli; ++ } ++ else { ++ apr_skiplist_find(sli->index, (void *)comp, &m); ++ sl = (apr_skiplist *) m->data; ++ } ++ skiplisti_find_compare(sl, data, iter, sl->comparek); ++ return (iter && *iter) ? ((*iter)->data) : NULL; ++} ++ ++ ++APR_DECLARE(void *) apr_skiplist_next(apr_skiplist *sl, apr_skiplistnode **iter) ++{ ++ if (!*iter) { ++ return NULL; ++ } ++ *iter = (*iter)->next; ++ return (*iter) ? ((*iter)->data) : NULL; ++} ++ ++APR_DECLARE(void *) apr_skiplist_previous(apr_skiplist *sl, apr_skiplistnode **iter) ++{ ++ if (!*iter) { ++ return NULL; ++ } ++ *iter = (*iter)->prev; ++ return (*iter) ? ((*iter)->data) : NULL; ++} ++ ++APR_DECLARE(apr_skiplistnode *) apr_skiplist_insert(apr_skiplist *sl, void *data) ++{ ++ if (!sl->compare) { ++ return 0; ++ } ++ return apr_skiplist_insert_compare(sl, data, sl->compare); ++} ++ ++APR_DECLARE(apr_skiplistnode *) apr_skiplist_insert_compare(apr_skiplist *sl, void *data, ++ apr_skiplist_compare comp) ++{ ++ apr_skiplistnode *m, *p, *tmp, *ret = NULL, **stack; ++ int nh = 1, ch, stacki; ++ if (!sl->top) { ++ sl->height = 1; ++ sl->topend = sl->bottomend = sl->top = sl->bottom = ++ (apr_skiplistnode *)apr_skiplist_alloc(sl, sizeof(apr_skiplistnode)); ++#if 0 ++ sl->top->next = (apr_skiplistnode *)NULL; ++ sl->top->data = (apr_skiplistnode *)NULL; ++ sl->top->prev = (apr_skiplistnode *)NULL; ++ sl->top->up = (apr_skiplistnode *)NULL; ++ sl->top->down = (apr_skiplistnode *)NULL; ++ sl->top->nextindex = (apr_skiplistnode *)NULL; ++ sl->top->previndex = (apr_skiplistnode *)NULL; ++#endif ++ sl->top->sl = sl; ++ } ++ if (sl->preheight) { ++ while (nh < sl->preheight && get_b_rand()) { ++ nh++; ++ } ++ } ++ else { ++ while (nh <= sl->height && get_b_rand()) { ++ nh++; ++ } ++ } ++ /* Now we have the new height at which we wish to insert our new node */ ++ /* ++ * Let us make sure that our tree is a least that tall (grow if ++ * necessary) ++ */ ++ for (; sl->height < nh; sl->height++) { ++ sl->top->up = ++ (apr_skiplistnode *)apr_skiplist_alloc(sl, sizeof(apr_skiplistnode)); ++ sl->top->up->down = sl->top; ++ sl->top = sl->topend = sl->top->up; ++#if 0 ++ sl->top->prev = sl->top->next = sl->top->nextindex = ++ sl->top->previndex = sl->top->up = NULL; ++ sl->top->data = NULL; ++#endif ++ sl->top->sl = sl; ++ } ++ ch = sl->height; ++ /* Find the node (or node after which we would insert) */ ++ /* Keep a stack to pop back through for insertion */ ++ /* malloc() is OK since we free the temp stack */ ++ m = sl->top; ++ stack = (apr_skiplistnode **)malloc(sizeof(apr_skiplistnode *) * (nh)); ++ stacki = 0; ++ while (m) { ++ int compared = -1; ++ if (m->next) { ++ compared = comp(data, m->next->data); ++ } ++ if (compared == 0) { ++ free(stack); /* OK. was malloc'ed */ ++ return 0; ++ } ++ if ((m->next == NULL) || (compared < 0)) { ++ if (ch <= nh) { ++ /* push on stack */ ++ stack[stacki++] = m; ++ } ++ m = m->down; ++ ch--; ++ } ++ else { ++ m = m->next; ++ } ++ } ++ /* Pop the stack and insert nodes */ ++ p = NULL; ++ for (; stacki > 0; stacki--) { ++ m = stack[stacki - 1]; ++ tmp = (apr_skiplistnode *)apr_skiplist_alloc(sl, sizeof(apr_skiplistnode)); ++ tmp->next = m->next; ++ if (m->next) { ++ m->next->prev = tmp; ++ } ++ tmp->prev = m; ++ tmp->up = NULL; ++ tmp->nextindex = tmp->previndex = NULL; ++ tmp->down = p; ++ if (p) { ++ p->up = tmp; ++ } ++ tmp->data = data; ++ tmp->sl = sl; ++ m->next = tmp; ++ /* This sets ret to the bottom-most node we are inserting */ ++ if (!p) { ++ ret = tmp; ++ sl->size++; /* this seems to go here got each element to be counted */ ++ } ++ p = tmp; ++ } ++ free(stack); /* OK. was malloc'ed */ ++ if (sl->index != NULL) { ++ /* ++ * this is a external insertion, we must insert into each index as ++ * well ++ */ ++ apr_skiplistnode *ni, *li; ++ li = ret; ++ for (p = apr_skiplist_getlist(sl->index); p; apr_skiplist_next(sl->index, &p)) { ++ ni = apr_skiplist_insert((apr_skiplist *) p->data, ret->data); ++ li->nextindex = ni; ++ ni->previndex = li; ++ li = ni; ++ } ++ } ++ else { ++ /* sl->size++; */ ++ } ++ sl->size++; ++ return ret; ++} ++ ++APR_DECLARE(int) apr_skiplist_remove(apr_skiplist *sl, void *data, apr_skiplist_freefunc myfree) ++{ ++ if (!sl->compare) { ++ return 0; ++ } ++ return apr_skiplist_remove_compare(sl, data, myfree, sl->comparek); ++} ++ ++#if 0 ++void skiplist_print_struct(apr_skiplist * sl, char *prefix) ++{ ++ apr_skiplistnode *p, *q; ++ fprintf(stderr, "Skiplist Structure (height: %d)\n", sl->height); ++ p = sl->bottom; ++ while (p) { ++ q = p; ++ fprintf(stderr, prefix); ++ while (q) { ++ fprintf(stderr, "%p ", q->data); ++ q = q->up; ++ } ++ fprintf(stderr, "\n"); ++ p = p->next; ++ } ++} ++#endif ++ ++static int skiplisti_remove(apr_skiplist *sl, apr_skiplistnode *m, apr_skiplist_freefunc myfree) ++{ ++ apr_skiplistnode *p; ++ if (!m) { ++ return 0; ++ } ++ if (m->nextindex) { ++ skiplisti_remove(m->nextindex->sl, m->nextindex, NULL); ++ } ++ while (m->up) { ++ m = m->up; ++ } ++ while (m) { ++ p = m; ++ p->prev->next = p->next;/* take me out of the list */ ++ if (p->next) { ++ p->next->prev = p->prev; /* take me out of the list */ ++ } ++ m = m->down; ++ /* This only frees the actual data in the bottom one */ ++ if (!m && myfree && p->data) { ++ myfree(p->data); ++ } ++ apr_skiplist_free(sl, p); ++ } ++ sl->size--; ++ while (sl->top && sl->top->next == NULL) { ++ /* While the row is empty and we are not on the bottom row */ ++ p = sl->top; ++ sl->top = sl->top->down;/* Move top down one */ ++ if (sl->top) { ++ sl->top->up = NULL; /* Make it think its the top */ ++ } ++ apr_skiplist_free(sl, p); ++ sl->height--; ++ } ++ if (!sl->top) { ++ sl->bottom = NULL; ++ } ++ return sl->height; /* return 1; ?? */ ++} ++ ++APR_DECLARE(int) apr_skiplist_remove_compare(apr_skiplist *sli, ++ void *data, ++ apr_skiplist_freefunc myfree, apr_skiplist_compare comp) ++{ ++ apr_skiplistnode *m; ++ apr_skiplist *sl; ++ if (comp == sli->comparek || !sli->index) { ++ sl = sli; ++ } ++ else { ++ apr_skiplist_find(sli->index, (void *)comp, &m); ++ sl = (apr_skiplist *) m->data; ++ } ++ skiplisti_find_compare(sl, data, &m, comp); ++ if (!m) { ++ return 0; ++ } ++ while (m->previndex) { ++ m = m->previndex; ++ } ++ return skiplisti_remove(sl, m, myfree); ++} ++ ++APR_DECLARE(void) apr_skiplist_remove_all(apr_skiplist *sl, apr_skiplist_freefunc myfree) ++{ ++ /* ++ * This must remove even the place holder nodes (bottom though top) ++ * because we specify in the API that one can free the Skiplist after ++ * making this call without memory leaks ++ */ ++ apr_skiplistnode *m, *p, *u; ++ m = sl->bottom; ++ while (m) { ++ p = m->next; ++ if (p && myfree && p->data) ++ myfree(p->data); ++ while (m) { ++ u = m->up; ++ apr_skiplist_free(sl, p); ++ m = u; ++ } ++ m = p; ++ } ++ sl->top = sl->bottom = NULL; ++ sl->height = 0; ++ sl->size = 0; ++} ++ ++APR_DECLARE(void *) apr_skiplist_pop(apr_skiplist *a, apr_skiplist_freefunc myfree) ++{ ++ apr_skiplistnode *sln; ++ void *data = NULL; ++ sln = apr_skiplist_getlist(a); ++ if (sln) { ++ data = sln->data; ++ skiplisti_remove(a, sln, myfree); ++ } ++ return data; ++} ++ ++APR_DECLARE(void *) apr_skiplist_peek(apr_skiplist *a) ++{ ++ apr_skiplistnode *sln; ++ sln = apr_skiplist_getlist(a); ++ if (sln) { ++ return sln->data; ++ } ++ return NULL; ++} ++ ++static void skiplisti_destroy(void *vsl) ++{ ++ apr_skiplist_destroy((apr_skiplist *) vsl, NULL); ++ apr_skiplist_free((apr_skiplist *) vsl, vsl); ++} ++ ++APR_DECLARE(void) apr_skiplist_destroy(apr_skiplist *sl, apr_skiplist_freefunc myfree) ++{ ++ while (apr_skiplist_pop(sl->index, skiplisti_destroy) != NULL) ++ ; ++ apr_skiplist_remove_all(sl, myfree); ++} ++ ++APR_DECLARE(apr_skiplist *) apr_skiplist_merge(apr_skiplist *sl1, apr_skiplist *sl2) ++{ ++ /* Check integrity! */ ++ apr_skiplist temp; ++ struct apr_skiplistnode *b2; ++ if (sl1->bottomend == NULL || sl1->bottomend->prev == NULL) { ++ apr_skiplist_remove_all(sl1, NULL); ++ temp = *sl1; ++ *sl1 = *sl2; ++ *sl2 = temp; ++ /* swap them so that sl2 can be freed normally upon return. */ ++ return sl1; ++ } ++ if(sl2->bottom == NULL || sl2->bottom->next == NULL) { ++ apr_skiplist_remove_all(sl2, NULL); ++ return sl1; ++ } ++ /* This is what makes it brute force... Just insert :/ */ ++ b2 = apr_skiplist_getlist(sl2); ++ while (b2) { ++ apr_skiplist_insert(sl1, b2->data); ++ apr_skiplist_next(sl2, &b2); ++ } ++ apr_skiplist_remove_all(sl2, NULL); ++ return sl1; ++} +diff --git a/server/mpm/event/apr_skiplist.h b/server/mpm/event/apr_skiplist.h +new file mode 100644 +index 0000000..bc17efd +--- /dev/null ++++ b/server/mpm/event/apr_skiplist.h +@@ -0,0 +1,259 @@ ++/* Licensed to the Apache Software Foundation (ASF) under one or more ++ * contributor license agreements. See the NOTICE file distributed with ++ * this work for additional information regarding copyright ownership. ++ * The ASF licenses this file to You under the Apache License, Version 2.0 ++ * (the "License"); you may not use this file except in compliance with ++ * the License. You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ */ ++ ++#ifndef APR_SKIPLIST_H ++#define APR_SKIPLIST_H ++/** ++ * @file apr_skiplist.h ++ * @brief APR skip list implementation ++ */ ++ ++#include "apr.h" ++#include "apr_portable.h" ++#include ++ ++#ifdef __cplusplus ++extern "C" { ++#endif /* __cplusplus */ ++ ++/** ++ * @defgroup apr_skiplist Skip list implementation ++ * Refer to http://en.wikipedia.org/wiki/Skip_list for information ++ * about the purpose of and ideas behind skip lists. ++ * @ingroup APR ++ * @{ ++ */ ++ ++/** ++ * apr_skiplist_compare is the function type that must be implemented ++ * per object type that is used in a skip list for comparisons to maintain ++ * order ++ * */ ++typedef int (*apr_skiplist_compare) (void *, void *); ++ ++/** ++ * apr_skiplist_freefunc is the function type that must be implemented ++ * to handle elements as they are removed from a skip list. ++ */ ++typedef void (*apr_skiplist_freefunc) (void *); ++ ++/** Opaque structure used to represent the skip list */ ++struct apr_skiplist; ++/** Opaque structure used to represent the skip list */ ++typedef struct apr_skiplist apr_skiplist; ++ ++/** ++ * Opaque structure used to represent abstract nodes in the skip list ++ * (an abstraction above the raw elements which are collected in the ++ * skip list). ++ */ ++struct apr_skiplistnode; ++/** Opaque structure */ ++typedef struct apr_skiplistnode apr_skiplistnode; ++ ++/** ++ * Allocate memory using the same mechanism as the skip list. ++ * @param sl The skip list ++ * @param size The amount to allocate ++ * @remark If a pool was provided to apr_skiplist_init(), memory will ++ * be allocated from the pool or from a free list maintained with ++ * the skip list. Otherwise, memory will be allocated using the ++ * C standard library heap functions. ++ */ ++APR_DECLARE(void *) apr_skiplist_alloc(apr_skiplist *sl, size_t size); ++ ++/** ++ * Free memory using the same mechanism as the skip list. ++ * @param sl The skip list ++ * @param mem The object to free ++ * @remark If a pool was provided to apr_skiplist_init(), memory will ++ * be added to a free list maintained with the skip list and be available ++ * to operations on the skip list or to other calls to apr_skiplist_alloc(). ++ * Otherwise, memory will be freed using the C standard library heap ++ * functions. ++ */ ++APR_DECLARE(void) apr_skiplist_free(apr_skiplist *sl, void *mem); ++ ++/** ++ * Allocate a new skip list ++ * @param sl The pointer in which to return the newly created skip list ++ * @param p The pool from which to allocate the skip list (optional). ++ * @remark Unlike most APR functions, a pool is optional. If no pool ++ * is provided, the C standard library heap functions will be used instead. ++ */ ++APR_DECLARE(apr_status_t) apr_skiplist_init(apr_skiplist **sl, apr_pool_t *p); ++ ++/** ++ * Set the comparison functions to be used for searching the skip list. ++ * @param sl The skip list ++ * @param XXX1 FIXME ++ * @param XXX2 FIXME ++ * ++ * @remark If existing comparison functions are being replaced, the index ++ * will be replaced during this call. That is a potentially expensive ++ * operation. ++ */ ++APR_DECLARE(void) apr_skiplist_set_compare(apr_skiplist *sl, apr_skiplist_compare XXX1, ++ apr_skiplist_compare XXX2); ++ ++/** ++ * Set the indexing functions to the specified comparison functions and ++ * rebuild the index. ++ * @param sl The skip list ++ * @param XXX1 FIXME ++ * @param XXX2 FIXME ++ * ++ * @remark If an index already exists, it will not be replaced and the ++ * comparison functions will not be changed. ++ */ ++APR_DECLARE(void) apr_skiplist_add_index(apr_skiplist *sl, apr_skiplist_compare XXX1, ++ apr_skiplist_compare XXX2); ++ ++/** ++ * Return the list maintained by the skip list abstraction. ++ * @param sl The skip list ++ */ ++APR_DECLARE(apr_skiplistnode *) apr_skiplist_getlist(apr_skiplist *sl); ++ ++/** ++ * Return the next matching element in the skip list using the specified ++ * comparison function. ++ * @param sl The skip list ++ * @param data The value to search for ++ * @param iter A pointer to the returned skip list node representing the element ++ * found ++ * @param func The comparison function to use ++ */ ++APR_DECLARE(void *) apr_skiplist_find_compare(apr_skiplist *sl, ++ void *data, ++ apr_skiplistnode **iter, ++ apr_skiplist_compare func); ++ ++/** ++ * Return the next matching element in the skip list using the current comparison ++ * function. ++ * @param sl The skip list ++ * @param data The value to search for ++ * @param iter A pointer to the returned skip list node representing the element ++ * found ++ */ ++APR_DECLARE(void *) apr_skiplist_find(apr_skiplist *sl, void *data, apr_skiplistnode **iter); ++ ++/** ++ * Return the next element in the skip list. ++ * @param sl The skip list ++ * @param iter On entry, a pointer to the skip list node to start with; on return, ++ * a pointer to the skip list node representing the element returned ++ * @remark If iter points to a NULL value on entry, NULL will be returned. ++ */ ++APR_DECLARE(void *) apr_skiplist_next(apr_skiplist *sl, apr_skiplistnode **iter); ++ ++/** ++ * Return the previous element in the skip list. ++ * @param sl The skip list ++ * @param iter On entry, a pointer to the skip list node to start with; on return, ++ * a pointer to the skip list node representing the element returned ++ * @remark If iter points to a NULL value on entry, NULL will be returned. ++ */ ++APR_DECLARE(void *) apr_skiplist_previous(apr_skiplist *sl, apr_skiplistnode **iter); ++ ++/** ++ * Insert an element into the skip list using the specified comparison function. ++ * @param sl The skip list ++ * @param data The element to insert ++ * @param comp The comparison function to use for placement into the skip list ++ */ ++APR_DECLARE(apr_skiplistnode *) apr_skiplist_insert_compare(apr_skiplist *sl, ++ void *data, apr_skiplist_compare comp); ++ ++/** ++ * Insert an element into the skip list using the existing comparison function. ++ * @param sl The skip list ++ * @param data The element to insert ++ * @remark If no comparison function has been set for the skip list, the element ++ * will not be inserted and NULL will be returned. ++ */ ++APR_DECLARE(apr_skiplistnode *) apr_skiplist_insert(apr_skiplist* sl, void *data); ++ ++/** ++ * Remove an element from the skip list using the specified comparison function for ++ * locating the element. ++ * @param sl The skip list ++ * @param data The element to remove ++ * @param myfree A function to be called for each removed element ++ * @param comp The comparison function to use for placement into the skip list ++ * @remark If the element is not found, 0 will be returned. Otherwise, the heightXXX ++ * will be returned. ++ */ ++APR_DECLARE(int) apr_skiplist_remove_compare(apr_skiplist *sl, void *data, ++ apr_skiplist_freefunc myfree, apr_skiplist_compare comp); ++ ++/** ++ * Remove an element from the skip list using the existing comparison function for ++ * locating the element. ++ * @param sl The skip list ++ * @param data The element to remove ++ * @param myfree A function to be called for each removed element ++ * @remark If the element is not found, 0 will be returned. Otherwise, the heightXXX ++ * will be returned. ++ * @remark If no comparison function has been set for the skip list, the element ++ * will not be removed and 0 will be returned. ++ */ ++APR_DECLARE(int) apr_skiplist_remove(apr_skiplist *sl, void *data, apr_skiplist_freefunc myfree); ++ ++/** ++ * Remove all elements from the skip list. ++ * @param sl The skip list ++ * @param myfree A function to be called for each removed element ++ */ ++APR_DECLARE(void) apr_skiplist_remove_all(apr_skiplist *sl, apr_skiplist_freefunc myfree); ++ ++/** ++ * Remove each element from the skip list. ++ * @param sl The skip list ++ * @param myfree A function to be called for each removed element ++ */ ++APR_DECLARE(void) apr_skiplist_destroy(apr_skiplist *sl, apr_skiplist_freefunc myfree); ++ ++/** ++ * Return the first element in the skip list, leaving the element in the skip list. ++ * @param sl The skip list ++ * @param myfree A function to be called for the removed element ++ * @remark NULL will be returned if there are no elements ++ */ ++APR_DECLARE(void *) apr_skiplist_pop(apr_skiplist *sl, apr_skiplist_freefunc myfree); ++ ++/** ++ * Return the first element in the skip list, leaving the element in the skip list. ++ * @param sl The skip list ++ * @remark NULL will be returned if there are no elements ++ */ ++APR_DECLARE(void *) apr_skiplist_peek(apr_skiplist *sl); ++ ++/** ++ * Merge two skip lists. XXX SEMANTICS ++ * @param sl1 One of two skip lists to be merged ++ * @param sl2 The other of two skip lists to be merged ++ */ ++APR_DECLARE(apr_skiplist *) apr_skiplist_merge(apr_skiplist *sl1, apr_skiplist *sl2); ++ ++/** @} */ ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* ! APR_SKIPLIST_H */ diff --git a/SOURCES/httpd-2.4.3-apxs.patch b/SOURCES/httpd-2.4.3-apxs.patch index f4d2a87..7016dec 100644 --- a/SOURCES/httpd-2.4.3-apxs.patch +++ b/SOURCES/httpd-2.4.3-apxs.patch @@ -1,5 +1,7 @@ ---- httpd-2.4.3/support/apxs.in.apxs -+++ httpd-2.4.3/support/apxs.in +diff --git a/support/apxs.in b/support/apxs.in +index ad1287f..efcfcf6 100644 +--- a/support/apxs.in ++++ b/support/apxs.in @@ -25,7 +25,18 @@ package apxs; my %config_vars = (); @@ -53,4 +55,4 @@ +include %LIBDIR%/httpd/build/special.mk # the used tools - APXS=apxs + APACHECTL=apachectl diff --git a/SOURCES/httpd-2.4.3-sslsninotreq.patch b/SOURCES/httpd-2.4.3-sslsninotreq.patch deleted file mode 100644 index 6e158c6..0000000 --- a/SOURCES/httpd-2.4.3-sslsninotreq.patch +++ /dev/null @@ -1,83 +0,0 @@ -diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c -index 15993f1..53ed6f1 100644 ---- a/modules/ssl/ssl_engine_config.c -+++ b/modules/ssl/ssl_engine_config.c -@@ -55,6 +55,7 @@ SSLModConfigRec *ssl_config_global_create(server_rec *s) - mc = (SSLModConfigRec *)apr_palloc(pool, sizeof(*mc)); - mc->pPool = pool; - mc->bFixed = FALSE; -+ mc->sni_required = FALSE; - - /* - * initialize per-module configuration -diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c -index bf1f0e4..a7523de 100644 ---- a/modules/ssl/ssl_engine_init.c -+++ b/modules/ssl/ssl_engine_init.c -@@ -409,7 +409,7 @@ int ssl_init_Module(apr_pool_t *p, apr_pool_t *plog, - /* - * Configuration consistency checks - */ -- ssl_init_CheckServers(base_server, ptemp); -+ ssl_init_CheckServers(mc, base_server, ptemp); - - /* - * Announce mod_ssl and SSL library in HTTP Server field -@@ -1475,7 +1475,7 @@ void ssl_init_ConfigureServer(server_rec *s, - } - } - --void ssl_init_CheckServers(server_rec *base_server, apr_pool_t *p) -+void ssl_init_CheckServers(SSLModConfigRec *mc, server_rec *base_server, apr_pool_t *p) - { - server_rec *s, *ps; - SSLSrvConfigRec *sc; -@@ -1557,6 +1557,7 @@ void ssl_init_CheckServers(server_rec *base_server, apr_pool_t *p) - } - - if (conflict) { -+ mc->sni_required = TRUE; - #ifdef OPENSSL_NO_TLSEXT - ap_log_error(APLOG_MARK, APLOG_WARNING, 0, base_server, APLOGNO(01917) - "Init: You should not use name-based " -diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c -index bc9e26b..2460f01 100644 ---- a/modules/ssl/ssl_engine_kernel.c -+++ b/modules/ssl/ssl_engine_kernel.c -@@ -164,6 +164,7 @@ int ssl_hook_ReadReq(request_rec *r) - return DECLINED; - } - #ifndef OPENSSL_NO_TLSEXT -+ if (myModConfig(r->server)->sni_required) { - if ((servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))) { - char *host, *scope_id; - apr_port_t port; -@@ -206,6 +207,7 @@ int ssl_hook_ReadReq(request_rec *r) - " virtual host"); - return HTTP_FORBIDDEN; - } -+ } - #endif - SSL_set_app_data2(ssl, r); - -diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h -index 75fc0e3..31dbfa9 100644 ---- a/modules/ssl/ssl_private.h -+++ b/modules/ssl/ssl_private.h -@@ -554,6 +554,7 @@ typedef struct { - struct { - void *pV1, *pV2, *pV3, *pV4, *pV5, *pV6, *pV7, *pV8, *pV9, *pV10; - } rCtx; -+ BOOL sni_required; - } SSLModConfigRec; - - /** Structure representing configured filenames for certs and keys for -@@ -786,7 +787,7 @@ const char *ssl_cmd_SSLFIPS(cmd_parms *cmd, void *dcfg, int flag); - int ssl_init_Module(apr_pool_t *, apr_pool_t *, apr_pool_t *, server_rec *); - void ssl_init_Engine(server_rec *, apr_pool_t *); - void ssl_init_ConfigureServer(server_rec *, apr_pool_t *, apr_pool_t *, SSLSrvConfigRec *); --void ssl_init_CheckServers(server_rec *, apr_pool_t *); -+void ssl_init_CheckServers(SSLModConfigRec *mc, server_rec *, apr_pool_t *); - STACK_OF(X509_NAME) - *ssl_init_FindCAList(server_rec *, apr_pool_t *, const char *, const char *); - void ssl_init_Child(apr_pool_t *, server_rec *); diff --git a/SOURCES/httpd-2.4.6-CVE-2013-4352.patch b/SOURCES/httpd-2.4.6-CVE-2013-4352.patch deleted file mode 100644 index 48a52f2..0000000 --- a/SOURCES/httpd-2.4.6-CVE-2013-4352.patch +++ /dev/null @@ -1,25 +0,0 @@ ---- a/modules/cache/cache_storage.c 2013/09/14 13:30:39 1523234 -+++ b/modules/cache/cache_storage.c 2013/09/14 13:32:25 1523235 -@@ -713,7 +713,9 @@ - || APR_SUCCESS - != cache_canonicalise_key(r, r->pool, location, - &location_uri, &location_key) -- || strcmp(r->parsed_uri.hostname, location_uri.hostname)) { -+ || !(r->parsed_uri.hostname && location_uri.hostname -+ && !strcmp(r->parsed_uri.hostname, -+ location_uri.hostname))) { - location_key = NULL; - } - } -@@ -726,8 +728,9 @@ - || APR_SUCCESS - != cache_canonicalise_key(r, r->pool, content_location, - &content_location_uri, &content_location_key) -- || strcmp(r->parsed_uri.hostname, -- content_location_uri.hostname)) { -+ || !(r->parsed_uri.hostname && content_location_uri.hostname -+ && !strcmp(r->parsed_uri.hostname, -+ content_location_uri.hostname))) { - content_location_key = NULL; - } - } diff --git a/SOURCES/httpd-2.4.6-CVE-2013-5704.patch b/SOURCES/httpd-2.4.6-CVE-2013-5704.patch deleted file mode 100644 index ee42b25..0000000 --- a/SOURCES/httpd-2.4.6-CVE-2013-5704.patch +++ /dev/null @@ -1,381 +0,0 @@ -diff --git a/include/http_core.h b/include/http_core.h -index 3c47989..f6f4aa2 100644 ---- a/include/http_core.h -+++ b/include/http_core.h -@@ -663,6 +663,10 @@ typedef struct { - #define AP_TRACE_ENABLE 1 - #define AP_TRACE_EXTENDED 2 - int trace_enable; -+#define AP_MERGE_TRAILERS_UNSET 0 -+#define AP_MERGE_TRAILERS_ENABLE 1 -+#define AP_MERGE_TRAILERS_DISABLE 2 -+ int merge_trailers; - - } core_server_config; - -diff --git a/include/httpd.h b/include/httpd.h -index 36cd58d..2e415f9 100644 ---- a/include/httpd.h -+++ b/include/httpd.h -@@ -1032,6 +1032,11 @@ struct request_rec { - */ - apr_sockaddr_t *useragent_addr; - char *useragent_ip; -+ -+ /** MIME trailer environment from the request */ -+ apr_table_t *trailers_in; -+ /** MIME trailer environment from the response */ -+ apr_table_t *trailers_out; - }; - - /** -diff --git a/modules/http/http_filters.c b/modules/http/http_filters.c -index 24a939a..2ae8f46 100644 ---- a/modules/http/http_filters.c -+++ b/modules/http/http_filters.c -@@ -214,6 +214,49 @@ static apr_status_t get_chunk_line(http_ctx_t *ctx, apr_bucket_brigade *b, - } - - -+static apr_status_t read_chunked_trailers(http_ctx_t *ctx, ap_filter_t *f, -+ apr_bucket_brigade *b, int merge) -+{ -+ int rv; -+ apr_bucket *e; -+ request_rec *r = f->r; -+ apr_table_t *saved_headers_in = r->headers_in; -+ int saved_status = r->status; -+ -+ r->status = HTTP_OK; -+ r->headers_in = r->trailers_in; -+ apr_table_clear(r->headers_in); -+ ctx->state = BODY_NONE; -+ ap_get_mime_headers(r); -+ -+ if(r->status == HTTP_OK) { -+ r->status = saved_status; -+ e = apr_bucket_eos_create(f->c->bucket_alloc); -+ APR_BRIGADE_INSERT_TAIL(b, e); -+ ctx->eos_sent = 1; -+ rv = APR_SUCCESS; -+ } -+ else { -+ const char *error_notes = apr_table_get(r->notes, -+ "error-notes"); -+ ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, -+ "Error while reading HTTP trailer: %i%s%s", -+ r->status, error_notes ? ": " : "", -+ error_notes ? error_notes : ""); -+ rv = APR_EINVAL; -+ } -+ -+ if(!merge) { -+ r->headers_in = saved_headers_in; -+ } -+ else { -+ r->headers_in = apr_table_overlay(r->pool, saved_headers_in, -+ r->trailers_in); -+ } -+ -+ return rv; -+} -+ - /* This is the HTTP_INPUT filter for HTTP requests and responses from - * proxied servers (mod_proxy). It handles chunked and content-length - * bodies. This can only be inserted/used after the headers -@@ -223,6 +266,7 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b, - ap_input_mode_t mode, apr_read_type_e block, - apr_off_t readbytes) - { -+ core_server_config *conf; - apr_bucket *e; - http_ctx_t *ctx = f->ctx; - apr_status_t rv; -@@ -230,6 +274,9 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b, - int http_error = HTTP_REQUEST_ENTITY_TOO_LARGE; - apr_bucket_brigade *bb; - -+ conf = (core_server_config *) -+ ap_get_module_config(f->r->server->module_config, &core_module); -+ - /* just get out of the way of things we don't want. */ - if (mode != AP_MODE_READBYTES && mode != AP_MODE_GETLINE) { - return ap_get_brigade(f->next, b, mode, block, readbytes); -@@ -403,13 +450,8 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b, - } - - if (!ctx->remaining) { -- /* Handle trailers by calling ap_get_mime_headers again! */ -- ctx->state = BODY_NONE; -- ap_get_mime_headers(f->r); -- e = apr_bucket_eos_create(f->c->bucket_alloc); -- APR_BRIGADE_INSERT_TAIL(b, e); -- ctx->eos_sent = 1; -- return APR_SUCCESS; -+ return read_chunked_trailers(ctx, f, b, -+ conf->merge_trailers == AP_MERGE_TRAILERS_ENABLE); - } - } - } -@@ -509,13 +551,8 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b, - } - - if (!ctx->remaining) { -- /* Handle trailers by calling ap_get_mime_headers again! */ -- ctx->state = BODY_NONE; -- ap_get_mime_headers(f->r); -- e = apr_bucket_eos_create(f->c->bucket_alloc); -- APR_BRIGADE_INSERT_TAIL(b, e); -- ctx->eos_sent = 1; -- return APR_SUCCESS; -+ return read_chunked_trailers(ctx, f, b, -+ conf->merge_trailers == AP_MERGE_TRAILERS_ENABLE); - } - } - break; -diff --git a/modules/http/http_request.c b/modules/http/http_request.c -index 796d506..cdfec8b 100644 ---- a/modules/http/http_request.c -+++ b/modules/http/http_request.c -@@ -463,6 +463,7 @@ static request_rec *internal_internal_redirect(const char *new_uri, - new->main = r->main; - - new->headers_in = r->headers_in; -+ new->trailers_in = r->trailers_in; - new->headers_out = apr_table_make(r->pool, 12); - if (ap_is_HTTP_REDIRECT(new->status)) { - const char *location = apr_table_get(r->headers_out, "Location"); -@@ -470,6 +471,7 @@ static request_rec *internal_internal_redirect(const char *new_uri, - apr_table_setn(new->headers_out, "Location", location); - } - new->err_headers_out = r->err_headers_out; -+ new->trailers_out = apr_table_make(r->pool, 5); - new->subprocess_env = rename_original_env(r->pool, r->subprocess_env); - new->notes = apr_table_make(r->pool, 5); - -@@ -583,6 +585,8 @@ AP_DECLARE(void) ap_internal_fast_redirect(request_rec *rr, request_rec *r) - r->headers_out); - r->err_headers_out = apr_table_overlay(r->pool, rr->err_headers_out, - r->err_headers_out); -+ r->trailers_out = apr_table_overlay(r->pool, rr->trailers_out, -+ r->trailers_out); - r->subprocess_env = apr_table_overlay(r->pool, rr->subprocess_env, - r->subprocess_env); - -diff --git a/modules/loggers/mod_log_config.c b/modules/loggers/mod_log_config.c -index 25f5030..b021dd3 100644 ---- a/modules/loggers/mod_log_config.c -+++ b/modules/loggers/mod_log_config.c -@@ -431,6 +431,12 @@ static const char *log_header_in(request_rec *r, char *a) - return ap_escape_logitem(r->pool, apr_table_get(r->headers_in, a)); - } - -+static const char *log_trailer_in(request_rec *r, char *a) -+{ -+ return ap_escape_logitem(r->pool, apr_table_get(r->trailers_in, a)); -+} -+ -+ - static APR_INLINE char *find_multiple_headers(apr_pool_t *pool, - const apr_table_t *table, - const char *key) -@@ -514,6 +520,11 @@ static const char *log_header_out(request_rec *r, char *a) - return ap_escape_logitem(r->pool, cp); - } - -+static const char *log_trailer_out(request_rec *r, char *a) -+{ -+ return ap_escape_logitem(r->pool, apr_table_get(r->trailers_out, a)); -+} -+ - static const char *log_note(request_rec *r, char *a) - { - return ap_escape_logitem(r->pool, apr_table_get(r->notes, a)); -@@ -916,7 +927,7 @@ static char *parse_log_misc_string(apr_pool_t *p, log_format_item *it, - static char *parse_log_item(apr_pool_t *p, log_format_item *it, const char **sa) - { - const char *s = *sa; -- ap_log_handler *handler; -+ ap_log_handler *handler = NULL; - - if (*s != '%') { - return parse_log_misc_string(p, it, sa); -@@ -986,7 +997,16 @@ static char *parse_log_item(apr_pool_t *p, log_format_item *it, const char **sa) - break; - - default: -- handler = (ap_log_handler *)apr_hash_get(log_hash, s++, 1); -+ /* check for '^' + two character format first */ -+ if (*s == '^' && *(s+1) && *(s+2)) { -+ handler = (ap_log_handler *)apr_hash_get(log_hash, s, 3); -+ if (handler) { -+ s += 3; -+ } -+ } -+ if (!handler) { -+ handler = (ap_log_handler *)apr_hash_get(log_hash, s++, 1); -+ } - if (!handler) { - char dummy[2]; - -@@ -1516,7 +1536,7 @@ static void ap_register_log_handler(apr_pool_t *p, char *tag, - log_struct->func = handler; - log_struct->want_orig_default = def; - -- apr_hash_set(log_hash, tag, 1, (const void *)log_struct); -+ apr_hash_set(log_hash, tag, strlen(tag), (const void *)log_struct); - } - static ap_log_writer_init* ap_log_set_writer_init(ap_log_writer_init *handle) - { -@@ -1686,6 +1706,9 @@ static int log_pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp) - log_pfn_register(p, "U", log_request_uri, 1); - log_pfn_register(p, "s", log_status, 1); - log_pfn_register(p, "R", log_handler, 1); -+ -+ log_pfn_register(p, "^ti", log_trailer_in, 0); -+ log_pfn_register(p, "^to", log_trailer_out, 0); - } - - /* reset to default conditions */ -diff --git a/modules/proxy/mod_proxy_http.c b/modules/proxy/mod_proxy_http.c -index 7ae0fa4..05f33b4 100644 ---- a/modules/proxy/mod_proxy_http.c -+++ b/modules/proxy/mod_proxy_http.c -@@ -994,8 +994,11 @@ static request_rec *make_fake_req(conn_rec *c, request_rec *r) - rp->status = HTTP_OK; - - rp->headers_in = apr_table_make(pool, 50); -+ rp->trailers_in = apr_table_make(pool, 5); -+ - rp->subprocess_env = apr_table_make(pool, 50); - rp->headers_out = apr_table_make(pool, 12); -+ rp->trailers_out = apr_table_make(pool, 5); - rp->err_headers_out = apr_table_make(pool, 5); - rp->notes = apr_table_make(pool, 5); - -@@ -1076,6 +1079,7 @@ static void ap_proxy_read_headers(request_rec *r, request_rec *rr, - psc = (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module); - - r->headers_out = apr_table_make(r->pool, 20); -+ r->trailers_out = apr_table_make(r->pool, 5); - *pread_len = 0; - - /* -@@ -1206,6 +1210,14 @@ apr_status_t ap_proxygetline(apr_bucket_brigade *bb, char *s, int n, request_rec - #define AP_MAX_INTERIM_RESPONSES 10 - #endif - -+static int add_trailers(void *data, const char *key, const char *val) -+{ -+ if (val) { -+ apr_table_add((apr_table_t*)data, key, val); -+ } -+ return 1; -+} -+ - static - apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r, - proxy_conn_rec **backend_ptr, -@@ -1717,6 +1729,12 @@ apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r, - /* next time try a non-blocking read */ - mode = APR_NONBLOCK_READ; - -+ if (!apr_is_empty_table(backend->r->trailers_in)) { -+ apr_table_do(add_trailers, r->trailers_out, -+ backend->r->trailers_in, NULL); -+ apr_table_clear(backend->r->trailers_in); -+ } -+ - apr_brigade_length(bb, 0, &readbytes); - backend->worker->s->read += readbytes; - #if DEBUGGING -diff --git a/server/core.c b/server/core.c -index 024bab6..7cfde63 100644 ---- a/server/core.c -+++ b/server/core.c -@@ -523,6 +523,10 @@ static void *merge_core_server_configs(apr_pool_t *p, void *basev, void *virtv) - if (virt->error_log_req) - conf->error_log_req = virt->error_log_req; - -+ conf->merge_trailers = (virt->merge_trailers != AP_MERGE_TRAILERS_UNSET) -+ ? virt->merge_trailers -+ : base->merge_trailers; -+ - return conf; - } - -@@ -3877,6 +3881,16 @@ AP_DECLARE(void) ap_register_errorlog_handler(apr_pool_t *p, char *tag, - } - - -+static const char *set_merge_trailers(cmd_parms *cmd, void *dummy, int arg) -+{ -+ core_server_config *conf = ap_get_module_config(cmd->server->module_config, -+ &core_module); -+ conf->merge_trailers = (arg ? AP_MERGE_TRAILERS_ENABLE : -+ AP_MERGE_TRAILERS_DISABLE); -+ -+ return NULL; -+} -+ - /* Note --- ErrorDocument will now work from .htaccess files. - * The AllowOverride of Fileinfo allows webmasters to turn it off - */ -@@ -4124,6 +4138,8 @@ AP_INIT_TAKE1("EnableExceptionHook", ap_mpm_set_exception_hook, NULL, RSRC_CONF, - #endif - AP_INIT_TAKE1("TraceEnable", set_trace_enable, NULL, RSRC_CONF, - "'on' (default), 'off' or 'extended' to trace request body content"), -+AP_INIT_FLAG("MergeTrailers", set_merge_trailers, NULL, RSRC_CONF, -+ "merge request trailers into request headers or not"), - { NULL } - }; - -@@ -4206,7 +4222,6 @@ static int core_map_to_storage(request_rec *r) - - static int do_nothing(request_rec *r) { return OK; } - -- - static int core_override_type(request_rec *r) - { - core_dir_config *conf = -diff --git a/server/protocol.c b/server/protocol.c -index 14329eb..46fc034 100644 ---- a/server/protocol.c -+++ b/server/protocol.c -@@ -718,6 +718,8 @@ AP_DECLARE(void) ap_get_mime_headers_core(request_rec *r, apr_bucket_brigade *bb - r->status = HTTP_REQUEST_TIME_OUT; - } - else { -+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, -+ "Failed to read request header line %s", field); - r->status = HTTP_BAD_REQUEST; - } - -@@ -917,9 +919,11 @@ request_rec *ap_read_request(conn_rec *conn) - r->allowed_methods = ap_make_method_list(p, 2); - - r->headers_in = apr_table_make(r->pool, 25); -+ r->trailers_in = apr_table_make(r->pool, 5); - r->subprocess_env = apr_table_make(r->pool, 25); - r->headers_out = apr_table_make(r->pool, 12); - r->err_headers_out = apr_table_make(r->pool, 5); -+ r->trailers_out = apr_table_make(r->pool, 5); - r->notes = apr_table_make(r->pool, 5); - - r->request_config = ap_create_request_config(r->pool); -@@ -1162,6 +1166,7 @@ AP_DECLARE(void) ap_set_sub_req_protocol(request_rec *rnew, - rnew->status = HTTP_OK; - - rnew->headers_in = apr_table_copy(rnew->pool, r->headers_in); -+ rnew->trailers_in = apr_table_copy(rnew->pool, r->trailers_in); - - /* did the original request have a body? (e.g. POST w/SSI tags) - * if so, make sure the subrequest doesn't inherit body headers -@@ -1173,6 +1178,7 @@ AP_DECLARE(void) ap_set_sub_req_protocol(request_rec *rnew, - rnew->subprocess_env = apr_table_copy(rnew->pool, r->subprocess_env); - rnew->headers_out = apr_table_make(rnew->pool, 5); - rnew->err_headers_out = apr_table_make(rnew->pool, 5); -+ rnew->trailers_out = apr_table_make(rnew->pool, 5); - rnew->notes = apr_table_make(rnew->pool, 5); - - rnew->expecting_100 = r->expecting_100; diff --git a/SOURCES/httpd-2.4.6-CVE-2013-6438.patch b/SOURCES/httpd-2.4.6-CVE-2013-6438.patch deleted file mode 100644 index 1b154f5..0000000 --- a/SOURCES/httpd-2.4.6-CVE-2013-6438.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- a/modules/dav/main/util.c 2014/01/09 14:28:39 1556815 -+++ b/modules/dav/main/util.c 2014/01/09 14:29:47 1556816 -@@ -396,8 +396,10 @@ - - if (strip_white) { - /* trim leading whitespace */ -- while (apr_isspace(*cdata)) /* assume: return false for '\0' */ -+ while (apr_isspace(*cdata)) { /* assume: return false for '\0' */ - ++cdata; -+ --len; -+ } - - /* trim trailing whitespace */ - while (len-- > 0 && apr_isspace(cdata[len])) diff --git a/SOURCES/httpd-2.4.6-CVE-2014-0098.patch b/SOURCES/httpd-2.4.6-CVE-2014-0098.patch deleted file mode 100644 index 64d5064..0000000 --- a/SOURCES/httpd-2.4.6-CVE-2014-0098.patch +++ /dev/null @@ -1,41 +0,0 @@ ---- a/modules/loggers/mod_log_config.c 2013/11/15 17:07:52 1542329 -+++ b/modules/loggers/mod_log_config.c 2014/03/10 11:23:47 1575904 -@@ -543,14 +543,24 @@ - - while ((cookie = apr_strtok(cookies, ";", &last1))) { - char *name = apr_strtok(cookie, "=", &last2); -- if (name) { -- char *value = name + strlen(name) + 1; -- apr_collapse_spaces(name, name); -+ /* last2 points to the next char following an '=' delim, -+ or the trailing NUL char of the string */ -+ char *value = last2; -+ if (name && *name && value && *value) { -+ char *last = value - 2; -+ /* Move past leading WS */ -+ name += strspn(name, " \t"); -+ while (last >= name && apr_isspace(*last)) { -+ *last = '\0'; -+ --last; -+ } - - if (!strcasecmp(name, a)) { -- char *last; -- value += strspn(value, " \t"); /* Move past leading WS */ -- last = value + strlen(value) - 1; -+ /* last1 points to the next char following the ';' delim, -+ or the trailing NUL char of the string */ -+ last = last1 - (*last1 ? 2 : 1); -+ /* Move past leading WS */ -+ value += strspn(value, " \t"); - while (last >= value && apr_isspace(*last)) { - *last = '\0'; - --last; -@@ -559,6 +569,7 @@ - return ap_escape_logitem(r->pool, value); - } - } -+ /* Iterate the remaining tokens using apr_strtok(NULL, ...) */ - cookies = NULL; - } - } diff --git a/SOURCES/httpd-2.4.6-CVE-2014-0117.patch b/SOURCES/httpd-2.4.6-CVE-2014-0117.patch deleted file mode 100644 index f548d99..0000000 --- a/SOURCES/httpd-2.4.6-CVE-2014-0117.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/modules/proxy/proxy_util.c 2014/07/15 16:07:44 1610736 -+++ b/modules/proxy/proxy_util.c 2014/07/15 16:11:04 1610737 -@@ -3132,7 +3132,7 @@ - const char *name; - - do { -- while (*val == ',') { -+ while (*val == ',' || *val == ';') { - val++; - } - name = ap_get_token(x->pool, &val, 0); diff --git a/SOURCES/httpd-2.4.6-CVE-2014-0118.patch b/SOURCES/httpd-2.4.6-CVE-2014-0118.patch deleted file mode 100644 index e82b79f..0000000 --- a/SOURCES/httpd-2.4.6-CVE-2014-0118.patch +++ /dev/null @@ -1,266 +0,0 @@ -diff --git a/modules/filters/mod_deflate.c b/modules/filters/mod_deflate.c -index 79f6f8d..6c415c8 100644 ---- a/modules/filters/mod_deflate.c -+++ b/modules/filters/mod_deflate.c -@@ -37,6 +37,7 @@ - #include "httpd.h" - #include "http_config.h" - #include "http_log.h" -+#include "http_core.h" - #include "apr_lib.h" - #include "apr_strings.h" - #include "apr_general.h" -@@ -52,6 +53,9 @@ - static const char deflateFilterName[] = "DEFLATE"; - module AP_MODULE_DECLARE_DATA deflate_module; - -+#define AP_INFLATE_RATIO_LIMIT 200 -+#define AP_INFLATE_RATIO_BURST 3 -+ - typedef struct deflate_filter_config_t - { - int windowSize; -@@ -63,6 +67,12 @@ typedef struct deflate_filter_config_t - char *note_output_name; - } deflate_filter_config; - -+typedef struct deflate_dirconf_t { -+ apr_off_t inflate_limit; -+ int ratio_limit, -+ ratio_burst; -+} deflate_dirconf_t; -+ - /* RFC 1952 Section 2.3 defines the gzip header: - * - * +---+---+---+---+---+---+---+---+---+---+ -@@ -204,6 +214,14 @@ static void *create_deflate_server_config(apr_pool_t *p, server_rec *s) - return c; - } - -+static void *create_deflate_dirconf(apr_pool_t *p, char *dummy) -+{ -+ deflate_dirconf_t *dc = apr_pcalloc(p, sizeof(*dc)); -+ dc->ratio_limit = AP_INFLATE_RATIO_LIMIT; -+ dc->ratio_burst = AP_INFLATE_RATIO_BURST; -+ return dc; -+} -+ - static const char *deflate_set_window_size(cmd_parms *cmd, void *dummy, - const char *arg) - { -@@ -295,6 +313,55 @@ static const char *deflate_set_compressionlevel(cmd_parms *cmd, void *dummy, - return NULL; - } - -+ -+static const char *deflate_set_inflate_limit(cmd_parms *cmd, void *dirconf, -+ const char *arg) -+{ -+ deflate_dirconf_t *dc = (deflate_dirconf_t*) dirconf; -+ char *errp; -+ -+ if (APR_SUCCESS != apr_strtoff(&dc->inflate_limit, arg, &errp, 10)) { -+ return "DeflateInflateLimitRequestBody is not parsable."; -+ } -+ if (*errp || dc->inflate_limit < 0) { -+ return "DeflateInflateLimitRequestBody requires a non-negative integer."; -+ } -+ -+ return NULL; -+} -+ -+static const char *deflate_set_inflate_ratio_limit(cmd_parms *cmd, -+ void *dirconf, -+ const char *arg) -+{ -+ deflate_dirconf_t *dc = (deflate_dirconf_t*) dirconf; -+ int i; -+ -+ i = atoi(arg); -+ if (i <= 0) -+ return "DeflateInflateRatioLimit must be positive"; -+ -+ dc->ratio_limit = i; -+ -+ return NULL; -+} -+ -+static const char *deflate_set_inflate_ratio_burst(cmd_parms *cmd, -+ void *dirconf, -+ const char *arg) -+{ -+ deflate_dirconf_t *dc = (deflate_dirconf_t*) dirconf; -+ int i; -+ -+ i = atoi(arg); -+ if (i <= 0) -+ return "DeflateInflateRatioBurst must be positive"; -+ -+ dc->ratio_burst = i; -+ -+ return NULL; -+} -+ - typedef struct deflate_ctx_t - { - z_stream stream; -@@ -304,6 +371,8 @@ typedef struct deflate_ctx_t - int (*libz_end_func)(z_streamp); - unsigned char *validation_buffer; - apr_size_t validation_buffer_length; -+ int ratio_hits; -+ apr_off_t inflate_total; - unsigned int inflate_init:1; - unsigned int filter_init:1; - unsigned int done:1; -@@ -422,6 +491,22 @@ static void deflate_check_etag(request_rec *r, const char *transform) - } - } - -+/* Check whether the (inflate) ratio exceeds the configured limit/burst. */ -+static int check_ratio(request_rec *r, deflate_ctx *ctx, -+ const deflate_dirconf_t *dc) -+{ -+ if (ctx->stream.total_in) { -+ int ratio = ctx->stream.total_out / ctx->stream.total_in; -+ if (ratio < dc->ratio_limit) { -+ ctx->ratio_hits = 0; -+ } -+ else if (++ctx->ratio_hits > dc->ratio_burst) { -+ return 0; -+ } -+ } -+ return 1; -+} -+ - static int have_ssl_compression(request_rec *r) - { - const char *comp; -@@ -897,6 +982,8 @@ static apr_status_t deflate_in_filter(ap_filter_t *f, - int zRC; - apr_status_t rv; - deflate_filter_config *c; -+ deflate_dirconf_t *dc; -+ apr_off_t inflate_limit; - - /* just get out of the way of things we don't want. */ - if (mode != AP_MODE_READBYTES) { -@@ -904,6 +991,7 @@ static apr_status_t deflate_in_filter(ap_filter_t *f, - } - - c = ap_get_module_config(r->server->module_config, &deflate_module); -+ dc = ap_get_module_config(r->per_dir_config, &deflate_module); - - if (!ctx) { - char deflate_hdr[10]; -@@ -994,6 +1082,12 @@ static apr_status_t deflate_in_filter(ap_filter_t *f, - apr_brigade_cleanup(ctx->bb); - } - -+ inflate_limit = dc->inflate_limit; -+ if (inflate_limit == 0) { -+ /* The core is checking the deflated body, we'll check the inflated */ -+ inflate_limit = ap_get_limit_req_body(f->r); -+ } -+ - if (APR_BRIGADE_EMPTY(ctx->proc_bb)) { - rv = ap_get_brigade(f->next, ctx->bb, mode, block, readbytes); - -@@ -1038,6 +1132,17 @@ static apr_status_t deflate_in_filter(ap_filter_t *f, - - ctx->stream.next_out = ctx->buffer; - len = c->bufferSize - ctx->stream.avail_out; -+ -+ ctx->inflate_total += len; -+ if (inflate_limit && ctx->inflate_total > inflate_limit) { -+ inflateEnd(&ctx->stream); -+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02647) -+ "Inflated content length of %" APR_OFF_T_FMT -+ " is larger than the configured limit" -+ " of %" APR_OFF_T_FMT, -+ ctx->inflate_total, inflate_limit); -+ return APR_ENOSPC; -+ } - - ctx->crc = crc32(ctx->crc, (const Bytef *)ctx->buffer, len); - tmp_heap = apr_bucket_heap_create((char *)ctx->buffer, len, -@@ -1073,6 +1178,26 @@ static apr_status_t deflate_in_filter(ap_filter_t *f, - ctx->stream.next_out = ctx->buffer; - len = c->bufferSize - ctx->stream.avail_out; - -+ ctx->inflate_total += len; -+ if (inflate_limit && ctx->inflate_total > inflate_limit) { -+ inflateEnd(&ctx->stream); -+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02648) -+ "Inflated content length of %" APR_OFF_T_FMT -+ " is larger than the configured limit" -+ " of %" APR_OFF_T_FMT, -+ ctx->inflate_total, inflate_limit); -+ return APR_ENOSPC; -+ } -+ -+ if (!check_ratio(r, ctx, dc)) { -+ inflateEnd(&ctx->stream); -+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02649) -+ "Inflated content ratio is larger than the " -+ "configured limit %i by %i time(s)", -+ dc->ratio_limit, dc->ratio_burst); -+ return APR_EINVAL; -+ } -+ - ctx->crc = crc32(ctx->crc, (const Bytef *)ctx->buffer, len); - tmp_heap = apr_bucket_heap_create((char *)ctx->buffer, len, - NULL, f->c->bucket_alloc); -@@ -1193,6 +1318,7 @@ static apr_status_t inflate_out_filter(ap_filter_t *f, - int zRC; - apr_status_t rv; - deflate_filter_config *c; -+ deflate_dirconf_t *dc; - - /* Do nothing if asked to filter nothing. */ - if (APR_BRIGADE_EMPTY(bb)) { -@@ -1200,6 +1326,7 @@ static apr_status_t inflate_out_filter(ap_filter_t *f, - } - - c = ap_get_module_config(r->server->module_config, &deflate_module); -+ dc = ap_get_module_config(r->per_dir_config, &deflate_module); - - if (!ctx) { - -@@ -1462,6 +1589,14 @@ static apr_status_t inflate_out_filter(ap_filter_t *f, - while (ctx->stream.avail_in != 0) { - if (ctx->stream.avail_out == 0) { - -+ if (!check_ratio(r, ctx, dc)) { -+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02650) -+ "Inflated content ratio is larger than the " -+ "configured limit %i by %i time(s)", -+ dc->ratio_limit, dc->ratio_burst); -+ return APR_EINVAL; -+ } -+ - ctx->stream.next_out = ctx->buffer; - len = c->bufferSize - ctx->stream.avail_out; - -@@ -1548,12 +1683,20 @@ static const command_rec deflate_filter_cmds[] = { - "Set the Deflate Memory Level (1-9)"), - AP_INIT_TAKE1("DeflateCompressionLevel", deflate_set_compressionlevel, NULL, RSRC_CONF, - "Set the Deflate Compression Level (1-9)"), -+ AP_INIT_TAKE1("DeflateInflateLimitRequestBody", deflate_set_inflate_limit, NULL, OR_ALL, -+ "Set a limit on size of inflated input"), -+ AP_INIT_TAKE1("DeflateInflateRatioLimit", deflate_set_inflate_ratio_limit, NULL, OR_ALL, -+ "Set the inflate ratio limit above which inflation is " -+ "aborted (default: " APR_STRINGIFY(AP_INFLATE_RATIO_LIMIT) ")"), -+ AP_INIT_TAKE1("DeflateInflateRatioBurst", deflate_set_inflate_ratio_burst, NULL, OR_ALL, -+ "Set the maximum number of following inflate ratios above limit " -+ "(default: " APR_STRINGIFY(AP_INFLATE_RATIO_BURST) ")"), - {NULL} - }; - - AP_DECLARE_MODULE(deflate) = { - STANDARD20_MODULE_STUFF, -- NULL, /* dir config creater */ -+ create_deflate_dirconf, /* dir config creater */ - NULL, /* dir merger --- default is to override */ - create_deflate_server_config, /* server config */ - NULL, /* merge server config */ diff --git a/SOURCES/httpd-2.4.6-CVE-2014-0226.patch b/SOURCES/httpd-2.4.6-CVE-2014-0226.patch deleted file mode 100644 index 67c7046..0000000 --- a/SOURCES/httpd-2.4.6-CVE-2014-0226.patch +++ /dev/null @@ -1,119 +0,0 @@ -Index: server/scoreboard.c -=================================================================== ---- a/server/scoreboard.c (revision 1610498) -+++ b/server/scoreboard.c (revision 1610499) -@@ -579,6 +579,21 @@ - sbh->thread_num); - } - -+AP_DECLARE(void) ap_copy_scoreboard_worker(worker_score *dest, -+ int child_num, -+ int thread_num) -+{ -+ worker_score *ws = ap_get_scoreboard_worker_from_indexes(child_num, thread_num); -+ -+ memcpy(dest, ws, sizeof *ws); -+ -+ /* For extra safety, NUL-terminate the strings returned, though it -+ * should be true those last bytes are always zero anyway. */ -+ dest->client[sizeof(dest->client) - 1] = '\0'; -+ dest->request[sizeof(dest->request) - 1] = '\0'; -+ dest->vhost[sizeof(dest->vhost) - 1] = '\0'; -+} -+ - AP_DECLARE(process_score *) ap_get_scoreboard_process(int x) - { - if ((x < 0) || (x >= server_limit)) { -Index: modules/generators/mod_status.c -=================================================================== ---- a/modules/generators/mod_status.c (revision 1610498) -+++ b/modules/generators/mod_status.c (revision 1610499) -@@ -194,7 +194,7 @@ - long req_time; - int short_report; - int no_table_report; -- worker_score *ws_record; -+ worker_score *ws_record = apr_palloc(r->pool, sizeof *ws_record); - process_score *ps_record; - char *stat_buffer; - pid_t *pid_buffer, worker_pid; -@@ -306,7 +306,7 @@ - for (j = 0; j < thread_limit; ++j) { - int indx = (i * thread_limit) + j; - -- ws_record = ap_get_scoreboard_worker_from_indexes(i, j); -+ ap_copy_scoreboard_worker(ws_record, i, j); - res = ws_record->status; - - if ((i >= max_servers || j >= threads_per_child) -@@ -637,7 +637,7 @@ - - for (i = 0; i < server_limit; ++i) { - for (j = 0; j < thread_limit; ++j) { -- ws_record = ap_get_scoreboard_worker_from_indexes(i, j); -+ ap_copy_scoreboard_worker(ws_record, i, j); - - if (ws_record->access_count == 0 && - (ws_record->status == SERVER_READY || -Index: modules/lua/lua_request.c -=================================================================== ---- a/modules/lua/lua_request.c (revision 1610498) -+++ b/modules/lua/lua_request.c (revision 1610499) -@@ -1245,16 +1245,22 @@ - */ - static int lua_ap_scoreboard_worker(lua_State *L) - { -- int i, -- j; -- worker_score *ws_record; -+ int i, j; -+ worker_score *ws_record = NULL; -+ request_rec *r = NULL; - - luaL_checktype(L, 1, LUA_TUSERDATA); - luaL_checktype(L, 2, LUA_TNUMBER); - luaL_checktype(L, 3, LUA_TNUMBER); -+ -+ r = ap_lua_check_request_rec(L, 1); -+ if (!r) return 0; -+ - i = lua_tointeger(L, 2); - j = lua_tointeger(L, 3); -- ws_record = ap_get_scoreboard_worker_from_indexes(i, j); -+ ws_record = apr_palloc(r->pool, sizeof *ws_record); -+ -+ ap_copy_scoreboard_worker(ws_record, i, j); - if (ws_record) { - lua_newtable(L); - -Index: include/scoreboard.h -=================================================================== ---- a/include/scoreboard.h (revision 1610498) -+++ b/include/scoreboard.h (revision 1610499) -@@ -183,8 +183,25 @@ - AP_DECLARE(void) ap_time_process_request(ap_sb_handle_t *sbh, int status); - - AP_DECLARE(worker_score *) ap_get_scoreboard_worker(ap_sb_handle_t *sbh); -+ -+/** Return a pointer to the worker_score for a given child, thread pair. -+ * @param child_num The child number. -+ * @param thread_num The thread number. -+ * @return A pointer to the worker_score structure. -+ * @deprecated This function is deprecated, use ap_copy_scoreboard_worker instead. */ - AP_DECLARE(worker_score *) ap_get_scoreboard_worker_from_indexes(int child_num, - int thread_num); -+ -+/** Copy the contents of a worker scoreboard entry. The contents of -+ * the worker_score structure are copied verbatim into the dest -+ * structure. -+ * @param dest Output parameter. -+ * @param child_num The child number. -+ * @param thread_num The thread number. -+ */ -+AP_DECLARE(void) ap_copy_scoreboard_worker(worker_score *dest, -+ int child_num, int thread_num); -+ - AP_DECLARE(process_score *) ap_get_scoreboard_process(int x); - AP_DECLARE(global_score *) ap_get_scoreboard_global(void); - - diff --git a/SOURCES/httpd-2.4.6-CVE-2014-0231.patch b/SOURCES/httpd-2.4.6-CVE-2014-0231.patch deleted file mode 100644 index 580123a..0000000 --- a/SOURCES/httpd-2.4.6-CVE-2014-0231.patch +++ /dev/null @@ -1,144 +0,0 @@ ---- a/modules/generators/mod_cgid.c 2014/07/14 20:16:45 1610511 -+++ b/modules/generators/mod_cgid.c 2014/07/14 20:18:26 1610512 -@@ -97,6 +97,10 @@ - static pid_t parent_pid; - static ap_unix_identity_t empty_ugid = { (uid_t)-1, (gid_t)-1, -1 }; - -+typedef struct { -+ apr_interval_time_t timeout; -+} cgid_dirconf; -+ - /* The APR other-child API doesn't tell us how the daemon exited - * (SIGSEGV vs. exit(1)). The other-child maintenance function - * needs to decide whether to restart the daemon after a failure -@@ -968,7 +972,14 @@ - return overrides->logname ? overrides : base; - } - -+static void *create_cgid_dirconf(apr_pool_t *p, char *dummy) -+{ -+ cgid_dirconf *c = (cgid_dirconf *) apr_pcalloc(p, sizeof(cgid_dirconf)); -+ return c; -+} -+ - static const char *set_scriptlog(cmd_parms *cmd, void *dummy, const char *arg) -+ - { - server_rec *s = cmd->server; - cgid_server_conf *conf = ap_get_module_config(s->module_config, -@@ -1021,7 +1032,16 @@ - - return NULL; - } -+static const char *set_script_timeout(cmd_parms *cmd, void *dummy, const char *arg) -+{ -+ cgid_dirconf *dc = dummy; - -+ if (ap_timeout_parameter_parse(arg, &dc->timeout, "s") != APR_SUCCESS) { -+ return "CGIDScriptTimeout has wrong format"; -+ } -+ -+ return NULL; -+} - static const command_rec cgid_cmds[] = - { - AP_INIT_TAKE1("ScriptLog", set_scriptlog, NULL, RSRC_CONF, -@@ -1033,6 +1053,10 @@ - AP_INIT_TAKE1("ScriptSock", set_script_socket, NULL, RSRC_CONF, - "the name of the socket to use for communication with " - "the cgi daemon."), -+ AP_INIT_TAKE1("CGIDScriptTimeout", set_script_timeout, NULL, RSRC_CONF | ACCESS_CONF, -+ "The amount of time to wait between successful reads from " -+ "the CGI script, in seconds."), -+ - {NULL} - }; - -@@ -1356,12 +1380,16 @@ - apr_file_t *tempsock; - struct cleanup_script_info *info; - apr_status_t rv; -+ cgid_dirconf *dc; - - if (strcmp(r->handler, CGI_MAGIC_TYPE) && strcmp(r->handler, "cgi-script")) { - return DECLINED; - } - - conf = ap_get_module_config(r->server->module_config, &cgid_module); -+ dc = ap_get_module_config(r->per_dir_config, &cgid_module); -+ -+ - is_included = !strcmp(r->protocol, "INCLUDED"); - - if ((argv0 = strrchr(r->filename, '/')) != NULL) { -@@ -1441,6 +1469,12 @@ - */ - - apr_os_pipe_put_ex(&tempsock, &sd, 1, r->pool); -+ if (dc->timeout > 0) { -+ apr_file_pipe_timeout_set(tempsock, dc->timeout); -+ } -+ else { -+ apr_file_pipe_timeout_set(tempsock, r->server->timeout); -+ } - apr_pool_cleanup_kill(r->pool, (void *)((long)sd), close_unix_socket); - - /* Transfer any put/post args, CERN style... -@@ -1517,6 +1551,10 @@ - if (rv != APR_SUCCESS) { - /* silly script stopped reading, soak up remaining message */ - child_stopped_reading = 1; -+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(02651) -+ "Error writing request body to script %s", -+ r->filename); -+ - } - } - apr_brigade_cleanup(bb); -@@ -1610,7 +1648,13 @@ - return HTTP_MOVED_TEMPORARILY; - } - -- ap_pass_brigade(r->output_filters, bb); -+ rv = ap_pass_brigade(r->output_filters, bb); -+ if (rv != APR_SUCCESS) { -+ /* APLOG_ERR because the core output filter message is at error, -+ * but doesn't know it's passing CGI output -+ */ -+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(02550) "Failed to flush CGI output to client"); -+ } - } - - if (nph) { -@@ -1741,6 +1785,8 @@ - request_rec *r = f->r; - cgid_server_conf *conf = ap_get_module_config(r->server->module_config, - &cgid_module); -+ cgid_dirconf *dc = ap_get_module_config(r->per_dir_config, &cgid_module); -+ - struct cleanup_script_info *info; - - add_ssi_vars(r); -@@ -1770,6 +1816,13 @@ - * get rid of the cleanup we registered when we created the socket. - */ - apr_os_pipe_put_ex(&tempsock, &sd, 1, r->pool); -+ if (dc->timeout > 0) { -+ apr_file_pipe_timeout_set(tempsock, dc->timeout); -+ } -+ else { -+ apr_file_pipe_timeout_set(tempsock, r->server->timeout); -+ } -+ - apr_pool_cleanup_kill(r->pool, (void *)((long)sd), close_unix_socket); - - APR_BRIGADE_INSERT_TAIL(bb, apr_bucket_pipe_create(tempsock, -@@ -1875,7 +1928,7 @@ - - AP_DECLARE_MODULE(cgid) = { - STANDARD20_MODULE_STUFF, -- NULL, /* dir config creater */ -+ create_cgid_dirconf, /* dir config creater */ - NULL, /* dir merger --- default is to override */ - create_cgid_config, /* server config */ - merge_cgid_config, /* merge server config */ diff --git a/SOURCES/httpd-2.4.6-CVE-2014-3581.patch b/SOURCES/httpd-2.4.6-CVE-2014-3581.patch deleted file mode 100644 index 2f2217d..0000000 --- a/SOURCES/httpd-2.4.6-CVE-2014-3581.patch +++ /dev/null @@ -1,17 +0,0 @@ -diff --git a/modules/cache/cache_util.c b/modules/cache/cache_util.c -index 7b7fb45..fbebb1e 100644 ---- a/modules/cache/cache_util.c -+++ b/modules/cache/cache_util.c -@@ -1251,8 +1251,10 @@ CACHE_DECLARE(apr_table_t *)ap_cache_cacheable_headers_out(request_rec *r) - - if (!apr_table_get(headers_out, "Content-Type") - && r->content_type) { -- apr_table_setn(headers_out, "Content-Type", -- ap_make_content_type(r, r->content_type)); -+ const char *ctype = ap_make_content_type(r, r->content_type); -+ if (ctype) { -+ apr_table_setn(headers_out, "Content-Type", ctype); -+ } - } - - if (!apr_table_get(headers_out, "Content-Encoding") diff --git a/SOURCES/httpd-2.4.6-ab-overflow.patch b/SOURCES/httpd-2.4.6-ab-overflow.patch new file mode 100644 index 0000000..91a76b2 --- /dev/null +++ b/SOURCES/httpd-2.4.6-ab-overflow.patch @@ -0,0 +1,20 @@ +--- a/support/ab.c 2014/08/14 12:12:38 1617912 ++++ b/support/ab.c 2014/08/14 12:15:31 1617913 +@@ -1029,7 +1029,7 @@ + ap_round_ms(stats[done - 1].time)); + else + printf(" %d%% %5" APR_TIME_T_FMT "\n", percs[i], +- ap_round_ms(stats[(int) (done * percs[i] / 100)].time)); ++ ap_round_ms(stats[(unsigned long)done * percs[i] / 100].time)); + } + } + if (csvperc) { +@@ -1046,7 +1046,7 @@ + else if (i == 100) + t = ap_double_ms(stats[done - 1].time); + else +- t = ap_double_ms(stats[(int) (0.5 + done * i / 100.0)].time); ++ t = ap_double_ms(stats[(unsigned long) (0.5 + (double)done * i / 100.0)].time); + fprintf(out, "%d,%.3f\n", i, t); + } + fclose(out); diff --git a/SOURCES/httpd-2.4.6-full-release.patch b/SOURCES/httpd-2.4.6-full-release.patch index 118c57c..2f8d176 100644 --- a/SOURCES/httpd-2.4.6-full-release.patch +++ b/SOURCES/httpd-2.4.6-full-release.patch @@ -6,7 +6,7 @@ index fb5e34a..e71f716 100644 SrvTk_MINIMAL, /* eg: Apache/2.0.41 */ SrvTk_OS, /* eg: Apache/2.0.41 (UNIX) */ SrvTk_FULL, /* eg: Apache/2.0.41 (UNIX) PHP/4.2.2 FooBar/1.2b */ -- SrvTk_PRODUCT_ONLY /* eg: Apache */ +- SrvTk_PRODUCT_ONLY /* eg: Apache */ + SrvTk_FULL_RELEASE, /* eg: Apache/2.0.41 (UNIX) (Release 32.el7) PHP/4.2.2 FooBar/1.2b */ + SrvTk_PRODUCT_ONLY /* eg: Apache */ }; @@ -34,15 +34,15 @@ index fb5e34a..e71f716 100644 } server_description = AP_SERVER_BASEVERSION " (" PLATFORM ")"; @@ -3232,8 +3236,11 @@ static const char *set_serv_tokens(cmd_parms *cmd, void *dummy, - else if (!strcasecmp(arg1, "Full")) { + else if (!strcasecmp(arg, "Full")) { ap_server_tokens = SrvTk_FULL; } -+ else if (!strcasecmp(arg1, "Full-Release")) { ++ else if (!strcasecmp(arg, "Full-Release")) { + ap_server_tokens = SrvTk_FULL_RELEASE; + } else { -- return "ServerTokens takes 1 argument, 'Prod', 'Major', 'Minor', 'Min', 'OS', or 'Full'"; -+ return "ServerTokens takes 1 argument, 'Prod', 'Major', 'Minor', 'Min', 'OS', 'Full' or 'Full-Release'"; +- return "ServerTokens takes 1 argument: 'Prod(uctOnly)', 'Major', 'Minor', 'Min(imal)', 'OS', or 'Full'"; ++ return "ServerTokens takes 1 argument: 'Prod(uctOnly)', 'Major', 'Minor', 'Min(imal)', 'OS', 'Full' or 'Full-Release'"; } return NULL; diff --git a/SOURCES/httpd-2.4.6-proxy-wss-ssl.patch b/SOURCES/httpd-2.4.6-proxy-wss-ssl.patch deleted file mode 100644 index 628e073..0000000 --- a/SOURCES/httpd-2.4.6-proxy-wss-ssl.patch +++ /dev/null @@ -1,23 +0,0 @@ ---- ./modules/proxy/mod_proxy_wstunnel.c 2013-06-13 10:09:31.000000000 -0500 -+++ ./modules/proxy/mod_proxy_wstunnel.c 2013-11-11 15:58:51.000000000 -0600 -@@ -315,9 +315,11 @@ - conn_rec *c = r->connection; - apr_pool_t *p = r->pool; - apr_uri_t *uri; -+ int is_ssl = 0; - - if (strncasecmp(url, "wss:", 4) == 0) { - scheme = "WSS"; -+ is_ssl = 1; - } - else if (strncasecmp(url, "ws:", 3) == 0) { - scheme = "WS"; -@@ -341,7 +343,7 @@ - return status; - } - -- backend->is_ssl = 0; -+ backend->is_ssl = is_ssl; - backend->close = 0; - - retry = 0; diff --git a/SOURCES/httpd-2.4.6-proxybrigade.patch b/SOURCES/httpd-2.4.6-proxybrigade.patch deleted file mode 100644 index 17f5c4a..0000000 --- a/SOURCES/httpd-2.4.6-proxybrigade.patch +++ /dev/null @@ -1,22 +0,0 @@ ---- a/modules/proxy/mod_proxy_http.c 2013/12/26 18:21:15 1553539 -+++ b/modules/proxy/mod_proxy_http.c 2013/12/26 18:25:04 1553540 -@@ -710,7 +710,7 @@ - force10 = 0; - } - -- header_brigade = apr_brigade_create(p, origin->bucket_alloc); -+ header_brigade = apr_brigade_create(p, bucket_alloc); - rv = ap_proxy_create_hdrbrgd(p, header_brigade, r, p_conn, - worker, conf, uri, url, server_portstr, - &old_cl_val, &old_te_val); -@@ -1813,6 +1813,10 @@ - } - } while (interim_response && (interim_response < AP_MAX_INTERIM_RESPONSES)); - -+ /* We have to cleanup bb brigade, because buckets inserted to it could be -+ * created from scpool and this pool can be freed before this brigade. */ -+ apr_brigade_cleanup(bb); -+ - /* See define of AP_MAX_INTERIM_RESPONSES for why */ - if (interim_response >= AP_MAX_INTERIM_RESPONSES) { - return ap_proxyerror(r, HTTP_BAD_GATEWAY, diff --git a/SOURCES/httpd-2.4.6-r1332643+.patch b/SOURCES/httpd-2.4.6-r1332643+.patch index d2e5565..508bc9d 100644 --- a/SOURCES/httpd-2.4.6-r1332643+.patch +++ b/SOURCES/httpd-2.4.6-r1332643+.patch @@ -100,7 +100,7 @@ http://svn.apache.org/viewvc?view=revision&revision=1487772 --- httpd-2.4.6/modules/ssl/ssl_engine_init.c.r1332643+ +++ httpd-2.4.6/modules/ssl/ssl_engine_init.c @@ -725,6 +725,11 @@ static void ssl_init_ctx_callbacks(serve - #endif + SSL_CTX_set_tmp_dh_callback(ctx, ssl_callback_TmpDH); SSL_CTX_set_info_callback(ctx, ssl_callback_Info); + @@ -110,7 +110,7 @@ http://svn.apache.org/viewvc?view=revision&revision=1487772 +#endif } - static void ssl_init_ctx_verify(server_rec *s, + static apr_status_t ssl_init_ctx_verify(server_rec *s, --- httpd-2.4.6/modules/ssl/ssl_engine_io.c.r1332643+ +++ httpd-2.4.6/modules/ssl/ssl_engine_io.c @@ -297,6 +297,7 @@ typedef struct { @@ -264,7 +264,7 @@ http://svn.apache.org/viewvc?view=revision&revision=1487772 + +#endif /* HAVE_TLS_NPN */ + - #ifndef OPENSSL_NO_SRP + #ifdef HAVE_SRP int ssl_callback_SRPServerParams(SSL *ssl, int *ad, void *arg) --- httpd-2.4.6/modules/ssl/ssl_private.h.r1332643+ @@ -287,9 +287,9 @@ http://svn.apache.org/viewvc?view=revision&revision=1487772 +#define HAVE_TLS_NPN +#endif + - #if (OPENSSL_VERSION_NUMBER >= 0x10000000) - #define MODSSL_SSL_CIPHER_CONST const - #define MODSSL_SSL_METHOD_CONST const + #if defined(SSL_OP_NO_TLSv1_2) + #define HAVE_TLSV1_X + #endif @@ -487,6 +494,12 @@ typedef struct { * connection */ } reneg_state; @@ -310,4 +310,4 @@ http://svn.apache.org/viewvc?view=revision&revision=1487772 +int ssl_callback_AdvertiseNextProtos(SSL *ssl, const unsigned char **data, unsigned int *len, void *arg); /** Session Cache Support */ - void ssl_scache_init(server_rec *, apr_pool_t *); + apr_status_t ssl_scache_init(server_rec *, apr_pool_t *); diff --git a/SOURCES/httpd-2.4.6-r1507681+.patch b/SOURCES/httpd-2.4.6-r1507681+.patch deleted file mode 100644 index 82a3b41..0000000 --- a/SOURCES/httpd-2.4.6-r1507681+.patch +++ /dev/null @@ -1,62 +0,0 @@ -# ./pullrev.sh 1507681 1533447 - -https://bugzilla.redhat.com/show_bug.cgi?id=1004046 - -http://svn.apache.org/viewvc?view=revision&revision=1507681 -http://svn.apache.org/viewvc?view=revision&revision=1533447 - ---- httpd-2.4.6/modules/dav/main/mod_dav.c -+++ httpd-2.4.6/modules/dav/main/mod_dav.c -@@ -2756,7 +2756,7 @@ - * The multistatus responses will contain the information about any - * resource that fails the validation. - * -- * We check the parent resource, too, since this is a MOVE. Moving the -+ * We check the parent resource, too, if this is a MOVE. Moving the - * resource effectively removes it from the parent collection, so we - * must ensure that we have met the appropriate conditions. - * -@@ -2765,7 +2765,9 @@ - */ - if ((err = dav_validate_request(r, resource, depth, NULL, - &multi_response, -- DAV_VALIDATE_PARENT -+ (is_move ? DAV_VALIDATE_PARENT -+ : DAV_VALIDATE_RESOURCE -+ | DAV_VALIDATE_NO_MODIFY) - | DAV_VALIDATE_USE_424, - NULL)) != NULL) { - err = dav_push_error(r->pool, err->status, 0, ---- httpd-2.4.6/modules/dav/main/util.c -+++ httpd-2.4.6/modules/dav/main/util.c -@@ -954,13 +954,16 @@ - /* - ** For methods other than LOCK: - ** -- ** If we have no locks, then can be set to true -- -+ ** If we have no locks or if the resource is not being modified -+ ** (per RFC 4918 the lock token is not required on resources -+ ** we are not changing), then can be set to true -- - ** pretending that we've already met the requirement of seeing one - ** of the resource's locks in the If: header. - ** - ** Otherwise, it must be cleared and we'll look for one. - */ -- seen_locktoken = (lock_list == NULL); -+ seen_locktoken = (lock_list == NULL -+ || flags & DAV_VALIDATE_NO_MODIFY); - } - - /* ---- httpd-2.4.6/modules/dav/main/mod_dav.h -+++ httpd-2.4.6/modules/dav/main/mod_dav.h -@@ -1297,6 +1297,9 @@ - the 424 DAV:response */ - #define DAV_VALIDATE_USE_424 0x0080 /* return 424 status, not 207 */ - #define DAV_VALIDATE_IS_PARENT 0x0100 /* for internal use */ -+#define DAV_VALIDATE_NO_MODIFY 0x0200 /* resource is not being modified -+ so allow even if lock token -+ is not provided */ - - /* Lock-null related public lock functions */ - DAV_DECLARE(int) dav_get_resource_state(request_rec *r, diff --git a/SOURCES/httpd-2.4.6-r1537535.patch b/SOURCES/httpd-2.4.6-r1537535.patch deleted file mode 100644 index dc2c6c9..0000000 --- a/SOURCES/httpd-2.4.6-r1537535.patch +++ /dev/null @@ -1,38 +0,0 @@ -# ./pullrev.sh 1537535 - -http://svn.apache.org/viewvc?view=revision&revision=1537535 - ---- httpd-2.4.6/modules/ssl/ssl_engine_config.c.r1537535 -+++ httpd-2.4.6/modules/ssl/ssl_engine_config.c -@@ -198,7 +198,7 @@ static SSLSrvConfigRec *ssl_config_serve - SSLSrvConfigRec *sc = apr_palloc(p, sizeof(*sc)); - - sc->mc = NULL; -- sc->enabled = SSL_ENABLED_FALSE; -+ sc->enabled = SSL_ENABLED_UNSET; - sc->proxy_enabled = UNSET; - sc->vhost_id = NULL; /* set during module init */ - sc->vhost_id_len = 0; /* set during module init */ ---- httpd-2.4.6/modules/ssl/ssl_engine_init.c.r1537535 -+++ httpd-2.4.6/modules/ssl/ssl_engine_init.c -@@ -289,13 +289,16 @@ int ssl_init_Module(apr_pool_t *p, apr_p - sc->vhost_id = ssl_util_vhostid(p, s); - sc->vhost_id_len = strlen(sc->vhost_id); - -- if (ap_get_server_protocol(s) && -- strcmp("https", ap_get_server_protocol(s)) == 0) { -+ /* Default to enabled if SSLEngine is not set explicitly, and -+ * the protocol is https. */ -+ if (ap_get_server_protocol(s) -+ && strcmp("https", ap_get_server_protocol(s)) == 0 -+ && sc->enabled == SSL_ENABLED_UNSET) { - sc->enabled = SSL_ENABLED_TRUE; - } - -- /* If sc->enabled is UNSET, then SSL is optional on this vhost */ -- /* Fix up stuff that may not have been set */ -+ /* Fix up stuff that may not have been set. If sc->enabled is -+ * UNSET, then SSL is disabled on this vhost. */ - if (sc->enabled == SSL_ENABLED_UNSET) { - sc->enabled = SSL_ENABLED_FALSE; - } diff --git a/SOURCES/httpd-2.4.6-sigint.patch b/SOURCES/httpd-2.4.6-sigint.patch new file mode 100644 index 0000000..7574a9c --- /dev/null +++ b/SOURCES/httpd-2.4.6-sigint.patch @@ -0,0 +1,45 @@ +From 20656c3b77cc548b59fea3bde5e2b7705d71c427 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jan=20Kalu=C5=BEa?= +Date: Mon, 18 Aug 2014 07:43:43 +0000 +Subject: [PATCH] prefork: Ignore SIGINT in child. This fixes race-condition in + signals handling when httpd is runnning on foreground and user hits ctrl+c. + In this case, SIGINT is sent to all children followed by SIGTERM from the + main process, which interrupts the SIGINT handler and leads to inconsistency + (process freezes or crashes). + +git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1618555 13f79535-47bb-0310-9956-ffa450edef68 +--- + server/mpm/prefork/prefork.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/server/mpm/prefork/prefork.c b/server/mpm/prefork/prefork.c +index 8790ec0..d6c038b 100644 +--- a/server/mpm/prefork/prefork.c ++++ b/server/mpm/prefork/prefork.c +@@ -222,6 +222,9 @@ static void clean_child_exit(int code) + { + mpm_state = AP_MPMQ_STOPPING; + ++ apr_signal(SIGHUP, SIG_IGN); ++ apr_signal(SIGTERM, SIG_IGN); ++ + if (pchild) { + apr_pool_destroy(pchild); + } +@@ -817,6 +820,13 @@ static int make_child(server_rec *s, int slot) + */ + apr_signal(SIGHUP, just_die); + apr_signal(SIGTERM, just_die); ++ /* Ignore SIGINT in child. This fixes race-condition in signals ++ * handling when httpd is runnning on foreground and user hits ctrl+c. ++ * In this case, SIGINT is sent to all children followed by SIGTERM ++ * from the main process, which interrupts the SIGINT handler and ++ * leads to inconsistency. ++ */ ++ apr_signal(SIGINT, SIG_IGN); + /* The child process just closes listeners on AP_SIG_GRACEFUL. + * The pod is used for signalling the graceful restart. + */ +-- +2.0.4 + diff --git a/SOURCES/httpd-scl-wrapper b/SOURCES/httpd-scl-wrapper new file mode 100644 index 0000000..d1bbee4 --- /dev/null +++ b/SOURCES/httpd-scl-wrapper @@ -0,0 +1,13 @@ +#!/bin/sh + +# We have to re-enable SCL environment, because /sbin/service +# clears almost all environment variables. +# Since X_SCLS is cleared as well, we lose information about other +# collections enabled. +. /opt/rh/httpd24/service-environment +for sclname in $HTTPD24_HTTPD_SCLS_ENABLED ; do + . /opt/rh/$sclname/enable + export X_SCLS="$X_SCLS $sclname" +done + +exec /opt/rh/httpd24/root/usr/sbin/httpd "$@" diff --git a/SOURCES/httpd.conf b/SOURCES/httpd.conf index 3af757c..2ea4d83 100644 --- a/SOURCES/httpd.conf +++ b/SOURCES/httpd.conf @@ -128,7 +128,7 @@ DocumentRoot "$localstatedir/www/html" # Further relax access to the default document root: - + # # Possible values for the Options directive are "None", "All", # or any combination of: diff --git a/SOURCES/httpd.service b/SOURCES/httpd.service index 1c210e2..6e36a09 100644 --- a/SOURCES/httpd.service +++ b/SOURCES/httpd.service @@ -5,9 +5,9 @@ After=network.target remote-fs.target nss-lookup.target [Service] Type=notify EnvironmentFile=$sysconfdir/sysconfig/httpd -ExecStart=$sbindir/httpd $OPTIONS -DFOREGROUND -ExecReload=$sbindir/httpd $OPTIONS -k graceful -ExecStop=$sbindir/httpd $OPTIONS -k graceful-stop +ExecStart=$sbindir/httpd-scl-wrapper $OPTIONS -DFOREGROUND +ExecReload=$sbindir/httpd-scl-wrapper $OPTIONS -k graceful +ExecStop=$sbindir/httpd-scl-wrapper $OPTIONS -k graceful-stop # We want systemd to give httpd some time to finish gracefully, but still want # it to kill httpd after TimeoutStopSec if something went wrong during the # graceful stop. Normally, Systemd sends SIGTERM signal right after the diff --git a/SPECS/httpd.spec b/SPECS/httpd.spec index 688922b..7dd2fc6 100644 --- a/SPECS/httpd.spec +++ b/SPECS/httpd.spec @@ -43,8 +43,8 @@ Summary: Apache HTTP Server Name: %{?scl:%scl_prefix}httpd -Version: 2.4.6 -Release: 25%{?dist} +Version: 2.4.12 +Release: 6%{?dist} URL: http://httpd.apache.org/ Source0: http://www.apache.org/dist/httpd/httpd-%{version}.tar.bz2 Source1: index.html @@ -72,6 +72,8 @@ Source24: 00-systemd.conf Source25: 01-session.conf Source26: action-graceful.sh Source27: action-configtest.sh +Source28: 00-optional.conf +Source29: httpd-scl-wrapper # Documentation Source30: README.confd Source40: htcacheclean.service @@ -83,6 +85,7 @@ Patch2: httpd-2.4.3-apxs.patch Patch3: httpd-2.4.1-deplibs.patch Patch5: httpd-2.4.3-layout.patch Patch6: httpd-2.4.3-apctl-systemd.patch +Patch7: httpd-2.4.12-skiplist.patch # Features/functional changes Patch21: httpd-2.4.6-full-release.patch Patch23: httpd-2.4.4-export.patch @@ -95,24 +98,11 @@ Patch29: httpd-2.4.3-mod_systemd.patch Patch30: httpd-2.4.4-cachehardmax.patch Patch31: httpd-2.4.6-sslmultiproxy.patch # Bug fixes -Patch51: httpd-2.4.3-sslsninotreq.patch Patch55: httpd-2.4.4-malformed-host.patch Patch56: httpd-2.4.4-mod_unique_id.patch -Patch57: httpd-2.4.6-proxybrigade.patch -Patch58: httpd-2.4.6-r1507681+.patch Patch59: httpd-2.4.6-r1556473.patch -Patch60: httpd-2.4.6-r1537535.patch -Patch61: httpd-2.4.6-proxy-wss-ssl.patch -# Security fixes -Patch200: httpd-2.4.6-CVE-2013-6438.patch -Patch201: httpd-2.4.6-CVE-2014-0098.patch -Patch202: httpd-2.4.6-CVE-2013-4352.patch -Patch203: httpd-2.4.6-CVE-2014-0117.patch -Patch204: httpd-2.4.6-CVE-2014-0118.patch -Patch205: httpd-2.4.6-CVE-2014-0226.patch -Patch206: httpd-2.4.6-CVE-2014-0231.patch -Patch207: httpd-2.4.6-CVE-2013-5704.patch -Patch208: httpd-2.4.6-CVE-2014-3581.patch +Patch63: httpd-2.4.6-ab-overflow.patch +Patch64: httpd-2.4.6-sigint.patch License: ASL 2.0 Group: System Environment/Daemons BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root @@ -202,7 +192,6 @@ Summary: HTML and XML content filters for the Apache HTTP Server Requires: %{?scl:%scl_prefix}httpd = 0:%{version}-%{release}, %{?scl:%scl_prefix}httpd-mmn = %{mmnisa} BuildRequires: libxml2-devel Epoch: 1 -Obsoletes: mod_proxy_html < 1:2.4.1-2 %description -n %{?scl:%scl_prefix}mod_proxy_html The mod_proxy_html and mod_xml2enc modules provide filters which can @@ -243,6 +232,7 @@ export LD_LIBRARY_PATH=%{_libdir}:$LD_LIBRARY_PATH %patch3 -p1 -b .deplibs %patch5 -p1 -b .layout %patch6 -p1 -b .apctlsystemd +%patch7 -p1 -b .skiplist %patch21 -p1 -b .fullrelease %patch23 -p1 -b .export @@ -255,24 +245,11 @@ export LD_LIBRARY_PATH=%{_libdir}:$LD_LIBRARY_PATH %patch30 -p1 -b .cachehardmax %patch31 -p1 -b .sslmultiproxy -%patch51 -p1 -b .sninotreq %patch55 -p1 -b .malformedhost %patch56 -p1 -b .uniqueid -%patch57 -p1 -b .proxybrigade -%patch58 -p1 -b .r1507681+ %patch59 -p1 -b .r1556473 -%patch60 -p1 -b .r1537535 -%patch61 -p1 -b .wssssl - -%patch200 -p1 -b .cve6438 -%patch201 -p1 -b .cve0098 -%patch202 -p1 -b .cve4352 -%patch203 -p1 -b .cve0117 -%patch204 -p1 -b .cve0118 -%patch205 -p1 -b .cve0226 -%patch206 -p1 -b .cve0231 -%patch207 -p1 -b .cve5704 -%patch208 -p1 -b .cve3581 +%patch63 -p1 -b .aboverflow +%patch64 -p1 -b .sigint # Patch in the vendor string and the release string sed -i '/^#define PLATFORM/s/Unix/%{vstring}/' os/unix/os.h @@ -367,6 +344,8 @@ sed -i 's|\$sysconfdir|%{_sysconfdir}|' \ $RPM_BUILD_ROOT%{_unitdir}/%{httpd_service} sed -i 's|\$localstatedir|%{_localstatedir}|' \ $RPM_BUILD_ROOT%{_unitdir}/%{httpd_service} +sed -i 's|\$sclscripts|%{?_scl_scripts}|' \ + $RPM_BUILD_ROOT%{_unitdir}/%{httpd_service} # Change the htcacheclean.service paths sed -i 's|\$sbindir|%{_sbindir}|' \ @@ -377,6 +356,8 @@ sed -i 's|\$localstatedir|%{_localstatedir}|' \ $RPM_BUILD_ROOT%{_unitdir}/%{htcacheclean_service} sed -i 's|\$httpd_service|%{httpd_service}|' \ $RPM_BUILD_ROOT%{_unitdir}/%{htcacheclean_service} +sed -i 's|\$sclscripts|%{?_scl_scripts}|' \ + $RPM_BUILD_ROOT%{_unitdir}/%{htcacheclean_service} %else # install SYSV init stuff mkdir -p $RPM_BUILD_ROOT/etc/rc.d/init.d @@ -392,6 +373,8 @@ sed -i 's|\$sysconfdir|%{_sysconfdir}|' \ $RPM_BUILD_ROOT/etc/rc.d/init.d/%{httpd_init} sed -i 's|\$localstatedir|%{_localstatedir}|' \ $RPM_BUILD_ROOT/etc/rc.d/init.d/%{httpd_init} +sed -i 's|\$sclscripts|%{?_scl_scripts}|' \ + $RPM_BUILD_ROOT/etc/rc.d/init.d/%{httpd_init} # Change the htcacheclean.init paths sed -i 's|\$sbindir|%{_sbindir}|' \ @@ -400,6 +383,8 @@ sed -i 's|\$sysconfdir|%{_sysconfdir}|' \ $RPM_BUILD_ROOT/etc/rc.d/init.d/%{htcacheclean_init} sed -i 's|\$localstatedir|%{_localstatedir}|' \ $RPM_BUILD_ROOT/etc/rc.d/init.d/%{htcacheclean_init} +sed -i 's|\$sclscripts|%{?_scl_scripts}|' \ + $RPM_BUILD_ROOT/etc/rc.d/init.d/%{htcacheclean_init} %endif # install conf file/directory @@ -409,7 +394,7 @@ install -m 644 $RPM_SOURCE_DIR/README.confd \ $RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf.d/README for f in 00-base.conf 00-mpm.conf 00-lua.conf 01-cgi.conf 00-dav.conf \ 00-proxy.conf 00-ssl.conf 01-ldap.conf 00-proxyhtml.conf \ - 01-ldap.conf 01-session.conf 00-systemd.conf; do + 01-ldap.conf 01-session.conf 00-systemd.conf 00-optional.conf; do install -m 644 -p $RPM_SOURCE_DIR/$f \ $RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf.modules.d/$f done @@ -536,12 +521,12 @@ install -m755 $RPM_SOURCE_DIR/httpd-ssl-pass-dialog \ %if %{use_systemd} # Install action scripts -mkdir -p $RPM_BUILD_ROOT%{_root_libexecdir}/initscripts/legacy-actions/%{?scl:%scl_prefix}httpd +mkdir -p $RPM_BUILD_ROOT/%{_root_libexecdir}/initscripts/legacy-actions/%{?scl:%scl_prefix}httpd for f in graceful configtest; do install -p -m 755 $RPM_SOURCE_DIR/action-${f}.sh \ - $RPM_BUILD_ROOT%{_root_libexecdir}/initscripts/legacy-actions/%{?scl:%scl_prefix}httpd/${f} + $RPM_BUILD_ROOT/%{_root_libexecdir}/initscripts/legacy-actions/%{?scl:%scl_prefix}httpd/${f} sed -i 's|\$sbindir|%{_sbindir}|' \ - $RPM_BUILD_ROOT%{_root_libexecdir}/initscripts/legacy-actions/%{?scl:%scl_prefix}httpd/${f} + $RPM_BUILD_ROOT/%{_root_libexecdir}/initscripts/legacy-actions/%{?scl:%scl_prefix}httpd/${f} done %endif @@ -580,7 +565,7 @@ rm -vf \ $RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf/mime.types \ $RPM_BUILD_ROOT%{_libdir}/httpd/modules/*.exp \ $RPM_BUILD_ROOT%{_libdir}/httpd/build/config.nice \ - $RPM_BUILD_ROOT%{_bindir}/ap?-config \ + $RPM_BUILD_ROOT%{_bindir}/{ap?-config,dbmmanage} \ $RPM_BUILD_ROOT%{_sbindir}/{checkgid,dbmmanage,envvars*} \ $RPM_BUILD_ROOT%{contentdir}/htdocs/* \ $RPM_BUILD_ROOT%{_mandir}/man1/dbmmanage.* \ @@ -591,6 +576,8 @@ rm -rf $RPM_BUILD_ROOT/%{_sysconfdir}/httpd/conf/{original,extra} # Make suexec a+rw so it can be stripped. %%files lists real permissions chmod 755 $RPM_BUILD_ROOT%{_sbindir}/suexec +install -pm 0755 %{SOURCE29} %{buildroot}%{_sbindir}/httpd-scl-wrapper + %pre # Add the "apache" user /usr/sbin/useradd -c "Apache" -u 48 \ @@ -607,6 +594,9 @@ chmod 755 $RPM_BUILD_ROOT%{_sbindir}/suexec semanage fcontext -a -e /var/log/httpd %{httpd_logdir} >/dev/null 2>&1 || : restorecon -R %{httpd_logdir} >/dev/null 2>&1 || : +semanage fcontext -a -t httpd_exec_t "%{_root_sbindir}/httpd-scl-wrapper" +restorecon -R %{_scl_root} >/dev/null 2>&1 || : + %preun %if %{use_systemd} %systemd_preun %{httpd_service} %{htcacheclean_service} @@ -642,7 +632,7 @@ if [ -f %{sslkey} -o -f %{sslcert} ]; then exit 0 fi -%{_root_bindir}/openssl genrsa -rand /proc/apm:/proc/cpuinfo:/proc/dma:/proc/filesystems:/proc/interrupts:/proc/ioports:/proc/pci:/proc/rtc:/proc/uptime 1024 > %{sslkey} 2> /dev/null +%{_root_bindir}/openssl genrsa -rand /proc/apm:/proc/cpuinfo:/proc/dma:/proc/filesystems:/proc/interrupts:/proc/ioports:/proc/pci:/proc/rtc:/proc/uptime 2048 > %{sslkey} 2> /dev/null FQDN=`hostname` if [ "x${FQDN}" = "x" ]; then @@ -650,7 +640,7 @@ if [ "x${FQDN}" = "x" ]; then fi cat << EOF | %{_root_bindir}/openssl req -new -key %{sslkey} \ - -x509 -days 365 -set_serial $RANDOM -extensions v3_req \ + -x509 -sha256 -days 365 -set_serial $RANDOM -extensions v3_req \ -out %{sslcert} 2>/dev/null -- SomeState @@ -715,6 +705,7 @@ rm -rf $RPM_BUILD_ROOT %{_sbindir}/fcgistarter %{_sbindir}/apachectl %{_sbindir}/rotatelogs +%{_sbindir}/httpd-scl-wrapper %caps(cap_setuid,cap_setgid+pe) %attr(510,root,%{suexec_caller}) %{_sbindir}/suexec %dir %{_libdir}/httpd @@ -811,6 +802,38 @@ rm -rf $RPM_BUILD_ROOT %endif %changelog +* Thu Mar 05 2015 Jan Kaluza - 2.4.12-6 +- remove old sslsninotreq patch (#1199040) + +* Thu Feb 26 2015 Jan Kaluza - 2.4.12-5 +- fix wrong path to document root in httpd.conf (#1196559) + +* Tue Feb 17 2015 Jan Kaluza - 2.4.12-4 +- fix SELinux context of httpd-scl-wrapper (#1193456) + +* Tue Feb 03 2015 Jan Kaluza - 2.4.12-3 +- include apr_skiplist and build against system APR/APR-util (#1187646) + +* Mon Feb 02 2015 Jan Kaluza - 2.4.12-2 +- rebuild against new APR/APR-util (#1187646) + +* Wed Jan 28 2015 Jan Kaluza - 2.4.12-1 +- update to version 2.4.12 +- fix possible crash in SIGINT handling (#1184034) + +* Thu Jan 08 2015 Jan Kaluza - 2.4.10-2 +- allow enabling additional SCLs using service-environment file +- enable mod_request by default for mod_auth_form +- move disabled-by-default modules from 00-base.conf to 00-optional.conf + +* Fri Jan 02 2015 Jan Kaluza - 2.4.10-1 +- update to 2.4.10 +- remove mod_proxy_html obsolete (#1174790) +- remove dbmmanage from httpd-tools (#1151375) +- add slash before root_libexecdir macro (#1149076) +- ab: fix integer overflow when printing stats with lot of requests (#1091650) +- mod_ssl: use 2048-bit RSA key with SHA-256 signature in dummy certificate (#1079925) + * Tue Nov 25 2014 Jan Kaluza - 2.4.6-25 - Remove mod_proxy_fcgi fix for heap-based buffer overflow, httpd-2.4.6 is not affected (CVE-2014-3583)