diff --git a/include/haproxy/conn_stream.h b/include/haproxy/conn_stream.h index 98921aae5..441146989 100644 --- a/include/haproxy/conn_stream.h +++ b/include/haproxy/conn_stream.h @@ -46,7 +46,7 @@ struct conn_stream *cs_new_from_strm(struct stream *strm, unsigned int flags); struct conn_stream *cs_new_from_check(struct check *check, unsigned int flags); void cs_free(struct conn_stream *cs); -void cs_attach_mux(struct conn_stream *cs, void *target, void *ctx); +int cs_attach_mux(struct conn_stream *cs, void *target, void *ctx); void cs_attach_applet(struct conn_stream *cs, void *target, void *ctx); int cs_attach_strm(struct conn_stream *cs, struct stream *strm); diff --git a/src/backend.c b/src/backend.c index ea27b8c4a..65ded4bd1 100644 --- a/src/backend.c +++ b/src/backend.c @@ -1611,7 +1611,10 @@ skip_reuse: return SF_ERR_INTERNAL; /* how did we get there ? */ } - cs_attach_mux(s->csb, NULL, srv_conn); + if (cs_attach_mux(s->csb, NULL, srv_conn) < 0) { + conn_free(srv_conn); + return SF_ERR_INTERNAL; /* how did we get there ? */ + } srv_conn->ctx = s->csb; #if defined(USE_OPENSSL) && defined(TLSEXT_TYPE_application_layer_protocol_negotiation) diff --git a/src/conn_stream.c b/src/conn_stream.c index 31979d881..b63291291 100644 --- a/src/conn_stream.c +++ b/src/conn_stream.c @@ -161,7 +161,7 @@ void cs_free(struct conn_stream *cs) /* Attaches a conn_stream to an mux endpoint and sets the endpoint ctx */ -void cs_attach_mux(struct conn_stream *cs, void *target, void *ctx) +int cs_attach_mux(struct conn_stream *cs, void *target, void *ctx) { struct connection *conn = ctx; @@ -177,6 +177,7 @@ void cs_attach_mux(struct conn_stream *cs, void *target, void *ctx) } else if (cs_check(cs)) cs->data_cb = &check_conn_cb; + return 0; } /* Attaches a conn_stream to an applet endpoint and sets the endpoint ctx */ diff --git a/src/mux_fcgi.c b/src/mux_fcgi.c index d34b1c5ec..5996e7e22 100644 --- a/src/mux_fcgi.c +++ b/src/mux_fcgi.c @@ -1134,7 +1134,8 @@ static struct fcgi_strm *fcgi_conn_stream_new(struct fcgi_conn *fconn, struct co TRACE_ERROR("fstream allocation failure", FCGI_EV_FSTRM_NEW|FCGI_EV_FSTRM_END|FCGI_EV_FSTRM_ERR, fconn->conn); goto out; } - cs_attach_mux(cs, fstrm, fconn->conn); + if (cs_attach_mux(cs, fstrm, fconn->conn) < 0) + goto out; fstrm->cs = cs; fstrm->endp = cs->endp; fstrm->sess = sess; @@ -1145,6 +1146,7 @@ static struct fcgi_strm *fcgi_conn_stream_new(struct fcgi_conn *fconn, struct co out: TRACE_DEVEL("leaving on error", FCGI_EV_FSTRM_NEW|FCGI_EV_FSTRM_END|FCGI_EV_FSTRM_ERR, fconn->conn); + fcgi_strm_destroy(fstrm); return NULL; } diff --git a/src/mux_h1.c b/src/mux_h1.c index bbdddf9a4..d7fd3da8f 100644 --- a/src/mux_h1.c +++ b/src/mux_h1.c @@ -814,7 +814,8 @@ static struct h1s *h1c_frt_stream_new(struct h1c *h1c, struct conn_stream *cs, s goto fail; if (cs) { - cs_attach_mux(cs, h1s, h1c->conn); + if (cs_attach_mux(cs, h1s, h1c->conn) < 0) + goto fail; h1s->cs = cs; h1s->endp = cs->endp; } @@ -853,7 +854,9 @@ static struct h1s *h1c_bck_stream_new(struct h1c *h1c, struct conn_stream *cs, s if (!h1s) goto fail; - cs_attach_mux(cs, h1s, h1c->conn); + if (cs_attach_mux(cs, h1s, h1c->conn) < 0) + goto fail; + h1s->flags |= H1S_F_RX_BLK; h1s->cs = cs; h1s->endp = cs->endp; @@ -872,6 +875,7 @@ static struct h1s *h1c_bck_stream_new(struct h1c *h1c, struct conn_stream *cs, s fail: TRACE_DEVEL("leaving on error", H1_EV_STRM_NEW|H1_EV_STRM_ERR, h1c->conn); + pool_free(pool_head_h1s, h1s); return NULL; } diff --git a/src/mux_h2.c b/src/mux_h2.c index b161278b5..d39de9409 100644 --- a/src/mux_h2.c +++ b/src/mux_h2.c @@ -1675,7 +1675,11 @@ static struct h2s *h2c_bck_stream_new(struct h2c *h2c, struct conn_stream *cs, s if (!h2s) goto out; - cs_attach_mux(cs, h2s, h2c->conn); + if (cs_attach_mux(cs, h2s, h2c->conn) < 0) { + h2s_destroy(h2s); + h2s = NULL; + goto out; + } h2s->cs = cs; h2s->endp = cs->endp; h2s->sess = sess; diff --git a/src/mux_pt.c b/src/mux_pt.c index 2b1c30d66..97b3b835d 100644 --- a/src/mux_pt.c +++ b/src/mux_pt.c @@ -315,7 +315,8 @@ static int mux_pt_init(struct connection *conn, struct proxy *prx, struct sessio TRACE_POINT(PT_EV_STRM_NEW, conn, cs); } else { - cs_attach_mux(cs, ctx, conn); + if (cs_attach_mux(cs, ctx, conn) < 0) + goto fail_free_ctx; ctx->endp = cs->endp; } conn->ctx = ctx; @@ -385,7 +386,8 @@ static int mux_pt_attach(struct connection *conn, struct conn_stream *cs, struct TRACE_ENTER(PT_EV_STRM_NEW, conn); if (ctx->wait_event.events) conn->xprt->unsubscribe(ctx->conn, conn->xprt_ctx, SUB_RETRY_RECV, &ctx->wait_event); - cs_attach_mux(cs, ctx, conn); + if (cs_attach_mux(cs, ctx, conn) < 0) + return -1; ctx->cs = cs; ctx->endp = cs->endp; ctx->endp->flags |= CS_EP_RCV_MORE; diff --git a/src/tcpcheck.c b/src/tcpcheck.c index 930735b70..0ac825e06 100644 --- a/src/tcpcheck.c +++ b/src/tcpcheck.c @@ -1101,7 +1101,13 @@ enum tcpcheck_eval_ret tcpcheck_eval_connect(struct check *check, struct tcpchec TRACE_ERROR("conn-stream allocation error", CHK_EV_TCPCHK_CONN|CHK_EV_TCPCHK_ERR, check); goto out; } - cs_attach_mux(check->cs, NULL, conn); + if (cs_attach_mux(check->cs, NULL, conn) < 0) { + TRACE_ERROR("mux attach error", CHK_EV_TCPCHK_CONN|CHK_EV_TCPCHK_ERR, check); + conn_free(conn); + conn = NULL; + status = SF_ERR_RESOURCE; + goto fail_check; + } conn->ctx = check->cs; tasklet_set_tid(check->wait_list.tasklet, tid); conn_set_owner(conn, check->sess, NULL);