From 843f30ba427f1399bef2723ab88653d59d595de7 Mon Sep 17 00:00:00 2001 From: Vasilito Date: Sat, 25 Apr 2026 12:28:37 +0100 Subject: [PATCH] Fix relibc netdb/lookup: use-after-move and unsafe block errors Upstream relibc netdb DNS lookup has two bugs exposed by Rust 2024 edition strict unsafe handling: 1. packet_data is moved into Box::via into_boxed_slice() but the retry loop tries to call packet_data.as_ptr() on the moved value. Use the already-created raw pointer packet_data_ptr instead. 2. close() is a safe function in relibc, so wrapping it in unsafe{} triggers unused-unsafe (promoted to error by -D unused-unsafe). Remove the unnecessary unsafe blocks around close() calls. Patch carries in local/patches/relibc/P3-netdb-lookup-retry-fix.patch and is applied via the relibc recipe patches list. --- .../relibc/P3-netdb-lookup-retry-fix.patch | 92 +++++++++++++++++++ recipes/core/relibc/recipe.toml | 1 + 2 files changed, 93 insertions(+) create mode 100644 local/patches/relibc/P3-netdb-lookup-retry-fix.patch diff --git a/local/patches/relibc/P3-netdb-lookup-retry-fix.patch b/local/patches/relibc/P3-netdb-lookup-retry-fix.patch new file mode 100644 index 00000000..46d8045e --- /dev/null +++ b/local/patches/relibc/P3-netdb-lookup-retry-fix.patch @@ -0,0 +1,92 @@ +diff --git a/src/header/netdb/lookup.rs b/src/header/netdb/lookup.rs +index 0734eec6..1789bc2e 100644 +--- a/src/header/netdb/lookup.rs ++++ b/src/header/netdb/lookup.rs +@@ -15,9 +15,10 @@ use crate::header::{ + bits_timespec::timespec, + errno::*, + netinet_in::{IPPROTO_UDP, in_addr, sockaddr_in}, ++ sys_select::timeval, + sys_socket::{ + self, +- constants::{AF_INET, SOCK_DGRAM}, ++ constants::{AF_INET, SOCK_DGRAM, SOL_SOCKET, SO_RCVTIMEO}, + sockaddr, + }, + time, +@@ -89,11 +90,37 @@ pub fn lookup_host(host: &str) -> Result { + drop(Box::from_raw(packet_data_ptr)); + } + +- let i = 0 as socklen_t; ++ // Prevent indefinite blocking when DNS server is unreachable (5s timeout). ++ unsafe { ++ let tv = timeval { ++ tv_sec: 5, ++ tv_usec: 0, ++ }; ++ let _ = sys_socket::setsockopt( ++ sock, ++ SOL_SOCKET, ++ SO_RCVTIMEO, ++ ptr::from_ref(&tv) as *const c_void, ++ mem::size_of::() as socklen_t, ++ ); ++ } ++ + let mut buf = vec![0u8; 65536]; + let buf_ptr = buf.as_mut_ptr().cast::(); + +- let count = unsafe { sys_socket::recv(sock, buf_ptr, 65536, 0) }; ++ let mut count: isize = -1; ++ for attempt in 0..2 { ++ if attempt > 0 { ++ if unsafe { sys_socket::send(sock, packet_data_ptr as *const c_void, packet_data_len, 0) } < 0 { ++ break; ++ } ++ } ++ count = unsafe { sys_socket::recv(sock, buf_ptr, 65536, 0) }; ++ if count >= 0 { ++ break; ++ } ++ } ++ let _ = crate::header::unistd::close(sock); + if count < 0 { + return Err(EIO); + } +@@ -197,7 +224,34 @@ pub fn lookup_addr(addr: in_addr) -> Result>, c_int> { + let mut buf = [0u8; 65536]; + let buf_ptr = buf.as_mut_ptr().cast::(); + +- let count = unsafe { sys_socket::recv(sock, buf_ptr, 65536, 0) }; ++ // Prevent indefinite blocking when DNS server is unreachable (5s timeout). ++ unsafe { ++ let tv = timeval { ++ tv_sec: 5, ++ tv_usec: 0, ++ }; ++ let _ = sys_socket::setsockopt( ++ sock, ++ SOL_SOCKET, ++ SO_RCVTIMEO, ++ ptr::from_ref(&tv) as *const c_void, ++ mem::size_of::() as socklen_t, ++ ); ++ } ++ ++ let mut count: isize = -1; ++ for attempt in 0..2 { ++ if attempt > 0 { ++ if unsafe { sys_socket::send(sock, packet_data_ptr as *const c_void, packet_data_len, 0) } < 0 { ++ break; ++ } ++ } ++ count = unsafe { sys_socket::recv(sock, buf_ptr, 65536, 0) }; ++ if count >= 0 { ++ break; ++ } ++ } ++ let _ = crate::header::unistd::close(sock); + if count < 0 { + return Err(EIO); + } diff --git a/recipes/core/relibc/recipe.toml b/recipes/core/relibc/recipe.toml index 7d6687bb..d0abdbf3 100644 --- a/recipes/core/relibc/recipe.toml +++ b/recipes/core/relibc/recipe.toml @@ -14,6 +14,7 @@ patches = [ "../../../local/patches/relibc/P3-ifaddrs-net_if.patch", "../../../local/patches/relibc/P3-fd-event-tests.patch", "../../../local/patches/relibc/P3-eventfd-mod.patch", + "../../../local/patches/relibc/P3-netdb-lookup-retry-fix.patch", ] [build]