diff --git a/.gitignore b/.gitignore index cfbe234..6e3f15e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1 @@ -SOURCES/apache-poweredby.png SOURCES/httpd-2.4.37.tar.bz2 diff --git a/.httpd.metadata b/.httpd.metadata index 06980e0..e540f7e 100644 --- a/.httpd.metadata +++ b/.httpd.metadata @@ -1,2 +1 @@ -3a7449d6cff00e5ccb3ed8571f34c0528555d38f SOURCES/apache-poweredby.png 4a38471de821288b0300148016f2b03dfee8adf2 SOURCES/httpd-2.4.37.tar.bz2 diff --git a/SOURCES/httpd-2.4.37-CVE-2021-26690.patch b/SOURCES/httpd-2.4.37-CVE-2021-26690.patch deleted file mode 100644 index f606576..0000000 --- a/SOURCES/httpd-2.4.37-CVE-2021-26690.patch +++ /dev/null @@ -1,14 +0,0 @@ -diff --git a/modules/session/mod_session.c b/modules/session/mod_session.c -index 7ee477c..049255d 100644 ---- a/modules/session/mod_session.c -+++ b/modules/session/mod_session.c -@@ -404,8 +404,8 @@ static apr_status_t session_identity_decode(request_rec * r, session_rec * z) - char *plast = NULL; - const char *psep = "="; - char *key = apr_strtok(pair, psep, &plast); -- char *val = apr_strtok(NULL, psep, &plast); - if (key && *key) { -+ char *val = apr_strtok(NULL, sep, &plast); - if (!val || !*val) { - apr_table_unset(z->entries, key); - } diff --git a/SOURCES/httpd-2.4.37-CVE-2021-30641.patch b/SOURCES/httpd-2.4.37-CVE-2021-30641.patch deleted file mode 100644 index 5a34afb..0000000 --- a/SOURCES/httpd-2.4.37-CVE-2021-30641.patch +++ /dev/null @@ -1,44 +0,0 @@ -diff --git a/server/request.c b/server/request.c -index d5c558a..18625af 100644 ---- a/server/request.c -+++ b/server/request.c -@@ -1419,7 +1419,20 @@ AP_DECLARE(int) ap_location_walk(request_rec *r) - - cache = prep_walk_cache(AP_NOTE_LOCATION_WALK, r); - cached = (cache->cached != NULL); -- entry_uri = r->uri; -+ -+ /* -+ * When merge_slashes is set to AP_CORE_CONFIG_OFF the slashes in r->uri -+ * have not been merged. But for Location walks we always go with merged -+ * slashes no matter what merge_slashes is set to. -+ */ -+ if (sconf->merge_slashes != AP_CORE_CONFIG_OFF) { -+ entry_uri = r->uri; -+ } -+ else { -+ char *uri = apr_pstrdup(r->pool, r->uri); -+ ap_no2slash(uri); -+ entry_uri = uri; -+ } - - /* If we have an cache->cached location that matches r->uri, - * and the vhost's list of locations hasn't changed, we can skip -@@ -1486,7 +1499,7 @@ AP_DECLARE(int) ap_location_walk(request_rec *r) - pmatch = apr_palloc(rxpool, nmatch*sizeof(ap_regmatch_t)); - } - -- if (ap_regexec(entry_core->r, entry_uri, nmatch, pmatch, 0)) { -+ if (ap_regexec(entry_core->r, r->uri, nmatch, pmatch, 0)) { - continue; - } - -@@ -1496,7 +1509,7 @@ AP_DECLARE(int) ap_location_walk(request_rec *r) - apr_table_setn(r->subprocess_env, - ((const char **)entry_core->refs->elts)[i], - apr_pstrndup(r->pool, -- entry_uri + pmatch[i].rm_so, -+ r->uri + pmatch[i].rm_so, - pmatch[i].rm_eo - pmatch[i].rm_so)); - } - } diff --git a/SOURCES/httpd-2.4.37-proxy-ws-idle-timeout.patch b/SOURCES/httpd-2.4.37-proxy-ws-idle-timeout.patch index ef4408c..25864bf 100644 --- a/SOURCES/httpd-2.4.37-proxy-ws-idle-timeout.patch +++ b/SOURCES/httpd-2.4.37-proxy-ws-idle-timeout.patch @@ -20,7 +20,7 @@ index 21ffbe2..16e1628 100644
  • Comments
  • +
    top
    -+

    ProxyWebsocketIdleTimeout Directive

    ++

    ProxyWebsocketIdleTimeout +Description:Sets the maximum amount of time to wait for data on the websockets tunnel +Syntax:ProxyWebsocketIdleTimeout num[ms] diff --git a/SOURCES/httpd-2.4.37-r1845768+.patch b/SOURCES/httpd-2.4.37-r1845768+.patch deleted file mode 100644 index a51934f..0000000 --- a/SOURCES/httpd-2.4.37-r1845768+.patch +++ /dev/null @@ -1,48 +0,0 @@ -diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c -index 70d151e..e4f5fc8 100644 ---- a/modules/ssl/ssl_engine_init.c -+++ b/modules/ssl/ssl_engine_init.c -@@ -1095,7 +1095,9 @@ static apr_status_t ssl_init_ctx_crl(server_rec *s, - /* - * Read a file that optionally contains the server certificate in PEM - * format, possibly followed by a sequence of CA certificates that -- * should be sent to the peer in the SSL Certificate message. -+ * should be sent to the peer in the SSL Certificate message. Returns -+ * 0 on success, otherwise the OpenSSL error stack contents should be -+ * reported. - */ - static int use_certificate_chain( - SSL_CTX *ctx, char *file, int skipfirst, pem_password_cb *cb) -@@ -1128,8 +1130,10 @@ static int use_certificate_chain( - ctx->extra_certs = NULL; - } - #endif -+ - /* create new extra chain by loading the certs */ - n = 0; -+ ERR_clear_error(); - while ((x509 = PEM_read_bio_X509(bio, NULL, cb, NULL)) != NULL) { - if (!SSL_CTX_add_extra_chain_cert(ctx, x509)) { - X509_free(x509); -@@ -1190,6 +1194,7 @@ static apr_status_t ssl_init_ctx_cert_chain(server_rec *s, - if (n < 0) { - ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01903) - "Failed to configure CA certificate chain!"); -+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); - return ssl_die(s); - } - -diff --git a/modules/ssl/ssl_util_ocsp.c b/modules/ssl/ssl_util_ocsp.c -index b11a6e9..b66e151 100644 ---- a/modules/ssl/ssl_util_ocsp.c -+++ b/modules/ssl/ssl_util_ocsp.c -@@ -363,7 +363,9 @@ static STACK_OF(X509) *modssl_read_ocsp_certificates(const char *file) - BIO_free(bio); - return NULL; - } -+ - /* create new extra chain by loading the certs */ -+ ERR_clear_error(); - while ((x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL)) != NULL) { - if (!other_certs) { - other_certs = sk_X509_new_null(); diff --git a/SOURCES/httpd-2.4.37-r1873907.patch b/SOURCES/httpd-2.4.37-r1873907.patch deleted file mode 100644 index 4ec0cfa..0000000 --- a/SOURCES/httpd-2.4.37-r1873907.patch +++ /dev/null @@ -1,265 +0,0 @@ -diff --git a/docs/manual/mod/mod_ssl.html.en b/docs/manual/mod/mod_ssl.html.en -index b543150..ab72d4f 100644 ---- a/docs/manual/mod/mod_ssl.html.en -+++ b/docs/manual/mod/mod_ssl.html.en -@@ -1524,6 +1524,32 @@ The available (case-insensitive) protocols are:

    -

    Example

    SSLProtocol TLSv1
    -
    - -+
    -+

    SSLProtocol for name-based virtual hosts

    -+

    -+Before OpenSSL 1.1.1, even though the Server Name Indication (SNI) allowed to -+determine the targeted virtual host early in the TLS handshake, it was not -+possible to switch the TLS protocol version of the connection at this point, -+and thus the SSLProtocol negotiated was always based off -+the one of the base virtual host (first virtual host declared on the -+listening IP:port of the connection). -+

    -+

    -+Beginning with Apache HTTP server version 2.4.42, when built/linked against -+OpenSSL 1.1.1 or later, and when the SNI is provided by the client in the TLS -+handshake, the SSLProtocol of each (name-based) virtual -+host can and will be honored. -+

    -+

    -+For compatibility with previous versions, if no -+SSLProtocol is configured in a name-based virtual host, -+the one from the base virtual host still applies, unless -+SSLProtocol is configured globally in which case the -+global value applies (this latter exception is more sensible than compatible, -+though). -+

    -+
    -+ -

    -
    top
    -

    SSLProxyCACertificateFile Directive

    -diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c -index 0c4bf1f..ca5f702 100644 ---- a/modules/ssl/ssl_engine_config.c -+++ b/modules/ssl/ssl_engine_config.c -@@ -269,6 +269,7 @@ static void modssl_ctx_cfg_merge(apr_pool_t *p, - mrg->protocol_set = 1; - } - else { -+ mrg->protocol_set = base->protocol_set; - mrg->protocol = base->protocol; - } - -diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c -index 31062bc..70d151e 100644 ---- a/modules/ssl/ssl_engine_init.c -+++ b/modules/ssl/ssl_engine_init.c -@@ -520,7 +520,9 @@ static apr_status_t ssl_init_ctx_tls_extensions(server_rec *s, - "Configuring TLS extension handling"); - - /* -- * Server name indication (SNI) -+ * The Server Name Indication (SNI) provided by the ClientHello can be -+ * used to select the right (name-based-)vhost and its SSL configuration -+ * before the handshake takes place. - */ - if (!SSL_CTX_set_tlsext_servername_callback(mctx->ssl_ctx, - ssl_callback_ServerNameIndication) || -@@ -532,6 +534,16 @@ static apr_status_t ssl_init_ctx_tls_extensions(server_rec *s, - return ssl_die(s); - } - -+#if OPENSSL_VERSION_NUMBER >= 0x10101000L && !defined(LIBRESSL_VERSION_NUMBER) -+ /* -+ * The ClientHello callback also allows to retrieve the SNI, but since it -+ * runs at the earliest possible connection stage we can even set the TLS -+ * protocol version(s) according to the selected (name-based-)vhost, which -+ * is not possible at the SNI callback stage (due to OpenSSL internals). -+ */ -+ SSL_CTX_set_client_hello_cb(mctx->ssl_ctx, ssl_callback_ClientHello, NULL); -+#endif -+ - #ifdef HAVE_OCSP_STAPLING - /* - * OCSP Stapling support, status_request extension -@@ -708,7 +720,7 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s, - #else /* #if OPENSSL_VERSION_NUMBER < 0x10100000L */ - /* We first determine the maximum protocol version we should provide */ - #if SSL_HAVE_PROTOCOL_TLSV1_3 -- if (SSL_HAVE_PROTOCOL_TLSV1_3 && (protocol & SSL_PROTOCOL_TLSV1_3)) { -+ if (protocol & SSL_PROTOCOL_TLSV1_3) { - prot = TLS1_3_VERSION; - } else - #endif -diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c -index 8b44674..7313a55 100644 ---- a/modules/ssl/ssl_engine_kernel.c -+++ b/modules/ssl/ssl_engine_kernel.c -@@ -2357,28 +2357,31 @@ static apr_status_t set_challenge_creds(conn_rec *c, const char *servername, - * This function sets the virtual host from an extended - * client hello with a server name indication extension ("SNI", cf. RFC 6066). - */ --static apr_status_t init_vhost(conn_rec *c, SSL *ssl) -+static apr_status_t init_vhost(conn_rec *c, SSL *ssl, const char *servername) - { -- const char *servername; - X509 *cert; - EVP_PKEY *key; - - if (c) { - SSLConnRec *sslcon = myConnConfig(c); -- -- if (sslcon->server != c->base_server) { -- /* already found the vhost */ -- return APR_SUCCESS; -+ -+ if (sslcon->vhost_found) { -+ /* already found the vhost? */ -+ return sslcon->vhost_found > 0 ? APR_SUCCESS : APR_NOTFOUND; - } -+ sslcon->vhost_found = -1; - -- servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name); -+ if (!servername) { -+ servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name); -+ } - if (servername) { - if (ap_vhost_iterate_given_conn(c, ssl_find_vhost, - (void *)servername)) { - ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(02043) - "SSL virtual host for servername %s found", - servername); -- -+ -+ sslcon->vhost_found = +1; - return APR_SUCCESS; - } - else if (ssl_is_challenge(c, servername, &cert, &key)) { -@@ -2428,11 +2431,72 @@ static apr_status_t init_vhost(conn_rec *c, SSL *ssl) - int ssl_callback_ServerNameIndication(SSL *ssl, int *al, modssl_ctx_t *mctx) - { - conn_rec *c = (conn_rec *)SSL_get_app_data(ssl); -- apr_status_t status = init_vhost(c, ssl); -+ apr_status_t status = init_vhost(c, ssl, NULL); - - return (status == APR_SUCCESS)? SSL_TLSEXT_ERR_OK : SSL_TLSEXT_ERR_NOACK; - } - -+#if OPENSSL_VERSION_NUMBER >= 0x10101000L && !defined(LIBRESSL_VERSION_NUMBER) -+/* -+ * This callback function is called when the ClientHello is received. -+ */ -+int ssl_callback_ClientHello(SSL *ssl, int *al, void *arg) -+{ -+ char *servername = NULL; -+ conn_rec *c = (conn_rec *)SSL_get_app_data(ssl); -+ const unsigned char *pos; -+ size_t len, remaining; -+ (void)arg; -+ -+ /* We can't use SSL_get_servername() at this earliest OpenSSL connection -+ * stage, and there is no SSL_client_hello_get0_servername() provided as -+ * of OpenSSL 1.1.1. So the code below, that extracts the SNI from the -+ * ClientHello's TLS extensions, is taken from some test code in OpenSSL, -+ * i.e. client_hello_select_server_ctx() in "test/handshake_helper.c". -+ */ -+ -+ /* -+ * The server_name extension was given too much extensibility when it -+ * was written, so parsing the normal case is a bit complex. -+ */ -+ if (!SSL_client_hello_get0_ext(ssl, TLSEXT_TYPE_server_name, &pos, -+ &remaining) -+ || remaining <= 2) -+ goto give_up; -+ -+ /* Extract the length of the supplied list of names. */ -+ len = (*(pos++) << 8); -+ len += *(pos++); -+ if (len + 2 != remaining) -+ goto give_up; -+ remaining = len; -+ -+ /* -+ * The list in practice only has a single element, so we only consider -+ * the first one. -+ */ -+ if (remaining <= 3 || *pos++ != TLSEXT_NAMETYPE_host_name) -+ goto give_up; -+ remaining--; -+ -+ /* Now we can finally pull out the byte array with the actual hostname. */ -+ len = (*(pos++) << 8); -+ len += *(pos++); -+ if (len + 2 != remaining) -+ goto give_up; -+ -+ /* Use the SNI to switch to the relevant vhost, should it differ from -+ * c->base_server. -+ */ -+ servername = apr_pstrmemdup(c->pool, (const char *)pos, len); -+ -+give_up: -+ init_vhost(c, ssl, servername); -+ return SSL_CLIENT_HELLO_SUCCESS; -+} -+#endif /* OPENSSL_VERSION_NUMBER < 0x10101000L */ -+ -+ - /* - * Find a (name-based) SSL virtual host where either the ServerName - * or one of the ServerAliases matches the supplied name (to be used -@@ -2452,12 +2516,25 @@ static int ssl_find_vhost(void *servername, conn_rec *c, server_rec *s) - if (found && (ssl = sslcon->ssl) && - (sc = mySrvConfig(s))) { - SSL_CTX *ctx = SSL_set_SSL_CTX(ssl, sc->server->ssl_ctx); -+ - /* - * SSL_set_SSL_CTX() only deals with the server cert, - * so we need to duplicate a few additional settings - * from the ctx by hand - */ - SSL_set_options(ssl, SSL_CTX_get_options(ctx)); -+#if OPENSSL_VERSION_NUMBER >= 0x10100000L \ -+ && (!defined(LIBRESSL_VERSION_NUMBER) \ -+ || LIBRESSL_VERSION_NUMBER >= 0x20800000L) -+ /* -+ * Don't switch the protocol if none is configured for this vhost, -+ * the default in this case is still the base server's SSLProtocol. -+ */ -+ if (myCtxConfig(sslcon, sc)->protocol_set) { -+ SSL_set_min_proto_version(ssl, SSL_CTX_get_min_proto_version(ctx)); -+ SSL_set_max_proto_version(ssl, SSL_CTX_get_max_proto_version(ctx)); -+ } -+#endif - if ((SSL_get_verify_mode(ssl) == SSL_VERIFY_NONE) || - (SSL_num_renegotiations(ssl) == 0)) { - /* -@@ -2654,7 +2731,7 @@ int ssl_callback_alpn_select(SSL *ssl, - * they callback the SNI. We need to make sure that we know which vhost - * we are dealing with so we respect the correct protocols. - */ -- init_vhost(c, ssl); -+ init_vhost(c, ssl, NULL); - - proposed = ap_select_protocol(c, NULL, sslconn->server, client_protos); - if (!proposed) { -diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h -index 8055200..f8a1db7 100644 ---- a/modules/ssl/ssl_private.h -+++ b/modules/ssl/ssl_private.h -@@ -563,6 +563,7 @@ typedef struct { - - const char *cipher_suite; /* cipher suite used in last reneg */ - int service_unavailable; /* thouugh we negotiate SSL, no requests will be served */ -+ int vhost_found; /* whether we found vhost from SNI already */ - } SSLConnRec; - - /* BIG FAT WARNING: SSLModConfigRec has unusual memory lifetime: it is -@@ -946,6 +947,9 @@ void ssl_callback_Info(const SSL *, int, int); - #ifdef HAVE_TLSEXT - int ssl_callback_ServerNameIndication(SSL *, int *, modssl_ctx_t *); - #endif -+#if OPENSSL_VERSION_NUMBER >= 0x10101000L && !defined(LIBRESSL_VERSION_NUMBER) -+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); diff --git a/SOURCES/httpd-2.4.37-reply-two-tls-rec.patch b/SOURCES/httpd-2.4.37-reply-two-tls-rec.patch deleted file mode 100644 index a4a3835..0000000 --- a/SOURCES/httpd-2.4.37-reply-two-tls-rec.patch +++ /dev/null @@ -1,188 +0,0 @@ -diff --git a/modules/ssl/ssl_engine_io.c b/modules/ssl/ssl_engine_io.c -index 018b667..4e3875a 100644 ---- a/modules/ssl/ssl_engine_io.c -+++ b/modules/ssl/ssl_engine_io.c -@@ -1598,18 +1598,32 @@ static apr_status_t ssl_io_filter_input(ap_filter_t *f, - } - - --/* ssl_io_filter_output() produces one SSL/TLS message per bucket -+/* ssl_io_filter_output() produces one SSL/TLS record per bucket - * passed down the output filter stack. This results in a high -- * overhead (network packets) for any output comprising many small -- * buckets. SSI page applied through the HTTP chunk filter, for -- * example, may produce many brigades containing small buckets - -- * [chunk-size CRLF] [chunk-data] [CRLF]. -+ * overhead (more network packets & TLS processing) for any output -+ * comprising many small buckets. SSI output passed through the HTTP -+ * chunk filter, for example, may produce many brigades containing -+ * small buckets - [chunk-size CRLF] [chunk-data] [CRLF]. - * -- * The coalescing filter merges many small buckets into larger buckets -- * where possible, allowing the SSL I/O output filter to handle them -- * more efficiently. */ -+ * Sending HTTP response headers as a separate TLS record to the -+ * response body also reveals information to a network observer (the -+ * size of headers) which can be significant. -+ * -+ * The coalescing filter merges data buckets with the aim of producing -+ * fewer, larger TLS records - without copying/buffering all content -+ * and introducing unnecessary overhead. -+ * -+ * ### This buffering could be probably be done more comprehensively -+ * ### in ssl_io_filter_output itself. -+ * -+ * ### Another possible performance optimisation in particular for the -+ * ### [HEAP] [FILE] HTTP response case is using a brigade rather than -+ * ### a char array to buffer; using apr_brigade_write() to append -+ * ### will use already-allocated memory from the HEAP, reducing # of -+ * ### copies. -+ */ - --#define COALESCE_BYTES (2048) -+#define COALESCE_BYTES (AP_IOBUFSIZE) - - struct coalesce_ctx { - char buffer[COALESCE_BYTES]; -@@ -1622,11 +1636,12 @@ static apr_status_t ssl_io_filter_coalesce(ap_filter_t *f, - apr_bucket *e, *upto; - apr_size_t bytes = 0; - struct coalesce_ctx *ctx = f->ctx; -+ apr_size_t buffered = ctx ? ctx->bytes : 0; /* space used on entry */ - unsigned count = 0; - - /* The brigade consists of zero-or-more small data buckets which -- * can be coalesced (the prefix), followed by the remainder of the -- * brigade. -+ * can be coalesced (referred to as the "prefix"), followed by the -+ * remainder of the brigade. - * - * Find the last bucket - if any - of that prefix. count gives - * the number of buckets in the prefix. The "prefix" must contain -@@ -1641,24 +1656,97 @@ static apr_status_t ssl_io_filter_coalesce(ap_filter_t *f, - e != APR_BRIGADE_SENTINEL(bb) - && !APR_BUCKET_IS_METADATA(e) - && e->length != (apr_size_t)-1 -- && e->length < COALESCE_BYTES -- && (bytes + e->length) < COALESCE_BYTES -- && (ctx == NULL -- || bytes + ctx->bytes + e->length < COALESCE_BYTES); -+ && e->length <= COALESCE_BYTES -+ && (buffered + bytes + e->length) <= COALESCE_BYTES; - e = APR_BUCKET_NEXT(e)) { - if (e->length) count++; /* don't count zero-length buckets */ - bytes += e->length; - } -+ -+ /* If there is room remaining and the next bucket is a data -+ * bucket, try to include it in the prefix to coalesce. For a -+ * typical [HEAP] [FILE] HTTP response brigade, this handles -+ * merging the headers and the start of the body into a single TLS -+ * record. */ -+ if (bytes + buffered > 0 -+ && bytes + buffered < COALESCE_BYTES -+ && e != APR_BRIGADE_SENTINEL(bb) -+ && !APR_BUCKET_IS_METADATA(e)) { -+ apr_status_t rv = APR_SUCCESS; -+ -+ /* For an indeterminate length bucket (PIPE/CGI/...), try a -+ * non-blocking read to have it morph into a HEAP. If the -+ * read fails with EAGAIN, it is harmless to try a split -+ * anyway, split is ENOTIMPL for most PIPE-like buckets. */ -+ if (e->length == (apr_size_t)-1) { -+ const char *discard; -+ apr_size_t ignore; -+ -+ rv = apr_bucket_read(e, &discard, &ignore, APR_NONBLOCK_READ); -+ if (rv != APR_SUCCESS && !APR_STATUS_IS_EAGAIN(rv)) { -+ ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, f->c, APLOGNO(10232) -+ "coalesce failed to read from %s bucket", -+ e->type->name); -+ return AP_FILTER_ERROR; -+ } -+ } -+ -+ if (rv == APR_SUCCESS) { -+ /* If the read above made the bucket morph, it may now fit -+ * entirely within the buffer. Otherwise, split it so it does -+ * fit. */ -+ if (e->length > COALESCE_BYTES -+ || e->length + buffered + bytes > COALESCE_BYTES) { -+ rv = apr_bucket_split(e, COALESCE_BYTES - (buffered + bytes)); -+ } -+ -+ if (rv == APR_SUCCESS && e->length == 0) { -+ /* As above, don't count in the prefix if the bucket is -+ * now zero-length. */ -+ } -+ else if (rv == APR_SUCCESS) { -+ ap_log_cerror(APLOG_MARK, APLOG_TRACE4, 0, f->c, -+ "coalesce: adding %" APR_SIZE_T_FMT " bytes " -+ "from split %s bucket, total %" APR_SIZE_T_FMT, -+ e->length, e->type->name, bytes + buffered); -+ -+ count++; -+ bytes += e->length; -+ e = APR_BUCKET_NEXT(e); -+ } -+ else if (rv != APR_ENOTIMPL) { -+ ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, f->c, APLOGNO(10233) -+ "coalesce: failed to split data bucket"); -+ return AP_FILTER_ERROR; -+ } -+ } -+ } -+ -+ /* The prefix is zero or more buckets. upto now points to the -+ * bucket AFTER the end of the prefix, which may be the brigade -+ * sentinel. */ - upto = e; - -- /* Coalesce the prefix, if: -- * a) more than one bucket is found to coalesce, or -- * b) the brigade contains only a single data bucket, or -- * c) the data bucket is not last but we have buffered data already. -+ /* Coalesce the prefix, if any of the following are true: -+ * -+ * a) the prefix is more than one bucket -+ * OR -+ * b) the prefix is the entire brigade, which is a single bucket -+ * AND the prefix length is smaller than the buffer size, -+ * OR -+ * c) the prefix is a single bucket -+ * AND there is buffered data from a previous pass. -+ * -+ * The aim with (b) is to buffer a small bucket so it can be -+ * coalesced with future invocations of this filter. e.g. three -+ * calls each with a single 100 byte HEAP bucket should get -+ * coalesced together. But an invocation with a 8192 byte HEAP -+ * should pass through untouched. - */ - if (bytes > 0 - && (count > 1 -- || (upto == APR_BRIGADE_SENTINEL(bb)) -+ || (upto == APR_BRIGADE_SENTINEL(bb) -+ && bytes < COALESCE_BYTES) - || (ctx && ctx->bytes > 0))) { - /* If coalescing some bytes, ensure a context has been - * created. */ -@@ -1669,7 +1757,8 @@ static apr_status_t ssl_io_filter_coalesce(ap_filter_t *f, - - ap_log_cerror(APLOG_MARK, APLOG_TRACE4, 0, f->c, - "coalesce: have %" APR_SIZE_T_FMT " bytes, " -- "adding %" APR_SIZE_T_FMT " more", ctx->bytes, bytes); -+ "adding %" APR_SIZE_T_FMT " more (buckets=%u)", -+ ctx->bytes, bytes, count); - - /* Iterate through the prefix segment. For non-fatal errors - * in this loop it is safe to break out and fall back to the -@@ -1684,7 +1773,8 @@ static apr_status_t ssl_io_filter_coalesce(ap_filter_t *f, - if (APR_BUCKET_IS_METADATA(e) - || e->length == (apr_size_t)-1) { - ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, f->c, APLOGNO(02012) -- "unexpected bucket type during coalesce"); -+ "unexpected %s bucket during coalesce", -+ e->type->name); - break; /* non-fatal error; break out */ - } - diff --git a/SOURCES/httpd-2.4.37-usertrack-samesite.patch b/SOURCES/httpd-2.4.37-usertrack-samesite.patch deleted file mode 100644 index 592616e..0000000 --- a/SOURCES/httpd-2.4.37-usertrack-samesite.patch +++ /dev/null @@ -1,178 +0,0 @@ -diff --git a/docs/manual/mod/mod_usertrack.html.en b/docs/manual/mod/mod_usertrack.html.en -index b212747..d2da9b9 100644 ---- a/docs/manual/mod/mod_usertrack.html.en -+++ b/docs/manual/mod/mod_usertrack.html.en -@@ -47,7 +47,10 @@ - -@@ -127,6 +130,22 @@ CustomLog "logs/clickstream.log" usertrack -
    CookieExpires "3 weeks"
    - - -+
    -+
    top
    -+

    CookieHTTPOnly Directive

    -+ -+ -+ -+ -+ -+ -+ -+ -+
    Description:Adds the 'HTTPOnly' attribute to the cookie
    Syntax:CookieHTTPOnly on|off
    Default:CookieHTTPOnly off
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Extension
    Module:mod_usertrack
    -+

    When set to 'ON', the 'HTTPOnly' cookie attribute is added to this -+ modules tracking cookie. This attribute instructs browsers to block javascript -+ from reading the value of the cookie.

    -+ -
    -
    top
    -

    CookieName Directive

    -@@ -150,6 +169,45 @@ CustomLog "logs/clickstream.log" usertrack -
    CookieName clicktrack
    - - -+
    -+
    top
    -+

    CookieSameSite Directive

    -+ -+ -+ -+ -+ -+ -+ -+ -+
    Description:Adds the 'SameSite' attribute to the cookie
    Syntax:CookieSameSite None|Lax|Strict
    Default:unset
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Extension
    Module:mod_usertrack
    -+

    When set to 'None', 'Lax', or 'Strict', the 'SameSite' cookie attribute -+ is added to this modules tracking cookie with the corresponding value. -+ This attribute instructs browser on how to treat the cookie when it is -+ requested in a cross-site context.

    -+ -+
    -+

    A value of 'None' sets 'SameSite=None', which is the most liberal setting. To -+ omit this attribute, omit the directive entirely.

    -+
    -+ -+ -+
    -+
    top
    -+

    CookieSecure Directive

    -+ -+ -+ -+ -+ -+ -+ -+ -+
    Description:Adds the 'Secure' attribute to the cookie
    Syntax:CookieSecure on|off
    Default:CookieSecure off
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Extension
    Module:mod_usertrack
    -+

    When set to 'ON', the 'Secure' cookie attribute is added to this -+ modules tracking cookie. This attribute instructs browsers to only -+ transmit the cookie over HTTPS.

    -+ -
    -
    top
    -

    CookieStyle Directive

    -diff --git a/modules/metadata/mod_usertrack.c b/modules/metadata/mod_usertrack.c -index 73a9f45..65759c2 100644 ---- a/modules/metadata/mod_usertrack.c -+++ b/modules/metadata/mod_usertrack.c -@@ -86,6 +86,9 @@ typedef struct { - const char *cookie_domain; - char *regexp_string; /* used to compile regexp; save for debugging */ - ap_regex_t *regexp; /* used to find usertrack cookie in cookie header */ -+ int is_secure; -+ int is_httponly; -+ const char *samesite; - } cookie_dir_rec; - - /* Make Cookie: Now we have to generate something that is going to be -@@ -143,6 +146,21 @@ static void make_cookie(request_rec *r) - : ""), - NULL); - } -+ if (dcfg->samesite != NULL) { -+ new_cookie = apr_pstrcat(r->pool, new_cookie, "; ", -+ dcfg->samesite, -+ NULL); -+ } -+ if (dcfg->is_secure) { -+ new_cookie = apr_pstrcat(r->pool, new_cookie, "; Secure", -+ NULL); -+ } -+ if (dcfg->is_httponly) { -+ new_cookie = apr_pstrcat(r->pool, new_cookie, "; HttpOnly", -+ NULL); -+ } -+ -+ - - apr_table_addn(r->err_headers_out, - (dcfg->style == CT_COOKIE2 ? "Set-Cookie2" : "Set-Cookie"), -@@ -269,6 +287,7 @@ static void *make_cookie_dir(apr_pool_t *p, char *d) - dcfg->cookie_domain = NULL; - dcfg->style = CT_UNSET; - dcfg->enabled = 0; -+ /* calloc'ed to disabled: samesite, is_secure, is_httponly */ - - /* In case the user does not use the CookieName directive, - * we need to compile the regexp for the default cookie name. */ -@@ -429,6 +448,31 @@ static const char *set_cookie_style(cmd_parms *cmd, void *mconfig, - return NULL; - } - -+/* -+ * SameSite enabled disabled -+ */ -+ -+static const char *set_samesite_value(cmd_parms *cmd, void *mconfig, -+ const char *name) -+{ -+ cookie_dir_rec *dcfg; -+ -+ dcfg = (cookie_dir_rec *) mconfig; -+ -+ if (strcasecmp(name, "strict") == 0) { -+ dcfg->samesite = "SameSite=Strict"; -+ } else if (strcasecmp(name, "lax") == 0) { -+ dcfg->samesite = "SameSite=Lax"; -+ } else if (strcasecmp(name, "none") == 0) { -+ dcfg->samesite = "SameSite=None"; -+ } else { -+ return "CookieSameSite accepts 'Strict', 'Lax', or 'None'"; -+ } -+ -+ -+ return NULL; -+} -+ - static const command_rec cookie_log_cmds[] = { - AP_INIT_TAKE1("CookieExpires", set_cookie_exp, NULL, OR_FILEINFO, - "an expiry date code"), -@@ -440,6 +484,17 @@ static const command_rec cookie_log_cmds[] = { - "whether or not to enable cookies"), - AP_INIT_TAKE1("CookieName", set_cookie_name, NULL, OR_FILEINFO, - "name of the tracking cookie"), -+ AP_INIT_FLAG("CookieTracking", set_cookie_enable, NULL, OR_FILEINFO, -+ "whether or not to enable cookies"), -+ AP_INIT_TAKE1("CookieSameSite", set_samesite_value, NULL, OR_FILEINFO, -+ "SameSite setting"), -+ AP_INIT_FLAG("CookieSecure", ap_set_flag_slot, -+ (void *)APR_OFFSETOF(cookie_dir_rec, is_secure), OR_FILEINFO, -+ "is cookie secure"), -+ AP_INIT_FLAG("CookieHttpOnly", ap_set_flag_slot, -+ (void *)APR_OFFSETOF(cookie_dir_rec, is_httponly),OR_FILEINFO, -+ "is cookie http only"), -+ - {NULL} - }; - diff --git a/SOURCES/welcome.conf b/SOURCES/welcome.conf index 37b7394..5158e8b 100644 --- a/SOURCES/welcome.conf +++ b/SOURCES/welcome.conf @@ -16,4 +16,4 @@ Alias /.noindex.html /usr/share/httpd/noindex/index.html -Alias /poweredby.png /usr/share/httpd/icons/apache_pb3.png \ No newline at end of file +Alias /poweredby.png /usr/share/httpd/icons/apache_pb2.png \ No newline at end of file diff --git a/SPECS/httpd.spec b/SPECS/httpd.spec index 1964e91..f0189f7 100644 --- a/SPECS/httpd.spec +++ b/SPECS/httpd.spec @@ -13,7 +13,7 @@ Summary: Apache HTTP Server Name: httpd Version: 2.4.37 -Release: 43%{?dist} +Release: 39%{?dist}.2 URL: https://httpd.apache.org/ Source0: https://www.apache.org/dist/httpd/httpd-%{version}.tar.bz2 Source2: httpd.logrotate @@ -54,7 +54,6 @@ Source42: httpd-init.service Source43: httpd-ssl-gencerts Source44: httpd@.service Source45: config.layout -Source46: apache-poweredby.png # build/scripts patches # http://bugzilla.redhat.com/show_bug.cgi?id=1231924 @@ -102,8 +101,6 @@ Patch38: httpd-2.4.37-pr37355.patch Patch39: httpd-2.4.37-proxy-ws-idle-timeout.patch # https://bugzilla.redhat.com/show_bug.cgi?id=1883648 Patch40: httpd-2.4.37-ssl-proxy-chains.patch -# https://bugzilla.redhat.com/show_bug.cgi?id=1935742 -Patch41: httpd-2.4.37-usertrack-samesite.patch # Bug fixes # https://bugzilla.redhat.com/show_bug.cgi?id=1397243 @@ -153,12 +150,6 @@ Patch83: httpd-2.4.37-r1878890.patch Patch84: httpd-2.4.37-r1878280.patch # https://bugzilla.redhat.com/show_bug.cgi?id=1891594 Patch85: httpd-2.4.37-htcacheclean-dont-break.patch -# https://bugzilla.redhat.com/show_bug.cgi?id=1937334 -Patch86: httpd-2.4.37-r1873907.patch -# https://bugzilla.redhat.com/show_bug.cgi?id=1680111 -Patch87: httpd-2.4.37-reply-two-tls-rec.patch -# https://bugzilla.redhat.com/show_bug.cgi?id=1905613 -Patch88: httpd-2.4.37-r1845768+.patch # Security fixes Patch200: httpd-2.4.37-r1851471.patch @@ -188,14 +179,10 @@ Patch209: httpd-2.4.37-CVE-2020-1934.patch Patch210: httpd-2.4.37-CVE-2018-17199.patch # https://bugzilla.redhat.com/show_bug.cgi?id=1866563 Patch211: httpd-2.4.37-CVE-2020-11984.patch -# https://bugzilla.redhat.com/show_bug.cgi?id=1972500 -Patch212: httpd-2.4.37-CVE-2021-30641.patch -# https://bugzilla.redhat.com/show_bug.cgi?id=1968307 -Patch213: httpd-2.4.37-CVE-2021-26690.patch # https://bugzilla.redhat.com/show_bug.cgi?id=2005117 -Patch214: httpd-2.4.37-CVE-2021-40438.patch +Patch212: httpd-2.4.37-CVE-2021-40438.patch # https://bugzilla.redhat.com/show_bug.cgi?id=1966732 -Patch215: httpd-2.4.37-CVE-2021-26691.patch +Patch213: httpd-2.4.37-CVE-2021-26691.patch License: ASL 2.0 Group: System Environment/Daemons @@ -205,8 +192,7 @@ 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: systemd-devel # web server testpage added to redhat-logos in 82.0 (rhbz1896319) -# new logo requires new footer copyring which was added in rhbz1934800 -Requires: /etc/mime.types, system-logos(httpd-logo-ng) +Requires: /etc/mime.types, system-logos-httpd >= 82.0 Obsoletes: httpd-suexec Provides: webserver Provides: mod_dav = %{version}-%{release}, httpd-suexec = %{version}-%{release} @@ -346,7 +332,6 @@ interface for storing and accessing per-user session data. %patch38 -p1 -b .pr37355 %patch39 -p1 -b .proxy-ws-idle-timeout %patch40 -p1 -b .ssl-proxy-chains -%patch41 -p1 -b .usertrack-samesite %patch61 -p1 -b .r1738878 %patch62 -p1 -b .r1633085 @@ -371,9 +356,6 @@ interface for storing and accessing per-user session data. %patch83 -p1 -b .r1878890 %patch84 -p1 -b .r1878280 %patch85 -p1 -b .htcacheclean-dont-break -%patch86 -p1 -b .r1873907 -%patch87 -p1 -b .reply-two-tls-rec -%patch88 -p1 -b .r1845768+ %patch200 -p1 -b .r1851471 %patch201 -p1 -b .CVE-2019-0211 @@ -387,10 +369,8 @@ interface for storing and accessing per-user session data. %patch209 -p1 -b .CVE-2020-1934 %patch210 -p1 -b .CVE-2018-17199 %patch211 -p1 -b .CVE-2020-11984 -%patch212 -p1 -b .CVE-2021-30641 -%patch213 -p1 -b .CVE-2021-26690 -%patch214 -p1 -b .CVE-2021-40438 -%patch215 -p1 -b .CVE-2021-26691 +%patch212 -p1 -b .CVE-2021-40438 +%patch213 -p1 -b .CVE-2021-26691 # Patch in the vendor string sed -i '/^#define PLATFORM/s/Unix/%{vstring}/' os/unix/os.h @@ -417,9 +397,6 @@ if test "x${vmmn}" != "x%{mmn}"; then exit 1 fi -# A new logo which comes together with a new test page -cp %{SOURCE46} ./docs/icons/apache_pb3.png - # Provide default layout cp $RPM_SOURCE_DIR/config.layout . @@ -896,30 +873,16 @@ rm -rf $RPM_BUILD_ROOT %{_rpmconfigdir}/macros.d/macros.httpd %changelog -* Tue Oct 26 2021 Luboš Uhliarik - 2.4.37-43 -- Related: #2007235 - CVE-2021-40438 httpd:2.4/httpd: mod_proxy: SSRF via - a crafted request uri-path +* Fri Oct 29 2021 Luboš Uhliarik - 2.4.37-39.2 +- Resolves: #2017856 - proxy rewrite to unix socket fails with CVE-2021-40438 + fix -* Thu Sep 30 2021 Luboš Uhliarik - 2.4.37-42 -- Resolves: #2007235 - CVE-2021-40438 httpd:2.4/httpd: mod_proxy: SSRF via +* Thu Sep 30 2021 Luboš Uhliarik - 2.4.37-39.1 +- Resolves: #2007234 - CVE-2021-40438 httpd:2.4/httpd: mod_proxy: SSRF via a crafted request uri-path -- Resolves: #2014063 - CVE-2021-26691 httpd:2.4/httpd: Heap overflow in +- Resolves: #2007646 - CVE-2021-26691 httpd:2.4/httpd: Heap overflow in mod_session -* Fri Jul 09 2021 Luboš Uhliarik - 2.4.37-41 -- Resolves: #1680111 - httpd sends reply to HTTPS GET using two TLS records -- Resolves: #1905613 - mod_ssl does not like valid certificate chain -- Resolves: #1935742 - [RFE] backport samesite/httponly/secure flags for - usertrack -- Resolves: #1972500 - CVE-2021-30641 httpd:2.4/httpd: MergeSlashes regression -- Resolves: #1968307 - CVE-2021-26690 httpd:2.4/httpd: mod_session NULL pointer - dereference in parser -- Resolves: #1934741 - Apache trademark update - new logo - -* Fri May 14 2021 Lubos Uhliarik - 2.4.37-40 -- Resolves: #1952557 - mod_proxy_wstunnel.html is a malformed XML -- Resolves: #1937334 - SSLProtocol with based virtual hosts - * Tue Jan 26 2021 Artem Egorenkov - 2.4.37-39 - prevent htcacheclean from while break when first file processed