]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: connection: panic when calling FD-specific functions on FD-less conns
authorWilly Tarreau <w@1wt.eu>
Mon, 11 Apr 2022 16:07:03 +0000 (18:07 +0200)
committerWilly Tarreau <w@1wt.eu>
Mon, 11 Apr 2022 17:31:47 +0000 (19:31 +0200)
Certain functions cannot be called on an FD-less conn because they are
normally called as part of the protocol-specific setup/teardown sequence.
Better place a few BUG_ON() to make sure none of them is called in other
situations. If any of them would trigger in ambiguous conditions, it would
always be possible to replace it with an error.

include/haproxy/connection.h
src/check.c
src/connection.c
src/raw_sock.c
src/sock.c
src/ssl_sock.c

index 5d9b5ca7485ac319e5ffc6be744e6e30c87f9ace..bc26f73b55223781e8288971311b8fd13a9f056b 100644 (file)
@@ -220,6 +220,7 @@ static inline void conn_sock_read0(struct connection *c)
                /* we don't risk keeping ports unusable if we found the
                 * zero from the other side.
                 */
+               BUG_ON(c->flags & CO_FL_FDLESS);
                HA_ATOMIC_AND(&fdtab[c->handle.fd].state, ~FD_LINGER_RISK);
        }
 }
@@ -236,6 +237,7 @@ static inline void conn_sock_shutw(struct connection *c, int clean)
                /* don't perform a clean shutdown if we're going to reset or
                 * if the shutr was already received.
                 */
+               BUG_ON(c->flags & CO_FL_FDLESS);
                if (!(c->flags & CO_FL_SOCK_RD_SH) && clean)
                        shutdown(c->handle.fd, SHUT_WR);
        }
index da2deab37ccedb9d2a8775042f6d6ad17fca2046..7e6430f052eb98a721395323209694607fab1850 100644 (file)
@@ -744,6 +744,8 @@ static int retrieve_errno_from_socket(struct connection *conn)
        if (!conn_ctrl_ready(conn))
                return 0;
 
+       BUG_ON(conn->flags & CO_FL_FDLESS);
+
        if (getsockopt(conn->handle.fd, SOL_SOCKET, SO_ERROR, &skerr, &lskerr) == 0)
                errno = skerr;
 
index af453a6b8657b269dc3f99d5e59150c4563a0e16..b666d18760a606fdc5af64187cce7c3eff6e4b87 100644 (file)
@@ -809,6 +809,8 @@ int conn_recv_proxy(struct connection *conn, int flag)
        if (!conn_ctrl_ready(conn))
                goto fail;
 
+       BUG_ON(conn->flags & CO_FL_FDLESS);
+
        if (!fd_recv_ready(conn->handle.fd))
                goto not_ready;
 
@@ -1188,6 +1190,8 @@ int conn_recv_netscaler_cip(struct connection *conn, int flag)
        if (!conn_ctrl_ready(conn))
                goto fail;
 
+       BUG_ON(conn->flags & CO_FL_FDLESS);
+
        if (!fd_recv_ready(conn->handle.fd))
                goto not_ready;
 
@@ -1454,6 +1458,8 @@ int conn_recv_socks4_proxy_response(struct connection *conn)
        if (!conn_ctrl_ready(conn))
                goto fail;
 
+       BUG_ON(conn->flags & CO_FL_FDLESS);
+
        if (!fd_recv_ready(conn->handle.fd))
                goto not_ready;
 
index 7ee5f9bc7f61d723be436719b7ccf43ce20bdd7f..553375bb51a4e4f1b775c867138390e03e33566c 100644 (file)
@@ -59,6 +59,8 @@ int raw_sock_to_pipe(struct connection *conn, void *xprt_ctx, struct pipe *pipe,
        if (!conn_ctrl_ready(conn))
                return 0;
 
+       BUG_ON(conn->flags & CO_FL_FDLESS);
+
        if (!fd_recv_ready(conn->handle.fd))
                return 0;
 
@@ -172,6 +174,8 @@ int raw_sock_from_pipe(struct connection *conn, void *xprt_ctx, struct pipe *pip
        if (!conn_ctrl_ready(conn))
                return 0;
 
+       BUG_ON(conn->flags & CO_FL_FDLESS);
+
        if (!fd_send_ready(conn->handle.fd))
                return 0;
 
@@ -231,6 +235,8 @@ static size_t raw_sock_to_buf(struct connection *conn, void *xprt_ctx, struct bu
        if (!conn_ctrl_ready(conn))
                return 0;
 
+       BUG_ON(conn->flags & CO_FL_FDLESS);
+
        if (!fd_recv_ready(conn->handle.fd))
                return 0;
 
@@ -350,6 +356,8 @@ static size_t raw_sock_from_buf(struct connection *conn, void *xprt_ctx, const s
        if (!conn_ctrl_ready(conn))
                return 0;
 
+       BUG_ON(conn->flags & CO_FL_FDLESS);
+
        if (!fd_send_ready(conn->handle.fd))
                return 0;
 
index ae825fc02e58b75120070700ac799268fc0ad317..5afa59f33c6be0dcde5fe709c5ee5ef2b2c70b81 100644 (file)
@@ -702,6 +702,7 @@ void sock_accept_iocb(int fd)
  */
 void sock_conn_ctrl_init(struct connection *conn)
 {
+       BUG_ON(conn->flags & CO_FL_FDLESS);
        fd_insert(conn->handle.fd, conn, sock_conn_iocb, tid_bit);
 }
 
@@ -711,6 +712,7 @@ void sock_conn_ctrl_init(struct connection *conn)
  */
 void sock_conn_ctrl_close(struct connection *conn)
 {
+       BUG_ON(conn->flags & CO_FL_FDLESS);
        fd_delete(conn->handle.fd);
        conn->handle.fd = DEAD_FD_MAGIC;
 }
@@ -736,6 +738,8 @@ int sock_conn_check(struct connection *conn)
        if (!(conn->flags & CO_FL_WAIT_L4_CONN))
                return 1; /* strange we were called while ready */
 
+       BUG_ON(conn->flags & CO_FL_FDLESS);
+
        if (!fd_send_ready(fd) && !(fdtab[fd].state & (FD_POLL_ERR|FD_POLL_HUP)))
                return 0;
 
@@ -901,6 +905,8 @@ int sock_drain(struct connection *conn)
        int fd = conn->handle.fd;
        int len;
 
+       BUG_ON(conn->flags & CO_FL_FDLESS);
+
        if (fdtab[fd].state & (FD_POLL_ERR|FD_POLL_HUP))
                goto shut;
 
@@ -953,6 +959,8 @@ int sock_check_events(struct connection *conn, int event_type)
 {
        int ret = 0;
 
+       BUG_ON(conn->flags & CO_FL_FDLESS);
+
        if (event_type & SUB_RETRY_RECV) {
                if (fd_recv_ready(conn->handle.fd))
                        ret |= SUB_RETRY_RECV;
@@ -975,6 +983,8 @@ int sock_check_events(struct connection *conn, int event_type)
  */
 void sock_ignore_events(struct connection *conn, int event_type)
 {
+       BUG_ON(conn->flags & CO_FL_FDLESS);
+
        if (event_type & SUB_RETRY_RECV)
                fd_stop_recv(conn->handle.fd);
 
index 748ab13241df7feb6e26bfb759341a648483badb..00c35d857cf19393b34f81e264b9f0c18956f1e6 100644 (file)
@@ -5849,6 +5849,8 @@ static int ssl_sock_handshake(struct connection *conn, unsigned int flag)
         * the xprt layers should provide some status indicating their knowledge
         * of shutdowns or error.
         */
+       BUG_ON(conn->flags & CO_FL_FDLESS);
+
        skerr = 0;
        lskerr = sizeof(skerr);
        if ((getsockopt(conn->handle.fd, SOL_SOCKET, SO_ERROR, &skerr, &lskerr) < 0) ||