From 285eedfab8d6f0c513780ec6add5bb189f75de11 Mon Sep 17 00:00:00 2001 From: Red Bear OS Date: Wed, 8 Jul 2026 21:15:31 +0300 Subject: [PATCH] relibc: fix freeaddrinfo memory leak for unknown address lengths Previously when getaddrinfo returned an addrinfo with an ai_addrlen that didn't match sockaddr_in or sockaddr_in6, the allocation was leaked (the function logged a TODO and returned without freeing the address). Now handles: - sockaddr_un (Unix domain socket addresses) - ai_addrlen=0 (no address to free) - Unknown sizes (free as raw allocation to prevent leak) The raw dealloc uses the address length as the size with sa_family_t alignment, which is sufficient for any address family's alignment requirements. --- src/header/netdb/mod.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/header/netdb/mod.rs b/src/header/netdb/mod.rs index 1d9941cbc5..d07b23331f 100644 --- a/src/header/netdb/mod.rs +++ b/src/header/netdb/mod.rs @@ -1069,10 +1069,22 @@ pub unsafe extern "C" fn freeaddrinfo(res: *mut addrinfo) { unsafe { drop(Box::from_raw(bai.ai_addr.cast::())) }; } else if bai.ai_addrlen == mem::size_of::() as socklen_t { unsafe { drop(Box::from_raw(bai.ai_addr.cast::())) }; + } else if bai.ai_addrlen == mem::size_of::() as socklen_t { + unsafe { drop(Box::from_raw(bai.ai_addr.cast::())) }; + } else if bai.ai_addrlen == 0 { + // No address to free. } else { - todo_skip!(0, "freeaddrinfo: unknown ai_addrlen {}", bai.ai_addrlen); + // Unknown ai_addrlen — free as raw allocation to avoid leak. + let layout = alloc::alloc::Layout::from_size_align( + bai.ai_addrlen as usize, + mem::align_of::(), + ).unwrap_or(alloc::alloc::Layout::new::()); + unsafe { + alloc::alloc::dealloc(bai.ai_addr.cast::(), layout); + } } } + } ai = bai.ai_next; } }