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

Side by Side 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, 8 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 unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/udp/udp_socket_libevent.h" 5 #include "net/udp/udp_socket_libevent.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <fcntl.h> 8 #include <fcntl.h>
9 #include <net/if.h>
9 #include <netdb.h> 10 #include <netdb.h>
10 #include <net/if.h>
11 #include <netinet/in.h> 11 #include <netinet/in.h>
12 #include <sys/ioctl.h> 12 #include <sys/ioctl.h>
13 #include <sys/socket.h> 13 #include <sys/socket.h>
14 14
15 #include "base/callback.h" 15 #include "base/callback.h"
16 #include "base/debug/alias.h" 16 #include "base/debug/alias.h"
17 #include "base/logging.h" 17 #include "base/logging.h"
18 #include "base/message_loop/message_loop.h" 18 #include "base/message_loop/message_loop.h"
19 #include "base/metrics/sparse_histogram.h" 19 #include "base/metrics/sparse_histogram.h"
20 #include "base/posix/eintr_wrapper.h" 20 #include "base/posix/eintr_wrapper.h"
(...skipping 28 matching lines...) Expand all
49 ifr.ifr_addr.sa_family = AF_INET; 49 ifr.ifr_addr.sa_family = AF_INET;
50 if (!if_indextoname(index, ifr.ifr_name)) 50 if (!if_indextoname(index, ifr.ifr_name))
51 return MapSystemError(errno); 51 return MapSystemError(errno);
52 int rv = ioctl(socket, SIOCGIFADDR, &ifr); 52 int rv = ioctl(socket, SIOCGIFADDR, &ifr);
53 if (rv == -1) 53 if (rv == -1)
54 return MapSystemError(errno); 54 return MapSystemError(errno);
55 *address = reinterpret_cast<sockaddr_in*>(&ifr.ifr_addr)->sin_addr.s_addr; 55 *address = reinterpret_cast<sockaddr_in*>(&ifr.ifr_addr)->sin_addr.s_addr;
56 return OK; 56 return OK;
57 } 57 }
58 58
59 // On OSX the file descriptor is guarded to detect the cause of
60 // crbug.com/461246. sys/guarded.h is not included in the SDK, so the API needs
61 // to be defined here.
Mark Mentovai 2015/04/02 14:37:06 Drive the point home by saying in the comment that
Sergey Ulanov 2015/04/02 18:05:42 Added TODO to remove it.
62
63 typedef uint64_t guardid_t;
64
65 int guarded_close_np(int fd, const guardid_t *guard) {
66 return syscall(442, fd, guard);
Mark Mentovai 2015/04/02 14:37:06 This is only available in 10.9 and 10.10. It’ll be
Sergey Ulanov 2015/04/02 18:05:42 Done.
67 }
68 int change_fdguard_np(int fd, const guardid_t *guard, u_int flags,
69 const guardid_t *nguard, u_int nflags, int *fdflagsp) {
70 return syscall(444, fd, guard, flags, nguard, nflags, fdflagsp);
71 }
72
73 const unsigned int GUARD_CLOSE = 1u<<0;
74 const unsigned int GUARD_DUP = 1u<<1;
75
76 const guardid_t kSocketFdGuard = 0xD712BC0BC9A4EAD4;
77
59 #endif // OS_MACOSX 78 #endif // OS_MACOSX
60 79
61 } // namespace 80 } // namespace
62 81
63 UDPSocketLibevent::UDPSocketLibevent( 82 UDPSocketLibevent::UDPSocketLibevent(
64 DatagramSocket::BindType bind_type, 83 DatagramSocket::BindType bind_type,
65 const RandIntCallback& rand_int_cb, 84 const RandIntCallback& rand_int_cb,
66 net::NetLog* net_log, 85 net::NetLog* net_log,
67 const net::NetLog::Source& source) 86 const net::NetLog::Source& source)
68 : socket_(kInvalidSocket), 87 : socket_(kInvalidSocket),
(...skipping 22 matching lines...) Expand all
91 } 110 }
92 111
93 int UDPSocketLibevent::Open(AddressFamily address_family) { 112 int UDPSocketLibevent::Open(AddressFamily address_family) {
94 DCHECK(CalledOnValidThread()); 113 DCHECK(CalledOnValidThread());
95 DCHECK_EQ(socket_, kInvalidSocket); 114 DCHECK_EQ(socket_, kInvalidSocket);
96 115
97 addr_family_ = ConvertAddressFamily(address_family); 116 addr_family_ = ConvertAddressFamily(address_family);
98 socket_ = CreatePlatformSocket(addr_family_, SOCK_DGRAM, 0); 117 socket_ = CreatePlatformSocket(addr_family_, SOCK_DGRAM, 0);
99 if (socket_ == kInvalidSocket) 118 if (socket_ == kInvalidSocket)
100 return MapSystemError(errno); 119 return MapSystemError(errno);
120 #if defined(OS_MACOSX)
121 PCHECK(change_fdguard_np(socket_, NULL, 0, &kSocketFdGuard,
122 GUARD_CLOSE | GUARD_DUP, NULL) == 0);
123 #endif // OS_MACOSX
101 if (SetNonBlocking(socket_)) { 124 if (SetNonBlocking(socket_)) {
102 const int err = MapSystemError(errno); 125 const int err = MapSystemError(errno);
103 Close(); 126 Close();
104 return err; 127 return err;
105 } 128 }
106 return OK; 129 return OK;
107 } 130 }
108 131
109 void UDPSocketLibevent::Close() { 132 void UDPSocketLibevent::Close() {
110 DCHECK(CalledOnValidThread()); 133 DCHECK(CalledOnValidThread());
111 134
112 if (socket_ == kInvalidSocket) 135 if (socket_ == kInvalidSocket)
113 return; 136 return;
114 137
115 // Zero out any pending read/write callback state. 138 // Zero out any pending read/write callback state.
116 read_buf_ = NULL; 139 read_buf_ = NULL;
117 read_buf_len_ = 0; 140 read_buf_len_ = 0;
118 read_callback_.Reset(); 141 read_callback_.Reset();
119 recv_from_address_ = NULL; 142 recv_from_address_ = NULL;
120 write_buf_ = NULL; 143 write_buf_ = NULL;
121 write_buf_len_ = 0; 144 write_buf_len_ = 0;
122 write_callback_.Reset(); 145 write_callback_.Reset();
123 send_to_address_.reset(); 146 send_to_address_.reset();
124 147
125 bool ok = read_socket_watcher_.StopWatchingFileDescriptor(); 148 bool ok = read_socket_watcher_.StopWatchingFileDescriptor();
126 DCHECK(ok); 149 DCHECK(ok);
127 ok = write_socket_watcher_.StopWatchingFileDescriptor(); 150 ok = write_socket_watcher_.StopWatchingFileDescriptor();
128 DCHECK(ok); 151 DCHECK(ok);
129 152
153 #if defined(OS_MACOSX)
154 PCHECK(IGNORE_EINTR(guarded_close_np(socket_, &kSocketFdGuard)) == 0);
155 #else
130 PCHECK(IGNORE_EINTR(close(socket_)) == 0); 156 PCHECK(IGNORE_EINTR(close(socket_)) == 0);
157 #endif // OS_MACOSX
131 158
132 socket_ = kInvalidSocket; 159 socket_ = kInvalidSocket;
133 addr_family_ = 0; 160 addr_family_ = 0;
134 is_connected_ = false; 161 is_connected_ = false;
135 } 162 }
136 163
137 int UDPSocketLibevent::GetPeerAddress(IPEndPoint* address) const { 164 int UDPSocketLibevent::GetPeerAddress(IPEndPoint* address) const {
138 DCHECK(CalledOnValidThread()); 165 DCHECK(CalledOnValidThread());
139 DCHECK(address); 166 DCHECK(address);
140 if (!is_connected()) 167 if (!is_connected())
(...skipping 603 matching lines...) Expand 10 before | Expand all | Expand 10 after
744 return MapSystemError(errno); 771 return MapSystemError(errno);
745 772
746 return OK; 773 return OK;
747 } 774 }
748 775
749 void UDPSocketLibevent::DetachFromThread() { 776 void UDPSocketLibevent::DetachFromThread() {
750 base::NonThreadSafe::DetachFromThread(); 777 base::NonThreadSafe::DetachFromThread();
751 } 778 }
752 779
753 } // namespace net 780 } // namespace net
OLDNEW
« 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