]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: muxes: Don't dereference mux context if null in release functions
authorChristopher Faulet <cfaulet@haproxy.com>
Mon, 15 Apr 2019 07:33:32 +0000 (09:33 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Mon, 15 Apr 2019 07:47:10 +0000 (09:47 +0200)
When a mux context is released, we must be sure it exists before dereferencing
it. The bug was introduced in the commit 39a96ee16 ("MEDIUM: muxes: Be prepared
to don't own connection during the release").

No need to backport this patch, expect if the commit 39a96ee16 is backported
too.

src/mux_h1.c
src/mux_h2.c
src/mux_pt.c

index 5ea5f3c0327a171ceae0db76e65cc59ee4350167..3a031e04f33f116ec940ffe8906390f2b922baaa 100644 (file)
@@ -445,14 +445,14 @@ static int h1_init(struct connection *conn, struct proxy *proxy, struct session
  */
 static void h1_release(struct h1c *h1c)
 {
-       struct connection *conn = h1c->conn;
-
-       /* The connection was attached to another mux */
-       if (conn && conn->ctx != h1c)
-               conn = NULL;
+       struct connection *conn = NULL;
 
        if (h1c) {
-               if (h1c->flags & H1C_F_UPG_H2C) {
+               /* The connection must be aattached to this mux to be released */
+               if (h1c->conn && h1c->conn->ctx == h1c)
+                       conn = h1c->conn;
+
+               if (conn && h1c->flags & H1C_F_UPG_H2C) {
                        h1c->flags &= ~H1C_F_UPG_H2C;
                        if (conn_upgrade_mux_fe(conn, NULL, &h1c->ibuf, ist("h2"), PROTO_MODE_HTX) != -1) {
                                /* connection successfully upgraded to H2, this
@@ -462,6 +462,7 @@ static void h1_release(struct h1c *h1c)
                        sess_log(conn->owner); /* Log if the upgrade failed */
                }
 
+
                if (!LIST_ISEMPTY(&h1c->buf_wait.list)) {
                        HA_SPIN_LOCK(BUF_WQ_LOCK, &buffer_wq_lock);
                        LIST_DEL(&h1c->buf_wait.list);
index 48876ee20db70119303f7cf6aa5c59ecdd5e94b0..894c4bdbbf30cc7dd679b8b48e613430ac035fd3 100644 (file)
@@ -619,14 +619,13 @@ static inline struct h2s *h2c_st_by_id(struct h2c *h2c, int id)
  */
 static void h2_release(struct h2c *h2c)
 {
-       struct connection *conn = h2c->conn;
-
-       /* The connection was attached to another mux (unexpected but safer to
-        * check) */
-       if (conn && conn->ctx != h2c)
-               conn = NULL;
+       struct connection *conn = NULL;;
 
        if (h2c) {
+               /* The connection must be aattached to this mux to be released */
+               if (h2c->conn && h2c->conn->ctx == h2c)
+                       conn = h2c->conn;
+
                hpack_dht_free(h2c->ddht);
 
                HA_SPIN_LOCK(BUF_WQ_LOCK, &buffer_wq_lock);
index 82ba124b11a3fffd71a490325ba7f7e745f6a527..278a8f55da1d0b6ab23b7e6a8c84f06732eb125d 100644 (file)
@@ -26,13 +26,10 @@ DECLARE_STATIC_POOL(pool_head_pt_ctx, "mux_pt", sizeof(struct mux_pt_ctx));
 
 static void mux_pt_destroy(struct mux_pt_ctx *ctx)
 {
-       struct connection *conn = ctx->conn;
+       /* The connection must be aattached to this mux to be released */
+       if (ctx && ctx->conn && ctx->conn->ctx == ctx) {
+               struct connection *conn = ctx->conn;
 
-       /* The connection was attached to another mux */
-       if (conn && conn->ctx != ctx)
-               conn = NULL;
-
-       if (conn) {
                conn_stop_tracking(conn);
                conn_full_close(conn);
                tasklet_free(ctx->wait_event.task);