]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MAJOR: quic: Big RX dgrams leak when fulfilling a buffer
authorFrédéric Lécaille <flecaille@haproxy.com>
Thu, 23 Jun 2022 16:00:37 +0000 (18:00 +0200)
committerWilly Tarreau <w@1wt.eu>
Thu, 23 Jun 2022 18:40:01 +0000 (20:40 +0200)
When entering quic_sock_fd_iocb() I/O handler which is responsible
of recvfrom() datagrams, the first thing which is done it to try
to reuse a dgram object containing metadata about the received
datagrams which has been consumed by the connection thread.
If this object could not be used for any reason, so when we
"goto out" of this function, we must release the memory allocated
for this objet, if not it will leak. Most of the time, this happened
when we fulfilled a buffer as reported in GH #1749 by Tristan. This is why we
added a pool_free() call just before the out label. We mark <new_dgram> as NULL
when it successfully could be used.

Thank you for Tristan and Willy for their participation on this issue.

Must be backported to 2.6.

src/quic_sock.c

index 4444ab8587a334017ea0fbaabf22062e2df4205d..090cec1bb5b61be33be0019ad7159a6eb46ebcd5 100644 (file)
@@ -278,6 +278,7 @@ void quic_sock_fd_iocb(int fd)
 
        BUG_ON(!l);
 
+       new_dgram = NULL;
        if (!l)
                return;
 
@@ -290,8 +291,7 @@ void quic_sock_fd_iocb(int fd)
 
        buf = &rxbuf->buf;
 
-       new_dgram = NULL;
-       /* Remove all consumed datagrams of this buffer */
+       /* Try to reuse an existing dgram */
        list_for_each_entry_safe(dgram, dgramp, &rxbuf->dgrams, list) {
                if (HA_ATOMIC_LOAD(&dgram->buf))
                        break;
@@ -300,8 +300,6 @@ void quic_sock_fd_iocb(int fd)
                b_del(buf, dgram->len);
                if (!new_dgram)
                        new_dgram = dgram;
-               else
-                       pool_free(pool_head_quic_dgram, dgram);
        }
 
        params = &l->bind_conf->quic_params;
@@ -349,7 +347,9 @@ void quic_sock_fd_iocb(int fd)
                /* If wrong, consume this datagram */
                b_del(buf, ret);
        }
+       new_dgram = NULL;
  out:
+       pool_free(pool_head_quic_dgram, new_dgram);
        MT_LIST_APPEND(&l->rx.rxbuf_list, &rxbuf->mt_list);
 }