From: Olivier Houchard Date: Wed, 29 Jul 2026 23:04:50 +0000 (+0200) Subject: MINOR: connection: Do not retrieve src/dst on another thread group's FD X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=d3bdb250c33030955a2bdfffddc57cc48795ea7d;p=thirdparty%2Fhaproxy.git MINOR: connection: Do not retrieve src/dst on another thread group's FD conn_get_src() and conn_get_dst() lazily fetch the connection's addresses with getsockname()/getpeername() when they were not known yet. They may be called on a foreign connection by observability code running on any thread, for example "show peers", which dumps the peers sessions' connections from whatever thread serves the CLI. With per-thread-group FD tables, the FD of a connection owned by another group is not usable from the calling thread. So just fail if we attempt to access a connection that is owned by another thread group. --- diff --git a/include/haproxy/connection.h b/include/haproxy/connection.h index 980d696a8..e51f2b423 100644 --- a/include/haproxy/connection.h +++ b/include/haproxy/connection.h @@ -384,8 +384,14 @@ static inline int conn_get_src(struct connection *conn) if (conn->ctrl->proto_type != PROTO_TYPE_STREAM) goto fail; - /* most other socket-based stream protocols will use their socket family's functions */ + /* most other socket-based stream protocols will use their socket + * family's functions. With per-thread-group FD tables however, the + * FD may belong to a connection of another group, its number is only + * usable within that group. + */ if (conn->ctrl->fam->get_src && !(conn->flags & CO_FL_FDLESS) && + (!(global.tune.options & GTUNE_NO_TG_FD_SHARING) || + fdtab[conn->handle.fd].owner == conn) && conn->ctrl->fam->get_src(conn->handle.fd, (struct sockaddr *)conn->src, sizeof(*conn->src), obj_type(conn->target) != OBJ_TYPE_LISTENER) != -1) @@ -424,6 +430,8 @@ static inline int conn_get_dst(struct connection *conn) /* most other socket-based stream protocols will use their socket family's functions */ if (conn->ctrl->fam->get_dst && !(conn->flags & CO_FL_FDLESS) && + (!(global.tune.options & GTUNE_NO_TG_FD_SHARING) || + fdtab[conn->handle.fd].owner == conn) && conn->ctrl->fam->get_dst(conn->handle.fd, (struct sockaddr *)conn->dst, sizeof(*conn->dst), obj_type(conn->target) != OBJ_TYPE_LISTENER) != -1)