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.
This commit is contained in:
Red Bear OS
2026-07-08 21:15:31 +03:00
parent f704b67f25
commit 285eedfab8
+13 -1
View File
@@ -1069,10 +1069,22 @@ pub unsafe extern "C" fn freeaddrinfo(res: *mut addrinfo) {
unsafe { drop(Box::from_raw(bai.ai_addr.cast::<sockaddr_in>())) };
} else if bai.ai_addrlen == mem::size_of::<sockaddr_in6>() as socklen_t {
unsafe { drop(Box::from_raw(bai.ai_addr.cast::<sockaddr_in6>())) };
} else if bai.ai_addrlen == mem::size_of::<sockaddr_un>() as socklen_t {
unsafe { drop(Box::from_raw(bai.ai_addr.cast::<sockaddr_un>())) };
} 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::<libc::sa_family_t>(),
).unwrap_or(alloc::alloc::Layout::new::<u8>());
unsafe {
alloc::alloc::dealloc(bai.ai_addr.cast::<u8>(), layout);
}
}
}
}
ai = bai.ai_next;
}
}