diff --git a/.gitignore b/.gitignore index 613e631..685fa21 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ SOURCES/apache-poweredby.png -SOURCES/httpd-2.4.51.tar.bz2 +SOURCES/httpd-2.4.53.tar.bz2 diff --git a/.httpd.metadata b/.httpd.metadata index d0f70f2..a97defb 100644 --- a/.httpd.metadata +++ b/.httpd.metadata @@ -1,2 +1,2 @@ 3a7449d6cff00e5ccb3ed8571f34c0528555d38f SOURCES/apache-poweredby.png -d8ae02630f836d7cf60e24f4676e633518f16e2b SOURCES/httpd-2.4.51.tar.bz2 +cc064ed39f3845f2d35183b9b7cb638aa4cabfc9 SOURCES/httpd-2.4.53.tar.bz2 diff --git a/README.debrand b/README.debrand deleted file mode 100644 index 01c46d2..0000000 --- a/README.debrand +++ /dev/null @@ -1,2 +0,0 @@ -Warning: This package was configured for automatic debranding, but the changes -failed to apply. diff --git a/SOURCES/00-base.conf b/SOURCES/00-base.conf index 7cabce0..d0123d1 100644 --- a/SOURCES/00-base.conf +++ b/SOURCES/00-base.conf @@ -23,7 +23,6 @@ LoadModule authz_host_module modules/mod_authz_host.so LoadModule authz_owner_module modules/mod_authz_owner.so LoadModule authz_user_module modules/mod_authz_user.so LoadModule autoindex_module modules/mod_autoindex.so -LoadModule brotli_module modules/mod_brotli.so LoadModule cache_module modules/mod_cache.so LoadModule cache_disk_module modules/mod_cache_disk.so LoadModule cache_socache_module modules/mod_cache_socache.so diff --git a/SOURCES/00-brotli.conf b/SOURCES/00-brotli.conf new file mode 100644 index 0000000..c2e0e9e --- /dev/null +++ b/SOURCES/00-brotli.conf @@ -0,0 +1 @@ +LoadModule brotli_module modules/mod_brotli.so diff --git a/SOURCES/httpd-2.4.43-detect-systemd.patch b/SOURCES/httpd-2.4.43-detect-systemd.patch deleted file mode 100644 index 540687f..0000000 --- a/SOURCES/httpd-2.4.43-detect-systemd.patch +++ /dev/null @@ -1,45 +0,0 @@ -diff --git a/Makefile.in b/Makefile.in -index 0b088ac..9eeb5c7 100644 ---- a/Makefile.in -+++ b/Makefile.in -@@ -4,7 +4,7 @@ CLEAN_SUBDIRS = test - - PROGRAM_NAME = $(progname) - PROGRAM_SOURCES = modules.c --PROGRAM_LDADD = buildmark.o $(HTTPD_LDFLAGS) $(PROGRAM_DEPENDENCIES) $(PCRE_LIBS) $(EXTRA_LIBS) $(AP_LIBS) $(LIBS) -+PROGRAM_LDADD = buildmark.o $(HTTPD_LDFLAGS) $(PROGRAM_DEPENDENCIES) $(HTTPD_LIBS) $(EXTRA_LIBS) $(AP_LIBS) $(LIBS) - PROGRAM_PRELINK = $(COMPILE) -c $(top_srcdir)/server/buildmark.c - PROGRAM_DEPENDENCIES = \ - server/libmain.la \ -diff --git a/acinclude.m4 b/acinclude.m4 -index 2a7e5d1..eb28321 100644 ---- a/acinclude.m4 -+++ b/acinclude.m4 -@@ -624,6 +624,7 @@ case $host in - if test "${ac_cv_header_systemd_sd_daemon_h}" = "no" || test -z "${SYSTEMD_LIBS}"; then - AC_MSG_WARN([Your system does not support systemd.]) - else -+ APR_ADDTO(HTTPD_LIBS, [$SYSTEMD_LIBS]) - AC_DEFINE(HAVE_SYSTEMD, 1, [Define if systemd is supported]) - fi - fi -diff --git a/configure.in b/configure.in -index 3618a5a..74a782b 100644 ---- a/configure.in -+++ b/configure.in -@@ -234,6 +234,7 @@ if test "$PCRE_CONFIG" != "false"; then - AC_MSG_NOTICE([Using external PCRE library from $PCRE_CONFIG]) - APR_ADDTO(PCRE_INCLUDES, [`$PCRE_CONFIG --cflags`]) - APR_ADDTO(PCRE_LIBS, [`$PCRE_CONFIG --libs`]) -+ APR_ADDTO(HTTPD_LIBS, [\$(PCRE_LIBS)]) - else - AC_MSG_ERROR([pcre-config for libpcre not found. PCRE is required and available from http://pcre.org/]) - fi -@@ -710,6 +711,7 @@ APACHE_SUBST(OS_DIR) - APACHE_SUBST(BUILTIN_LIBS) - APACHE_SUBST(SHLIBPATH_VAR) - APACHE_SUBST(OS_SPECIFIC_VARS) -+APACHE_SUBST(HTTPD_LIBS) - - PRE_SHARED_CMDS='echo ""' - POST_SHARED_CMDS='echo ""' diff --git a/SOURCES/httpd-2.4.43-icons.patch b/SOURCES/httpd-2.4.43-icons.patch deleted file mode 100644 index 21518d7..0000000 --- a/SOURCES/httpd-2.4.43-icons.patch +++ /dev/null @@ -1,22 +0,0 @@ -diff --git a/docs/conf/extra/httpd-autoindex.conf.in b/docs/conf/extra/httpd-autoindex.conf.in -index 51b02ed..0e8b626 100644 ---- a/docs/conf/extra/httpd-autoindex.conf.in -+++ b/docs/conf/extra/httpd-autoindex.conf.in -@@ -21,7 +21,7 @@ IndexOptions FancyIndexing HTMLTable VersionSort - Alias /icons/ "@exp_iconsdir@/" - - -- Options Indexes MultiViews -+ Options Indexes MultiViews FollowSymlinks - AllowOverride None - Require all granted - -@@ -53,7 +53,7 @@ AddIcon /icons/dvi.gif .dvi - AddIcon /icons/uuencoded.gif .uu - AddIcon /icons/script.gif .conf .sh .shar .csh .ksh .tcl - AddIcon /icons/tex.gif .tex --AddIcon /icons/bomb.gif core -+AddIcon /icons/bomb.gif core. - - AddIcon /icons/back.gif .. - AddIcon /icons/hand.right.gif README diff --git a/SOURCES/httpd-2.4.51-CVE-2021-44224.patch b/SOURCES/httpd-2.4.51-CVE-2021-44224.patch deleted file mode 100644 index e4d8b03..0000000 --- a/SOURCES/httpd-2.4.51-CVE-2021-44224.patch +++ /dev/null @@ -1,252 +0,0 @@ -diff --git a/include/http_protocol.h b/include/http_protocol.h -index 9ccac89..20bd202 100644 ---- a/include/http_protocol.h -+++ b/include/http_protocol.h -@@ -96,6 +96,13 @@ AP_DECLARE(void) ap_get_mime_headers(request_rec *r); - AP_DECLARE(void) ap_get_mime_headers_core(request_rec *r, - apr_bucket_brigade *bb); - -+/** -+ * Run post_read_request hook and validate. -+ * @param r The current request -+ * @return OK or HTTP_... -+ */ -+AP_DECLARE(int) ap_post_read_request(request_rec *r); -+ - /* Finish up stuff after a request */ - - /** -diff --git a/modules/http/http_request.c b/modules/http/http_request.c -index c9ae5af..d59cfe2 100644 ---- a/modules/http/http_request.c -+++ b/modules/http/http_request.c -@@ -680,7 +680,7 @@ static request_rec *internal_internal_redirect(const char *new_uri, - * to do their thing on internal redirects as well. Perhaps this is a - * misnamed function. - */ -- if ((access_status = ap_run_post_read_request(new))) { -+ if ((access_status = ap_post_read_request(new))) { - ap_die(access_status, new); - return NULL; - } -diff --git a/modules/proxy/mod_proxy.c b/modules/proxy/mod_proxy.c -index ee4f1fb..ff9f81d 100644 ---- a/modules/proxy/mod_proxy.c -+++ b/modules/proxy/mod_proxy.c -@@ -777,11 +777,12 @@ static int proxy_detect(request_rec *r) - - if (conf->req && r->parsed_uri.scheme) { - /* but it might be something vhosted */ -- if (!(r->parsed_uri.hostname -- && !ap_cstr_casecmp(r->parsed_uri.scheme, ap_http_scheme(r)) -- && ap_matches_request_vhost(r, r->parsed_uri.hostname, -- (apr_port_t)(r->parsed_uri.port_str ? r->parsed_uri.port -- : ap_default_port(r))))) { -+ if (!r->parsed_uri.hostname -+ || ap_cstr_casecmp(r->parsed_uri.scheme, ap_http_scheme(r)) != 0 -+ || !ap_matches_request_vhost(r, r->parsed_uri.hostname, -+ (apr_port_t)(r->parsed_uri.port_str -+ ? r->parsed_uri.port -+ : ap_default_port(r)))) { - r->proxyreq = PROXYREQ_PROXY; - r->uri = r->unparsed_uri; - r->filename = apr_pstrcat(r->pool, "proxy:", r->uri, NULL); -@@ -2021,6 +2022,7 @@ static const char * - struct proxy_alias *new; - char *f = cmd->path; - char *r = NULL; -+ const char *real; - char *word; - apr_table_t *params = apr_table_make(cmd->pool, 5); - const apr_array_header_t *arr; -@@ -2107,6 +2109,10 @@ static const char * - if (r == NULL) { - return "ProxyPass|ProxyPassMatch needs a path when not defined in a location"; - } -+ if (!(real = ap_proxy_de_socketfy(cmd->temp_pool, r))) { -+ return "ProxyPass|ProxyPassMatch uses an invalid \"unix:\" URL"; -+ } -+ - - /* if per directory, save away the single alias */ - if (cmd->path) { -@@ -2123,7 +2129,7 @@ static const char * - } - - new->fake = apr_pstrdup(cmd->pool, f); -- new->real = apr_pstrdup(cmd->pool, ap_proxy_de_socketfy(cmd->pool, r)); -+ new->real = apr_pstrdup(cmd->pool, real); - new->flags = flags; - if (worker_type & AP_PROXY_WORKER_IS_MATCH) { - new->regex = ap_pregcomp(cmd->pool, f, AP_REG_EXTENDED); -@@ -2649,6 +2655,7 @@ static const char *add_member(cmd_parms *cmd, void *dummy, const char *arg) - proxy_worker *worker; - char *path = cmd->path; - char *name = NULL; -+ const char *real; - char *word; - apr_table_t *params = apr_table_make(cmd->pool, 5); - const apr_array_header_t *arr; -@@ -2689,6 +2696,9 @@ static const char *add_member(cmd_parms *cmd, void *dummy, const char *arg) - return "BalancerMember must define balancer name when outside section"; - if (!name) - return "BalancerMember must define remote proxy server"; -+ if (!(real = ap_proxy_de_socketfy(cmd->temp_pool, name))) { -+ return "BalancerMember uses an invalid \"unix:\" URL"; -+ } - - ap_str_tolower(path); /* lowercase scheme://hostname */ - -@@ -2701,8 +2711,7 @@ static const char *add_member(cmd_parms *cmd, void *dummy, const char *arg) - } - - /* Try to find existing worker */ -- worker = ap_proxy_get_worker(cmd->temp_pool, balancer, conf, -- ap_proxy_de_socketfy(cmd->temp_pool, name)); -+ worker = ap_proxy_get_worker(cmd->temp_pool, balancer, conf, real); - if (!worker) { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server, APLOGNO(01147) - "Defining worker '%s' for balancer '%s'", -@@ -2799,9 +2808,14 @@ static const char * - } - } - else { -+ const char *real; -+ -+ if (!(real = ap_proxy_de_socketfy(cmd->temp_pool, name))) { -+ return "ProxySet uses an invalid \"unix:\" URL"; -+ } -+ - worker = ap_proxy_get_worker_ex(cmd->temp_pool, NULL, conf, -- ap_proxy_de_socketfy(cmd->temp_pool, name), -- worker_type); -+ real, worker_type); - if (!worker) { - if (in_proxy_section) { - err = ap_proxy_define_worker_ex(cmd->pool, &worker, NULL, -@@ -2944,9 +2958,14 @@ static const char *proxysection(cmd_parms *cmd, void *mconfig, const char *arg) - } - } - else { -+ const char *real; -+ -+ if (!(real = ap_proxy_de_socketfy(cmd->temp_pool, conf->p))) { -+ return " uses an invalid \"unix:\" URL"; -+ } -+ - worker = ap_proxy_get_worker_ex(cmd->temp_pool, NULL, sconf, -- ap_proxy_de_socketfy(cmd->temp_pool, conf->p), -- worker_type); -+ real, worker_type); - if (!worker) { - err = ap_proxy_define_worker_ex(cmd->pool, &worker, NULL, sconf, - conf->p, worker_type); -diff --git a/modules/proxy/mod_proxy.h b/modules/proxy/mod_proxy.h -index 044a6c4..c21c4d8 100644 ---- a/modules/proxy/mod_proxy.h -+++ b/modules/proxy/mod_proxy.h -@@ -751,6 +751,7 @@ PROXY_DECLARE(int) ap_proxy_worker_can_upgrade(apr_pool_t *p, - #define AP_PROXY_WORKER_IS_PREFIX (1u << 0) - #define AP_PROXY_WORKER_IS_MATCH (1u << 1) - #define AP_PROXY_WORKER_IS_MALLOCED (1u << 2) -+#define AP_PROXY_WORKER_NO_UDS (1u << 3) - - /** - * Get the worker from proxy configuration, looking for either PREFIXED or -diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c -index 8225045..cbe300f 100644 ---- a/modules/proxy/proxy_util.c -+++ b/modules/proxy/proxy_util.c -@@ -1741,7 +1741,12 @@ PROXY_DECLARE(proxy_worker *) ap_proxy_get_worker_ex(apr_pool_t *p, - return NULL; - } - -+ if (!(mask & AP_PROXY_WORKER_NO_UDS)) { - url = ap_proxy_de_socketfy(p, url); -+ if (!url) { -+ return NULL; -+ } -+ } - - c = ap_strchr_c(url, ':'); - if (c == NULL || c[1] != '/' || c[2] != '/' || c[3] == '\0') { -@@ -2323,22 +2328,22 @@ PROXY_DECLARE(int) ap_proxy_pre_request(proxy_worker **worker, - - access_status = proxy_run_pre_request(worker, balancer, r, conf, url); - if (access_status == DECLINED && *balancer == NULL) { -- *worker = ap_proxy_get_worker(r->pool, NULL, conf, *url); -+ const int forward = (r->proxyreq == PROXYREQ_PROXY); -+ *worker = ap_proxy_get_worker_ex(r->pool, NULL, conf, *url, -+ forward ? AP_PROXY_WORKER_NO_UDS : 0); - if (*worker) { - ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, - "%s: found worker %s for %s", - (*worker)->s->scheme, (*worker)->s->name, *url); -- *balancer = NULL; -- if (!fix_uds_filename(r, url)) { -+ if (!forward && !fix_uds_filename(r, url)) { - return HTTP_INTERNAL_SERVER_ERROR; - } - access_status = OK; - } -- else if (r->proxyreq == PROXYREQ_PROXY) { -+ else if (forward) { - if (conf->forward) { - ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, - "*: found forward proxy worker for %s", *url); -- *balancer = NULL; - *worker = conf->forward; - access_status = OK; - /* -@@ -2352,8 +2357,8 @@ PROXY_DECLARE(int) ap_proxy_pre_request(proxy_worker **worker, - else if (r->proxyreq == PROXYREQ_REVERSE) { - if (conf->reverse) { - ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, -- "*: using default reverse proxy worker for %s (no keepalive)", *url); -- *balancer = NULL; -+ "*: using default reverse proxy worker for %s " -+ "(no keepalive)", *url); - *worker = conf->reverse; - access_status = OK; - /* -diff --git a/server/protocol.c b/server/protocol.c -index 3d74c5b..2214f72 100644 ---- a/server/protocol.c -+++ b/server/protocol.c -@@ -1548,7 +1548,7 @@ request_rec *ap_read_request(conn_rec *conn) - /* we may have switched to another server */ - apply_server_config(r); - -- if ((access_status = ap_run_post_read_request(r))) { -+ if ((access_status = ap_post_read_request(r))) { - goto die; - } - -@@ -1603,6 +1603,27 @@ ignore: - return NULL; - } - -+AP_DECLARE(int) ap_post_read_request(request_rec *r) -+{ -+ int status; -+ -+ if ((status = ap_run_post_read_request(r))) { -+ return status; -+ } -+ -+ /* Enforce http(s) only scheme for non-forward-proxy requests */ -+ if (!r->proxyreq -+ && r->parsed_uri.scheme -+ && (ap_cstr_casecmpn(r->parsed_uri.scheme, "http", 4) != 0 -+ || (r->parsed_uri.scheme[4] != '\0' -+ && (apr_tolower(r->parsed_uri.scheme[4]) != 's' -+ || r->parsed_uri.scheme[5] != '\0')))) { -+ return HTTP_BAD_REQUEST; -+ } -+ -+ return OK; -+} -+ - /* if a request with a body creates a subrequest, remove original request's - * input headers which pertain to the body which has already been read. - * out-of-line helper function for ap_set_sub_req_protocol. diff --git a/SOURCES/httpd-2.4.51-CVE-2021-44790.patch b/SOURCES/httpd-2.4.51-CVE-2021-44790.patch deleted file mode 100644 index ddf4738..0000000 --- a/SOURCES/httpd-2.4.51-CVE-2021-44790.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- a/modules/lua/lua_request.c 2021/12/16 11:09:40 1896038 -+++ b/modules/lua/lua_request.c 2021/12/16 11:15:47 1896039 -@@ -410,6 +410,7 @@ - if (end == NULL) break; - key = (char *) apr_pcalloc(r->pool, 256); - filename = (char *) apr_pcalloc(r->pool, 256); -+ if (end - crlf <= 8) break; - vlen = end - crlf - 8; - buffer = (char *) apr_pcalloc(r->pool, vlen+1); - memcpy(buffer, crlf + 4, vlen); diff --git a/SOURCES/httpd-2.4.51-CVE-2022-22720.patch b/SOURCES/httpd-2.4.51-CVE-2022-22720.patch deleted file mode 100644 index a91923c..0000000 --- a/SOURCES/httpd-2.4.51-CVE-2022-22720.patch +++ /dev/null @@ -1,154 +0,0 @@ -diff --git a/modules/http/http_filters.c b/modules/http/http_filters.c -index b10d2b7..5659c4b 100644 ---- a/modules/http/http_filters.c -+++ b/modules/http/http_filters.c -@@ -1595,9 +1595,9 @@ AP_DECLARE(int) ap_map_http_request_error(apr_status_t rv, int status) - */ - AP_DECLARE(int) ap_discard_request_body(request_rec *r) - { -+ int rc = OK; -+ conn_rec *c = r->connection; - apr_bucket_brigade *bb; -- int seen_eos; -- apr_status_t rv; - - /* Sometimes we'll get in a state where the input handling has - * detected an error where we want to drop the connection, so if -@@ -1606,54 +1606,57 @@ AP_DECLARE(int) ap_discard_request_body(request_rec *r) - * - * This function is also a no-op on a subrequest. - */ -- if (r->main || r->connection->keepalive == AP_CONN_CLOSE || -- ap_status_drops_connection(r->status)) { -+ if (r->main || c->keepalive == AP_CONN_CLOSE) { -+ return OK; -+ } -+ if (ap_status_drops_connection(r->status)) { -+ c->keepalive = AP_CONN_CLOSE; - return OK; - } - - bb = apr_brigade_create(r->pool, r->connection->bucket_alloc); -- seen_eos = 0; -- do { -- apr_bucket *bucket; -+ for (;;) { -+ apr_status_t rv; - - rv = ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES, - APR_BLOCK_READ, HUGE_STRING_LEN); -- - if (rv != APR_SUCCESS) { -- apr_brigade_destroy(bb); -- return ap_map_http_request_error(rv, HTTP_BAD_REQUEST); -+ rc = ap_map_http_request_error(rv, HTTP_BAD_REQUEST); -+ goto cleanup; - } - -- for (bucket = APR_BRIGADE_FIRST(bb); -- bucket != APR_BRIGADE_SENTINEL(bb); -- bucket = APR_BUCKET_NEXT(bucket)) -- { -- const char *data; -- apr_size_t len; -+ while (!APR_BRIGADE_EMPTY(bb)) { -+ apr_bucket *b = APR_BRIGADE_FIRST(bb); - -- if (APR_BUCKET_IS_EOS(bucket)) { -- seen_eos = 1; -- break; -+ if (APR_BUCKET_IS_EOS(b)) { -+ goto cleanup; - } - -- /* These are metadata buckets. */ -- if (bucket->length == 0) { -- continue; -- } -- -- /* We MUST read because in case we have an unknown-length -- * bucket or one that morphs, we want to exhaust it. -+ /* There is no need to read empty or metadata buckets or -+ * buckets of known length, but we MUST read buckets of -+ * unknown length in order to exhaust them. - */ -- rv = apr_bucket_read(bucket, &data, &len, APR_BLOCK_READ); -+ if (b->length == (apr_size_t)-1) { -+ apr_size_t len; -+ const char *data; -+ -+ rv = apr_bucket_read(b, &data, &len, APR_BLOCK_READ); - if (rv != APR_SUCCESS) { -- apr_brigade_destroy(bb); -- return HTTP_BAD_REQUEST; -+ rc = HTTP_BAD_REQUEST; -+ goto cleanup; - } - } -- apr_brigade_cleanup(bb); -- } while (!seen_eos); - -- return OK; -+ apr_bucket_delete(b); -+ } -+ } -+ -+cleanup: -+ apr_brigade_cleanup(bb); -+ if (rc != OK) { -+ c->keepalive = AP_CONN_CLOSE; -+ } -+ return rc; - } - - /* Here we deal with getting the request message body from the client. -diff --git a/server/protocol.c b/server/protocol.c -index 3d74c5b..03b5419 100644 ---- a/server/protocol.c -+++ b/server/protocol.c -@@ -1666,23 +1666,29 @@ AP_DECLARE(void) ap_set_sub_req_protocol(request_rec *rnew, - rnew->main = (request_rec *) r; - } - --static void end_output_stream(request_rec *r) -+static void end_output_stream(request_rec *r, int status) - { - conn_rec *c = r->connection; - apr_bucket_brigade *bb; - apr_bucket *b; - - bb = apr_brigade_create(r->pool, c->bucket_alloc); -+ if (status != OK) { -+ b = ap_bucket_error_create(status, NULL, r->pool, c->bucket_alloc); -+ APR_BRIGADE_INSERT_TAIL(bb, b); -+ } - b = apr_bucket_eos_create(c->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(bb, b); -+ - ap_pass_brigade(r->output_filters, bb); -+ apr_brigade_cleanup(bb); - } - - AP_DECLARE(void) ap_finalize_sub_req_protocol(request_rec *sub) - { - /* tell the filter chain there is no more content coming */ - if (!sub->eos_sent) { -- end_output_stream(sub); -+ end_output_stream(sub, OK); - } - } - -@@ -1693,11 +1699,11 @@ AP_DECLARE(void) ap_finalize_sub_req_protocol(request_rec *sub) - */ - AP_DECLARE(void) ap_finalize_request_protocol(request_rec *r) - { -- (void) ap_discard_request_body(r); -+ int status = ap_discard_request_body(r); - - /* tell the filter chain there is no more content coming */ - if (!r->eos_sent) { -- end_output_stream(r); -+ end_output_stream(r, status); - } - } - diff --git a/SOURCES/httpd-2.4.51-openssl3.patch b/SOURCES/httpd-2.4.51-openssl3.patch deleted file mode 100644 index a4423c7..0000000 --- a/SOURCES/httpd-2.4.51-openssl3.patch +++ /dev/null @@ -1,505 +0,0 @@ - -https://github.com/apache/httpd/pull/258 - ---- httpd-2.4.51/modules/ssl/ssl_engine_init.c.openssl3 -+++ httpd-2.4.51/modules/ssl/ssl_engine_init.c -@@ -91,7 +91,6 @@ - - return 1; - } --#endif - - /* - * Grab well-defined DH parameters from OpenSSL, see the BN_get_rfc* -@@ -171,6 +170,7 @@ - - return NULL; /* impossible to reach. */ - } -+#endif - - static void ssl_add_version_components(apr_pool_t *ptemp, apr_pool_t *pconf, - server_rec *s) -@@ -440,8 +440,9 @@ - - modssl_init_app_data2_idx(); /* for modssl_get_app_data2() at request time */ - -+#if MODSSL_USE_OPENSSL_PRE_1_1_API - init_dh_params(); --#if !MODSSL_USE_OPENSSL_PRE_1_1_API -+#else - init_bio_methods(); - #endif - -@@ -862,7 +863,11 @@ - { - SSL_CTX *ctx = mctx->ssl_ctx; - -+#if MODSSL_USE_OPENSSL_PRE_1_1_API -+ /* Note that for OpenSSL>=1.1, auto selection is enabled via -+ * SSL_CTX_set_dh_auto(,1) if no parameter is configured. */ - SSL_CTX_set_tmp_dh_callback(ctx, ssl_callback_TmpDH); -+#endif - - SSL_CTX_set_info_callback(ctx, ssl_callback_Info); - -@@ -871,6 +876,23 @@ - #endif - } - -+static APR_INLINE -+int modssl_CTX_load_verify_locations(SSL_CTX *ctx, -+ const char *file, -+ const char *path) -+{ -+#if OPENSSL_VERSION_NUMBER < 0x30000000L -+ if (!SSL_CTX_load_verify_locations(ctx, file, path)) -+ return 0; -+#else -+ if (file && !SSL_CTX_load_verify_file(ctx, file)) -+ return 0; -+ if (path && !SSL_CTX_load_verify_dir(ctx, path)) -+ return 0; -+#endif -+ return 1; -+} -+ - static apr_status_t ssl_init_ctx_verify(server_rec *s, - apr_pool_t *p, - apr_pool_t *ptemp, -@@ -911,10 +933,8 @@ - ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, s, - "Configuring client authentication"); - -- if (!SSL_CTX_load_verify_locations(ctx, -- mctx->auth.ca_cert_file, -- mctx->auth.ca_cert_path)) -- { -+ if (!modssl_CTX_load_verify_locations(ctx, mctx->auth.ca_cert_file, -+ mctx->auth.ca_cert_path)) { - ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01895) - "Unable to configure verify locations " - "for client authentication"); -@@ -999,6 +1019,23 @@ - return APR_SUCCESS; - } - -+static APR_INLINE -+int modssl_X509_STORE_load_locations(X509_STORE *store, -+ const char *file, -+ const char *path) -+{ -+#if OPENSSL_VERSION_NUMBER < 0x30000000L -+ if (!X509_STORE_load_locations(store, file, path)) -+ return 0; -+#else -+ if (file && !X509_STORE_load_file(store, file)) -+ return 0; -+ if (path && !X509_STORE_load_path(store, path)) -+ return 0; -+#endif -+ return 1; -+} -+ - static apr_status_t ssl_init_ctx_crl(server_rec *s, - apr_pool_t *p, - apr_pool_t *ptemp, -@@ -1037,8 +1074,8 @@ - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01900) - "Configuring certificate revocation facility"); - -- if (!store || !X509_STORE_load_locations(store, mctx->crl_file, -- mctx->crl_path)) { -+ if (!store || !modssl_X509_STORE_load_locations(store, mctx->crl_file, -+ mctx->crl_path)) { - ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01901) - "Host %s: unable to configure X.509 CRL storage " - "for certificate revocation", mctx->sc->vhost_id); -@@ -1267,6 +1304,31 @@ - return 0; - } - -+static APR_INLINE int modssl_DH_bits(DH *dh) -+{ -+#if OPENSSL_VERSION_NUMBER < 0x30000000L -+ return DH_bits(dh); -+#else -+ return BN_num_bits(DH_get0_p(dh)); -+#endif -+} -+ -+/* SSL_CTX_use_PrivateKey_file() can fail either because the private -+ * key was encrypted, or due to a mismatch between an already-loaded -+ * cert and the key - a common misconfiguration - from calling -+ * X509_check_private_key(). This macro is passed the last error code -+ * off the OpenSSL stack and evaluates to true only for the first -+ * case. With OpenSSL < 3 the second case is identifiable by the -+ * function code, but function codes are not used from 3.0. */ -+#if OPENSSL_VERSION_NUMBER < 0x30000000L -+#define CHECK_PRIVKEY_ERROR(ec) (ERR_GET_FUNC(ec) != X509_F_X509_CHECK_PRIVATE_KEY) -+#else -+#define CHECK_PRIVKEY_ERROR(ec) (ERR_GET_LIB != ERR_LIB_X509 \ -+ || (ERR_GET_REASON(ec) != X509_R_KEY_TYPE_MISMATCH \ -+ && ERR_GET_REASON(ec) != X509_R_KEY_VALUES_MISMATCH \ -+ && ERR_GET_REASON(ec) != X509_R_UNKNOWN_KEY_TYPE)) -+#endif -+ - static apr_status_t ssl_init_server_certs(server_rec *s, - apr_pool_t *p, - apr_pool_t *ptemp, -@@ -1277,7 +1339,7 @@ - const char *vhost_id = mctx->sc->vhost_id, *key_id, *certfile, *keyfile; - int i; - X509 *cert; -- DH *dhparams; -+ DH *dh; - #ifdef HAVE_ECC - EC_GROUP *ecparams = NULL; - int nid; -@@ -1372,8 +1434,7 @@ - } - else if ((SSL_CTX_use_PrivateKey_file(mctx->ssl_ctx, keyfile, - SSL_FILETYPE_PEM) < 1) -- && (ERR_GET_FUNC(ERR_peek_last_error()) -- != X509_F_X509_CHECK_PRIVATE_KEY)) { -+ && CHECK_PRIVKEY_ERROR(ERR_peek_last_error())) { - ssl_asn1_t *asn1; - const unsigned char *ptr; - -@@ -1462,13 +1523,22 @@ - */ - certfile = APR_ARRAY_IDX(mctx->pks->cert_files, 0, const char *); - if (certfile && !modssl_is_engine_id(certfile) -- && (dhparams = ssl_dh_GetParamFromFile(certfile))) { -- SSL_CTX_set_tmp_dh(mctx->ssl_ctx, dhparams); -+ && (dh = ssl_dh_GetParamFromFile(certfile))) { -+ /* ### This should be replaced with SSL_CTX_set0_tmp_dh_pkey() -+ * for OpenSSL 3.0+. */ -+ SSL_CTX_set_tmp_dh(mctx->ssl_ctx, dh); - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02540) - "Custom DH parameters (%d bits) for %s loaded from %s", -- DH_bits(dhparams), vhost_id, certfile); -- DH_free(dhparams); -+ modssl_DH_bits(dh), vhost_id, certfile); -+ DH_free(dh); - } -+#if !MODSSL_USE_OPENSSL_PRE_1_1_API -+ else { -+ /* If no parameter is manually configured, enable auto -+ * selection. */ -+ SSL_CTX_set_dh_auto(mctx->ssl_ctx, 1); -+ } -+#endif - - #ifdef HAVE_ECC - /* -@@ -1518,6 +1588,7 @@ - char buf[TLSEXT_TICKET_KEY_LEN]; - char *path; - modssl_ticket_key_t *ticket_key = mctx->ticket_key; -+ int res; - - if (!ticket_key->file_path) { - return APR_SUCCESS; -@@ -1545,11 +1616,22 @@ - } - - memcpy(ticket_key->key_name, buf, 16); -- memcpy(ticket_key->hmac_secret, buf + 16, 16); - memcpy(ticket_key->aes_key, buf + 32, 16); -- -- if (!SSL_CTX_set_tlsext_ticket_key_cb(mctx->ssl_ctx, -- ssl_callback_SessionTicket)) { -+#if OPENSSL_VERSION_NUMBER < 0x30000000L -+ memcpy(ticket_key->hmac_secret, buf + 16, 16); -+ res = SSL_CTX_set_tlsext_ticket_key_cb(mctx->ssl_ctx, -+ ssl_callback_SessionTicket); -+#else -+ ticket_key->mac_params[0] = -+ OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, buf + 16, 16); -+ ticket_key->mac_params[1] = -+ OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, "sha256", 0); -+ ticket_key->mac_params[2] = -+ OSSL_PARAM_construct_end(); -+ res = SSL_CTX_set_tlsext_ticket_key_evp_cb(mctx->ssl_ctx, -+ ssl_callback_SessionTicket); -+#endif -+ if (!res) { - ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01913) - "Unable to initialize TLS session ticket key callback " - "(incompatible OpenSSL version?)"); -@@ -1680,7 +1762,7 @@ - return ssl_die(s); - } - -- X509_STORE_load_locations(store, pkp->ca_cert_file, NULL); -+ modssl_X509_STORE_load_locations(store, pkp->ca_cert_file, NULL); - - for (n = 0; n < ncerts; n++) { - int i; -@@ -2277,10 +2359,11 @@ - - } - --#if !MODSSL_USE_OPENSSL_PRE_1_1_API -+#if MODSSL_USE_OPENSSL_PRE_1_1_API -+ free_dh_params(); -+#else - free_bio_methods(); - #endif -- free_dh_params(); - - return APR_SUCCESS; - } ---- httpd-2.4.51/modules/ssl/ssl_engine_io.c.openssl3 -+++ httpd-2.4.51/modules/ssl/ssl_engine_io.c -@@ -194,6 +194,10 @@ - static int bio_filter_out_read(BIO *bio, char *out, int outl) - { - /* this is never called */ -+ bio_filter_out_ctx_t *outctx = (bio_filter_out_ctx_t *)BIO_get_data(bio); -+ ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, outctx->c, -+ "BUG: %s() should not be called", "bio_filter_out_read"); -+ AP_DEBUG_ASSERT(0); - return -1; - } - -@@ -293,12 +297,20 @@ - static int bio_filter_out_gets(BIO *bio, char *buf, int size) - { - /* this is never called */ -+ bio_filter_out_ctx_t *outctx = (bio_filter_out_ctx_t *)BIO_get_data(bio); -+ ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, outctx->c, -+ "BUG: %s() should not be called", "bio_filter_out_gets"); -+ AP_DEBUG_ASSERT(0); - return -1; - } - - static int bio_filter_out_puts(BIO *bio, const char *str) - { - /* this is never called */ -+ bio_filter_out_ctx_t *outctx = (bio_filter_out_ctx_t *)BIO_get_data(bio); -+ ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, outctx->c, -+ "BUG: %s() should not be called", "bio_filter_out_puts"); -+ AP_DEBUG_ASSERT(0); - return -1; - } - -@@ -533,22 +545,47 @@ - - static int bio_filter_in_write(BIO *bio, const char *in, int inl) - { -+ bio_filter_in_ctx_t *inctx = (bio_filter_in_ctx_t *)BIO_get_data(bio); -+ ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, inctx->f->c, -+ "BUG: %s() should not be called", "bio_filter_in_write"); -+ AP_DEBUG_ASSERT(0); - return -1; - } - - static int bio_filter_in_puts(BIO *bio, const char *str) - { -+ bio_filter_in_ctx_t *inctx = (bio_filter_in_ctx_t *)BIO_get_data(bio); -+ ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, inctx->f->c, -+ "BUG: %s() should not be called", "bio_filter_in_puts"); -+ AP_DEBUG_ASSERT(0); - return -1; - } - - static int bio_filter_in_gets(BIO *bio, char *buf, int size) - { -+ bio_filter_in_ctx_t *inctx = (bio_filter_in_ctx_t *)BIO_get_data(bio); -+ ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, inctx->f->c, -+ "BUG: %s() should not be called", "bio_filter_in_gets"); -+ AP_DEBUG_ASSERT(0); - return -1; - } - - static long bio_filter_in_ctrl(BIO *bio, int cmd, long num, void *ptr) - { -- return -1; -+ bio_filter_in_ctx_t *inctx = (bio_filter_in_ctx_t *)BIO_get_data(bio); -+ switch (cmd) { -+#ifdef BIO_CTRL_EOF -+ case BIO_CTRL_EOF: -+ return inctx->rc == APR_EOF; -+#endif -+ default: -+ break; -+ } -+ ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, inctx->f->c, -+ "BUG: bio_filter_in_ctrl() should not be called with cmd=%i", -+ cmd); -+ AP_DEBUG_ASSERT(0); -+ return 0; - } - - #if MODSSL_USE_OPENSSL_PRE_1_1_API -@@ -573,7 +610,7 @@ - bio_filter_in_read, - bio_filter_in_puts, /* puts is never called */ - bio_filter_in_gets, /* gets is never called */ -- bio_filter_in_ctrl, /* ctrl is never called */ -+ bio_filter_in_ctrl, /* ctrl is called for EOF check */ - bio_filter_create, - bio_filter_destroy, - NULL ---- httpd-2.4.51/modules/ssl/ssl_engine_kernel.c.openssl3 -+++ httpd-2.4.51/modules/ssl/ssl_engine_kernel.c -@@ -1685,6 +1685,7 @@ - ** _________________________________________________________________ - */ - -+#if MODSSL_USE_OPENSSL_PRE_1_1_API - /* - * Hand out standard DH parameters, based on the authentication strength - */ -@@ -1730,6 +1731,7 @@ - - return modssl_get_dh_params(keylen); - } -+#endif - - /* - * This OpenSSL callback function is called when OpenSSL -@@ -2614,7 +2616,11 @@ - unsigned char *keyname, - unsigned char *iv, - EVP_CIPHER_CTX *cipher_ctx, -- HMAC_CTX *hctx, -+#if OPENSSL_VERSION_NUMBER < 0x30000000L -+ HMAC_CTX *hmac_ctx, -+#else -+ EVP_MAC_CTX *mac_ctx, -+#endif - int mode) - { - conn_rec *c = (conn_rec *)SSL_get_app_data(ssl); -@@ -2640,7 +2646,13 @@ - } - EVP_EncryptInit_ex(cipher_ctx, EVP_aes_128_cbc(), NULL, - ticket_key->aes_key, iv); -- HMAC_Init_ex(hctx, ticket_key->hmac_secret, 16, tlsext_tick_md(), NULL); -+ -+#if OPENSSL_VERSION_NUMBER < 0x30000000L -+ HMAC_Init_ex(hmac_ctx, ticket_key->hmac_secret, 16, -+ tlsext_tick_md(), NULL); -+#else -+ EVP_MAC_CTX_set_params(mac_ctx, ticket_key->mac_params); -+#endif - - ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(02289) - "TLS session ticket key for %s successfully set, " -@@ -2661,7 +2673,13 @@ - - EVP_DecryptInit_ex(cipher_ctx, EVP_aes_128_cbc(), NULL, - ticket_key->aes_key, iv); -- HMAC_Init_ex(hctx, ticket_key->hmac_secret, 16, tlsext_tick_md(), NULL); -+ -+#if OPENSSL_VERSION_NUMBER < 0x30000000L -+ HMAC_Init_ex(hmac_ctx, ticket_key->hmac_secret, 16, -+ tlsext_tick_md(), NULL); -+#else -+ EVP_MAC_CTX_set_params(mac_ctx, ticket_key->mac_params); -+#endif - - ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(02290) - "TLS session ticket key for %s successfully set, " ---- httpd-2.4.51/modules/ssl/ssl_engine_log.c.openssl3 -+++ httpd-2.4.51/modules/ssl/ssl_engine_log.c -@@ -78,6 +78,16 @@ - return APR_EGENERAL; - } - -+static APR_INLINE -+unsigned long modssl_ERR_peek_error_data(const char **data, int *flags) -+{ -+#if OPENSSL_VERSION_NUMBER < 0x30000000L -+ return ERR_peek_error_line_data(NULL, NULL, data, flags); -+#else -+ return ERR_peek_error_data(data, flags); -+#endif -+} -+ - /* - * Prints the SSL library error information. - */ -@@ -87,7 +97,7 @@ - const char *data; - int flags; - -- while ((e = ERR_peek_error_line_data(NULL, NULL, &data, &flags))) { -+ while ((e = modssl_ERR_peek_error_data(&data, &flags))) { - const char *annotation; - char err[256]; - ---- httpd-2.4.51/modules/ssl/ssl_private.h.openssl3 -+++ httpd-2.4.51/modules/ssl/ssl_private.h -@@ -89,6 +89,9 @@ - /* must be defined before including ssl.h */ - #define OPENSSL_NO_SSL_INTERN - #endif -+#if OPENSSL_VERSION_NUMBER >= 0x30000000 -+#include -+#endif - #include - #include - #include -@@ -134,13 +137,12 @@ - SSL_CTX_ctrl(ctx, SSL_CTRL_SET_MIN_PROTO_VERSION, version, NULL) - #define SSL_CTX_set_max_proto_version(ctx, version) \ - SSL_CTX_ctrl(ctx, SSL_CTRL_SET_MAX_PROTO_VERSION, version, NULL) --#elif LIBRESSL_VERSION_NUMBER < 0x2070000f -+#endif /* LIBRESSL_VERSION_NUMBER < 0x2060000f */ - /* LibreSSL before 2.7 declares OPENSSL_VERSION_NUMBER == 2.0 but does not - * include most changes from OpenSSL >= 1.1 (new functions, macros, - * deprecations, ...), so we have to work around this... - */ --#define MODSSL_USE_OPENSSL_PRE_1_1_API (1) --#endif /* LIBRESSL_VERSION_NUMBER < 0x2060000f */ -+#define MODSSL_USE_OPENSSL_PRE_1_1_API (LIBRESSL_VERSION_NUMBER < 0x2070000f) - #else /* defined(LIBRESSL_VERSION_NUMBER) */ - #define MODSSL_USE_OPENSSL_PRE_1_1_API (OPENSSL_VERSION_NUMBER < 0x10100000L) - #endif -@@ -681,7 +683,11 @@ - typedef struct { - const char *file_path; - unsigned char key_name[16]; -+#if OPENSSL_VERSION_NUMBER < 0x30000000L - unsigned char hmac_secret[16]; -+#else -+ OSSL_PARAM mac_params[3]; -+#endif - unsigned char aes_key[16]; - } modssl_ticket_key_t; - #endif -@@ -945,8 +951,16 @@ - int ssl_callback_ClientHello(SSL *, int *, void *); - #endif - #ifdef HAVE_TLS_SESSION_TICKETS --int ssl_callback_SessionTicket(SSL *, unsigned char *, unsigned char *, -- EVP_CIPHER_CTX *, HMAC_CTX *, int); -+int ssl_callback_SessionTicket(SSL *ssl, -+ unsigned char *keyname, -+ unsigned char *iv, -+ EVP_CIPHER_CTX *cipher_ctx, -+#if OPENSSL_VERSION_NUMBER < 0x30000000L -+ HMAC_CTX *hmac_ctx, -+#else -+ EVP_MAC_CTX *mac_ctx, -+#endif -+ int mode); - #endif - - #ifdef HAVE_TLS_ALPN -@@ -1124,10 +1138,12 @@ - - #endif - -+#if MODSSL_USE_OPENSSL_PRE_1_1_API - /* Retrieve DH parameters for given key length. Return value should - * be treated as unmutable, since it is stored in process-global - * memory. */ - DH *modssl_get_dh_params(unsigned keylen); -+#endif - - /* Returns non-zero if the request was made over SSL/TLS. If sslconn - * is non-NULL and the request is using SSL/TLS, sets *sslconn to the diff --git a/SOURCES/httpd-2.4.51-r1811831.patch b/SOURCES/httpd-2.4.51-r1811831.patch new file mode 100644 index 0000000..b8d8215 --- /dev/null +++ b/SOURCES/httpd-2.4.51-r1811831.patch @@ -0,0 +1,81 @@ +diff --git a/server/util_script.c b/server/util_script.c +index 4121ae0..b7f8674 100644 +--- a/server/util_script.c ++++ b/server/util_script.c +@@ -92,9 +92,21 @@ static void add_unless_null(apr_table_t *table, const char *name, const char *va + } + } + +-static void env2env(apr_table_t *table, const char *name) ++/* Sets variable @name in table @dest from r->subprocess_env if ++ * available, else from the environment, else from @fallback if ++ * non-NULL. */ ++static void env2env(apr_table_t *dest, request_rec *r, ++ const char *name, const char *fallback) + { +- add_unless_null(table, name, getenv(name)); ++ const char *val; ++ ++ val = apr_table_get(r->subprocess_env, name); ++ if (!val) ++ val = apr_pstrdup(r->pool, getenv(name)); ++ if (!val) ++ val = apr_pstrdup(r->pool, fallback); ++ if (val) ++ apr_table_addn(dest, name, val); + } + + AP_DECLARE(char **) ap_create_environment(apr_pool_t *p, apr_table_t *t) +@@ -211,37 +223,29 @@ AP_DECLARE(void) ap_add_common_vars(request_rec *r) + add_unless_null(e, http2env(r, hdrs[i].key), hdrs[i].val); + } + +- env_temp = apr_table_get(r->subprocess_env, "PATH"); +- if (env_temp == NULL) { +- env_temp = getenv("PATH"); +- } +- if (env_temp == NULL) { +- env_temp = DEFAULT_PATH; +- } +- apr_table_addn(e, "PATH", apr_pstrdup(r->pool, env_temp)); +- ++ env2env(e, r, "PATH", DEFAULT_PATH); + #if defined(WIN32) +- env2env(e, "SystemRoot"); +- env2env(e, "COMSPEC"); +- env2env(e, "PATHEXT"); +- env2env(e, "WINDIR"); ++ env2env(e, r, "SystemRoot", NULL); ++ env2env(e, r, "COMSPEC", NULL); ++ env2env(e, r, "PATHEXT", NULL); ++ env2env(e, r, "WINDIR", NULL); + #elif defined(OS2) +- env2env(e, "COMSPEC"); +- env2env(e, "ETC"); +- env2env(e, "DPATH"); +- env2env(e, "PERLLIB_PREFIX"); ++ env2env(e, r, "COMSPEC", NULL); ++ env2env(e, r, "ETC", NULL); ++ env2env(e, r, "DPATH", NULL); ++ env2env(e, r, "PERLLIB_PREFIX", NULL); + #elif defined(BEOS) +- env2env(e, "LIBRARY_PATH"); ++ env2env(e, r, "LIBRARY_PATH", NULL); + #elif defined(DARWIN) +- env2env(e, "DYLD_LIBRARY_PATH"); ++ env2env(e, r, "DYLD_LIBRARY_PATH", NULL); + #elif defined(_AIX) +- env2env(e, "LIBPATH"); ++ env2env(e, r, "LIBPATH", NULL); + #elif defined(__HPUX__) + /* HPUX PARISC 2.0W knows both, otherwise redundancy is harmless */ +- env2env(e, "SHLIB_PATH"); +- env2env(e, "LD_LIBRARY_PATH"); ++ env2env(e, r, "SHLIB_PATH", NULL); ++ env2env(e, r, "LD_LIBRARY_PATH", NULL); + #else /* Some Unix */ +- env2env(e, "LD_LIBRARY_PATH"); ++ env2env(e, r, "LD_LIBRARY_PATH", NULL); + #endif + + apr_table_addn(e, "SERVER_SIGNATURE", ap_psignature("", r)); diff --git a/SOURCES/httpd-2.4.51.tar.bz2.asc b/SOURCES/httpd-2.4.51.tar.bz2.asc deleted file mode 100644 index 5c06626..0000000 --- a/SOURCES/httpd-2.4.51.tar.bz2.asc +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN PGP SIGNATURE----- -Comment: GPGTools - https://gpgtools.org - -iQIzBAABCgAdFiEEJvUe+agvSstD8ZA+03fJ59GUTGYFAmFe8kEACgkQ03fJ59GU -TGatthAAtWzeOD1TCIEvf5f9bAIZDK9vjEEnBZDeYMMrH1wVJGNJm48XP08O/Kbq -qhvc9201RUwkAtWEUX811ZBAYd5A8lAqetfmIuCSHerYSOU0CbhvBjKsuIJVIKWD -Wo1uPUDWk068V0HBquQtW6AEB4oo16fKPMEr1aOOxFpR+F806daJN1gt3ubPzkNJ -rZd4E6dV00eEymeUIfk0BjDqSWKHmUr+08/dtWqc7kGYGcnJzu0e5pr6cc0hOV2o -mqYm28F7eMSe5JCnAOd1LnnqtOwV81mZLxiAxR40PoFhV7IoBLo0zAJ99AHxJfA2 -9RjCmZ/WYtleeDT7mC1cdATHKOPRaubklzK6Ntf7tMaRIO07hnIfIRXQveKG7h+G -Og6PGtfR9bwDGrg2f5Dr+R2fwUJO7EL31IxTYQFBUDe2Q82aNIWpdIFdte93nc+S -HqjWq3w6zq+jdSm3xvyLB0LLSOguXhcjj5VEqV+aExZPASbf+Q8bG51mSbMQhkaq -fEheFcdhu3Sm0x5xQXvEM3gX5XUr8vmrPWaacayPYfS7MinWukV0hXe5/DoYkFTt -a1pt6bHcyVfR0tB0Q3bvm59EeaxLVfogb6Eq74RlrfYiCU/Qx7bMUs3tSeIkHGmY -cNhpxzc/36i4Cf+fBDPKuJroXYV5wFoQmpnXVLAqRd6jWZcOizY= -=f5dx ------END PGP SIGNATURE----- diff --git a/SOURCES/httpd-2.4.53-CVE-2022-26377.patch b/SOURCES/httpd-2.4.53-CVE-2022-26377.patch new file mode 100644 index 0000000..0b05fec --- /dev/null +++ b/SOURCES/httpd-2.4.53-CVE-2022-26377.patch @@ -0,0 +1,26 @@ +diff --git a/modules/proxy/mod_proxy_ajp.c b/modules/proxy/mod_proxy_ajp.c +index e2992fc..46d42bc 100644 +--- a/modules/proxy/mod_proxy_ajp.c ++++ b/modules/proxy/mod_proxy_ajp.c +@@ -246,9 +246,18 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r, + /* read the first block of data */ + input_brigade = apr_brigade_create(p, r->connection->bucket_alloc); + tenc = apr_table_get(r->headers_in, "Transfer-Encoding"); +- if (tenc && (ap_cstr_casecmp(tenc, "chunked") == 0)) { +- /* The AJP protocol does not want body data yet */ +- ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00870) "request is chunked"); ++ if (tenc) { ++ if (ap_cstr_casecmp(tenc, "chunked") == 0) { ++ /* The AJP protocol does not want body data yet */ ++ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00870) ++ "request is chunked"); ++ } ++ else { ++ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10396) ++ "%s Transfer-Encoding is not supported", ++ tenc); ++ return HTTP_INTERNAL_SERVER_ERROR; ++ } + } else { + /* Get client provided Content-Length header */ + content_length = get_content_length(r); diff --git a/SOURCES/httpd-2.4.53-CVE-2022-28614.patch b/SOURCES/httpd-2.4.53-CVE-2022-28614.patch new file mode 100644 index 0000000..ef2b535 --- /dev/null +++ b/SOURCES/httpd-2.4.53-CVE-2022-28614.patch @@ -0,0 +1,61 @@ +From 8c14927162cf3b4f810683e1c5505e9ef9e1f123 Mon Sep 17 00:00:00 2001 +From: Eric Covener +Date: Wed, 1 Jun 2022 12:34:16 +0000 +Subject: [PATCH] Merge r1901500 from trunk: + +handle large writes in ap_rputs + + +git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1901501 13f79535-47bb-0310-9956-ffa450edef68 +--- + include/http_protocol.h | 22 +++++++++++++++++++++- + server/protocol.c | 3 +++ + 2 files changed, 24 insertions(+), 1 deletion(-) + +diff --git a/include/http_protocol.h b/include/http_protocol.h +index 20bd2022266..94c481e5f43 100644 +--- a/include/http_protocol.h ++++ b/include/http_protocol.h +@@ -475,7 +475,27 @@ AP_DECLARE(int) ap_rwrite(const void *buf, int nbyte, request_rec *r); + */ + static APR_INLINE int ap_rputs(const char *str, request_rec *r) + { +- return ap_rwrite(str, (int)strlen(str), r); ++ apr_size_t len; ++ ++ len = strlen(str); ++ ++ for (;;) { ++ if (len <= INT_MAX) { ++ return ap_rwrite(str, (int)len, r); ++ } ++ else { ++ int rc; ++ ++ rc = ap_rwrite(str, INT_MAX, r); ++ if (rc < 0) { ++ return rc; ++ } ++ else { ++ str += INT_MAX; ++ len -= INT_MAX; ++ } ++ } ++ } + } + + /** +diff --git a/server/protocol.c b/server/protocol.c +index 298f61e1fb8..7adc7f75c10 100644 +--- a/server/protocol.c ++++ b/server/protocol.c +@@ -2128,6 +2128,9 @@ AP_DECLARE(int) ap_rputc(int c, request_rec *r) + + AP_DECLARE(int) ap_rwrite(const void *buf, int nbyte, request_rec *r) + { ++ if (nbyte < 0) ++ return -1; ++ + if (r->connection->aborted) + return -1; + diff --git a/SOURCES/httpd-2.4.53-CVE-2022-28615.patch b/SOURCES/httpd-2.4.53-CVE-2022-28615.patch new file mode 100644 index 0000000..75a3d0f --- /dev/null +++ b/SOURCES/httpd-2.4.53-CVE-2022-28615.patch @@ -0,0 +1,22 @@ +diff --git a/server/util.c b/server/util.c +index 604be1a..6808164 100644 +--- a/server/util.c ++++ b/server/util.c +@@ -185,7 +185,7 @@ AP_DECLARE(char *) ap_ht_time(apr_pool_t *p, apr_time_t t, const char *fmt, + */ + AP_DECLARE(int) ap_strcmp_match(const char *str, const char *expected) + { +- int x, y; ++ apr_size_t x, y; + + for (x = 0, y = 0; expected[y]; ++y, ++x) { + if (expected[y] == '*') { +@@ -209,7 +209,7 @@ AP_DECLARE(int) ap_strcmp_match(const char *str, const char *expected) + + AP_DECLARE(int) ap_strcasecmp_match(const char *str, const char *expected) + { +- int x, y; ++ apr_size_t x, y; + + for (x = 0, y = 0; expected[y]; ++y, ++x) { + if (!str[x] && expected[y] != '*') diff --git a/SOURCES/httpd-2.4.53-CVE-2022-29404.patch b/SOURCES/httpd-2.4.53-CVE-2022-29404.patch new file mode 100644 index 0000000..df4f70f --- /dev/null +++ b/SOURCES/httpd-2.4.53-CVE-2022-29404.patch @@ -0,0 +1,126 @@ +diff --git a/docs/manual/mod/core.html.en b/docs/manual/mod/core.html.en +index bb6b90a..d14aed4 100644 +--- a/docs/manual/mod/core.html.en ++++ b/docs/manual/mod/core.html.en +@@ -2796,16 +2796,16 @@ subrequests + Description:Restricts the total size of the HTTP request body sent + from the client + Syntax:LimitRequestBody bytes +-Default:LimitRequestBody 0 ++Default:LimitRequestBody 1073741824 + Context:server config, virtual host, directory, .htaccess + Override:All + Status:Core + Module:core ++Compatibility:In Apache HTTP Server 2.4.53 and earlier, the default value ++ was 0 (unlimited) + +-

This directive specifies the number of bytes from 0 +- (meaning unlimited) to 2147483647 (2GB) that are allowed in a +- request body. See the note below for the limited applicability +- to proxy requests.

++

This directive specifies the number of bytes ++ that are allowed in a request body. A value of 0 means unlimited.

+ +

The LimitRequestBody directive allows + the user to set a limit on the allowed size of an HTTP request +@@ -2831,12 +2831,6 @@ from the client + +

LimitRequestBody 102400
+ +- +-

For a full description of how this directive is interpreted by +- proxy requests, see the mod_proxy documentation.

+-
+- +- + +
top
+

LimitRequestFields Directive

+diff --git a/docs/manual/mod/mod_proxy.html.en b/docs/manual/mod/mod_proxy.html.en +index ee7b1e3..233d234 100644 +--- a/docs/manual/mod/mod_proxy.html.en ++++ b/docs/manual/mod/mod_proxy.html.en +@@ -463,9 +463,6 @@ ProxyPass "/examples" "http://backend.example.com/examples" timeout=10 + Content-Length header, but the server is configured to filter incoming + request bodies.

+ +-

LimitRequestBody only applies to +- request bodies that the server will spool to disk

+- +
top
+
+

Reverse Proxy Request Headers

+diff --git a/modules/http/http_filters.c b/modules/http/http_filters.c +index 43e8c6d..33c78f3 100644 +--- a/modules/http/http_filters.c ++++ b/modules/http/http_filters.c +@@ -1703,6 +1703,7 @@ AP_DECLARE(int) ap_setup_client_block(request_rec *r, int read_policy) + { + const char *tenc = apr_table_get(r->headers_in, "Transfer-Encoding"); + const char *lenp = apr_table_get(r->headers_in, "Content-Length"); ++ apr_off_t limit_req_body = ap_get_limit_req_body(r); + + r->read_body = read_policy; + r->read_chunked = 0; +@@ -1738,6 +1739,11 @@ AP_DECLARE(int) ap_setup_client_block(request_rec *r, int read_policy) + return HTTP_REQUEST_ENTITY_TOO_LARGE; + } + ++ if (limit_req_body > 0 && (r->remaining > limit_req_body)) { ++ /* will be logged when the body is discarded */ ++ return HTTP_REQUEST_ENTITY_TOO_LARGE; ++ } ++ + #ifdef AP_DEBUG + { + /* Make sure ap_getline() didn't leave any droppings. */ +diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c +index bc86253..85f2f9c 100644 +--- a/modules/proxy/proxy_util.c ++++ b/modules/proxy/proxy_util.c +@@ -4260,13 +4260,10 @@ PROXY_DECLARE(int) ap_proxy_spool_input(request_rec *r, + apr_bucket *e; + apr_off_t bytes, fsize = 0; + apr_file_t *tmpfile = NULL; +- apr_off_t limit; + + *bytes_spooled = 0; + body_brigade = apr_brigade_create(p, bucket_alloc); + +- limit = ap_get_limit_req_body(r); +- + do { + if (APR_BRIGADE_EMPTY(input_brigade)) { + rv = ap_proxy_read_input(r, backend, input_brigade, +@@ -4284,17 +4281,6 @@ PROXY_DECLARE(int) ap_proxy_spool_input(request_rec *r, + apr_brigade_length(input_brigade, 1, &bytes); + + if (*bytes_spooled + bytes > max_mem_spool) { +- /* +- * LimitRequestBody does not affect Proxy requests (Should it?). +- * Let it take effect if we decide to store the body in a +- * temporary file on disk. +- */ +- if (limit && (*bytes_spooled + bytes > limit)) { +- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01088) +- "Request body is larger than the configured " +- "limit of %" APR_OFF_T_FMT, limit); +- return HTTP_REQUEST_ENTITY_TOO_LARGE; +- } + /* can't spool any more in memory; write latest brigade to disk */ + if (tmpfile == NULL) { + const char *temp_dir; +diff --git a/server/core.c b/server/core.c +index 3d44e0e..682259f 100644 +--- a/server/core.c ++++ b/server/core.c +@@ -71,7 +71,7 @@ + + /* LimitRequestBody handling */ + #define AP_LIMIT_REQ_BODY_UNSET ((apr_off_t) -1) +-#define AP_DEFAULT_LIMIT_REQ_BODY ((apr_off_t) 0) ++#define AP_DEFAULT_LIMIT_REQ_BODY ((apr_off_t) 1<<30) /* 1GB */ + + /* LimitXMLRequestBody handling */ + #define AP_LIMIT_UNSET ((long) -1) diff --git a/SOURCES/httpd-2.4.53-CVE-2022-30522.patch b/SOURCES/httpd-2.4.53-CVE-2022-30522.patch new file mode 100644 index 0000000..50e0ea3 --- /dev/null +++ b/SOURCES/httpd-2.4.53-CVE-2022-30522.patch @@ -0,0 +1,557 @@ +From db47781128e42bd49f55076665b3f6ca4e2bc5e2 Mon Sep 17 00:00:00 2001 +From: Eric Covener +Date: Wed, 1 Jun 2022 12:50:40 +0000 +Subject: [PATCH] Merge r1901506 from trunk: + +limit mod_sed memory use + +Resync mod_sed.c with trunk due to merge conflicts. + + +git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1901509 13f79535-47bb-0310-9956-ffa450edef68 +--- + modules/filters/mod_sed.c | 75 ++++++++---------- + modules/filters/sed1.c | 158 +++++++++++++++++++++++++++----------- + 2 files changed, 147 insertions(+), 86 deletions(-) + +diff --git a/modules/filters/mod_sed.c b/modules/filters/mod_sed.c +index 4bdb4ce33ae..12cb04a20f9 100644 +--- a/modules/filters/mod_sed.c ++++ b/modules/filters/mod_sed.c +@@ -59,7 +59,7 @@ typedef struct sed_filter_ctxt + module AP_MODULE_DECLARE_DATA sed_module; + + /* This function will be call back from libsed functions if there is any error +- * happend during execution of sed scripts ++ * happened during execution of sed scripts + */ + static apr_status_t log_sed_errf(void *data, const char *error) + { +@@ -277,7 +277,7 @@ static apr_status_t sed_response_filter(ap_filter_t *f, + apr_bucket_brigade *bb) + { + apr_bucket *b; +- apr_status_t status; ++ apr_status_t status = APR_SUCCESS; + sed_config *cfg = ap_get_module_config(f->r->per_dir_config, + &sed_module); + sed_filter_ctxt *ctx = f->ctx; +@@ -302,9 +302,9 @@ static apr_status_t sed_response_filter(ap_filter_t *f, + return status; + ctx = f->ctx; + apr_table_unset(f->r->headers_out, "Content-Length"); +- } + +- ctx->bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc); ++ ctx->bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc); ++ } + + /* Here is the main logic. Iterate through all the buckets, read the + * content of the bucket, call sed_eval_buffer on the data. +@@ -326,63 +326,52 @@ static apr_status_t sed_response_filter(ap_filter_t *f, + * in sed's internal buffer which can't be flushed until new line + * character is arrived. + */ +- for (b = APR_BRIGADE_FIRST(bb); b != APR_BRIGADE_SENTINEL(bb);) { +- const char *buf = NULL; +- apr_size_t bytes = 0; ++ while (!APR_BRIGADE_EMPTY(bb)) { ++ b = APR_BRIGADE_FIRST(bb); + if (APR_BUCKET_IS_EOS(b)) { +- apr_bucket *b1 = APR_BUCKET_NEXT(b); + /* Now clean up the internal sed buffer */ + sed_finalize_eval(&ctx->eval, ctx); + status = flush_output_buffer(ctx); + if (status != APR_SUCCESS) { +- clear_ctxpool(ctx); +- return status; ++ break; + } ++ /* Move the eos bucket to ctx->bb brigade */ + APR_BUCKET_REMOVE(b); +- /* Insert the eos bucket to ctx->bb brigade */ + APR_BRIGADE_INSERT_TAIL(ctx->bb, b); +- b = b1; + } + else if (APR_BUCKET_IS_FLUSH(b)) { +- apr_bucket *b1 = APR_BUCKET_NEXT(b); +- APR_BUCKET_REMOVE(b); + status = flush_output_buffer(ctx); + if (status != APR_SUCCESS) { +- clear_ctxpool(ctx); +- return status; ++ break; + } ++ /* Move the flush bucket to ctx->bb brigade */ ++ APR_BUCKET_REMOVE(b); + APR_BRIGADE_INSERT_TAIL(ctx->bb, b); +- b = b1; +- } +- else if (APR_BUCKET_IS_METADATA(b)) { +- b = APR_BUCKET_NEXT(b); + } +- else if (apr_bucket_read(b, &buf, &bytes, APR_BLOCK_READ) +- == APR_SUCCESS) { +- apr_bucket *b1 = APR_BUCKET_NEXT(b); +- status = sed_eval_buffer(&ctx->eval, buf, bytes, ctx); +- if (status != APR_SUCCESS) { +- clear_ctxpool(ctx); +- return status; ++ else { ++ if (!APR_BUCKET_IS_METADATA(b)) { ++ const char *buf = NULL; ++ apr_size_t bytes = 0; ++ ++ status = apr_bucket_read(b, &buf, &bytes, APR_BLOCK_READ); ++ if (status == APR_SUCCESS) { ++ status = sed_eval_buffer(&ctx->eval, buf, bytes, ctx); ++ } ++ if (status != APR_SUCCESS) { ++ ap_log_rerror(APLOG_MARK, APLOG_ERR, status, f->r, APLOGNO(10394) "error evaluating sed on output"); ++ break; ++ } + } +- APR_BUCKET_REMOVE(b); + apr_bucket_delete(b); +- b = b1; +- } +- else { +- apr_bucket *b1 = APR_BUCKET_NEXT(b); +- APR_BUCKET_REMOVE(b); +- b = b1; + } + } +- apr_brigade_cleanup(bb); +- status = flush_output_buffer(ctx); +- if (status != APR_SUCCESS) { +- clear_ctxpool(ctx); +- return status; ++ if (status == APR_SUCCESS) { ++ status = flush_output_buffer(ctx); + } + if (!APR_BRIGADE_EMPTY(ctx->bb)) { +- status = ap_pass_brigade(f->next, ctx->bb); ++ if (status == APR_SUCCESS) { ++ status = ap_pass_brigade(f->next, ctx->bb); ++ } + apr_brigade_cleanup(ctx->bb); + } + clear_ctxpool(ctx); +@@ -433,7 +422,7 @@ static apr_status_t sed_request_filter(ap_filter_t *f, + * the buckets in bbinp and read the data from buckets and invoke + * sed_eval_buffer on the data. libsed will generate its output using + * sed_write_output which will add data in ctx->bb. Do it until it have +- * atleast one bucket in ctx->bb. At the end of data eos bucket ++ * at least one bucket in ctx->bb. At the end of data eos bucket + * should be there. + * + * Once eos bucket is seen, then invoke sed_finalize_eval to clear the +@@ -475,8 +464,10 @@ static apr_status_t sed_request_filter(ap_filter_t *f, + if (apr_bucket_read(b, &buf, &bytes, APR_BLOCK_READ) + == APR_SUCCESS) { + status = sed_eval_buffer(&ctx->eval, buf, bytes, ctx); +- if (status != APR_SUCCESS) ++ if (status != APR_SUCCESS) { ++ ap_log_rerror(APLOG_MARK, APLOG_ERR, status, f->r, APLOGNO(10395) "error evaluating sed on input"); + return status; ++ } + flush_output_buffer(ctx); + } + } +diff --git a/modules/filters/sed1.c b/modules/filters/sed1.c +index 67a8d06515e..047f49ba131 100644 +--- a/modules/filters/sed1.c ++++ b/modules/filters/sed1.c +@@ -87,18 +87,20 @@ static void eval_errf(sed_eval_t *eval, const char *fmt, ...) + } + + #define INIT_BUF_SIZE 1024 ++#define MAX_BUF_SIZE 1024*8192 + + /* + * grow_buffer + */ +-static void grow_buffer(apr_pool_t *pool, char **buffer, ++static apr_status_t grow_buffer(apr_pool_t *pool, char **buffer, + char **spend, apr_size_t *cursize, + apr_size_t newsize) + { + char* newbuffer = NULL; + apr_size_t spendsize = 0; +- if (*cursize >= newsize) +- return; ++ if (*cursize >= newsize) { ++ return APR_SUCCESS; ++ } + /* Avoid number of times realloc is called. It could cause huge memory + * requirement if line size is huge e.g 2 MB */ + if (newsize < *cursize * 2) { +@@ -107,6 +109,9 @@ static void grow_buffer(apr_pool_t *pool, char **buffer, + + /* Align it to 4 KB boundary */ + newsize = (newsize + ((1 << 12) - 1)) & ~((1 << 12) - 1); ++ if (newsize > MAX_BUF_SIZE) { ++ return APR_ENOMEM; ++ } + newbuffer = apr_pcalloc(pool, newsize); + if (*spend && *buffer && (*cursize > 0)) { + spendsize = *spend - *buffer; +@@ -119,63 +124,77 @@ static void grow_buffer(apr_pool_t *pool, char **buffer, + if (spend != buffer) { + *spend = *buffer + spendsize; + } ++ return APR_SUCCESS; + } + + /* + * grow_line_buffer + */ +-static void grow_line_buffer(sed_eval_t *eval, apr_size_t newsize) ++static apr_status_t grow_line_buffer(sed_eval_t *eval, apr_size_t newsize) + { +- grow_buffer(eval->pool, &eval->linebuf, &eval->lspend, ++ return grow_buffer(eval->pool, &eval->linebuf, &eval->lspend, + &eval->lsize, newsize); + } + + /* + * grow_hold_buffer + */ +-static void grow_hold_buffer(sed_eval_t *eval, apr_size_t newsize) ++static apr_status_t grow_hold_buffer(sed_eval_t *eval, apr_size_t newsize) + { +- grow_buffer(eval->pool, &eval->holdbuf, &eval->hspend, ++ return grow_buffer(eval->pool, &eval->holdbuf, &eval->hspend, + &eval->hsize, newsize); + } + + /* + * grow_gen_buffer + */ +-static void grow_gen_buffer(sed_eval_t *eval, apr_size_t newsize, ++static apr_status_t grow_gen_buffer(sed_eval_t *eval, apr_size_t newsize, + char **gspend) + { ++ apr_status_t rc = 0; + if (gspend == NULL) { + gspend = &eval->genbuf; + } +- grow_buffer(eval->pool, &eval->genbuf, gspend, +- &eval->gsize, newsize); +- eval->lcomend = &eval->genbuf[71]; ++ rc = grow_buffer(eval->pool, &eval->genbuf, gspend, ++ &eval->gsize, newsize); ++ if (rc == APR_SUCCESS) { ++ eval->lcomend = &eval->genbuf[71]; ++ } ++ return rc; + } + + /* + * appendmem_to_linebuf + */ +-static void appendmem_to_linebuf(sed_eval_t *eval, const char* sz, apr_size_t len) ++static apr_status_t appendmem_to_linebuf(sed_eval_t *eval, const char* sz, apr_size_t len) + { ++ apr_status_t rc = 0; + apr_size_t reqsize = (eval->lspend - eval->linebuf) + len; + if (eval->lsize < reqsize) { +- grow_line_buffer(eval, reqsize); ++ rc = grow_line_buffer(eval, reqsize); ++ if (rc != APR_SUCCESS) { ++ return rc; ++ } + } + memcpy(eval->lspend, sz, len); + eval->lspend += len; ++ return APR_SUCCESS; + } + + /* + * append_to_linebuf + */ +-static void append_to_linebuf(sed_eval_t *eval, const char* sz, ++static apr_status_t append_to_linebuf(sed_eval_t *eval, const char* sz, + step_vars_storage *step_vars) + { + apr_size_t len = strlen(sz); + char *old_linebuf = eval->linebuf; ++ apr_status_t rc = 0; + /* Copy string including null character */ +- appendmem_to_linebuf(eval, sz, len + 1); ++ rc = appendmem_to_linebuf(eval, sz, len + 1); ++ if (rc != APR_SUCCESS) { ++ return rc; ++ } + --eval->lspend; /* lspend will now point to NULL character */ + /* Sync step_vars after a possible linebuf expansion */ + if (step_vars && old_linebuf != eval->linebuf) { +@@ -189,68 +208,84 @@ static void append_to_linebuf(sed_eval_t *eval, const char* sz, + step_vars->locs = step_vars->locs - old_linebuf + eval->linebuf; + } + } ++ return APR_SUCCESS; + } + + /* + * copy_to_linebuf + */ +-static void copy_to_linebuf(sed_eval_t *eval, const char* sz, ++static apr_status_t copy_to_linebuf(sed_eval_t *eval, const char* sz, + step_vars_storage *step_vars) + { + eval->lspend = eval->linebuf; +- append_to_linebuf(eval, sz, step_vars); ++ return append_to_linebuf(eval, sz, step_vars); + } + + /* + * append_to_holdbuf + */ +-static void append_to_holdbuf(sed_eval_t *eval, const char* sz) ++static apr_status_t append_to_holdbuf(sed_eval_t *eval, const char* sz) + { + apr_size_t len = strlen(sz); + apr_size_t reqsize = (eval->hspend - eval->holdbuf) + len + 1; ++ apr_status_t rc = 0; + if (eval->hsize <= reqsize) { +- grow_hold_buffer(eval, reqsize); ++ rc = grow_hold_buffer(eval, reqsize); ++ if (rc != APR_SUCCESS) { ++ return rc; ++ } + } + memcpy(eval->hspend, sz, len + 1); + /* hspend will now point to NULL character */ + eval->hspend += len; ++ return APR_SUCCESS; + } + + /* + * copy_to_holdbuf + */ +-static void copy_to_holdbuf(sed_eval_t *eval, const char* sz) ++static apr_status_t copy_to_holdbuf(sed_eval_t *eval, const char* sz) + { + eval->hspend = eval->holdbuf; +- append_to_holdbuf(eval, sz); ++ return append_to_holdbuf(eval, sz); + } + + /* + * append_to_genbuf + */ +-static void append_to_genbuf(sed_eval_t *eval, const char* sz, char **gspend) ++static apr_status_t append_to_genbuf(sed_eval_t *eval, const char* sz, char **gspend) + { + apr_size_t len = strlen(sz); + apr_size_t reqsize = (*gspend - eval->genbuf) + len + 1; ++ apr_status_t rc = 0; + if (eval->gsize < reqsize) { +- grow_gen_buffer(eval, reqsize, gspend); ++ rc = grow_gen_buffer(eval, reqsize, gspend); ++ if (rc != APR_SUCCESS) { ++ return rc; ++ } + } + memcpy(*gspend, sz, len + 1); + /* *gspend will now point to NULL character */ + *gspend += len; ++ return APR_SUCCESS; + } + + /* + * copy_to_genbuf + */ +-static void copy_to_genbuf(sed_eval_t *eval, const char* sz) ++static apr_status_t copy_to_genbuf(sed_eval_t *eval, const char* sz) + { + apr_size_t len = strlen(sz); + apr_size_t reqsize = len + 1; ++ apr_status_t rc = APR_SUCCESS;; + if (eval->gsize < reqsize) { +- grow_gen_buffer(eval, reqsize, NULL); ++ rc = grow_gen_buffer(eval, reqsize, NULL); ++ if (rc != APR_SUCCESS) { ++ return rc; ++ } + } + memcpy(eval->genbuf, sz, len + 1); ++ return rc; + } + + /* +@@ -397,6 +432,7 @@ apr_status_t sed_eval_buffer(sed_eval_t *eval, const char *buf, apr_size_t bufsz + } + + while (bufsz) { ++ apr_status_t rc = 0; + char *n; + apr_size_t llen; + +@@ -411,7 +447,10 @@ apr_status_t sed_eval_buffer(sed_eval_t *eval, const char *buf, apr_size_t bufsz + break; + } + +- appendmem_to_linebuf(eval, buf, llen + 1); ++ rc = appendmem_to_linebuf(eval, buf, llen + 1); ++ if (rc != APR_SUCCESS) { ++ return rc; ++ } + --eval->lspend; + /* replace new line character with NULL */ + *eval->lspend = '\0'; +@@ -426,7 +465,10 @@ apr_status_t sed_eval_buffer(sed_eval_t *eval, const char *buf, apr_size_t bufsz + + /* Save the leftovers for later */ + if (bufsz) { +- appendmem_to_linebuf(eval, buf, bufsz); ++ apr_status_t rc = appendmem_to_linebuf(eval, buf, bufsz); ++ if (rc != APR_SUCCESS) { ++ return rc; ++ } + } + + return APR_SUCCESS; +@@ -448,6 +490,7 @@ apr_status_t sed_finalize_eval(sed_eval_t *eval, void *fout) + /* Process leftovers */ + if (eval->lspend > eval->linebuf) { + apr_status_t rv; ++ apr_status_t rc = 0; + + if (eval->lreadyflag) { + eval->lreadyflag = 0; +@@ -457,7 +500,10 @@ apr_status_t sed_finalize_eval(sed_eval_t *eval, void *fout) + * buffer is not a newline. + */ + /* Assure space for NULL */ +- append_to_linebuf(eval, "", NULL); ++ rc = append_to_linebuf(eval, "", NULL); ++ if (rc != APR_SUCCESS) { ++ return rc; ++ } + } + + *eval->lspend = '\0'; +@@ -655,11 +701,15 @@ static apr_status_t dosub(sed_eval_t *eval, char *rhsbuf, int n, + sp = eval->genbuf; + rp = rhsbuf; + sp = place(eval, sp, lp, step_vars->loc1); ++ if (sp == NULL) { ++ return APR_EGENERAL; ++ } + while ((c = *rp++) != 0) { + if (c == '&') { + sp = place(eval, sp, step_vars->loc1, step_vars->loc2); +- if (sp == NULL) ++ if (sp == NULL) { + return APR_EGENERAL; ++ } + } + else if (c == '\\') { + c = *rp++; +@@ -675,13 +725,19 @@ static apr_status_t dosub(sed_eval_t *eval, char *rhsbuf, int n, + *sp++ = c; + if (sp >= eval->genbuf + eval->gsize) { + /* expand genbuf and set the sp appropriately */ +- grow_gen_buffer(eval, eval->gsize + 1024, &sp); ++ rv = grow_gen_buffer(eval, eval->gsize + 1024, &sp); ++ if (rv != APR_SUCCESS) { ++ return rv; ++ } + } + } + lp = step_vars->loc2; + step_vars->loc2 = sp - eval->genbuf + eval->linebuf; +- append_to_genbuf(eval, lp, &sp); +- copy_to_linebuf(eval, eval->genbuf, step_vars); ++ rv = append_to_genbuf(eval, lp, &sp); ++ if (rv != APR_SUCCESS) { ++ return rv; ++ } ++ rv = copy_to_linebuf(eval, eval->genbuf, step_vars); + return rv; + } + +@@ -695,7 +751,10 @@ static char *place(sed_eval_t *eval, char *asp, char *al1, char *al2) + apr_size_t reqsize = (sp - eval->genbuf) + n + 1; + + if (eval->gsize < reqsize) { +- grow_gen_buffer(eval, reqsize, &sp); ++ apr_status_t rc = grow_gen_buffer(eval, reqsize, &sp); ++ if (rc != APR_SUCCESS) { ++ return NULL; ++ } + } + memcpy(sp, al1, n); + return sp + n; +@@ -750,7 +809,8 @@ static apr_status_t command(sed_eval_t *eval, sed_reptr_t *ipc, + } + + p1++; +- copy_to_linebuf(eval, p1, step_vars); ++ rv = copy_to_linebuf(eval, p1, step_vars); ++ if (rv != APR_SUCCESS) return rv; + eval->jflag++; + break; + +@@ -760,21 +820,27 @@ static apr_status_t command(sed_eval_t *eval, sed_reptr_t *ipc, + break; + + case GCOM: +- copy_to_linebuf(eval, eval->holdbuf, step_vars); ++ rv = copy_to_linebuf(eval, eval->holdbuf, step_vars); ++ if (rv != APR_SUCCESS) return rv; + break; + + case CGCOM: +- append_to_linebuf(eval, "\n", step_vars); +- append_to_linebuf(eval, eval->holdbuf, step_vars); ++ rv = append_to_linebuf(eval, "\n", step_vars); ++ if (rv != APR_SUCCESS) return rv; ++ rv = append_to_linebuf(eval, eval->holdbuf, step_vars); ++ if (rv != APR_SUCCESS) return rv; + break; + + case HCOM: +- copy_to_holdbuf(eval, eval->linebuf); ++ rv = copy_to_holdbuf(eval, eval->linebuf); ++ if (rv != APR_SUCCESS) return rv; + break; + + case CHCOM: +- append_to_holdbuf(eval, "\n"); +- append_to_holdbuf(eval, eval->linebuf); ++ rv = append_to_holdbuf(eval, "\n"); ++ if (rv != APR_SUCCESS) return rv; ++ rv = append_to_holdbuf(eval, eval->linebuf); ++ if (rv != APR_SUCCESS) return rv; + break; + + case ICOM: +@@ -896,7 +962,8 @@ static apr_status_t command(sed_eval_t *eval, sed_reptr_t *ipc, + if (rv != APR_SUCCESS) + return rv; + } +- append_to_linebuf(eval, "\n", step_vars); ++ rv = append_to_linebuf(eval, "\n", step_vars); ++ if (rv != APR_SUCCESS) return rv; + eval->pending = ipc->next; + break; + +@@ -970,9 +1037,12 @@ static apr_status_t command(sed_eval_t *eval, sed_reptr_t *ipc, + break; + + case XCOM: +- copy_to_genbuf(eval, eval->linebuf); +- copy_to_linebuf(eval, eval->holdbuf, step_vars); +- copy_to_holdbuf(eval, eval->genbuf); ++ rv = copy_to_genbuf(eval, eval->linebuf); ++ if (rv != APR_SUCCESS) return rv; ++ rv = copy_to_linebuf(eval, eval->holdbuf, step_vars); ++ if (rv != APR_SUCCESS) return rv; ++ rv = copy_to_holdbuf(eval, eval->genbuf); ++ if (rv != APR_SUCCESS) return rv; + break; + + case YCOM: diff --git a/SOURCES/httpd-2.4.53-CVE-2022-30556.patch b/SOURCES/httpd-2.4.53-CVE-2022-30556.patch new file mode 100644 index 0000000..1b8a112 --- /dev/null +++ b/SOURCES/httpd-2.4.53-CVE-2022-30556.patch @@ -0,0 +1,246 @@ +From 3a561759fcb37af179585adb8478922dc9bc6a85 Mon Sep 17 00:00:00 2001 +From: Eric Covener +Date: Wed, 1 Jun 2022 12:36:39 +0000 +Subject: [PATCH] Merge r1901502 from trunk: + +use filters consistently + + +git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1901503 13f79535-47bb-0310-9956-ffa450edef68 +--- + modules/lua/lua_request.c | 144 ++++++++++++++------------------------ + 1 file changed, 53 insertions(+), 91 deletions(-) + +diff --git a/modules/lua/lua_request.c b/modules/lua/lua_request.c +index a3e3b613bc9..2ec453e86b4 100644 +--- a/modules/lua/lua_request.c ++++ b/modules/lua/lua_request.c +@@ -2227,23 +2227,20 @@ static int lua_websocket_greet(lua_State *L) + return 0; + } + +-static apr_status_t lua_websocket_readbytes(conn_rec* c, char* buffer, +- apr_off_t len) ++static apr_status_t lua_websocket_readbytes(conn_rec* c, ++ apr_bucket_brigade *brigade, ++ char* buffer, apr_off_t len) + { +- apr_bucket_brigade *brigade = apr_brigade_create(c->pool, c->bucket_alloc); ++ apr_size_t delivered; + apr_status_t rv; ++ + rv = ap_get_brigade(c->input_filters, brigade, AP_MODE_READBYTES, + APR_BLOCK_READ, len); + if (rv == APR_SUCCESS) { +- if (!APR_BRIGADE_EMPTY(brigade)) { +- apr_bucket* bucket = APR_BRIGADE_FIRST(brigade); +- const char* data = NULL; +- apr_size_t data_length = 0; +- rv = apr_bucket_read(bucket, &data, &data_length, APR_BLOCK_READ); +- if (rv == APR_SUCCESS) { +- memcpy(buffer, data, len); +- } +- apr_bucket_delete(bucket); ++ delivered = len; ++ rv = apr_brigade_flatten(brigade, buffer, &delivered); ++ if ((rv == APR_SUCCESS) && (delivered < len)) { ++ rv = APR_INCOMPLETE; + } + } + apr_brigade_cleanup(brigade); +@@ -2273,35 +2270,28 @@ static int lua_websocket_peek(lua_State *L) + + static int lua_websocket_read(lua_State *L) + { +- apr_socket_t *sock; + apr_status_t rv; + int do_read = 1; + int n = 0; +- apr_size_t len = 1; + apr_size_t plen = 0; + unsigned short payload_short = 0; + apr_uint64_t payload_long = 0; + unsigned char *mask_bytes; + char byte; +- int plaintext; +- +- ++ apr_bucket_brigade *brigade; ++ conn_rec* c; ++ + request_rec *r = ap_lua_check_request_rec(L, 1); +- plaintext = ap_lua_ssl_is_https(r->connection) ? 0 : 1; ++ c = r->connection; + +- + mask_bytes = apr_pcalloc(r->pool, 4); +- sock = ap_get_conn_socket(r->connection); ++ ++ brigade = apr_brigade_create(r->pool, c->bucket_alloc); + + while (do_read) { + do_read = 0; + /* Get opcode and FIN bit */ +- if (plaintext) { +- rv = apr_socket_recv(sock, &byte, &len); +- } +- else { +- rv = lua_websocket_readbytes(r->connection, &byte, 1); +- } ++ rv = lua_websocket_readbytes(c, brigade, &byte, 1); + if (rv == APR_SUCCESS) { + unsigned char ubyte, fin, opcode, mask, payload; + ubyte = (unsigned char)byte; +@@ -2311,12 +2301,7 @@ static int lua_websocket_read(lua_State *L) + opcode = ubyte & 0xf; + + /* Get the payload length and mask bit */ +- if (plaintext) { +- rv = apr_socket_recv(sock, &byte, &len); +- } +- else { +- rv = lua_websocket_readbytes(r->connection, &byte, 1); +- } ++ rv = lua_websocket_readbytes(c, brigade, &byte, 1); + if (rv == APR_SUCCESS) { + ubyte = (unsigned char)byte; + /* Mask is the first bit */ +@@ -2327,40 +2312,25 @@ static int lua_websocket_read(lua_State *L) + + /* Extended payload? */ + if (payload == 126) { +- len = 2; +- if (plaintext) { +- /* XXX: apr_socket_recv does not receive len bits, only up to len bits! */ +- rv = apr_socket_recv(sock, (char*) &payload_short, &len); +- } +- else { +- rv = lua_websocket_readbytes(r->connection, +- (char*) &payload_short, 2); +- } +- payload_short = ntohs(payload_short); ++ rv = lua_websocket_readbytes(c, brigade, ++ (char*) &payload_short, 2); + +- if (rv == APR_SUCCESS) { +- plen = payload_short; +- } +- else { ++ if (rv != APR_SUCCESS) { + return 0; + } ++ ++ plen = ntohs(payload_short); + } + /* Super duper extended payload? */ + if (payload == 127) { +- len = 8; +- if (plaintext) { +- rv = apr_socket_recv(sock, (char*) &payload_long, &len); +- } +- else { +- rv = lua_websocket_readbytes(r->connection, +- (char*) &payload_long, 8); +- } +- if (rv == APR_SUCCESS) { +- plen = ap_ntoh64(&payload_long); +- } +- else { ++ rv = lua_websocket_readbytes(c, brigade, ++ (char*) &payload_long, 8); ++ ++ if (rv != APR_SUCCESS) { + return 0; + } ++ ++ plen = ap_ntoh64(&payload_long); + } + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03210) + "Websocket: Reading %" APR_SIZE_T_FMT " (%s) bytes, masking is %s. %s", +@@ -2369,46 +2339,27 @@ static int lua_websocket_read(lua_State *L) + mask ? "on" : "off", + fin ? "This is a final frame" : "more to follow"); + if (mask) { +- len = 4; +- if (plaintext) { +- rv = apr_socket_recv(sock, (char*) mask_bytes, &len); +- } +- else { +- rv = lua_websocket_readbytes(r->connection, +- (char*) mask_bytes, 4); +- } ++ rv = lua_websocket_readbytes(c, brigade, ++ (char*) mask_bytes, 4); ++ + if (rv != APR_SUCCESS) { + return 0; + } + } + if (plen < (HUGE_STRING_LEN*1024) && plen > 0) { + apr_size_t remaining = plen; +- apr_size_t received; +- apr_off_t at = 0; + char *buffer = apr_palloc(r->pool, plen+1); + buffer[plen] = 0; + +- if (plaintext) { +- while (remaining > 0) { +- received = remaining; +- rv = apr_socket_recv(sock, buffer+at, &received); +- if (received > 0 ) { +- remaining -= received; +- at += received; +- } +- } +- ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, +- "Websocket: Frame contained %" APR_OFF_T_FMT " bytes, pushed to Lua stack", +- at); +- } +- else { +- rv = lua_websocket_readbytes(r->connection, buffer, +- remaining); +- ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, +- "Websocket: SSL Frame contained %" APR_SIZE_T_FMT " bytes, "\ +- "pushed to Lua stack", +- remaining); ++ rv = lua_websocket_readbytes(c, brigade, buffer, remaining); ++ ++ if (rv != APR_SUCCESS) { ++ return 0; + } ++ ++ ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, ++ "Websocket: Frame contained %" APR_SIZE_T_FMT \ ++ " bytes, pushed to Lua stack", remaining); + if (mask) { + for (n = 0; n < plen; n++) { + buffer[n] ^= mask_bytes[n%4]; +@@ -2420,14 +2371,25 @@ static int lua_websocket_read(lua_State *L) + return 2; + } + +- + /* Decide if we need to react to the opcode or not */ + if (opcode == 0x09) { /* ping */ + char frame[2]; +- plen = 2; ++ apr_bucket *b; ++ + frame[0] = 0x8A; + frame[1] = 0; +- apr_socket_send(sock, frame, &plen); /* Pong! */ ++ ++ /* Pong! */ ++ b = apr_bucket_transient_create(frame, 2, c->bucket_alloc); ++ APR_BRIGADE_INSERT_TAIL(brigade, b); ++ ++ rv = ap_pass_brigade(c->output_filters, brigade); ++ apr_brigade_cleanup(brigade); ++ ++ if (rv != APR_SUCCESS) { ++ return 0; ++ } ++ + do_read = 1; + } + } diff --git a/SOURCES/httpd-2.4.53-CVE-2022-31813.patch b/SOURCES/httpd-2.4.53-CVE-2022-31813.patch new file mode 100644 index 0000000..325b5cd --- /dev/null +++ b/SOURCES/httpd-2.4.53-CVE-2022-31813.patch @@ -0,0 +1,230 @@ +diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c +index 3af5aed..bc86253 100644 +--- a/modules/proxy/proxy_util.c ++++ b/modules/proxy/proxy_util.c +@@ -3854,12 +3854,14 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p, + char **old_cl_val, + char **old_te_val) + { ++ int rc = OK; + conn_rec *c = r->connection; + int counter; + char *buf; ++ apr_table_t *saved_headers_in = r->headers_in; ++ const char *saved_host = apr_table_get(saved_headers_in, "Host"); + const apr_array_header_t *headers_in_array; + const apr_table_entry_t *headers_in; +- apr_table_t *saved_headers_in; + apr_bucket *e; + int do_100_continue; + conn_rec *origin = p_conn->connection; +@@ -3896,6 +3898,52 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p, + ap_xlate_proto_to_ascii(buf, strlen(buf)); + e = apr_bucket_pool_create(buf, strlen(buf), p, c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(header_brigade, e); ++ ++ /* ++ * Make a copy on r->headers_in for the request we make to the backend, ++ * modify the copy in place according to our configuration and connection ++ * handling, use it to fill in the forwarded headers' brigade, and finally ++ * restore the saved/original ones in r->headers_in. ++ * ++ * Note: We need to take r->pool for apr_table_copy as the key / value ++ * pairs in r->headers_in have been created out of r->pool and ++ * p might be (and actually is) a longer living pool. ++ * This would trigger the bad pool ancestry abort in apr_table_copy if ++ * apr is compiled with APR_POOL_DEBUG. ++ * ++ * icing: if p indeed lives longer than r->pool, we should allocate ++ * all new header values from r->pool as well and avoid leakage. ++ */ ++ r->headers_in = apr_table_copy(r->pool, saved_headers_in); ++ ++ /* Return the original Transfer-Encoding and/or Content-Length values ++ * then drop the headers, they must be set by the proxy handler based ++ * on the actual body being forwarded. ++ */ ++ if ((*old_te_val = (char *)apr_table_get(r->headers_in, ++ "Transfer-Encoding"))) { ++ apr_table_unset(r->headers_in, "Transfer-Encoding"); ++ } ++ if ((*old_cl_val = (char *)apr_table_get(r->headers_in, ++ "Content-Length"))) { ++ apr_table_unset(r->headers_in, "Content-Length"); ++ } ++ ++ /* Clear out hop-by-hop request headers not to forward */ ++ if (ap_proxy_clear_connection(r, r->headers_in) < 0) { ++ rc = HTTP_BAD_REQUEST; ++ goto cleanup; ++ } ++ ++ /* RFC2616 13.5.1 says we should strip these */ ++ apr_table_unset(r->headers_in, "Keep-Alive"); ++ apr_table_unset(r->headers_in, "Upgrade"); ++ apr_table_unset(r->headers_in, "Trailer"); ++ apr_table_unset(r->headers_in, "TE"); ++ ++ /* We used to send `Host: ` always first, so let's keep it that ++ * way. No telling which legacy backend is relying no this. ++ */ + if (dconf->preserve_host == 0) { + if (ap_strchr_c(uri->hostname, ':')) { /* if literal IPv6 address */ + if (uri->port_str && uri->port != DEFAULT_HTTP_PORT) { +@@ -3917,7 +3965,7 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p, + /* don't want to use r->hostname, as the incoming header might have a + * port attached + */ +- const char* hostname = apr_table_get(r->headers_in,"Host"); ++ const char* hostname = saved_host; + if (!hostname) { + hostname = r->server->server_hostname; + ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01092) +@@ -3931,21 +3979,7 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p, + ap_xlate_proto_to_ascii(buf, strlen(buf)); + e = apr_bucket_pool_create(buf, strlen(buf), p, c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(header_brigade, e); +- +- /* +- * Save the original headers in here and restore them when leaving, since +- * we will apply proxy purpose only modifications (eg. clearing hop-by-hop +- * headers, add Via or X-Forwarded-* or Expect...), whereas the originals +- * will be needed later to prepare the correct response and logging. +- * +- * Note: We need to take r->pool for apr_table_copy as the key / value +- * pairs in r->headers_in have been created out of r->pool and +- * p might be (and actually is) a longer living pool. +- * This would trigger the bad pool ancestry abort in apr_table_copy if +- * apr is compiled with APR_POOL_DEBUG. +- */ +- saved_headers_in = r->headers_in; +- r->headers_in = apr_table_copy(r->pool, saved_headers_in); ++ apr_table_unset(r->headers_in, "Host"); + + /* handle Via */ + if (conf->viaopt == via_block) { +@@ -4012,8 +4046,6 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p, + */ + if (dconf->add_forwarded_headers) { + if (PROXYREQ_REVERSE == r->proxyreq) { +- const char *buf; +- + /* Add X-Forwarded-For: so that the upstream has a chance to + * determine, where the original request came from. + */ +@@ -4023,8 +4055,9 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p, + /* Add X-Forwarded-Host: so that upstream knows what the + * original request hostname was. + */ +- if ((buf = apr_table_get(r->headers_in, "Host"))) { +- apr_table_mergen(r->headers_in, "X-Forwarded-Host", buf); ++ if (saved_host) { ++ apr_table_mergen(r->headers_in, "X-Forwarded-Host", ++ saved_host); + } + + /* Add X-Forwarded-Server: so that upstream knows what the +@@ -4036,11 +4069,28 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p, + } + } + +- proxy_run_fixups(r); +- if (ap_proxy_clear_connection(r, r->headers_in) < 0) { +- return HTTP_BAD_REQUEST; ++ /* Do we want to strip Proxy-Authorization ? ++ * If we haven't used it, then NO ++ * If we have used it then MAYBE: RFC2616 says we MAY propagate it. ++ * So let's make it configurable by env. ++ */ ++ if (r->user != NULL /* we've authenticated */ ++ && !apr_table_get(r->subprocess_env, "Proxy-Chain-Auth")) { ++ apr_table_unset(r->headers_in, "Proxy-Authorization"); + } + ++ /* for sub-requests, ignore freshness/expiry headers */ ++ if (r->main) { ++ apr_table_unset(r->headers_in, "If-Match"); ++ apr_table_unset(r->headers_in, "If-Modified-Since"); ++ apr_table_unset(r->headers_in, "If-Range"); ++ apr_table_unset(r->headers_in, "If-Unmodified-Since"); ++ apr_table_unset(r->headers_in, "If-None-Match"); ++ } ++ ++ /* run hook to fixup the request we are about to send */ ++ proxy_run_fixups(r); ++ + creds = apr_table_get(r->notes, "proxy-basic-creds"); + if (creds) { + apr_table_mergen(r->headers_in, "Proxy-Authorization", creds); +@@ -4051,55 +4101,8 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p, + headers_in = (const apr_table_entry_t *) headers_in_array->elts; + for (counter = 0; counter < headers_in_array->nelts; counter++) { + if (headers_in[counter].key == NULL +- || headers_in[counter].val == NULL +- +- /* Already sent */ +- || !ap_cstr_casecmp(headers_in[counter].key, "Host") +- +- /* Clear out hop-by-hop request headers not to send +- * RFC2616 13.5.1 says we should strip these headers +- */ +- || !ap_cstr_casecmp(headers_in[counter].key, "Keep-Alive") +- || !ap_cstr_casecmp(headers_in[counter].key, "TE") +- || !ap_cstr_casecmp(headers_in[counter].key, "Trailer") +- || !ap_cstr_casecmp(headers_in[counter].key, "Upgrade") +- +- ) { +- continue; +- } +- /* Do we want to strip Proxy-Authorization ? +- * If we haven't used it, then NO +- * If we have used it then MAYBE: RFC2616 says we MAY propagate it. +- * So let's make it configurable by env. +- */ +- if (!ap_cstr_casecmp(headers_in[counter].key,"Proxy-Authorization")) { +- if (r->user != NULL) { /* we've authenticated */ +- if (!apr_table_get(r->subprocess_env, "Proxy-Chain-Auth")) { +- continue; +- } +- } +- } +- +- /* Skip Transfer-Encoding and Content-Length for now. +- */ +- if (!ap_cstr_casecmp(headers_in[counter].key, "Transfer-Encoding")) { +- *old_te_val = headers_in[counter].val; +- continue; +- } +- if (!ap_cstr_casecmp(headers_in[counter].key, "Content-Length")) { +- *old_cl_val = headers_in[counter].val; +- continue; +- } +- +- /* for sub-requests, ignore freshness/expiry headers */ +- if (r->main) { +- if ( !ap_cstr_casecmp(headers_in[counter].key, "If-Match") +- || !ap_cstr_casecmp(headers_in[counter].key, "If-Modified-Since") +- || !ap_cstr_casecmp(headers_in[counter].key, "If-Range") +- || !ap_cstr_casecmp(headers_in[counter].key, "If-Unmodified-Since") +- || !ap_cstr_casecmp(headers_in[counter].key, "If-None-Match")) { +- continue; +- } ++ || headers_in[counter].val == NULL) { ++ continue; + } + + buf = apr_pstrcat(p, headers_in[counter].key, ": ", +@@ -4110,11 +4113,9 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p, + APR_BRIGADE_INSERT_TAIL(header_brigade, e); + } + +- /* Restore the original headers in (see comment above), +- * we won't modify them anymore. +- */ ++cleanup: + r->headers_in = saved_headers_in; +- return OK; ++ return rc; + } + + PROXY_DECLARE(int) ap_proxy_prefetch_input(request_rec *r, diff --git a/SOURCES/httpd-2.4.53-detect-systemd.patch b/SOURCES/httpd-2.4.53-detect-systemd.patch new file mode 100644 index 0000000..d501b06 --- /dev/null +++ b/SOURCES/httpd-2.4.53-detect-systemd.patch @@ -0,0 +1,45 @@ +diff --git a/Makefile.in b/Makefile.in +index a2e9c82..bd8045c 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -4,7 +4,7 @@ CLEAN_SUBDIRS = test + + PROGRAM_NAME = $(progname) + PROGRAM_SOURCES = modules.c +-PROGRAM_LDADD = buildmark.o $(HTTPD_LDFLAGS) $(PROGRAM_DEPENDENCIES) $(PCRE_LIBS) $(EXTRA_LIBS) $(AP_LIBS) $(LIBS) ++PROGRAM_LDADD = buildmark.o $(HTTPD_LDFLAGS) $(PROGRAM_DEPENDENCIES) $(HTTPD_LIBS) $(EXTRA_LIBS) $(AP_LIBS) $(LIBS) + PROGRAM_PRELINK = $(COMPILE) -c $(top_srcdir)/server/buildmark.c + PROGRAM_DEPENDENCIES = \ + server/libmain.la \ +diff --git a/acinclude.m4 b/acinclude.m4 +index 97484c9..05abe18 100644 +--- a/acinclude.m4 ++++ b/acinclude.m4 +@@ -631,6 +631,7 @@ case $host in + if test "${ac_cv_header_systemd_sd_daemon_h}" = "no" || test -z "${SYSTEMD_LIBS}"; then + AC_MSG_WARN([Your system does not support systemd.]) + else ++ APR_ADDTO(HTTPD_LIBS, [$SYSTEMD_LIBS]) + AC_DEFINE(HAVE_SYSTEMD, 1, [Define if systemd is supported]) + fi + fi +diff --git a/configure.in b/configure.in +index cf437fe..521fc45 100644 +--- a/configure.in ++++ b/configure.in +@@ -239,6 +239,7 @@ if test "x$PCRE_CONFIG" != "x"; then + AC_MSG_NOTICE([Using external PCRE library from $PCRE_CONFIG]) + APR_ADDTO(PCRE_INCLUDES, [`$PCRE_CONFIG --cflags`]) + APR_ADDTO(PCRE_LIBS, [`$PCRE_CONFIG --libs8 2>/dev/null || $PCRE_CONFIG --libs`]) ++ APR_ADDTO(HTTPD_LIBS, [\$(PCRE_LIBS)]) + else + AC_MSG_ERROR([pcre(2)-config for libpcre not found. PCRE is required and available from http://pcre.org/]) + fi +@@ -734,6 +735,7 @@ APACHE_SUBST(OS_DIR) + APACHE_SUBST(BUILTIN_LIBS) + APACHE_SUBST(SHLIBPATH_VAR) + APACHE_SUBST(OS_SPECIFIC_VARS) ++APACHE_SUBST(HTTPD_LIBS) + + PRE_SHARED_CMDS='echo ""' + POST_SHARED_CMDS='echo ""' diff --git a/SOURCES/httpd-2.4.53-icons.patch b/SOURCES/httpd-2.4.53-icons.patch new file mode 100644 index 0000000..efc0c4d --- /dev/null +++ b/SOURCES/httpd-2.4.53-icons.patch @@ -0,0 +1,49 @@ +diff --git a/docs/conf/extra/httpd-autoindex.conf.in b/docs/conf/extra/httpd-autoindex.conf.in +index 51b02ed..93a2b87 100644 +--- a/docs/conf/extra/httpd-autoindex.conf.in ++++ b/docs/conf/extra/httpd-autoindex.conf.in +@@ -21,7 +21,7 @@ IndexOptions FancyIndexing HTMLTable VersionSort + Alias /icons/ "@exp_iconsdir@/" + + +- Options Indexes MultiViews ++ Options Indexes MultiViews FollowSymlinks + AllowOverride None + Require all granted + +@@ -37,6 +37,7 @@ AddIconByType (TXT,/icons/text.gif) text/* + AddIconByType (IMG,/icons/image2.gif) image/* + AddIconByType (SND,/icons/sound2.gif) audio/* + AddIconByType (VID,/icons/movie.gif) video/* ++AddIconByType /icons/bomb.gif application/x-coredump + + AddIcon /icons/binary.gif .bin .exe + AddIcon /icons/binhex.gif .hqx +@@ -53,7 +54,6 @@ AddIcon /icons/dvi.gif .dvi + AddIcon /icons/uuencoded.gif .uu + AddIcon /icons/script.gif .conf .sh .shar .csh .ksh .tcl + AddIcon /icons/tex.gif .tex +-AddIcon /icons/bomb.gif core + + AddIcon /icons/back.gif .. + AddIcon /icons/hand.right.gif README +diff --git a/docs/conf/magic b/docs/conf/magic +index bc891d9..9a41b44 100644 +--- a/docs/conf/magic ++++ b/docs/conf/magic +@@ -383,3 +383,15 @@ + 4 string moov video/quicktime + 4 string mdat video/quicktime + ++ ++#------------------------------------------------------------------------------ ++# application/x-coredump for LE/BE ELF ++# ++0 string \177ELF ++>5 byte 1 ++>16 leshort 4 application/x-coredump ++ ++0 string \177ELF ++>5 byte 2 ++>16 beshort 4 application/x-coredump ++ diff --git a/SOURCES/httpd-2.4.53-r1878890.patch b/SOURCES/httpd-2.4.53-r1878890.patch new file mode 100644 index 0000000..945c498 --- /dev/null +++ b/SOURCES/httpd-2.4.53-r1878890.patch @@ -0,0 +1,116 @@ +diff --git a/include/util_ldap.h b/include/util_ldap.h +index 28e0760..edb8a81 100644 +--- a/include/util_ldap.h ++++ b/include/util_ldap.h +@@ -32,7 +32,6 @@ + #if APR_MAJOR_VERSION < 2 + /* The LDAP API is currently only present in APR 1.x */ + #include "apr_ldap.h" +-#include "apr_ldap_rebind.h" + #else + #define APR_HAS_LDAP 0 + #endif +diff --git a/modules/ldap/util_ldap.c b/modules/ldap/util_ldap.c +index 4d92ec9..864bd62 100644 +--- a/modules/ldap/util_ldap.c ++++ b/modules/ldap/util_ldap.c +@@ -154,6 +154,38 @@ static int util_ldap_handler(request_rec *r) + return OK; + } + ++/* For OpenLDAP with the 3-arg version of ldap_set_rebind_proc(), use ++ * a simpler rebind callback than the implementation in APR-util. ++ * Testing for API version >= 3001 appears safe although OpenLDAP ++ * 2.1.x (API version = 2004) also has the 3-arg API. */ ++#if APR_HAS_OPENLDAP_LDAPSDK && defined(LDAP_API_VERSION) && LDAP_API_VERSION >= 3001 ++ ++#define uldap_rebind_init(p) APR_SUCCESS /* noop */ ++ ++static int uldap_rebind_proc(LDAP *ld, const char *url, ber_tag_t request, ++ ber_int_t msgid, void *params) ++{ ++ util_ldap_connection_t *ldc = params; ++ ++ return ldap_bind_s(ld, ldc->binddn, ldc->bindpw, LDAP_AUTH_SIMPLE); ++} ++ ++static apr_status_t uldap_rebind_add(util_ldap_connection_t *ldc) ++{ ++ ldap_set_rebind_proc(ldc->ldap, uldap_rebind_proc, ldc); ++ return APR_SUCCESS; ++} ++ ++#else /* !APR_HAS_OPENLDAP_LDAPSDK */ ++ ++#define USE_APR_LDAP_REBIND ++#include ++ ++#define uldap_rebind_init(p) apr_ldap_rebind_init(p) ++#define uldap_rebind_add(ldc) apr_ldap_rebind_add((ldc)->rebind_pool, \ ++ (ldc)->ldap, (ldc)->binddn, \ ++ (ldc)->bindpw) ++#endif + + + /* ------------------------------------------------------------------ */ +@@ -195,6 +227,13 @@ static apr_status_t uldap_connection_unbind(void *param) + util_ldap_connection_t *ldc = param; + + if (ldc) { ++#ifdef USE_APR_LDAP_REBIND ++ /* forget the rebind info for this conn */ ++ if (ldc->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) { ++ apr_pool_clear(ldc->rebind_pool); ++ } ++#endif ++ + if (ldc->ldap) { + if (ldc->r) { + ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, ldc->r, "LDC %pp unbind", ldc); +@@ -203,12 +242,6 @@ static apr_status_t uldap_connection_unbind(void *param) + ldc->ldap = NULL; + } + ldc->bound = 0; +- +- /* forget the rebind info for this conn */ +- if (ldc->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) { +- apr_ldap_rebind_remove(ldc->ldap); +- apr_pool_clear(ldc->rebind_pool); +- } + } + + return APR_SUCCESS; +@@ -344,7 +377,7 @@ static int uldap_connection_init(request_rec *r, + + if (ldc->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) { + /* Now that we have an ldap struct, add it to the referral list for rebinds. */ +- rc = apr_ldap_rebind_add(ldc->rebind_pool, ldc->ldap, ldc->binddn, ldc->bindpw); ++ rc = uldap_rebind_add(ldc); + if (rc != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, rc, r->server, APLOGNO(01277) + "LDAP: Unable to add rebind cross reference entry. Out of memory?"); +@@ -870,6 +903,7 @@ static util_ldap_connection_t * + /* whether or not to keep this connection in the pool when it's returned */ + l->keep = (st->connection_pool_ttl == 0) ? 0 : 1; + ++#ifdef USE_APR_LDAP_REBIND + if (l->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) { + if (apr_pool_create(&(l->rebind_pool), l->pool) != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, APLOGNO(01286) +@@ -881,6 +915,7 @@ static util_ldap_connection_t * + } + apr_pool_tag(l->rebind_pool, "util_ldap_rebind"); + } ++#endif + + if (p) { + p->next = l; +@@ -3068,7 +3103,7 @@ static int util_ldap_post_config(apr_pool_t *p, apr_pool_t *plog, + } + + /* Initialize the rebind callback's cross reference list. */ +- apr_ldap_rebind_init (p); ++ (void) uldap_rebind_init(p); + + #ifdef AP_LDAP_OPT_DEBUG + if (st->debug_level > 0) { diff --git a/SOURCES/httpd-2.4.53-r1901199.patch b/SOURCES/httpd-2.4.53-r1901199.patch new file mode 100644 index 0000000..978e653 --- /dev/null +++ b/SOURCES/httpd-2.4.53-r1901199.patch @@ -0,0 +1,336 @@ +--- a/server/mpm/event/event.c 2022/05/24 08:59:30 1901198 ++++ b/server/mpm/event/event.c 2022/05/24 09:00:19 1901199 +@@ -379,7 +379,7 @@ + * We use this value to optimize routines that have to scan the entire + * scoreboard. + */ +- int max_daemons_limit; ++ int max_daemon_used; + + /* + * All running workers, active and shutting down, including those that +@@ -645,7 +645,7 @@ + *rv = APR_SUCCESS; + switch (query_code) { + case AP_MPMQ_MAX_DAEMON_USED: +- *result = retained->max_daemons_limit; ++ *result = retained->max_daemon_used; + break; + case AP_MPMQ_IS_THREADED: + *result = AP_MPMQ_STATIC; +@@ -696,14 +696,32 @@ + return OK; + } + +-static void event_note_child_killed(int childnum, pid_t pid, ap_generation_t gen) ++static void event_note_child_stopped(int slot, pid_t pid, ap_generation_t gen) + { +- if (childnum != -1) { /* child had a scoreboard slot? */ +- ap_run_child_status(ap_server_conf, +- ap_scoreboard_image->parent[childnum].pid, +- ap_scoreboard_image->parent[childnum].generation, +- childnum, MPM_CHILD_EXITED); +- ap_scoreboard_image->parent[childnum].pid = 0; ++ if (slot != -1) { /* child had a scoreboard slot? */ ++ process_score *ps = &ap_scoreboard_image->parent[slot]; ++ int i; ++ ++ pid = ps->pid; ++ gen = ps->generation; ++ for (i = 0; i < threads_per_child; i++) { ++ ap_update_child_status_from_indexes(slot, i, SERVER_DEAD, NULL); ++ } ++ ap_run_child_status(ap_server_conf, pid, gen, slot, MPM_CHILD_EXITED); ++ if (ps->quiescing != 2) { /* vs perform_idle_server_maintenance() */ ++ retained->active_daemons--; ++ } ++ retained->total_daemons--; ++ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, ++ "Child %d stopped: pid %d, gen %d, " ++ "active %d/%d, total %d/%d/%d, quiescing %d", ++ slot, (int)pid, (int)gen, ++ retained->active_daemons, active_daemons_limit, ++ retained->total_daemons, retained->max_daemon_used, ++ server_limit, ps->quiescing); ++ ps->not_accepting = 0; ++ ps->quiescing = 0; ++ ps->pid = 0; + } + else { + ap_run_child_status(ap_server_conf, pid, gen, -1, MPM_CHILD_EXITED); +@@ -713,9 +731,19 @@ + static void event_note_child_started(int slot, pid_t pid) + { + ap_generation_t gen = retained->mpm->my_generation; ++ ++ retained->total_daemons++; ++ retained->active_daemons++; + ap_scoreboard_image->parent[slot].pid = pid; + ap_scoreboard_image->parent[slot].generation = gen; + ap_run_child_status(ap_server_conf, pid, gen, slot, MPM_CHILD_STARTED); ++ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, ++ "Child %d started: pid %d, gen %d, " ++ "active %d/%d, total %d/%d/%d", ++ slot, (int)pid, (int)gen, ++ retained->active_daemons, active_daemons_limit, ++ retained->total_daemons, retained->max_daemon_used, ++ server_limit); + } + + static const char *event_get_name(void) +@@ -737,7 +765,7 @@ + } + + if (one_process) { +- event_note_child_killed(/* slot */ 0, 0, 0); ++ event_note_child_stopped(/* slot */ 0, 0, 0); + } + + exit(code); +@@ -2712,8 +2740,8 @@ + { + int pid; + +- if (slot + 1 > retained->max_daemons_limit) { +- retained->max_daemons_limit = slot + 1; ++ if (slot + 1 > retained->max_daemon_used) { ++ retained->max_daemon_used = slot + 1; + } + + if (ap_scoreboard_image->parent[slot].pid != 0) { +@@ -2781,11 +2809,7 @@ + return -1; + } + +- ap_scoreboard_image->parent[slot].quiescing = 0; +- ap_scoreboard_image->parent[slot].not_accepting = 0; + event_note_child_started(slot, pid); +- retained->active_daemons++; +- retained->total_daemons++; + return 0; + } + +@@ -2805,7 +2829,8 @@ + } + } + +-static void perform_idle_server_maintenance(int child_bucket) ++static void perform_idle_server_maintenance(int child_bucket, ++ int *max_daemon_used) + { + int num_buckets = retained->mpm->num_buckets; + int idle_thread_count = 0; +@@ -2821,7 +2846,7 @@ + /* We only care about child_bucket in this call */ + continue; + } +- if (i >= retained->max_daemons_limit && ++ if (i >= retained->max_daemon_used && + free_length == retained->idle_spawn_rate[child_bucket]) { + /* short cut if all active processes have been examined and + * enough empty scoreboard slots have been found +@@ -2835,6 +2860,13 @@ + if (ps->quiescing == 1) { + ps->quiescing = 2; + retained->active_daemons--; ++ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, ++ "Child %d quiescing: pid %d, gen %d, " ++ "active %d/%d, total %d/%d/%d", ++ i, (int)ps->pid, (int)ps->generation, ++ retained->active_daemons, active_daemons_limit, ++ retained->total_daemons, retained->max_daemon_used, ++ server_limit); + } + for (j = 0; j < threads_per_child; j++) { + int status = ap_scoreboard_image->servers[i][j].status; +@@ -2863,8 +2895,9 @@ + free_slots[free_length++] = i; + } + } +- +- retained->max_daemons_limit = last_non_dead + 1; ++ if (*max_daemon_used < last_non_dead + 1) { ++ *max_daemon_used = last_non_dead + 1; ++ } + + if (retained->sick_child_detected) { + if (had_healthy_child) { +@@ -2893,6 +2926,10 @@ + } + } + ++ AP_DEBUG_ASSERT(retained->active_daemons <= retained->total_daemons ++ && retained->total_daemons <= retained->max_daemon_used ++ && retained->max_daemon_used <= server_limit); ++ + if (idle_thread_count > max_spare_threads / num_buckets) { + /* + * Child processes that we ask to shut down won't die immediately +@@ -2915,13 +2952,12 @@ + active_daemons_limit)); + ap_log_error(APLOG_MARK, APLOG_TRACE5, 0, ap_server_conf, + "%shutting down one child: " +- "active daemons %d / active limit %d / " +- "total daemons %d / ServerLimit %d / " +- "idle threads %d / max workers %d", ++ "active %d/%d, total %d/%d/%d, " ++ "idle threads %d, max workers %d", + (do_kill) ? "S" : "Not s", + retained->active_daemons, active_daemons_limit, +- retained->total_daemons, server_limit, +- idle_thread_count, max_workers); ++ retained->total_daemons, retained->max_daemon_used, ++ server_limit, idle_thread_count, max_workers); + if (do_kill) { + ap_mpm_podx_signal(all_buckets[child_bucket].pod, + AP_MPM_PODX_GRACEFUL); +@@ -2970,10 +3006,14 @@ + else { + ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, ap_server_conf, + "server is at active daemons limit, spawning " +- "of %d children cancelled: %d/%d active, " +- "rate %d", free_length, ++ "of %d children cancelled: active %d/%d, " ++ "total %d/%d/%d, rate %d", free_length, + retained->active_daemons, active_daemons_limit, +- retained->idle_spawn_rate[child_bucket]); ++ retained->total_daemons, retained->max_daemon_used, ++ server_limit, retained->idle_spawn_rate[child_bucket]); ++ /* reset the spawning rate and prevent its growth below */ ++ retained->idle_spawn_rate[child_bucket] = 1; ++ ++retained->hold_off_on_exponential_spawning; + free_length = 0; + } + } +@@ -2989,12 +3029,13 @@ + retained->total_daemons); + } + for (i = 0; i < free_length; ++i) { +- ap_log_error(APLOG_MARK, APLOG_TRACE5, 0, ap_server_conf, +- "Spawning new child: slot %d active / " +- "total daemons: %d/%d", +- free_slots[i], retained->active_daemons, +- retained->total_daemons); +- make_child(ap_server_conf, free_slots[i], child_bucket); ++ int slot = free_slots[i]; ++ if (make_child(ap_server_conf, slot, child_bucket) < 0) { ++ continue; ++ } ++ if (*max_daemon_used < slot + 1) { ++ *max_daemon_used = slot + 1; ++ } + } + /* the next time around we want to spawn twice as many if this + * wasn't good enough, but not if we've just done a graceful +@@ -3016,6 +3057,7 @@ + static void server_main_loop(int remaining_children_to_start) + { + int num_buckets = retained->mpm->num_buckets; ++ int max_daemon_used = 0; + int child_slot; + apr_exit_why_e exitwhy; + int status, processed_status; +@@ -3061,19 +3103,8 @@ + } + /* non-fatal death... note that it's gone in the scoreboard. */ + if (child_slot >= 0) { +- process_score *ps; ++ event_note_child_stopped(child_slot, 0, 0); + +- for (i = 0; i < threads_per_child; i++) +- ap_update_child_status_from_indexes(child_slot, i, +- SERVER_DEAD, NULL); +- +- event_note_child_killed(child_slot, 0, 0); +- ps = &ap_scoreboard_image->parent[child_slot]; +- if (ps->quiescing != 2) +- retained->active_daemons--; +- ps->quiescing = 0; +- /* NOTE: We don't dec in the (child_slot < 0) case! */ +- retained->total_daemons--; + if (processed_status == APEXIT_CHILDSICK) { + /* resource shortage, minimize the fork rate */ + retained->idle_spawn_rate[child_slot % num_buckets] = 1; +@@ -3123,9 +3154,11 @@ + continue; + } + ++ max_daemon_used = 0; + for (i = 0; i < num_buckets; i++) { +- perform_idle_server_maintenance(i); ++ perform_idle_server_maintenance(i, &max_daemon_used); + } ++ retained->max_daemon_used = max_daemon_used; + } + } + +@@ -3213,7 +3246,7 @@ + AP_MPM_PODX_RESTART); + } + ap_reclaim_child_processes(1, /* Start with SIGTERM */ +- event_note_child_killed); ++ event_note_child_stopped); + + if (!child_fatal) { + /* cleanup pid file on normal shutdown */ +@@ -3239,7 +3272,7 @@ + ap_mpm_podx_killpg(all_buckets[i].pod, active_daemons_limit, + AP_MPM_PODX_GRACEFUL); + } +- ap_relieve_child_processes(event_note_child_killed); ++ ap_relieve_child_processes(event_note_child_stopped); + + if (!child_fatal) { + /* cleanup pid file on normal shutdown */ +@@ -3261,10 +3294,10 @@ + apr_sleep(apr_time_from_sec(1)); + + /* Relieve any children which have now exited */ +- ap_relieve_child_processes(event_note_child_killed); ++ ap_relieve_child_processes(event_note_child_stopped); + + active_children = 0; +- for (index = 0; index < retained->max_daemons_limit; ++index) { ++ for (index = 0; index < retained->max_daemon_used; ++index) { + if (ap_mpm_safe_kill(MPM_CHILD_PID(index), 0) == APR_SUCCESS) { + active_children = 1; + /* Having just one child is enough to stay around */ +@@ -3282,7 +3315,7 @@ + ap_mpm_podx_killpg(all_buckets[i].pod, active_daemons_limit, + AP_MPM_PODX_RESTART); + } +- ap_reclaim_child_processes(1, event_note_child_killed); ++ ap_reclaim_child_processes(1, event_note_child_stopped); + + return DONE; + } +@@ -3302,8 +3335,7 @@ + + if (!retained->mpm->is_ungraceful) { + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00493) +- AP_SIG_GRACEFUL_STRING +- " received. Doing graceful restart"); ++ AP_SIG_GRACEFUL_STRING " received. Doing graceful restart"); + /* wake up the children...time to die. But we'll have more soon */ + for (i = 0; i < num_buckets; i++) { + ap_mpm_podx_killpg(all_buckets[i].pod, active_daemons_limit, +@@ -3316,6 +3348,8 @@ + + } + else { ++ ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00494) ++ "SIGHUP received. Attempting to restart"); + /* Kill 'em all. Since the child acts the same on the parents SIGTERM + * and a SIGHUP, we may as well use the same signal, because some user + * pthreads are stealing signals from us left and right. +@@ -3326,9 +3360,7 @@ + } + + ap_reclaim_child_processes(1, /* Start with SIGTERM */ +- event_note_child_killed); +- ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00494) +- "SIGHUP received. Attempting to restart"); ++ event_note_child_stopped); + } + + return OK; diff --git a/SOURCES/httpd-2.4.53-separate-systemd-fns.patch b/SOURCES/httpd-2.4.53-separate-systemd-fns.patch new file mode 100644 index 0000000..88b99ff --- /dev/null +++ b/SOURCES/httpd-2.4.53-separate-systemd-fns.patch @@ -0,0 +1,286 @@ +diff --git a/acinclude.m4 b/acinclude.m4 +index 05abe18..97484c9 100644 +--- a/acinclude.m4 ++++ b/acinclude.m4 +@@ -631,7 +631,6 @@ case $host in + if test "${ac_cv_header_systemd_sd_daemon_h}" = "no" || test -z "${SYSTEMD_LIBS}"; then + AC_MSG_WARN([Your system does not support systemd.]) + else +- APR_ADDTO(HTTPD_LIBS, [$SYSTEMD_LIBS]) + AC_DEFINE(HAVE_SYSTEMD, 1, [Define if systemd is supported]) + fi + fi +diff --git a/include/ap_listen.h b/include/ap_listen.h +index 58c2574..d5ed968 100644 +--- a/include/ap_listen.h ++++ b/include/ap_listen.h +@@ -29,6 +29,7 @@ + #include "apr_network_io.h" + #include "httpd.h" + #include "http_config.h" ++#include "apr_optional.h" + + #ifdef __cplusplus + extern "C" { +@@ -143,6 +144,15 @@ AP_DECLARE_NONSTD(const char *) ap_set_receive_buffer_size(cmd_parms *cmd, + void *dummy, + const char *arg); + ++#ifdef HAVE_SYSTEMD ++APR_DECLARE_OPTIONAL_FN(int, ++ ap_find_systemd_socket, (process_rec *, apr_port_t)); ++ ++APR_DECLARE_OPTIONAL_FN(int, ++ ap_systemd_listen_fds, (int)); ++#endif ++ ++ + #define LISTEN_COMMANDS \ + AP_INIT_TAKE1("ListenBacklog", ap_set_listenbacklog, NULL, RSRC_CONF, \ + "Maximum length of the queue of pending connections, as used by listen(2)"), \ +diff --git a/modules/arch/unix/mod_systemd.c b/modules/arch/unix/mod_systemd.c +index eda1272..fc059fc 100644 +--- a/modules/arch/unix/mod_systemd.c ++++ b/modules/arch/unix/mod_systemd.c +@@ -35,6 +35,15 @@ + #include + #endif + ++APR_DECLARE_OPTIONAL_FN(int, ++ ap_find_systemd_socket, (process_rec *, apr_port_t)); ++ ++APR_DECLARE_OPTIONAL_FN(int, ++ ap_systemd_listen_fds, (int)); ++ ++APR_DECLARE_OPTIONAL_FN(int, ++ ap_systemd_journal_stream_fd, (const char *, int, int)); ++ + static char describe_listeners[30]; + + static int systemd_pre_config(apr_pool_t *pconf, apr_pool_t *plog, +@@ -145,8 +154,47 @@ static int systemd_monitor(apr_pool_t *p, server_rec *s) + return DECLINED; + } + ++static int ap_find_systemd_socket(process_rec * process, apr_port_t port) { ++ int fdcount, fd; ++ int sdc = sd_listen_fds(0); ++ ++ if (sdc < 0) { ++ ap_log_perror(APLOG_MARK, APLOG_CRIT, sdc, process->pool, APLOGNO(02486) ++ "find_systemd_socket: Error parsing enviroment, sd_listen_fds returned %d", ++ sdc); ++ return -1; ++ } ++ ++ if (sdc == 0) { ++ ap_log_perror(APLOG_MARK, APLOG_CRIT, sdc, process->pool, APLOGNO(02487) ++ "find_systemd_socket: At least one socket must be set."); ++ return -1; ++ } ++ ++ fdcount = atoi(getenv("LISTEN_FDS")); ++ for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + fdcount; fd++) { ++ if (sd_is_socket_inet(fd, 0, 0, -1, port) > 0) { ++ return fd; ++ } ++ } ++ ++ return -1; ++} ++ ++static int ap_systemd_listen_fds(int unset_environment){ ++ return sd_listen_fds(unset_environment); ++} ++ ++static int ap_systemd_journal_stream_fd(const char *identifier, int priority, int level_prefix){ ++ return sd_journal_stream_fd("httpd", priority, 0); ++} ++ + static void systemd_register_hooks(apr_pool_t *p) + { ++ APR_REGISTER_OPTIONAL_FN(ap_systemd_listen_fds); ++ APR_REGISTER_OPTIONAL_FN(ap_find_systemd_socket); ++ APR_REGISTER_OPTIONAL_FN(ap_systemd_journal_stream_fd); ++ + /* Enable ap_extended_status. */ + ap_hook_pre_config(systemd_pre_config, NULL, NULL, APR_HOOK_LAST); + /* Signal service is ready. */ +diff --git a/modules/loggers/config.m4 b/modules/loggers/config.m4 +index 0848d2e..8af2299 100644 +--- a/modules/loggers/config.m4 ++++ b/modules/loggers/config.m4 +@@ -5,7 +5,6 @@ dnl APACHE_MODULE(name, helptext[, objects[, structname[, default[, config]]]]) + APACHE_MODPATH_INIT(loggers) + + APACHE_MODULE(log_config, logging configuration. You won't be able to log requests to the server without this module., , , yes) +-APR_ADDTO(MOD_LOG_CONFIG_LDADD, [$SYSTEMD_LIBS]) + + APACHE_MODULE(log_debug, configurable debug logging, , , most) + APACHE_MODULE(log_forensic, forensic logging) +diff --git a/modules/loggers/mod_log_config.c b/modules/loggers/mod_log_config.c +index 0b11f60..c3f0a51 100644 +--- a/modules/loggers/mod_log_config.c ++++ b/modules/loggers/mod_log_config.c +@@ -172,10 +172,6 @@ + #include + #endif + +-#ifdef HAVE_SYSTEMD +-#include +-#endif +- + #define DEFAULT_LOG_FORMAT "%h %l %u %t \"%r\" %>s %b" + + module AP_MODULE_DECLARE_DATA log_config_module; +@@ -1640,8 +1636,15 @@ static apr_status_t wrap_journal_stream(apr_pool_t *p, apr_file_t **outfd, + { + #ifdef HAVE_SYSTEMD + int fd; ++ APR_OPTIONAL_FN_TYPE(ap_systemd_journal_stream_fd) *systemd_journal_stream_fd; ++ ++ systemd_journal_stream_fd = APR_RETRIEVE_OPTIONAL_FN(ap_systemd_journal_stream_fd); ++ if (systemd_journal_stream_fd == NULL) { ++ return APR_ENOTIMPL; ++ } + +- fd = sd_journal_stream_fd("httpd", priority, 0); ++ fd = systemd_journal_stream_fd("httpd", priority, 0); ++ + if (fd < 0) return fd; + + /* This is an AF_UNIX socket fd so is more pipe-like than +diff --git a/modules/loggers/mod_log_config.h b/modules/loggers/mod_log_config.h +index 877a593..bd52a98 100644 +--- a/modules/loggers/mod_log_config.h ++++ b/modules/loggers/mod_log_config.h +@@ -69,6 +69,10 @@ APR_DECLARE_OPTIONAL_FN(ap_log_writer_init*, ap_log_set_writer_init,(ap_log_writ + */ + APR_DECLARE_OPTIONAL_FN(ap_log_writer*, ap_log_set_writer, (ap_log_writer* func)); + ++#ifdef HAVE_SYSTEMD ++APR_DECLARE_OPTIONAL_FN(int, ap_systemd_journal_stream_fd, (const char *, int, int)); ++#endif ++ + #endif /* MOD_LOG_CONFIG */ + /** @} */ + +diff --git a/server/listen.c b/server/listen.c +index e2e028a..5d1c0e1 100644 +--- a/server/listen.c ++++ b/server/listen.c +@@ -34,10 +34,6 @@ + #include + #endif + +-#ifdef HAVE_SYSTEMD +-#include +-#endif +- + /* we know core's module_index is 0 */ + #undef APLOG_MODULE_INDEX + #define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX +@@ -325,34 +321,6 @@ static int find_listeners(ap_listen_rec **from, ap_listen_rec **to, + } + + #ifdef HAVE_SYSTEMD +- +-static int find_systemd_socket(process_rec * process, apr_port_t port) { +- int fdcount, fd; +- int sdc = sd_listen_fds(0); +- +- if (sdc < 0) { +- ap_log_perror(APLOG_MARK, APLOG_CRIT, sdc, process->pool, APLOGNO(02486) +- "find_systemd_socket: Error parsing enviroment, sd_listen_fds returned %d", +- sdc); +- return -1; +- } +- +- if (sdc == 0) { +- ap_log_perror(APLOG_MARK, APLOG_CRIT, sdc, process->pool, APLOGNO(02487) +- "find_systemd_socket: At least one socket must be set."); +- return -1; +- } +- +- fdcount = atoi(getenv("LISTEN_FDS")); +- for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + fdcount; fd++) { +- if (sd_is_socket_inet(fd, 0, 0, -1, port) > 0) { +- return fd; +- } +- } +- +- return -1; +-} +- + static apr_status_t alloc_systemd_listener(process_rec * process, + int fd, const char *proto, + ap_listen_rec **out_rec) +@@ -412,6 +380,14 @@ static const char *set_systemd_listener(process_rec *process, apr_port_t port, + { + ap_listen_rec *last, *new; + apr_status_t rv; ++ APR_OPTIONAL_FN_TYPE(ap_find_systemd_socket) *find_systemd_socket; ++ ++ find_systemd_socket = APR_RETRIEVE_OPTIONAL_FN(ap_find_systemd_socket); ++ ++ if (!find_systemd_socket) ++ return "Systemd socket activation is used, but mod_systemd is probably " ++ "not loaded"; ++ + int fd = find_systemd_socket(process, port); + if (fd < 0) { + return "Systemd socket activation is used, but this port is not " +@@ -438,7 +414,6 @@ static const char *set_systemd_listener(process_rec *process, apr_port_t port, + + return NULL; + } +- + #endif /* HAVE_SYSTEMD */ + + static const char *alloc_listener(process_rec *process, const char *addr, +@@ -707,6 +682,9 @@ AP_DECLARE(int) ap_setup_listeners(server_rec *s) + int num_listeners = 0; + const char* proto; + int found; ++#ifdef HAVE_SYSTEMD ++ APR_OPTIONAL_FN_TYPE(ap_systemd_listen_fds) *systemd_listen_fds; ++#endif + + for (ls = s; ls; ls = ls->next) { + proto = ap_get_server_protocol(ls); +@@ -746,7 +724,10 @@ AP_DECLARE(int) ap_setup_listeners(server_rec *s) + apr_pool_cleanup_null, s->process->pool); + } + else { +- sd_listen_fds(1); ++ systemd_listen_fds = APR_RETRIEVE_OPTIONAL_FN(ap_systemd_listen_fds); ++ if (systemd_listen_fds != NULL) { ++ systemd_listen_fds(1); ++ } + } + } + else +@@ -963,6 +944,9 @@ AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy, + apr_port_t port; + apr_status_t rv; + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); ++#ifdef HAVE_SYSTEMD ++ APR_OPTIONAL_FN_TYPE(ap_systemd_listen_fds) *systemd_listen_fds; ++#endif + + if (err != NULL) { + return err; +@@ -973,7 +957,12 @@ AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy, + } + #ifdef HAVE_SYSTEMD + if (use_systemd == -1) { +- use_systemd = sd_listen_fds(0) > 0; ++ systemd_listen_fds = APR_RETRIEVE_OPTIONAL_FN(ap_systemd_listen_fds); ++ if (systemd_listen_fds != NULL) { ++ use_systemd = systemd_listen_fds(0) > 0; ++ } else { ++ use_systemd = 0; ++ } + } + #endif + diff --git a/SOURCES/httpd-2.4.53.tar.bz2.asc b/SOURCES/httpd-2.4.53.tar.bz2.asc new file mode 100644 index 0000000..9ad167f --- /dev/null +++ b/SOURCES/httpd-2.4.53.tar.bz2.asc @@ -0,0 +1,17 @@ +-----BEGIN PGP SIGNATURE----- +Comment: GPGTools - https://gpgtools.org + +iQIzBAABCgAdFiEEJvUe+agvSstD8ZA+03fJ59GUTGYFAmIotxoACgkQ03fJ59GU +TGbaAQ//TeVio63uLRIhyhW4qoUlGCL4KfCyY3aj5Yh6JGea9lYdioZ4JdHJan2y +IYRuF7B2S/MgfWESsEkPq8Nh0+ym78ZObdTFsskUF9so3+3WN9szQwTP/9suNd4+ +fv1vOKKGdy2h4hakR+E182A8gJ9FO6FabiETLvPvYVma3+5Zd2duzyvAOAQUDvkj +JhFXYVQCrWfiJN7gARePAzZyxbfWd5QVQMuCiWSIQ2PG0SkfQa07CsEiDiN8r8fZ +NGpNmyfUNqz4aUkBssNr0rVfmLzG2vicrfWaOgyS0rAEqn7fYhgF3s9k5y2htgOu +mdv2TPYl39NBf3uQNtR5tTUCPaop2GvH1GMJnz18W2fpessscHsuWiqeVVNUDmvV +zrFWlH2ehYPIOt07moP80nWJzpP7F5BGSG3DqcXPSG1JM/TM8uC3dgbC7k26i3vh ++8ypE1unHjop4nGff4cSkGeC5W2PkXrYNJC8xyjwbT098Q+Z8kAcO8TLpdaSx6tf +fI/9IwX+2uOhGx+ZHok0BSX0EpGK+i51Kspih++AcNaf6T4urXKdrpEgNm4jdHw7 +maCHPDelUMyxffBM/Jl8/VZD+SHuhK2LzPBFGOJdNhbNKzdkfg5TaxhfIywvV1T6 +JzRtvx/HoglaqCNFsBqflWpctC5dS2DeKEbP9FaDbqfxLmxp/G8= +=7fpY +-----END PGP SIGNATURE----- diff --git a/SPECS/httpd.spec b/SPECS/httpd.spec index a2a5eef..1e0e486 100644 --- a/SPECS/httpd.spec +++ b/SPECS/httpd.spec @@ -12,7 +12,7 @@ Summary: Apache HTTP Server Name: httpd -Version: 2.4.51 +Version: 2.4.53 Release: 7%{?dist} URL: https://httpd.apache.org/ Source0: https://www.apache.org/dist/httpd/httpd-%{version}.tar.bz2 @@ -52,6 +52,7 @@ Source31: README.confmod Source32: httpd.service.xml Source33: htcacheclean.service.xml Source34: httpd.conf.xml +Source35: 00-brotli.conf Source40: htcacheclean.service Source41: htcacheclean.sysconf Source42: httpd-init.service @@ -66,7 +67,7 @@ Source48: apache-poweredby.png Patch2: httpd-2.4.43-apxs.patch Patch3: httpd-2.4.43-deplibs.patch # Needed for socket activation and mod_systemd patch -Patch19: httpd-2.4.43-detect-systemd.patch +Patch19: httpd-2.4.53-detect-systemd.patch # Features/functional changes Patch21: httpd-2.4.48-r1842929+.patch Patch22: httpd-2.4.43-mod_systemd.patch @@ -74,7 +75,7 @@ Patch23: httpd-2.4.48-export.patch Patch24: httpd-2.4.43-corelimit.patch Patch25: httpd-2.4.43-selinux.patch Patch26: httpd-2.4.43-gettid.patch -Patch27: httpd-2.4.43-icons.patch +Patch27: httpd-2.4.53-icons.patch Patch30: httpd-2.4.43-cachehardmax.patch Patch34: httpd-2.4.43-socket-activation.patch Patch38: httpd-2.4.43-sslciphdefault.patch @@ -92,29 +93,43 @@ Patch48: httpd-2.4.46-freebind.patch Patch49: httpd-2.4.48-ssl-proxy-chains.patch # https://bugzilla.redhat.com/show_bug.cgi?id=2004143 Patch50: httpd-2.4.48-r1825120.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=2079939 +# backported regression fix +Patch51: httpd-2.4.53-r1901199.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=2065677 +Patch52: httpd-2.4.53-separate-systemd-fns.patch # Bug fixes # https://bugzilla.redhat.com/show_bug.cgi?id=1397243 Patch60: httpd-2.4.43-enable-sslv3.patch Patch61: httpd-2.4.46-htcacheclean-dont-break.patch -# https://bugzilla.redhat.com/show_bug.cgi?id=1986822 -# https://bugzilla.redhat.com/show_bug.cgi?id=1976080 -Patch62: httpd-2.4.51-openssl3.patch # https://bugzilla.redhat.com/show_bug.cgi?id=1932442 Patch64: httpd-2.4.48-full-release.patch # https://bugzilla.redhat.com/show_bug.cgi?id=1950011 Patch65: httpd-2.4.51-r1877397.patch # https://bugzilla.redhat.com/show_bug.cgi?id=1938740 Patch66: httpd-2.4.51-r1892413+.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=2073459 +Patch67: httpd-2.4.51-r1811831.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=2098056 +Patch68: httpd-2.4.53-r1878890.patch # Security fixes -# https://bugzilla.redhat.com/show_bug.cgi?id=2034674 -Patch200: httpd-2.4.51-CVE-2021-44790.patch -# https://bugzilla.redhat.com/show_bug.cgi?id=2034672 -Patch201: httpd-2.4.51-CVE-2021-44224.patch -# https://bugzilla.redhat.com/show_bug.cgi?id=2065250 -Patch202: httpd-2.4.51-CVE-2022-22720.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=2094997 +Patch200: httpd-2.4.53-CVE-2022-26377.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=2095006 +Patch201: httpd-2.4.53-CVE-2022-28615.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=2095020 +Patch202: httpd-2.4.53-CVE-2022-31813.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=2095002 +Patch203: httpd-2.4.53-CVE-2022-28614.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=2095012 +Patch204: httpd-2.4.53-CVE-2022-29404.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=2095015 +Patch205: httpd-2.4.53-CVE-2022-30522.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=2095018 +Patch206: httpd-2.4.53-CVE-2022-30556.patch License: ASL 2.0 BuildRequires: gcc, autoconf, pkgconfig, findutils, xmlto @@ -122,29 +137,38 @@ BuildRequires: perl-interpreter, perl-generators, systemd-devel BuildRequires: zlib-devel, libselinux-devel, lua-devel, brotli-devel BuildRequires: apr-devel >= 1.5.0, apr-util-devel >= 1.5.0, pcre-devel >= 5.0 BuildRequires: gnupg2 -Requires: /etc/mime.types, system-logos-httpd +Requires: system-logos-httpd Provides: webserver -Provides: mod_dav = %{version}-%{release}, httpd-suexec = %{version}-%{release} -Provides: httpd-mmn = %{mmn}, httpd-mmn = %{mmnisa} -Requires: httpd-tools = %{version}-%{release} -Requires: httpd-filesystem = %{version}-%{release} +Requires: httpd-core = 0:%{version}-%{release} Recommends: mod_http2, mod_lua -Requires(pre): httpd-filesystem Requires(preun): systemd-units Requires(postun): systemd-units Requires(post): systemd-units -Conflicts: apr < 1.5.0-1 -Provides: mod_proxy_uwsgi = %{version}-%{release} -Obsoletes: mod_proxy_uwsgi < 2.0.17.1-2 %description The Apache HTTP Server is a powerful, efficient, and extensible web server. +%package core +Summary: httpd minimal core +Provides: mod_dav = %{version}-%{release}, httpd-suexec = %{version}-%{release} +Provides: httpd-mmn = %{mmn}, httpd-mmn = %{mmnisa} +Provides: mod_proxy_uwsgi = %{version}-%{release} +Requires: /etc/mime.types +Requires: httpd-tools = %{version}-%{release} +Requires: httpd-filesystem = %{version}-%{release} +Requires(pre): httpd-filesystem +Conflicts: apr < 1.5.0-1 +Conflicts: httpd < 2.4.53-3 +Obsoletes: mod_proxy_uwsgi < 2.0.17.1-2 + +%description core +The httpd-core package contains essential httpd binaries. + %package devel Summary: Development interfaces for the Apache HTTP Server Requires: apr-devel, apr-util-devel, pkgconfig -Requires: httpd = %{version}-%{release} +Requires: httpd-core = %{version}-%{release} %description devel The httpd-devel package contains the APXS binary and other files @@ -157,7 +181,7 @@ to install this package. %package manual Summary: Documentation for the Apache HTTP Server -Requires: httpd = %{version}-%{release} +Requires: httpd-core = 0:%{version}-%{release} BuildArch: noarch %description manual @@ -187,7 +211,7 @@ Summary: SSL/TLS module for the Apache HTTP Server Epoch: 1 BuildRequires: openssl-devel Requires(pre): httpd-filesystem -Requires: httpd = 0:%{version}-%{release}, httpd-mmn = %{mmnisa} +Requires: httpd-core = 0:%{version}-%{release}, httpd-mmn = %{mmnisa} Requires: sscg >= 2.2.0, /usr/bin/hostname # Require an OpenSSL which supports PROFILE=SYSTEM Conflicts: openssl-libs < 1:1.0.1h-4 @@ -199,7 +223,7 @@ Security (TLS) protocols. %package -n mod_proxy_html Summary: HTML and XML content filters for the Apache HTTP Server -Requires: httpd = 0:%{version}-%{release}, httpd-mmn = %{mmnisa} +Requires: httpd-core = 0:%{version}-%{release}, httpd-mmn = %{mmnisa} BuildRequires: libxml2-devel BuildRequires: make Epoch: 1 @@ -211,7 +235,7 @@ transform and modify HTML and XML content. %package -n mod_ldap Summary: LDAP authentication modules for the Apache HTTP Server -Requires: httpd = 0:%{version}-%{release}, httpd-mmn = %{mmnisa} +Requires: httpd-core = 0:%{version}-%{release}, httpd-mmn = %{mmnisa} Requires: apr-util-ldap %description -n mod_ldap @@ -220,7 +244,7 @@ authentication to the Apache HTTP Server. %package -n mod_session Summary: Session interface for the Apache HTTP Server -Requires: httpd = 0:%{version}-%{release}, httpd-mmn = %{mmnisa} +Requires: httpd-core = 0:%{version}-%{release}, httpd-mmn = %{mmnisa} %description -n mod_session The mod_session module and associated backends provide an abstract @@ -228,7 +252,7 @@ interface for storing and accessing per-user session data. %package -n mod_lua Summary: Lua scripting support for the Apache HTTP Server -Requires: httpd = 0:%{version}-%{release}, httpd-mmn = %{mmnisa} +Requires: httpd-core = 0:%{version}-%{release}, httpd-mmn = %{mmnisa} %description -n mod_lua The mod_lua module allows the server to be extended with scripts @@ -262,17 +286,24 @@ written in the Lua programming language. %patch48 -p1 -b .freebind %patch49 -p1 -b .ssl-proxy-chains %patch50 -p1 -b .r1825120 +%patch51 -p1 -b .r1901199 +%patch52 -p1 -b .separatesystemd %patch60 -p1 -b .enable-sslv3 %patch61 -p1 -b .htcacheclean-dont-break -%patch62 -p1 -b .r1876934 %patch64 -p1 -b .full-release %patch65 -p1 -b .r1877397 %patch66 -p1 -b .r1892413+ +%patch67 -p1 -b .r1811831 +%patch68 -p1 -b .r1878890 -%patch200 -p1 -b .CVE-2021-44790 -%patch201 -p1 -b .CVE-2021-44224 -%patch202 -p1 -b .CVE-2022-22720 +%patch200 -p1 -b .CVE-2022-26377 +%patch201 -p1 -b .CVE-2022-28615 +%patch202 -p1 -b .CVE-2022-31813 +%patch203 -p1 -b .CVE-2022-28614 +%patch204 -p1 -b .CVE-2022-29404 +%patch205 -p1 -b .CVE-2022-30522 +%patch206 -p1 -b .CVE-2022-30556 # Patch in the vendor string sed -i '/^#define PLATFORM/s/Unix/%{vstring}/' os/unix/os.h @@ -366,7 +397,7 @@ export LYNX_PATH=/usr/bin/links --with-suexec-uidmin=1000 --with-suexec-gidmin=1000 \ --with-brotli \ --enable-pie \ - --with-pcre \ + --with-pcre=/usr/bin/pcre-config \ --enable-mods-shared=all \ --enable-ssl --with-ssl --disable-distcache \ --enable-proxy --enable-proxy-fdpass \ @@ -405,7 +436,8 @@ install -m 644 $RPM_SOURCE_DIR/README.confmod \ $RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf.modules.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 00-systemd.conf 01-session.conf 00-optional.conf; do + 01-ldap.conf 00-systemd.conf 01-session.conf 00-optional.conf \ + 00-brotli.conf; do install -m 644 -p $RPM_SOURCE_DIR/$f \ $RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf.modules.d/$f done @@ -678,6 +710,22 @@ set -x exit $rv %files +%{_mandir}/man8/* +%{_mandir}/man5/* +%exclude %{_mandir}/man8/httpd-init.* + +%config(noreplace) %{_sysconfdir}/httpd/conf.modules.d/00-brotli.conf +%config(noreplace) %{_sysconfdir}/httpd/conf.modules.d/00-systemd.conf + +%{_libdir}/httpd/modules/mod_brotli.so +%{_libdir}/httpd/modules/mod_systemd.so + +%{_unitdir}/httpd.service +%{_unitdir}/httpd@.service +%{_unitdir}/htcacheclean.service +%{_unitdir}/*.socket + +%files core %doc ABOUT_APACHE README CHANGES LICENSE VERSIONING NOTICE %doc docs/conf/extra/*.conf @@ -699,7 +747,10 @@ exit $rv %dir %{_sysconfdir}/httpd/conf.modules.d %{_sysconfdir}/httpd/conf.modules.d/README + %config(noreplace) %{_sysconfdir}/httpd/conf.modules.d/*.conf +%exclude %{_sysconfdir}/httpd/conf.modules.d/00-brotli.conf +%exclude %{_sysconfdir}/httpd/conf.modules.d/00-systemd.conf %exclude %{_sysconfdir}/httpd/conf.modules.d/00-ssl.conf %exclude %{_sysconfdir}/httpd/conf.modules.d/00-proxyhtml.conf %exclude %{_sysconfdir}/httpd/conf.modules.d/00-lua.conf @@ -721,6 +772,8 @@ exit $rv %dir %{_libdir}/httpd %dir %{_libdir}/httpd/modules %{_libdir}/httpd/modules/mod*.so +%exclude %{_libdir}/httpd/modules/mod_brotli.so +%exclude %{_libdir}/httpd/modules/mod_systemd.so %exclude %{_libdir}/httpd/modules/mod_auth_form.so %exclude %{_libdir}/httpd/modules/mod_ssl.so %exclude %{_libdir}/httpd/modules/mod_*ldap.so @@ -747,15 +800,6 @@ exit $rv %attr(0700,apache,apache) %dir %{_localstatedir}/cache/httpd %attr(0700,apache,apache) %dir %{_localstatedir}/cache/httpd/proxy -%{_mandir}/man8/* -%{_mandir}/man5/* -%exclude %{_mandir}/man8/httpd-init.* - -%{_unitdir}/httpd.service -%{_unitdir}/httpd@.service -%{_unitdir}/htcacheclean.service -%{_unitdir}/*.socket - %files filesystem %dir %{_sysconfdir}/httpd %dir %{_sysconfdir}/httpd/conf.d @@ -819,12 +863,47 @@ exit $rv %{_rpmconfigdir}/macros.d/macros.httpd %changelog +* Wed Jul 20 2022 Luboš Uhliarik - 2.4.53-7 +- Resolves: #2094997 - CVE-2022-26377 httpd: mod_proxy_ajp: Possible request + smuggling +- Resolves: #2097032 - CVE-2022-28615 httpd: out-of-bounds read in + ap_strcmp_match() +- Resolves: #2098248 - CVE-2022-31813 httpd: mod_proxy: X-Forwarded-For dropped + by hop-by-hop mechanism +- Resolves: #2097016 - CVE-2022-28614 httpd: out-of-bounds read via ap_rwrite() +- Resolves: #2097452 - CVE-2022-29404 httpd: mod_lua: DoS in r:parsebody +- Resolves: #2097459 - CVE-2022-30522 httpd: mod_sed: DoS vulnerability +- Resolves: #2097481 - CVE-2022-30556 httpd: mod_lua: Information disclosure + with websockets + +* Mon Jun 27 2022 Luboš Uhliarik - 2.4.53-6 +- Related: #2065677 - httpd minimisation for ubi-micro + +* Fri Jun 24 2022 Luboš Uhliarik - 2.4.53-5 +- Resolves: #2098056 - mod_ldap: High CPU usage at apr_ldap_rebind_remove() + +* Thu Jun 16 2022 Luboš Uhliarik - 2.4.53-4 +- Resolves: #2095838 - mod_mime_magic: invalid type 0 in mconvert() + +* Wed Jun 01 2022 Luboš Uhliarik - 2.4.53-3 +- Resolves: #2065677 - httpd minimisation for ubi-micro +- minimize httpd dependencies (new httpd-core package) +- mod_systemd and mod_brotli are now packaged in the main httpd package + +* Tue May 31 2022 Luboš Uhliarik - 2.4.53-1 +- new version 2.4.53 +- Resolves: #2079939 - httpd rebase to 2.4.53 +- Resolves: #2075406 - httpd.conf uses icon bomb.gif for all files/dirs ending + with core + +* Mon Apr 11 2022 Luboš Uhliarik - 2.4.51-8 +- Resolves: #2073459 - Cannot override LD_LIBARY_PATH in Apache HTTPD using + SetEnv or PassEnv + * Mon Mar 21 2022 Luboš Uhliarik - 2.4.51-7 -- Resolves: #2065250 - CVE-2022-22720 httpd: HTTP request smuggling +- Resolves: #2065251 - CVE-2022-22720 httpd: HTTP request smuggling vulnerability in Apache HTTP Server 2.4.52 and earlier - -* Wed Mar 16 2022 Luboš Uhliarik - 2.4.51-6 -- Resolves: #2035031 - CVE-2021-44224 httpd: possible NULL dereference or SSRF +- Resolves: #2066311 - CVE-2021-44224 httpd: possible NULL dereference or SSRF in forward proxy configurations * Mon Jan 10 2022 Luboš Uhliarik - 2.4.51-5