diff --git a/.cvsignore b/.cvsignore index 532539e..79a4910 100644 --- a/.cvsignore +++ b/.cvsignore @@ -1 +1,2 @@ httpd-2.2.4.tar.gz +httpd-2.2.4 diff --git a/httpd-2.2.3-CVE-2006-5752.patch b/httpd-2.2.3-CVE-2006-5752.patch new file mode 100644 index 0000000..cbf3297 --- /dev/null +++ b/httpd-2.2.3-CVE-2006-5752.patch @@ -0,0 +1,40 @@ +--- httpd-2.2.3/modules/generators/mod_status.c.cve5752 ++++ httpd-2.2.3/modules/generators/mod_status.c +@@ -270,7 +270,7 @@ + if (r->method_number != M_GET) + return DECLINED; + +- ap_set_content_type(r, "text/html"); ++ ap_set_content_type(r, "text/html; charset=ISO-8859-1"); + + /* + * Simple table-driven form data set parser that lets you alter the header +@@ -299,7 +299,7 @@ + no_table_report = 1; + break; + case STAT_OPT_AUTO: +- ap_set_content_type(r, "text/plain"); ++ ap_set_content_type(r, "text/plain; charset=ISO-8859-1"); + short_report = 1; + break; + } +@@ -673,7 +673,8 @@ + ap_escape_html(r->pool, + ws_record->client), + ap_escape_html(r->pool, +- ws_record->request), ++ ap_escape_logitem(r->pool, ++ ws_record->request)), + ap_escape_html(r->pool, + ws_record->vhost)); + } +@@ -763,7 +764,8 @@ + ap_escape_html(r->pool, + ws_record->vhost), + ap_escape_html(r->pool, +- ws_record->request)); ++ ap_escape_logitem(r->pool, ++ ws_record->request))); + } /* no_table_report */ + } /* for (j...) */ + } /* for (i...) */ diff --git a/httpd-2.2.3-CVE-2007-1863.patch b/httpd-2.2.3-CVE-2007-1863.patch new file mode 100644 index 0000000..41c3ba7 --- /dev/null +++ b/httpd-2.2.3-CVE-2007-1863.patch @@ -0,0 +1,74 @@ +--- httpd-2.2.3/modules/cache/cache_util.c.cve1863 ++++ httpd-2.2.3/modules/cache/cache_util.c +@@ -231,7 +231,8 @@ + age = ap_cache_current_age(info, age_c, r->request_time); + + /* extract s-maxage */ +- if (cc_cresp && ap_cache_liststr(r->pool, cc_cresp, "s-maxage", &val)) { ++ if (cc_cresp && ap_cache_liststr(r->pool, cc_cresp, "s-maxage", &val) ++ && val != NULL) { + smaxage = apr_atoi64(val); + } + else { +@@ -240,7 +241,8 @@ + + /* extract max-age from request */ + if (!conf->ignorecachecontrol +- && cc_req && ap_cache_liststr(r->pool, cc_req, "max-age", &val)) { ++ && cc_req && ap_cache_liststr(r->pool, cc_req, "max-age", &val) ++ && val != NULL) { + maxage_req = apr_atoi64(val); + } + else { +@@ -248,7 +250,8 @@ + } + + /* extract max-age from response */ +- if (cc_cresp && ap_cache_liststr(r->pool, cc_cresp, "max-age", &val)) { ++ if (cc_cresp && ap_cache_liststr(r->pool, cc_cresp, "max-age", &val) ++ && val != NULL) { + maxage_cresp = apr_atoi64(val); + } + else { +@@ -270,7 +273,20 @@ + + /* extract max-stale */ + if (cc_req && ap_cache_liststr(r->pool, cc_req, "max-stale", &val)) { +- maxstale = apr_atoi64(val); ++ if(val != NULL) { ++ maxstale = apr_atoi64(val); ++ } ++ else { ++ /* ++ * If no value is assigned to max-stale, then the client is willing ++ * to accept a stale response of any age (RFC2616 14.9.3). We will ++ * set it to one year in this case as this situation is somewhat ++ * similar to a "never expires" Expires header (RFC2616 14.21) ++ * which is set to a date one year from the time the response is ++ * sent in this case. ++ */ ++ maxstale = APR_INT64_C(86400*365); ++ } + } + else { + maxstale = 0; +@@ -278,7 +294,8 @@ + + /* extract min-fresh */ + if (!conf->ignorecachecontrol +- && cc_req && ap_cache_liststr(r->pool, cc_req, "min-fresh", &val)) { ++ && cc_req && ap_cache_liststr(r->pool, cc_req, "min-fresh", &val) ++ && val != NULL) { + minfresh = apr_atoi64(val); + } + else { +@@ -407,6 +424,9 @@ + next - val_start); + } + } ++ else { ++ *val = NULL; ++ } + } + return 1; + } diff --git a/httpd-2.2.3-CVE-2007-3304.patch b/httpd-2.2.3-CVE-2007-3304.patch new file mode 100644 index 0000000..32a1af2 --- /dev/null +++ b/httpd-2.2.3-CVE-2007-3304.patch @@ -0,0 +1,110 @@ +--- httpd-2.2.3/include/mpm_common.h.cve3304 ++++ httpd-2.2.3/include/mpm_common.h +@@ -145,6 +145,17 @@ + #endif + + /** ++ * Safely signal an MPM child process, if the process is in the ++ * current process group. Otherwise fail. ++ * @param pid the process id of a child process to signal ++ * @param sig the signal number to send ++ * @return APR_SUCCESS if signal is sent, otherwise an error as per kill(3) ++ */ ++#ifdef AP_MPM_WANT_RECLAIM_CHILD_PROCESSES ++apr_status_t ap_mpm_safe_kill(pid_t pid, int sig); ++#endif ++ ++/** + * Determine if any child process has died. If no child process died, then + * this process sleeps for the amount of time specified by the MPM defined + * macro SCOREBOARD_MAINTENANCE_INTERVAL. +--- httpd-2.2.3/server/mpm_common.c.cve3304 ++++ httpd-2.2.3/server/mpm_common.c +@@ -126,6 +126,10 @@ + apr_proc_t proc; + apr_status_t waitret; + ++ if (!MPM_VALID_PID(pid)) { ++ return 1; ++ } ++ + proc.pid = pid; + waitret = apr_proc_wait(&proc, NULL, NULL, APR_NOWAIT); + if (waitret != APR_CHILD_NOTDONE) { +@@ -305,6 +309,16 @@ + cur_extra = next; + } + } ++ ++apr_status_t ap_mpm_safe_kill(pid_t pid, int sig) ++{ ++ if (MPM_VALID_PID(pid)) { ++ return kill(pid, sig) ? errno : APR_SUCCESS; ++ } ++ else { ++ return APR_EINVAL; ++ } ++} + #endif /* AP_MPM_WANT_RECLAIM_CHILD_PROCESSES */ + + #ifdef AP_MPM_WANT_WAIT_OR_TIMEOUT +--- httpd-2.2.3/server/mpm/prefork/prefork.c.cve3304 ++++ httpd-2.2.3/server/mpm/prefork/prefork.c +@@ -1127,7 +1127,7 @@ + for (index = 0; index < ap_daemons_limit; ++index) { + if (ap_scoreboard_image->servers[index][0].status != SERVER_DEAD) { + /* Ask each child to close its listeners. */ +- kill(MPM_CHILD_PID(index), AP_SIG_GRACEFUL); ++ ap_mpm_safe_kill(MPM_CHILD_PID(index), AP_SIG_GRACEFUL); + active_children++; + } + } +@@ -1166,7 +1166,7 @@ + active_children = 0; + for (index = 0; index < ap_daemons_limit; ++index) { + if (MPM_CHILD_PID(index) != 0) { +- if (kill(MPM_CHILD_PID(index), 0) == 0) { ++ if (ap_mpm_safe_kill(MPM_CHILD_PID(index), 0) == 0) { + active_children = 1; + /* Having just one child is enough to stay around */ + break; +@@ -1222,7 +1222,7 @@ + * piped loggers, etc. They almost certainly won't handle + * it gracefully. + */ +- kill(ap_scoreboard_image->parent[index].pid, AP_SIG_GRACEFUL); ++ ap_mpm_safe_kill(ap_scoreboard_image->parent[index].pid, AP_SIG_GRACEFUL); + } + } + } +--- httpd-2.2.3/server/mpm/prefork/mpm.h.cve3304 ++++ httpd-2.2.3/server/mpm/prefork/mpm.h +@@ -53,6 +53,7 @@ + #define AP_MPM_USES_POD 1 + #define MPM_CHILD_PID(i) (ap_scoreboard_image->parent[i].pid) + #define MPM_NOTE_CHILD_KILLED(i) (MPM_CHILD_PID(i) = 0) ++#define MPM_VALID_PID(p) (getpgid(p) == getpgrp()) + #define MPM_ACCEPT_FUNC unixd_accept + + extern int ap_threads_per_child; +--- httpd-2.2.3/server/mpm/worker/worker.c.cve3304 ++++ httpd-2.2.3/server/mpm/worker/worker.c +@@ -1814,7 +1814,7 @@ + active_children = 0; + for (index = 0; index < ap_daemons_limit; ++index) { + if (MPM_CHILD_PID(index) != 0) { +- if (kill(MPM_CHILD_PID(index), 0) == 0) { ++ if (ap_mpm_safe_kill(MPM_CHILD_PID(index), 0) == 0) { + active_children = 1; + /* Having just one child is enough to stay around */ + break; +--- httpd-2.2.3/server/mpm/worker/mpm.h.cve3304 ++++ httpd-2.2.3/server/mpm/worker/mpm.h +@@ -52,6 +52,7 @@ + #define MPM_CHILD_PID(i) (ap_scoreboard_image->parent[i].pid) + #define MPM_NOTE_CHILD_KILLED(i) (MPM_CHILD_PID(i) = 0) + #define MPM_ACCEPT_FUNC unixd_accept ++#define MPM_VALID_PID(p) (getpgid(p) == getpgrp()) + + extern int ap_threads_per_child; + extern int ap_max_daemons_limit; diff --git a/httpd-2.2.4-CVE-2007-1862.patch b/httpd-2.2.4-CVE-2007-1862.patch new file mode 100644 index 0000000..17e6cc5 --- /dev/null +++ b/httpd-2.2.4-CVE-2007-1862.patch @@ -0,0 +1,51 @@ +--- httpd-2.2.4/modules/cache/mod_mem_cache.c.cve1862 ++++ httpd-2.2.4/modules/cache/mod_mem_cache.c +@@ -539,12 +539,28 @@ + return OK; + } + ++static apr_table_t *deep_table_copy(apr_pool_t *p, const apr_table_t *table) ++{ ++ const apr_array_header_t *array = apr_table_elts(table); ++ apr_table_entry_t *elts = (apr_table_entry_t *) array->elts; ++ apr_table_t *copy = apr_table_make(p, array->nelts); ++ int i; ++ ++ for (i = 0; i < array->nelts; i++) { ++ if (elts[i].key) { ++ apr_table_add(copy, elts[i].key, elts[i].val); ++ } ++ } ++ ++ return copy; ++} ++ + static apr_status_t recall_headers(cache_handle_t *h, request_rec *r) + { + mem_cache_object_t *mobj = (mem_cache_object_t*) h->cache_obj->vobj; + +- h->req_hdrs = apr_table_copy(r->pool, mobj->req_hdrs); +- h->resp_hdrs = apr_table_copy(r->pool, mobj->header_out); ++ h->req_hdrs = deep_table_copy(r->pool, mobj->req_hdrs); ++ h->resp_hdrs = deep_table_copy(r->pool, mobj->header_out); + + return OK; + } +@@ -585,7 +601,7 @@ + * - The original response headers (for returning with a cached response) + * - The body of the message + */ +- mobj->req_hdrs = apr_table_copy(mobj->pool, r->headers_in); ++ mobj->req_hdrs = deep_table_copy(mobj->pool, r->headers_in); + + /* Precompute how much storage we need to hold the headers */ + headers_out = ap_cache_cacheable_hdrs_out(r->pool, r->headers_out, +@@ -599,7 +615,7 @@ + } + + headers_out = apr_table_overlay(r->pool, headers_out, r->err_headers_out); +- mobj->header_out = apr_table_copy(mobj->pool, headers_out); ++ mobj->header_out = deep_table_copy(mobj->pool, headers_out); + + /* Init the info struct */ + obj->info.status = info->status; diff --git a/httpd.spec b/httpd.spec index b9b2d81..0fdb365 100644 --- a/httpd.spec +++ b/httpd.spec @@ -6,7 +6,7 @@ Summary: Apache HTTP Server Name: httpd Version: 2.2.4 -Release: 4 +Release: 4.1%{?dist} URL: http://httpd.apache.org/ Source0: http://www.apache.org/dist/httpd/httpd-%{version}.tar.gz Source1: index.html @@ -36,6 +36,11 @@ Patch24: httpd-2.0.48-corelimit.patch Patch25: httpd-2.0.54-selinux.patch # Bug fixes Patch54: httpd-2.2.0-authnoprov.patch +# Security fixes +Patch70: httpd-2.2.3-CVE-2006-5752.patch +Patch71: httpd-2.2.3-CVE-2007-1863.patch +Patch72: httpd-2.2.3-CVE-2007-3304.patch +Patch73: httpd-2.2.4-CVE-2007-1862.patch License: Apache Software License Group: System Environment/Daemons BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root @@ -113,6 +118,11 @@ Security (TLS) protocols. %patch54 -p1 -b .authnoprov +%patch70 -p1 -b .cve5752 +%patch71 -p1 -b .cve1863 +%patch72 -p1 -b .cve3304 +%patch73 -p1 -b .cve1862 + # Patch in vendor/release string sed "s/@RELEASE@/%{vstring}/" < %{PATCH20} | patch -p1 @@ -461,6 +471,11 @@ rm -rf $RPM_BUILD_ROOT %{_libdir}/httpd/build/*.sh %changelog +* Tue Jun 26 2007 Joe Orton 2.2.4-4.1.fc7 +- add security fixes for CVE-2007-1863, CVE-2007-3304, + and CVE-2006-5752 (#244665) +- add security fix for CVE-2007-1862 (#242606) + * Wed May 9 2007 Joe Orton 2.2.4-4 - update welcome page branding