From: Amaury Denoyelle Date: Fri, 13 Jun 2025 08:19:16 +0000 (+0200) Subject: BUG/MINOR: quic: don't restrict reception on backend privileged ports X-Git-Tag: v3.3-dev2~57 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=46cee079316e9bec85ea81e7261c82484269cdf0;p=thirdparty%2Fhaproxy.git BUG/MINOR: quic: don't restrict reception on backend privileged ports When QUIC is used on the frontend side, communication is restricted with clients using privileged port. This is a simple protection against DNS/NTP spoofing. This feature should not be activated on the backend side, as in this case it is quite frequent to exchange with server running on privileged ports. As such, a new parameter is added to quic_recv() so that it is only active on the frontend side. Without this patch, it is impossible to communicate with QUIC servers running on privileged ports, as incoming datagrams would be silently dropped. No need to backport. --- diff --git a/src/quic_sock.c b/src/quic_sock.c index 490e5bfb0..d7149ab84 100644 --- a/src/quic_sock.c +++ b/src/quic_sock.c @@ -351,12 +351,16 @@ static struct quic_dgram *quic_rxbuf_purge_dgrams(struct quic_receiver_buf *rbuf * will be set as AF_UNSPEC. The caller must specify to ensure * that address is completely filled. * + * Set if communication with privileged port should be handle with + * constraint, which is desirable when interacting with QUIC clients on + * frontend side. + * * Returns value from recvmsg syscall. */ static ssize_t quic_recv(int fd, void *out, size_t len, struct sockaddr *from, socklen_t from_len, struct sockaddr *to, socklen_t to_len, - uint16_t dst_port) + uint16_t dst_port, int check_port) { union pktinfo { #ifdef IP_PKTINFO @@ -398,7 +402,7 @@ static ssize_t quic_recv(int fd, void *out, size_t len, if (ret < 0) goto end; - if (unlikely(port_is_restricted((struct sockaddr_storage *)from, HA_PROTO_QUIC))) { + if (check_port && unlikely(port_is_restricted((struct sockaddr_storage *)from, HA_PROTO_QUIC))) { ret = -1; goto end; } @@ -535,7 +539,7 @@ void quic_lstnr_sock_fd_iocb(int fd) ret = quic_recv(fd, dgram_buf, max_sz, (struct sockaddr *)&saddr, sizeof(saddr), (struct sockaddr *)&daddr, sizeof(daddr), - get_net_port(&l->rx.addr)); + get_net_port(&l->rx.addr), 1); if (ret <= 0) goto out; @@ -841,7 +845,7 @@ int qc_rcv_buf(struct quic_conn *qc) ret = quic_recv(qc->fd, dgram_buf, qc->max_udp_payload, (struct sockaddr *)&saddr, sizeof(saddr), (struct sockaddr *)&daddr, sizeof(daddr), - get_net_port(&qc->local_addr)); + get_net_port(&qc->local_addr), !!l); if (ret <= 0) { /* Subscribe FD for future reception. */ if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOTCONN)