mod_ssl: fix request body buffering w/TLSv1.3 PHA (#1775146)

Resolves: rhbz#1775146
This commit is contained in:
Joe Orton 2019-11-21 16:54:17 +00:00
parent 9d23b8bc3a
commit 401f5d1ca7
2 changed files with 125 additions and 1 deletions

119
httpd-2.4.41-r1870095.patch Normal file
View File

@ -0,0 +1,119 @@
# ./pullrev.sh 1870095
http://svn.apache.org/viewvc?view=revision&revision=1870095
https://bugzilla.redhat.com/show_bug.cgi?id=1775146
--- httpd-2.4.41/modules/ssl/ssl_engine_kernel.c
+++ httpd-2.4.41/modules/ssl/ssl_engine_kernel.c
@@ -114,6 +114,45 @@
return result;
}
+/* If a renegotiation is required for the location, and the request
+ * includes a message body (and the client has not requested a "100
+ * Continue" response), then the client will be streaming the request
+ * body over the wire already. In that case, it is not possible to
+ * stop and perform a new SSL handshake immediately; once the SSL
+ * library moves to the "accept" state, it will reject the SSL packets
+ * which the client is sending for the request body.
+ *
+ * To allow authentication to complete in the hook, the solution used
+ * here is to fill a (bounded) buffer with the request body, and then
+ * to reinject that request body later.
+ *
+ * This function is called to fill the renegotiation buffer for the
+ * location as required, or fail. Returns zero on success or HTTP_
+ * error code on failure.
+ */
+static int fill_reneg_buffer(request_rec *r, SSLDirConfigRec *dc)
+{
+ int rv;
+ apr_size_t rsize;
+
+ /* ### this is HTTP/1.1 specific, special case for protocol? */
+ if (r->expecting_100 || !ap_request_has_body(r)) {
+ return 0;
+ }
+
+ rsize = dc->nRenegBufferSize == UNSET ? DEFAULT_RENEG_BUFFER_SIZE : dc->nRenegBufferSize;
+ if (rsize > 0) {
+ /* Fill the I/O buffer with the request body if possible. */
+ rv = ssl_io_buffer_fill(r, rsize);
+ }
+ else {
+ /* If the reneg buffer size is set to zero, just fail. */
+ rv = HTTP_REQUEST_ENTITY_TOO_LARGE;
+ }
+
+ return rv;
+}
+
#ifdef HAVE_TLSEXT
static int ap_array_same_str_set(apr_array_header_t *s1, apr_array_header_t *s2)
{
@@ -814,41 +853,14 @@
}
}
- /* If a renegotiation is now required for this location, and the
- * request includes a message body (and the client has not
- * requested a "100 Continue" response), then the client will be
- * streaming the request body over the wire already. In that
- * case, it is not possible to stop and perform a new SSL
- * handshake immediately; once the SSL library moves to the
- * "accept" state, it will reject the SSL packets which the client
- * is sending for the request body.
- *
- * To allow authentication to complete in this auth hook, the
- * solution used here is to fill a (bounded) buffer with the
- * request body, and then to reinject that request body later.
- */
- if (renegotiate && !renegotiate_quick
- && !r->expecting_100
- && ap_request_has_body(r)) {
- int rv;
- apr_size_t rsize;
-
- rsize = dc->nRenegBufferSize == UNSET ? DEFAULT_RENEG_BUFFER_SIZE :
- dc->nRenegBufferSize;
- if (rsize > 0) {
- /* Fill the I/O buffer with the request body if possible. */
- rv = ssl_io_buffer_fill(r, rsize);
- }
- else {
- /* If the reneg buffer size is set to zero, just fail. */
- rv = HTTP_REQUEST_ENTITY_TOO_LARGE;
- }
-
- if (rv) {
+ /* Fill reneg buffer if required. */
+ if (renegotiate && !renegotiate_quick) {
+ rc = fill_reneg_buffer(r, dc);
+ if (rc) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02257)
"could not buffer message body to allow "
"SSL renegotiation to proceed");
- return rv;
+ return rc;
}
}
@@ -1132,7 +1144,18 @@
}
}
+ /* Fill reneg buffer if required. */
if (change_vmode) {
+ rc = fill_reneg_buffer(r, dc);
+ if (rc) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO()
+ "could not buffer message body to allow "
+ "TLS Post-Handshake Authentication to proceed");
+ return rc;
+ }
+ }
+
+ if (change_vmode) {
char peekbuf[1];
if (r->connection->master) {

View File

@ -13,7 +13,7 @@
Summary: Apache HTTP Server
Name: httpd
Version: 2.4.41
Release: 8%{?dist}
Release: 9%{?dist}
URL: https://httpd.apache.org/
Source0: https://www.apache.org/dist/httpd/httpd-%{version}.tar.bz2
Source1: https://www.apache.org/dist/httpd/httpd-%{version}.tar.bz2.asc
@ -87,6 +87,7 @@ Patch42: httpd-2.4.41-r1828172+.patch
Patch58: httpd-2.4.34-r1738878.patch
Patch60: httpd-2.4.34-enable-sslv3.patch
Patch61: httpd-2.4.41-r1865749.patch
Patch62: httpd-2.4.41-r1870095.patch
# Security fixes
@ -227,6 +228,7 @@ interface for storing and accessing per-user session data.
%patch58 -p1 -b .r1738878
%patch60 -p1 -b .enable-sslv3
%patch61 -p1 -b .r1865749
%patch62 -p1 -b .r1870095
# Patch in the vendor string
sed -i '/^#define PLATFORM/s/Unix/%{vstring}/' os/unix/os.h
@ -747,6 +749,9 @@ exit $rv
%{_rpmconfigdir}/macros.d/macros.httpd
%changelog
* Thu Nov 21 2019 Joe Orton <jorton@redhat.com> - 2.4.41-9
- mod_ssl: fix request body buffering w/TLSv1.3 PHA (#1775146)
* Wed Nov 13 2019 Joe Orton <jorton@redhat.com> - 2.4.41-8
- apachectl: in graceful/graceful-stop, only signal main process (#1758798)