tipc_update_nametbl() inserts a binding advertised by a peer node using the lower and upper service-range bounds taken directly from the wire, without checking that lower <= upper. The local bind path validates the ordering (tipc_uaddr_valid()), but the name-distribution path does not. A binding with lower > upper is inserted at the far end of the service-range rbtree (keyed on lower) where no lookup or withdrawal can ever match it (service_range_foreach_match() requires sr->lower <= end). The publication, its service_range node and the augmented rbtree entry are then leaked for the lifetime of the namespace, and there is no per-peer cap equivalent to TIPC_MAX_PUBL on locally created bindings. Reject inverted ranges in the network path as well. A peer node can otherwise leak unbounded binding-table memory by sending PUBLICATION items with lower > upper. Fixes: 37922ea4a310 ("tipc: permit overlapping service ranges in name table") Assisted-by: Claude:claude-opus-4-7 Signed-off-by: Michael Bommarito --- v2: - Reorder the new u32 declarations in reverse-Xmas-tree order. net/tipc/name_distr.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c index 190b49c5cbc3e..da8a5eb6e63f1 100644 --- a/net/tipc/name_distr.c +++ b/net/tipc/name_distr.c @@ -282,10 +282,19 @@ static bool tipc_update_nametbl(struct net *net, struct distr_item *i, struct publication *p = NULL; struct tipc_socket_addr sk; struct tipc_uaddr ua; + u32 lower = ntohl(i->lower); + u32 upper = ntohl(i->upper); u32 key = ntohl(i->key); + /* A peer-advertised binding with lower > upper can never be matched + * or withdrawn and would leak the publication; the local bind path + * rejects such ranges, so reject ranges learned from the network too. + */ + if (lower > upper) + return false; + tipc_uaddr(&ua, TIPC_SERVICE_RANGE, TIPC_CLUSTER_SCOPE, - ntohl(i->type), ntohl(i->lower), ntohl(i->upper)); + ntohl(i->type), lower, upper); sk.ref = ntohl(i->port); sk.node = node; -- 2.53.0