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

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 a6c1b72b50ac651c8a711c568c042e0d9ddcd504..85032cede648fdbc4868b1cbe3505a2c5a590b3e 100644
--- a/net/udp/udp_socket_libevent.cc
+++ b/net/udp/udp_socket_libevent.cc
@@ -6,8 +6,8 @@
#include <errno.h>
#include <fcntl.h>
-#include <netdb.h>
#include <net/if.h>
+#include <netdb.h>
#include <netinet/in.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
@@ -28,6 +28,12 @@
#include "net/socket/socket_descriptor.h"
#include "net/udp/udp_net_log_parameters.h"
+#if defined(OS_MACOSX)
+// 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)
namespace net {
@@ -56,6 +62,66 @@ int GetIPv4AddressFromIndex(int socket, uint32 index, uint32* address){
return OK;
}
+// On OSX the file descriptor is guarded to detect the cause of
+// crbug.com/461246. sys/guarded.h is not included in the SDK, so the API needs
+// to be defined here.
+// 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);
+
+void* g_libsystem_handle = nullptr;
Mark Mentovai 2015/04/02 18:21:57 This is only used in InitGuardedFunctions, make it
Sergey Ulanov 2015/04/02 18:28:19 Done. It doesn't need to be static.
+GuardedCloseNpFunction g_guarded_close_np = nullptr;
+ChangeFdguardNpFunction g_change_fdguard_np = nullptr;
+
+static pthread_once_t g_guarded_functions_once = PTHREAD_ONCE_INIT;
Mark Mentovai 2015/04/02 18:21:57 You’re in an unnamed namespace, you shouldn’t have
Sergey Ulanov 2015/04/02 18:28:18 Done.
+
+static void InitGuardedFunctions() {
+ g_libsystem_handle = dlopen("/usr/lib/libSystem.dylib", 0);
Mark Mentovai 2015/04/02 18:21:57 Use RTLD_LAZY | RTLD_LOCAL | RTLD_NOLOAD, not 0.
Sergey Ulanov 2015/04/02 18:28:18 Done.
+ if (g_libsystem_handle) {
+ g_guarded_close_np = reinterpret_cast<GuardedCloseNpFunction>(
+ dlsym(g_libsystem_handle, "guarded_close_np"));
+ g_change_fdguard_np = reinterpret_cast<ChangeFdguardNpFunction>(
+ dlsym(g_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 // OS_MACOSX
} // namespace
@@ -98,6 +164,10 @@ int UDPSocketLibevent::Open(AddressFamily address_family) {
socket_ = CreatePlatformSocket(addr_family_, SOCK_DGRAM, 0);
if (socket_ == kInvalidSocket)
return MapSystemError(errno);
+#if defined(OS_MACOSX)
+ PCHECK(change_fdguard_np(socket_, NULL, 0, &kSocketFdGuard,
+ GUARD_CLOSE | GUARD_DUP, NULL) == 0);
+#endif // OS_MACOSX
if (SetNonBlocking(socket_)) {
const int err = MapSystemError(errno);
Close();
@@ -127,7 +197,11 @@ void UDPSocketLibevent::Close() {
ok = write_socket_watcher_.StopWatchingFileDescriptor();
DCHECK(ok);
+#if defined(OS_MACOSX)
+ PCHECK(IGNORE_EINTR(guarded_close_np(socket_, &kSocketFdGuard)) == 0);
+#else
PCHECK(IGNORE_EINTR(close(socket_)) == 0);
+#endif // OS_MACOSX
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