summaryrefslogtreecommitdiffstats
path: root/debian/patches/CVE-2019-10097.patch
blob: 0be05f5f2344db811351e0ddcff4684b70d69758 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
Description: Fix for CVE-2019-10097
Author: jorton
Origin: upstream, https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1864613
Bug: https://security-tracker.debian.org/tracker/CVE-2019-10097
Forwarded: not-needed
Reviewed-By: Xavier Guimard <yadd@debian.org>
Last-Update: 2019-08-17

--- a/modules/metadata/mod_remoteip.c
+++ b/modules/metadata/mod_remoteip.c
@@ -987,15 +987,13 @@
                     return HDR_ERROR;
 #endif
                 default:
-                    /* unsupported protocol, keep local connection address */
-                    return HDR_DONE;
+                    /* unsupported protocol */
+                    ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(10183)
+                                  "RemoteIPProxyProtocol: unsupported protocol %.2hx",
+                                  (unsigned short)hdr->v2.fam);
+                    return HDR_ERROR;
             }
             break;  /* we got a sockaddr now */
-
-        case 0x00: /* LOCAL command */
-            /* keep local connection address for LOCAL */
-            return HDR_DONE;
-
         default:
             /* not a supported command */
             ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(03507)
@@ -1087,11 +1085,24 @@
     /* try to read a header's worth of data */
     while (!ctx->done) {
         if (APR_BRIGADE_EMPTY(ctx->bb)) {
-            ret = ap_get_brigade(f->next, ctx->bb, ctx->mode, block,
-                                 ctx->need - ctx->rcvd);
+            apr_off_t got, want = ctx->need - ctx->rcvd;
+
+            ret = ap_get_brigade(f->next, ctx->bb, ctx->mode, block, want);
             if (ret != APR_SUCCESS) {
+                ap_log_cerror(APLOG_MARK, APLOG_ERR, ret, f->c, APLOGNO(10184)
+                              "failed reading input");
                 return ret;
             }
+
+            ret = apr_brigade_length(ctx->bb, 1, &got);
+            if (ret || got > want) {
+                ap_log_cerror(APLOG_MARK, APLOG_ERR, ret, f->c, APLOGNO(10185)
+                              "RemoteIPProxyProtocol header too long, "
+                              "got %" APR_OFF_T_FMT " expected %" APR_OFF_T_FMT,
+                              got, want);
+                f->c->aborted = 1;
+                return APR_ECONNABORTED;
+            }
         }
         if (APR_BRIGADE_EMPTY(ctx->bb)) {
             return block == APR_NONBLOCK_READ ? APR_SUCCESS : APR_EOF;
@@ -1139,6 +1150,13 @@
                 if (ctx->rcvd >= MIN_V2_HDR_LEN) {
                     ctx->need = MIN_V2_HDR_LEN +
                         remoteip_get_v2_len((proxy_header *) ctx->header);
+                    if (ctx->need > sizeof(proxy_v2)) {
+                        ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, f->c, APLOGNO(10186)
+                                      "RemoteIPProxyProtocol protocol header length too long");
+                        f->c->aborted = 1;
+                        apr_brigade_destroy(ctx->bb);
+                        return APR_ECONNABORTED;
+                    }
                 }
                 if (ctx->rcvd >= ctx->need) {
                     psts = remoteip_process_v2_header(f->c, conn_conf,