[libc-commits] [libc] [libc] Fix unpoisoning for recvfrom (PR #117366)
via libc-commits
libc-commits at lists.llvm.org
Fri Nov 22 11:31:13 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libc
Author: Michael Jones (michaelrj-google)
<details>
<summary>Changes</summary>
Turns out there were also errors in the recvfrom unpoisoning logic. This
patch fixes those.
---
Full diff: https://github.com/llvm/llvm-project/pull/117366.diff
2 Files Affected:
- (modified) libc/src/sys/socket/linux/recvfrom.cpp (+18-4)
- (modified) libc/src/sys/socket/recvfrom.h (+1-1)
``````````diff
diff --git a/libc/src/sys/socket/linux/recvfrom.cpp b/libc/src/sys/socket/linux/recvfrom.cpp
index a0f8278cd5deb4..574e65f64a54b0 100644
--- a/libc/src/sys/socket/linux/recvfrom.cpp
+++ b/libc/src/sys/socket/linux/recvfrom.cpp
@@ -23,17 +23,26 @@ namespace LIBC_NAMESPACE_DECL {
LLVM_LIBC_FUNCTION(ssize_t, recvfrom,
(int sockfd, void *buf, size_t len, int flags,
- struct sockaddr *__restrict dest_addr,
+ sockaddr *__restrict src_addr,
socklen_t *__restrict addrlen)) {
+ // addrlen is a value-result argument. If it's not null, it passes the max
+ // size of the buffer src_addr to the syscall. After the syscall, it's updated
+ // to the actual size of the source address. This may be larger than the
+ // buffer, in which case the buffer contains a truncated result.
+ size_t srcaddr_sz;
+ if (src_addr)
+ srcaddr_sz = *addrlen;
+ (void)srcaddr_sz; // prevent "set but not used" warning
+
#ifdef SYS_recvfrom
ssize_t ret = LIBC_NAMESPACE::syscall_impl<ssize_t>(
- SYS_recvfrom, sockfd, buf, len, flags, dest_addr, addrlen);
+ SYS_recvfrom, sockfd, buf, len, flags, src_addr, addrlen);
#elif defined(SYS_socketcall)
unsigned long sockcall_args[6] = {static_cast<unsigned long>(sockfd),
reinterpret_cast<unsigned long>(buf),
static_cast<unsigned long>(len),
static_cast<unsigned long>(flags),
- reinterpret_cast<unsigned long>(dest_addr),
+ reinterpret_cast<unsigned long>(src_addr),
static_cast<unsigned long>(addrlen)};
ssize_t ret = LIBC_NAMESPACE::syscall_impl<ssize_t>(
SYS_socketcall, SYS_RECVFROM, sockcall_args);
@@ -46,8 +55,13 @@ LLVM_LIBC_FUNCTION(ssize_t, recvfrom,
}
MSAN_UNPOISON(buf, ret);
- MSAN_UNPOISON(addrlen, sizeof(socklen_t));
+ if (src_addr) {
+ size_t min_src_addr_size = (*addrlen < srcaddr_sz) ? *addrlen : srcaddr_sz;
+ (void)min_src_addr_size; // prevent "set but not used" warning
+
+ MSAN_UNPOISON(src_addr, min_src_addr_size);
+ }
return ret;
}
diff --git a/libc/src/sys/socket/recvfrom.h b/libc/src/sys/socket/recvfrom.h
index 14869802e72563..15d70d6d010f06 100644
--- a/libc/src/sys/socket/recvfrom.h
+++ b/libc/src/sys/socket/recvfrom.h
@@ -18,7 +18,7 @@
namespace LIBC_NAMESPACE_DECL {
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
- struct sockaddr *__restrict address,
+ struct sockaddr *__restrict src_addr,
socklen_t *__restrict addrlen);
} // namespace LIBC_NAMESPACE_DECL
``````````
</details>
https://github.com/llvm/llvm-project/pull/117366
More information about the libc-commits
mailing list