Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(919)

Unified Diff: net/udp/udp_socket_libevent.cc

Issue 1053873003: Guard socket file descriptor in UDPSocketLibevent (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@close
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/udp/udp_socket_libevent.cc
diff --git a/net/udp/udp_socket_libevent.cc b/net/udp/udp_socket_libevent.cc
index 9dc5c95e46d57e26f4e960cb8a34449e0d0ff003..82597777b58c63d30b55508d59864d461f26bd67 100644
--- a/net/udp/udp_socket_libevent.cc
+++ b/net/udp/udp_socket_libevent.cc
@@ -28,6 +28,12 @@
#include "net/socket/socket_descriptor.h"
#include "net/udp/udp_net_log_parameters.h"
+#if defined(OS_MACOSX) && !defined(OS_IOS)
+// Needed temporarily to debug crbug.com/461246.
+// TODO(sergeyu): Remove once the bug is resolved.
+#include <dlfcn.h>
+#include <pthread.h>
+#endif // defined(OS_MACOSX) && !defined(OS_IOS)
namespace net {
@@ -58,6 +64,74 @@ int GetIPv4AddressFromIndex(int socket, uint32 index, uint32* address){
#endif // OS_MACOSX
+#if defined(OS_MACOSX) && !defined(OS_IOS)
+
+// On OSX the file descriptor is guarded to detect the cause of
+// crbug.com/461246. guarded API is supported only on newer versions of OSX,
+// so the symbols need to be resolved dynamically.
+// TODO(sergeyu): Removed this code once the bug is resolved.
+
+typedef uint64_t guardid_t;
+
+typedef int (*GuardedCloseNpFunction)(int fd, const guardid_t* guard);
+typedef int (*ChangeFdguardNpFunction)(int fd,
+ const guardid_t* guard,
+ u_int flags,
+ const guardid_t* nguard,
+ u_int nflags,
+ int* fdflagsp);
+
+GuardedCloseNpFunction g_guarded_close_np = nullptr;
+ChangeFdguardNpFunction g_change_fdguard_np = nullptr;
+
+pthread_once_t g_guarded_functions_once = PTHREAD_ONCE_INIT;
+
+void InitGuardedFunctions() {
+ void* libsystem_handle =
+ dlopen("/usr/lib/libSystem.dylib", RTLD_LAZY | RTLD_LOCAL | RTLD_NOLOAD);
+ if (libsystem_handle) {
+ g_guarded_close_np = reinterpret_cast<GuardedCloseNpFunction>(
+ dlsym(libsystem_handle, "guarded_close_np"));
+ g_change_fdguard_np = reinterpret_cast<ChangeFdguardNpFunction>(
+ dlsym(libsystem_handle, "change_fdguard_np"));
+
+ // If for any reason only one of the functions is found, set both of them to
+ // nullptr.
+ if (!g_guarded_close_np || !g_change_fdguard_np) {
+ g_guarded_close_np = nullptr;
+ g_change_fdguard_np = nullptr;
+ }
+ }
+}
+
+int change_fdguard_np(int fd,
+ const guardid_t* guard,
+ u_int flags,
+ const guardid_t* nguard,
+ u_int nflags,
+ int* fdflagsp) {
+ CHECK_EQ(pthread_once(&g_guarded_functions_once, InitGuardedFunctions), 0);
+ // Older version of OSX may not support guarded API.
+ if (!g_change_fdguard_np)
+ return 0;
+ return g_change_fdguard_np(fd, guard, flags, nguard, nflags, fdflagsp);
+}
+
+int guarded_close_np(int fd, const guardid_t* guard) {
+ // Older version of OSX may not support guarded API.
+ if (!g_guarded_close_np)
+ return close(fd);
+
+ return g_guarded_close_np(fd, guard);
+}
+
+const unsigned int GUARD_CLOSE = 1u << 0;
+const unsigned int GUARD_DUP = 1u << 1;
+
+const guardid_t kSocketFdGuard = 0xD712BC0BC9A4EAD4;
+
+#endif // defined(OS_MACOSX) && !defined(OS_IOS)
+
} // namespace
UDPSocketLibevent::UDPSocketLibevent(
@@ -98,6 +172,10 @@ int UDPSocketLibevent::Open(AddressFamily address_family) {
socket_ = CreatePlatformSocket(addr_family_, SOCK_DGRAM, 0);
if (socket_ == kInvalidSocket)
return MapSystemError(errno);
+#if defined(OS_MACOSX) && !defined(OS_IOS)
+ PCHECK(change_fdguard_np(socket_, NULL, 0, &kSocketFdGuard,
+ GUARD_CLOSE | GUARD_DUP, NULL) == 0);
+#endif // defined(OS_MACOSX) && !defined(OS_IOS)
if (SetNonBlocking(socket_)) {
const int err = MapSystemError(errno);
Close();
@@ -127,7 +205,11 @@ void UDPSocketLibevent::Close() {
ok = write_socket_watcher_.StopWatchingFileDescriptor();
DCHECK(ok);
+#if defined(OS_MACOSX) && !defined(OS_IOS)
+ PCHECK(IGNORE_EINTR(guarded_close_np(socket_, &kSocketFdGuard)) == 0);
+#else
PCHECK(IGNORE_EINTR(close(socket_)) == 0);
+#endif // defined(OS_MACOSX) && !defined(OS_IOS)
socket_ = kInvalidSocket;
addr_family_ = 0;
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698