]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MAJOR: mux_h2: Don't consume more payload than received for skipped frames
authorChristopher Faulet <cfaulet@haproxy.com>
Thu, 26 Sep 2019 14:38:28 +0000 (16:38 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Thu, 26 Sep 2019 14:51:02 +0000 (16:51 +0200)
When a frame is received for a unknown or already closed stream, it must be
skipped. This also happens when a stream error is reported. But we must be sure
to only skip received data. In the loop in h2_process_demux(), when such frames
are handled, all the frame lenght is systematically skipped. If the frame
payload is partially received, it leaves the demux buffer in an undefined
state. Because of this bug, all sort of errors may be observed, like crash or
intermittent freeze.

This patch must be backported to 2.0, 1.9 and 1.8.

src/mux_h2.c

index b59c7fa63fa9a50661097213a91034729798780a..41c41deb01d71afb7f8dde03fa33a7bbd6efda4a 100644 (file)
@@ -3103,10 +3103,15 @@ static void h2_process_demux(struct h2c *h2c)
                }
 
                if (h2c->st0 != H2_CS_FRAME_H) {
-                       b_del(&h2c->dbuf, h2c->dfl);
-                       h2c->dsi = -1;
-                       TRACE_STATE("switching to FRAME_H", H2_EV_RX_FRAME|H2_EV_RX_FHDR, h2c->conn);
-                       h2c->st0 = H2_CS_FRAME_H;
+                       TRACE_DEVEL("stream error, skip frame payload", H2_EV_RX_FRAME, h2c->conn, h2s);
+                       ret = MIN(b_data(&h2c->dbuf), h2c->dfl);
+                       b_del(&h2c->dbuf, ret);
+                       h2c->dfl -= ret;
+                       if (!h2c->dfl) {
+                               TRACE_STATE("switching to FRAME_H", H2_EV_RX_FRAME|H2_EV_RX_FHDR, h2c->conn);
+                               h2c->st0 = H2_CS_FRAME_H;
+                               h2c->dsi = -1;
+                       }
                }
        }