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:
+13
-1
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user