Both TIPC_NL_MEDIA_SET and TIPC_NL_BEARER_SET accept user-supplied MTU values but only enforce a minimum bound, not a maximum. When a user sets the MTU to a value exceeding U16_MAX (65535), it passes validation but is silently truncated when assigned to u16 fields l->mtu and l->advertised_mtu in tipc_link_create(). Values like 65536 (0x10000) truncate to 0, causing a division by zero in tipc_link_set_queue_limits() which computes TIPC_MAX_PUBL / (l->mtu / ITEM_SIZE). Other overflowing values (e.g. 65537-131071) produce small incorrect MTU values, resulting in link malfunction behaviors. Crash stack (triggered as unprivileged user): tipc_link_set_queue_limits net/tipc/link.c:2531 tipc_link_create net/tipc/link.c:520 tipc_node_check_dest net/tipc/node.c:1279 tipc_disc_rcv net/tipc/discover.c:252 tipc_rcv net/tipc/node.c:2129 tipc_udp_recv net/tipc/udp_media.c:392 Two independent paths lack the upper bound check: 1. tipc_udp_mtu_bad() -- called from __tipc_nl_media_set() (MEDIA_SET) 2. inline check in __tipc_nl_bearer_set() at bearer.c:1160 (BEARER_SET) Fix both by rejecting MTU values above U16_MAX. Fixes: 901271e0403a ("tipc: implement configuration of UDP media MTU") Reported-by: AutonomousCodeSecurity@microsoft.com Signed-off-by: Cen Zhang (Microsoft) --- net/tipc/bearer.c | 6 ++++++ net/tipc/udp_media.h | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index 05dcd2f9e..0926692dd 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c @@ -1163,6 +1163,12 @@ int __tipc_nl_bearer_set(struct sk_buff *skb, struct genl_info *info) "MTU value is out-of-range"); return -EINVAL; } + if (nla_get_u32(props[TIPC_NLA_PROP_MTU]) > + U16_MAX) { + NL_SET_ERR_MSG(info->extack, + "MTU value is out-of-range"); + return -EINVAL; + } b->mtu = nla_get_u32(props[TIPC_NLA_PROP_MTU]); tipc_node_apply_property(net, b, TIPC_NLA_PROP_MTU); #endif diff --git a/net/tipc/udp_media.h b/net/tipc/udp_media.h index e7455cc73..0d62a57c8 100644 --- a/net/tipc/udp_media.h +++ b/net/tipc/udp_media.h @@ -48,6 +48,11 @@ int tipc_udp_nl_dump_remoteip(struct sk_buff *skb, struct netlink_callback *cb); /* check if configured MTU is too low for tipc headers */ static inline bool tipc_udp_mtu_bad(u32 mtu) { + if (mtu > U16_MAX) { + pr_warn("MTU too large for tipc bearer\n"); + return true; + } + if (mtu >= (TIPC_MIN_BEARER_MTU + sizeof(struct iphdr) + sizeof(struct udphdr))) return false; -- 2.43.0