1// Copyright 2016 The Fuchsia Authors 2// 3// Use of this source code is governed by a MIT-style 4// license that can be found in the LICENSE file or at 5// https://opensource.org/licenses/MIT 6 7#include <object/socket_dispatcher.h> 8 9#include <string.h> 10 11#include <assert.h> 12#include <err.h> 13#include <pow2.h> 14#include <trace.h> 15 16#include <lib/user_copy/user_ptr.h> 17 18#include <vm/vm_aspace.h> 19#include <vm/vm_object.h> 20#include <vm/vm_object_paged.h> 21#include <object/handle.h> 22 23#include <zircon/rights.h> 24#include <fbl/alloc_checker.h> 25#include <fbl/auto_lock.h> 26 27#define LOCAL_TRACE 0 28 29// static 30zx_status_t SocketDispatcher::Create(uint32_t flags, 31 fbl::RefPtr<Dispatcher>* dispatcher0, 32 fbl::RefPtr<Dispatcher>* dispatcher1, 33 zx_rights_t* rights) { 34 LTRACE_ENTRY; 35 36 if (flags & ~ZX_SOCKET_CREATE_MASK) 37 return ZX_ERR_INVALID_ARGS; 38 39 fbl::AllocChecker ac; 40 41 zx_signals_t starting_signals = ZX_SOCKET_WRITABLE; 42 43 if (flags & ZX_SOCKET_HAS_ACCEPT) 44 starting_signals |= ZX_SOCKET_SHARE; 45 46 fbl::unique_ptr<ControlMsg> control0; 47 fbl::unique_ptr<ControlMsg> control1; 48 49 // TODO: use mbufs to avoid pinning control buffer memory. 50 if (flags & ZX_SOCKET_HAS_CONTROL) { 51 starting_signals |= ZX_SOCKET_CONTROL_WRITABLE; 52 53 control0.reset(new (&ac) ControlMsg()); 54 if (!ac.check()) 55 return ZX_ERR_NO_MEMORY; 56 57 control1.reset(new (&ac) ControlMsg()); 58 if (!ac.check()) 59 return ZX_ERR_NO_MEMORY; 60 } 61 62 auto holder0 = fbl::AdoptRef(new (&ac) PeerHolder<SocketDispatcher>()); 63 if (!ac.check()) 64 return ZX_ERR_NO_MEMORY; 65 auto holder1 = holder0; 66 67 auto socket0 = fbl::AdoptRef(new (&ac) SocketDispatcher(fbl::move(holder0), starting_signals, 68 flags, fbl::move(control0))); 69 if (!ac.check()) 70 return ZX_ERR_NO_MEMORY; 71 72 auto socket1 = fbl::AdoptRef(new (&ac) SocketDispatcher(fbl::move(holder1), starting_signals, 73 flags, fbl::move(control1))); 74 if (!ac.check()) 75 return ZX_ERR_NO_MEMORY; 76 77 socket0->Init(socket1); 78 socket1->Init(socket0); 79 80 *rights = ZX_DEFAULT_SOCKET_RIGHTS; 81 *dispatcher0 = fbl::move(socket0); 82 *dispatcher1 = fbl::move(socket1); 83 return ZX_OK; 84} 85 86SocketDispatcher::SocketDispatcher(fbl::RefPtr<PeerHolder<SocketDispatcher>> holder, 87 zx_signals_t starting_signals, uint32_t flags, 88 fbl::unique_ptr<ControlMsg> control_msg) 89 : PeeredDispatcher(fbl::move(holder), starting_signals), 90 flags_(flags), 91 control_msg_(fbl::move(control_msg)), 92 control_msg_len_(0), 93 read_threshold_(0), 94 write_threshold_(0), 95 read_disabled_(false) { 96} 97 98SocketDispatcher::~SocketDispatcher() { 99} 100 101// This is called before either SocketDispatcher is accessible from threads other than the one 102// initializing the socket, so it does not need locking. 103void SocketDispatcher::Init(fbl::RefPtr<SocketDispatcher> other) TA_NO_THREAD_SAFETY_ANALYSIS { 104 peer_ = fbl::move(other); 105 peer_koid_ = peer_->get_koid(); 106} 107 108void SocketDispatcher::on_zero_handles_locked() { 109 canary_.Assert(); 110} 111 112void SocketDispatcher::OnPeerZeroHandlesLocked() { 113 canary_.Assert(); 114 115 UpdateStateLocked(ZX_SOCKET_WRITABLE, ZX_SOCKET_PEER_CLOSED); 116} 117 118zx_status_t SocketDispatcher::UserSignalSelfLocked(uint32_t clear_mask, uint32_t set_mask) { 119 canary_.Assert(); 120 UpdateStateLocked(clear_mask, set_mask); 121 return ZX_OK; 122} 123 124zx_status_t SocketDispatcher::Shutdown(uint32_t how) TA_NO_THREAD_SAFETY_ANALYSIS { 125 canary_.Assert(); 126 127 LTRACE_ENTRY; 128 129 const bool shutdown_read = how & ZX_SOCKET_SHUTDOWN_READ; 130 const bool shutdown_write = how & ZX_SOCKET_SHUTDOWN_WRITE; 131 132 Guard<fbl::Mutex> guard{get_lock()}; 133 134 zx_signals_t signals = GetSignalsStateLocked(); 135 // If we're already shut down in the requested way, return immediately. 136 const uint32_t want_signals = 137 (shutdown_read ? ZX_SOCKET_READ_DISABLED : 0) | 138 (shutdown_write ? ZX_SOCKET_WRITE_DISABLED : 0); 139 const uint32_t have_signals = signals & (ZX_SOCKET_READ_DISABLED | ZX_SOCKET_WRITE_DISABLED); 140 if (want_signals == have_signals) { 141 return ZX_OK; 142 } 143 zx_signals_t clear_mask = 0u; 144 zx_signals_t set_mask = 0u; 145 if (shutdown_read) { 146 read_disabled_ = true; 147 if (is_empty()) 148 set_mask |= ZX_SOCKET_READ_DISABLED; 149 } 150 if (shutdown_write) { 151 clear_mask |= ZX_SOCKET_WRITABLE; 152 set_mask |= ZX_SOCKET_WRITE_DISABLED; 153 } 154 UpdateStateLocked(clear_mask, set_mask); 155 156 // Our peer already be closed - if so, we've already updated our own bits so we are done. If the 157 // peer is done, we need to notify them of the state change. 158 if (peer_ != nullptr) { 159 return peer_->ShutdownOtherLocked(how); 160 } else { 161 return ZX_OK; 162 } 163} 164 165zx_status_t SocketDispatcher::ShutdownOtherLocked(uint32_t how) { 166 canary_.Assert(); 167 168 const bool shutdown_read = how & ZX_SOCKET_SHUTDOWN_READ; 169 const bool shutdown_write = how & ZX_SOCKET_SHUTDOWN_WRITE; 170 171 zx_signals_t clear_mask = 0u; 172 zx_signals_t set_mask = 0u; 173 if (shutdown_read) { 174 // If the other end shut down reading, we can't write any more. 175 clear_mask |= ZX_SOCKET_WRITABLE; 176 set_mask |= ZX_SOCKET_WRITE_DISABLED; 177 } 178 if (shutdown_write) { 179 // If the other end shut down writing, we can't read any more than already exists in the 180 // buffer. If we're empty, set ZX_SOCKET_READ_DISABLED now. If we aren't empty, Read() will 181 // set this bit after reading the remaining data from the socket. 182 read_disabled_ = true; 183 if (is_empty()) 184 set_mask |= ZX_SOCKET_READ_DISABLED; 185 } 186 187 UpdateStateLocked(clear_mask, set_mask); 188 return ZX_OK; 189} 190 191zx_status_t SocketDispatcher::Write(user_in_ptr<const void> src, size_t len, 192 size_t* nwritten) TA_NO_THREAD_SAFETY_ANALYSIS { 193 canary_.Assert(); 194 195 LTRACE_ENTRY; 196 197 Guard<fbl::Mutex> guard{get_lock()}; 198 199 if (!peer_) 200 return ZX_ERR_PEER_CLOSED; 201 zx_signals_t signals = GetSignalsStateLocked(); 202 if (signals & ZX_SOCKET_WRITE_DISABLED) 203 return ZX_ERR_BAD_STATE; 204 205 if (len == 0) { 206 *nwritten = 0; 207 return ZX_OK; 208 } 209 if (len != static_cast<size_t>(static_cast<uint32_t>(len))) 210 return ZX_ERR_INVALID_ARGS; 211 212 return peer_->WriteSelfLocked(src, len, nwritten); 213} 214 215zx_status_t SocketDispatcher::WriteControl(user_in_ptr<const void> src, size_t len) 216 TA_NO_THREAD_SAFETY_ANALYSIS { 217 canary_.Assert(); 218 219 if ((flags_ & ZX_SOCKET_HAS_CONTROL) == 0) 220 return ZX_ERR_BAD_STATE; 221 222 if (len == 0) 223 return ZX_ERR_INVALID_ARGS; 224 225 if (len > ControlMsg::kSize) 226 return ZX_ERR_OUT_OF_RANGE; 227 228 Guard<fbl::Mutex> guard{get_lock()}; 229 if (!peer_) 230 return ZX_ERR_PEER_CLOSED; 231 232 return peer_->WriteControlSelfLocked(src, len); 233} 234 235zx_status_t SocketDispatcher::WriteControlSelfLocked(user_in_ptr<const void> src, 236 size_t len) TA_NO_THREAD_SAFETY_ANALYSIS { 237 canary_.Assert(); 238 239 if (control_msg_len_ != 0) 240 return ZX_ERR_SHOULD_WAIT; 241 242 if (src.copy_array_from_user(&control_msg_->msg, len) != ZX_OK) 243 return ZX_ERR_INVALID_ARGS; // Bad user buffer. 244 245 control_msg_len_ = static_cast<uint32_t>(len); 246 247 UpdateStateLocked(0u, ZX_SOCKET_CONTROL_READABLE); 248 if (peer_) 249 peer_->UpdateStateLocked(ZX_SOCKET_CONTROL_WRITABLE, 0u); 250 251 return ZX_OK; 252} 253 254zx_status_t SocketDispatcher::WriteSelfLocked(user_in_ptr<const void> src, size_t len, 255 size_t* written) TA_NO_THREAD_SAFETY_ANALYSIS { 256 canary_.Assert(); 257 258 if (is_full()) 259 return ZX_ERR_SHOULD_WAIT; 260 261 bool was_empty = is_empty(); 262 263 size_t st = 0u; 264 zx_status_t status; 265 if (flags_ & ZX_SOCKET_DATAGRAM) { 266 status = data_.WriteDatagram(src, len, &st); 267 } else { 268 status = data_.WriteStream(src, len, &st); 269 } 270 if (status) 271 return status; 272 273 zx_signals_t clear = 0u; 274 zx_signals_t set = 0u; 275 276 if (st > 0) { 277 if (was_empty) 278 set |= ZX_SOCKET_READABLE; 279 // Assert signal if we go above the read threshold 280 if ((read_threshold_ > 0) && (data_.size() >= read_threshold_)) 281 set |= ZX_SOCKET_READ_THRESHOLD; 282 if (set) { 283 UpdateStateLocked(0u, set); 284 } 285 if (peer_) { 286 size_t peer_write_threshold = peer_->write_threshold_; 287 // If free space falls below threshold, de-signal 288 if ((peer_write_threshold > 0) && 289 ((data_.max_size() - data_.size()) < peer_write_threshold)) 290 clear |= ZX_SOCKET_WRITE_THRESHOLD; 291 } 292 } 293 294 if (peer_ && is_full()) 295 clear |= ZX_SOCKET_WRITABLE; 296 297 if (clear) 298 peer_->UpdateStateLocked(clear, 0u); 299 300 *written = st; 301 return status; 302} 303 304zx_status_t SocketDispatcher::Read(user_out_ptr<void> dst, size_t len, 305 size_t* nread) TA_NO_THREAD_SAFETY_ANALYSIS { 306 canary_.Assert(); 307 308 LTRACE_ENTRY; 309 310 Guard<fbl::Mutex> guard{get_lock()}; 311 312 // Just query for bytes outstanding. 313 if (!dst && len == 0) { 314 *nread = data_.size(); 315 return ZX_OK; 316 } 317 318 if (len != (size_t)((uint32_t)len)) 319 return ZX_ERR_INVALID_ARGS; 320 321 if (is_empty()) { 322 if (!peer_) 323 return ZX_ERR_PEER_CLOSED; 324 // If reading is disabled on our end and we're empty, we'll never become readable again. 325 // Return a different error to let the caller know. 326 if (read_disabled_) 327 return ZX_ERR_BAD_STATE; 328 return ZX_ERR_SHOULD_WAIT; 329 } 330 331 bool was_full = is_full(); 332 333 auto st = data_.Read(dst, len, flags_ & ZX_SOCKET_DATAGRAM); 334 335 zx_signals_t clear = 0u; 336 zx_signals_t set = 0u; 337 338 // Deassert signal if we fell below the read threshold 339 if ((read_threshold_ > 0) && (data_.size() < read_threshold_)) 340 clear |= ZX_SOCKET_READ_THRESHOLD; 341 342 if (is_empty()) { 343 if (read_disabled_) 344 set |= ZX_SOCKET_READ_DISABLED; 345 clear |= ZX_SOCKET_READABLE; 346 } 347 if (set || clear) { 348 UpdateStateLocked(clear, set); 349 clear = set = 0u; 350 } 351 if (peer_) { 352 // Assert (write threshold) signal if space available is above 353 // threshold. 354 size_t peer_write_threshold = peer_->write_threshold_; 355 if (peer_write_threshold > 0 && 356 ((data_.max_size() - data_.size()) >= peer_write_threshold)) 357 set |= ZX_SOCKET_WRITE_THRESHOLD; 358 if (was_full && (st > 0)) 359 set |= ZX_SOCKET_WRITABLE; 360 if (set) 361 peer_->UpdateStateLocked(0u, set); 362 } 363 364 *nread = static_cast<size_t>(st); 365 return ZX_OK; 366} 367 368zx_status_t SocketDispatcher::ReadControl(user_out_ptr<void> dst, size_t len, 369 size_t* nread) TA_NO_THREAD_SAFETY_ANALYSIS { 370 canary_.Assert(); 371 372 if ((flags_ & ZX_SOCKET_HAS_CONTROL) == 0) { 373 return ZX_ERR_BAD_STATE; 374 } 375 376 Guard<fbl::Mutex> guard{get_lock()}; 377 378 if (control_msg_len_ == 0) 379 return ZX_ERR_SHOULD_WAIT; 380 381 size_t copy_len = MIN(control_msg_len_, len); 382 if (dst.copy_array_to_user(&control_msg_->msg, copy_len) != ZX_OK) 383 return ZX_ERR_INVALID_ARGS; // Invalid user buffer. 384 385 control_msg_len_ = 0; 386 UpdateStateLocked(ZX_SOCKET_CONTROL_READABLE, 0u); 387 if (peer_) 388 peer_->UpdateStateLocked(0u, ZX_SOCKET_CONTROL_WRITABLE); 389 390 *nread = copy_len; 391 return ZX_OK; 392} 393 394zx_status_t SocketDispatcher::CheckShareable(SocketDispatcher* to_send) { 395 // We disallow sharing of sockets that support sharing themselves 396 // and disallow sharing either end of the socket we're going to 397 // share on, thus preventing loops, etc. 398 Guard<fbl::Mutex> guard{get_lock()}; 399 if ((to_send->flags_ & ZX_SOCKET_HAS_ACCEPT) || 400 (to_send == this) || (to_send == peer_.get())) 401 return ZX_ERR_BAD_STATE; 402 return ZX_OK; 403} 404 405zx_status_t SocketDispatcher::Share(HandleOwner h) TA_NO_THREAD_SAFETY_ANALYSIS { 406 canary_.Assert(); 407 408 LTRACE_ENTRY; 409 410 if (!(flags_ & ZX_SOCKET_HAS_ACCEPT)) 411 return ZX_ERR_NOT_SUPPORTED; 412 413 Guard<fbl::Mutex> guard{get_lock()}; 414 if (!peer_) 415 return ZX_ERR_PEER_CLOSED; 416 417 return peer_->ShareSelfLocked(fbl::move(h)); 418} 419 420zx_status_t SocketDispatcher::ShareSelfLocked(HandleOwner h) TA_NO_THREAD_SAFETY_ANALYSIS { 421 canary_.Assert(); 422 423 if (accept_queue_) 424 return ZX_ERR_SHOULD_WAIT; 425 426 accept_queue_ = fbl::move(h); 427 428 UpdateStateLocked(0, ZX_SOCKET_ACCEPT); 429 if (peer_) 430 peer_->UpdateStateLocked(ZX_SOCKET_SHARE, 0); 431 432 return ZX_OK; 433} 434 435zx_status_t SocketDispatcher::Accept(HandleOwner* h) TA_NO_THREAD_SAFETY_ANALYSIS { 436 canary_.Assert(); 437 438 if (!(flags_ & ZX_SOCKET_HAS_ACCEPT)) 439 return ZX_ERR_NOT_SUPPORTED; 440 441 Guard<fbl::Mutex> guard{get_lock()}; 442 443 if (!accept_queue_) 444 return ZX_ERR_SHOULD_WAIT; 445 446 *h = fbl::move(accept_queue_); 447 448 UpdateStateLocked(ZX_SOCKET_ACCEPT, 0); 449 if (peer_) 450 peer_->UpdateStateLocked(0, ZX_SOCKET_SHARE); 451 452 return ZX_OK; 453} 454 455size_t SocketDispatcher::ReceiveBufferMax() const { 456 canary_.Assert(); 457 Guard<fbl::Mutex> guard{get_lock()}; 458 return data_.max_size(); 459} 460 461size_t SocketDispatcher::ReceiveBufferSize() const { 462 canary_.Assert(); 463 Guard<fbl::Mutex> guard{get_lock()}; 464 return data_.size(); 465} 466 467// NOTE(abdulla): peer_ is protected by get_lock() while peer_->data_ 468// is protected by peer_->get_lock(). These two locks are aliases of 469// one another so must only acquire one of them. Thread-safety 470// analysis does not know they are the same lock so we must disable 471// analysis. 472size_t SocketDispatcher::TransmitBufferMax() const TA_NO_THREAD_SAFETY_ANALYSIS { 473 canary_.Assert(); 474 Guard<fbl::Mutex> guard{get_lock()}; 475 return peer_ ? peer_->data_.max_size() : 0; 476} 477 478size_t SocketDispatcher::TransmitBufferSize() const TA_NO_THREAD_SAFETY_ANALYSIS { 479 canary_.Assert(); 480 Guard<fbl::Mutex> guard{get_lock()}; 481 return peer_ ? peer_->data_.size() : 0; 482} 483 484void SocketDispatcher::GetInfo(zx_info_socket_t* info) const TA_NO_THREAD_SAFETY_ANALYSIS { 485 canary_.Assert(); 486 Guard<fbl::Mutex> guard{get_lock()}; 487 *info = zx_info_socket_t{ 488 .options = flags_, 489 .rx_buf_max = data_.max_size(), 490 .rx_buf_size = data_.size(), 491 .tx_buf_max = peer_ ? peer_->data_.max_size() : 0, 492 .tx_buf_size = peer_ ? peer_->data_.size() : 0, 493 }; 494} 495 496size_t SocketDispatcher::GetReadThreshold() const TA_NO_THREAD_SAFETY_ANALYSIS { 497 canary_.Assert(); 498 Guard<fbl::Mutex> guard{get_lock()}; 499 return read_threshold_; 500} 501 502size_t SocketDispatcher::GetWriteThreshold() const TA_NO_THREAD_SAFETY_ANALYSIS { 503 canary_.Assert(); 504 Guard<fbl::Mutex> guard{get_lock()}; 505 return write_threshold_; 506} 507 508zx_status_t SocketDispatcher::SetReadThreshold(size_t value) TA_NO_THREAD_SAFETY_ANALYSIS { 509 canary_.Assert(); 510 Guard<fbl::Mutex> guard{get_lock()}; 511 if (value > data_.max_size()) 512 return ZX_ERR_INVALID_ARGS; 513 read_threshold_ = value; 514 // Setting 0 disables thresholding. Deassert signal unconditionally. 515 if (value == 0) { 516 UpdateStateLocked(ZX_SOCKET_READ_THRESHOLD, 0u); 517 } else { 518 // Assert signal if we have queued data above the read threshold 519 if (data_.size() >= read_threshold_) 520 UpdateStateLocked(0u, ZX_SOCKET_READ_THRESHOLD); 521 } 522 return ZX_OK; 523} 524 525zx_status_t SocketDispatcher::SetWriteThreshold(size_t value) TA_NO_THREAD_SAFETY_ANALYSIS { 526 canary_.Assert(); 527 Guard<fbl::Mutex> guard{get_lock()}; 528 size_t tx_buffer_max; 529 tx_buffer_max = peer_ ? peer_->data_.max_size() : 0; 530 if (value > tx_buffer_max) 531 return ZX_ERR_INVALID_ARGS; 532 write_threshold_ = value; 533 // Setting 0 disables thresholding. Deassert signal unconditionally. 534 if (value == 0) { 535 UpdateStateLocked(ZX_SOCKET_WRITE_THRESHOLD, 0u); 536 } else { 537 // Assert signal if we have available space above the write threshold 538 if (peer_ && 539 (peer_->data_.max_size() - peer_->data_.size()) >= write_threshold_) 540 UpdateStateLocked(0u, ZX_SOCKET_WRITE_THRESHOLD); 541 } 542 return ZX_OK; 543} 544