From 9896c81d426e4b4143388a187ba764e8fc0b01b7 Mon Sep 17 00:00:00 2001 From: "randomizedcoder dave.seddon.ca@gmail.com" Date: Fri, 18 Sep 2026 10:30:41 -0700 Subject: [PATCH] fix(outgoing): keep homa_tx_skb_alloc frag length arithmetic signed In homa_tx_skb_alloc() the per-frag length is computed as: frag_bytes = min(skb_frag_size(msg_frag) - bytes_to_skip, bytes_left); skb_frag_size() is unsigned, so the first argument is unsigned while bytes_left (and the frag_bytes result) are int -- a mixed-sign min(). The skip loop guarantees bytes_to_skip < skb_frag_size() today, so the value is correct; but should that invariant ever break, the unsigned subtraction would wrap to a huge positive length and the mixed-sign comparison would happily pick it. Compute the available bytes as a signed int first, so min() compares two ints and an underflow stays negative (and loses the min). Pure refactor of the arithmetic's type; no behavior change. The homa_outgoing unit suite stays green (52/52), including all the homa_tx_skb_alloc frag offset/size checks. Co-Authored-By: Claude Opus 4.8 --- homa_outgoing.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/homa_outgoing.c b/homa_outgoing.c index 52d0311b..853b1c9e 100644 --- a/homa_outgoing.c +++ b/homa_outgoing.c @@ -289,10 +289,14 @@ struct sk_buff *homa_tx_skb_alloc(struct homa_rpc *rpc, u32 offset, u32 *end) msg_frags_left > 0) { skb_frag_t *skb_frag = &shinfo->frags[shinfo->nr_frags]; struct page *page; - int frag_bytes; + int frag_avail, frag_bytes; - frag_bytes = min(skb_frag_size(msg_frag) - bytes_to_skip, - bytes_left); + /* skb_frag_size() is unsigned; keep the min() operands signed + * (matching bytes_left and frag_bytes) so a mixed-sign compare + * can't turn an underflow into a huge positive length. + */ + frag_avail = (int)skb_frag_size(msg_frag) - bytes_to_skip; + frag_bytes = min(frag_avail, bytes_left); page = skb_frag_page(msg_frag); get_page(page); skb_frag->netmem = page_to_netmem(page);