1use super::{
6 NetlinkFamily, QipcrtrSocket, SocketAddress, SocketDomain, SocketFile, SocketMessageFlags,
7 SocketProtocol, SocketShutdownFlags, SocketType, UnixSocket, VsockSocket, ZxioBackedSocket,
8 new_netlink_socket,
9};
10use crate::mm::MemoryAccessorExt;
11use crate::security;
12use crate::syscalls::time::TimeValPtr;
13use crate::task::{CurrentTask, EventHandler, WaitCanceler, Waiter};
14use crate::vfs::buffers::{AncillaryData, InputBuffer, MessageReadInfo, OutputBuffer};
15use crate::vfs::{DowncastedFile, FileHandle, FileObject, FsNodeHandle};
16use starnix_logging::track_stub;
17use starnix_sync::{LockDepMutex, SocketStateLock};
18use starnix_syscalls::{SyscallArg, SyscallResult};
19use starnix_types::time::{duration_from_timeval, timeval_from_duration};
20use starnix_types::user_buffer::UserBuffer;
21use starnix_uapi::as_any::AsAny;
22use starnix_uapi::auth::CAP_NET_RAW;
23use starnix_uapi::errors::{ENOTTY, Errno};
24use starnix_uapi::user_address::MappingMultiArchUserRef;
25use starnix_uapi::vfs::FdEvents;
26use starnix_uapi::{
27 SO_DOMAIN, SO_PROTOCOL, SO_RCVTIMEO, SO_SNDTIMEO, SO_TYPE, SOL_SOCKET, errno, error, uapi,
28};
29use std::collections::VecDeque;
30use std::sync::Arc;
31use std::sync::atomic::Ordering;
32use zerocopy::FromBytes;
33
34pub const DEFAULT_LISTEN_BACKLOG: usize = 1024;
35
36const SO_ANDROID_DROP_REASON: u32 = 0xAD01D01;
38const ANDROID_DROP_REASON_NONE: u64 = 0;
39
40pub trait SocketOps: Send + Sync + AsAny {
41 fn get_socket_info(&self) -> Result<(SocketDomain, SocketType, SocketProtocol), Errno> {
45 error!(EINVAL)
48 }
49
50 fn connect(
53 &self,
54 socket: &SocketHandle,
55 current_task: &CurrentTask,
56 peer: SocketPeer,
57 ) -> Result<(), Errno>;
58
59 fn listen(&self, socket: &Socket, backlog: i32, credentials: uapi::ucred) -> Result<(), Errno>;
61
62 fn accept(&self, socket: &Socket, current_task: &CurrentTask) -> Result<SocketHandle, Errno>;
65
66 fn bind(
70 &self,
71 socket: &Socket,
72 current_task: &CurrentTask,
73 socket_address: SocketAddress,
74 ) -> Result<(), Errno>;
75
76 fn read(
86 &self,
87 socket: &Socket,
88 current_task: &CurrentTask,
89 data: &mut dyn OutputBuffer,
90 flags: SocketMessageFlags,
91 ) -> Result<MessageReadInfo, Errno>;
92
93 fn write(
102 &self,
103 socket: &Socket,
104 current_task: &CurrentTask,
105 data: &mut dyn InputBuffer,
106 dest_address: &mut Option<SocketAddress>,
107 ancillary_data: &mut Vec<AncillaryData>,
108 ) -> Result<usize, Errno>;
109
110 fn wait_async(
121 &self,
122 socket: &Socket,
123 current_task: &CurrentTask,
124 waiter: &Waiter,
125 events: FdEvents,
126 handler: EventHandler,
127 ) -> WaitCanceler;
128
129 fn query_events(&self, socket: &Socket, current_task: &CurrentTask) -> Result<FdEvents, Errno>;
131
132 fn shutdown(&self, socket: &Socket, how: SocketShutdownFlags) -> Result<(), Errno>;
136
137 fn close(&self, current_task: &CurrentTask, socket: &Socket);
148
149 fn getsockname(&self, socket: &Socket) -> Result<SocketAddress, Errno>;
154
155 fn getpeername(&self, socket: &Socket) -> Result<SocketAddress, Errno>;
159
160 fn setsockopt(
162 &self,
163 _socket: &Socket,
164 _current_task: &CurrentTask,
165 _level: u32,
166 _optname: u32,
167 _optval: SockOptValue,
168 ) -> Result<(), Errno> {
169 error!(ENOPROTOOPT)
170 }
171
172 fn getsockopt(
174 &self,
175 _socket: &Socket,
176 _current_task: &CurrentTask,
177 _level: u32,
178 _optname: u32,
179 _optlen: u32,
180 ) -> Result<Vec<u8>, Errno> {
181 error!(ENOPROTOOPT)
182 }
183
184 fn ioctl(
186 &self,
187 _socket: &Socket,
188 _file: &FileObject,
189 _current_task: &CurrentTask,
190 _request: u32,
191 _arg: SyscallArg,
192 ) -> Result<SyscallResult, Errno> {
193 error!(ENOTTY)
194 }
195
196 fn to_handle(
200 &self,
201 _socket: &Socket,
202 _current_task: &CurrentTask,
203 ) -> Result<Option<zx::NullableHandle>, Errno> {
204 Ok(None)
205 }
206}
207
208pub struct Socket {
210 pub(super) ops: Box<dyn SocketOps>,
211
212 pub domain: SocketDomain,
214
215 pub socket_type: SocketType,
217
218 pub protocol: SocketProtocol,
220
221 state: LockDepMutex<SocketState, SocketStateLock>,
222
223 pub security: security::SocketState,
226}
227
228#[derive(Default)]
229struct SocketState {
230 receive_timeout: Option<zx::MonotonicDuration>,
232
233 send_timeout: Option<zx::MonotonicDuration>,
235
236 fs_node: Option<FsNodeHandle>,
240}
241
242pub type SocketHandle = Arc<Socket>;
243
244#[derive(Clone)]
245pub enum SocketPeer {
246 Handle(SocketHandle),
247 Address(SocketAddress),
248}
249
250fn resolve_protocol(
254 domain: SocketDomain,
255 socket_type: SocketType,
256 protocol: SocketProtocol,
257) -> SocketProtocol {
258 if domain.is_inet() && protocol.as_raw() == 0 {
259 match socket_type {
260 SocketType::Stream => SocketProtocol::TCP,
261 SocketType::Datagram => SocketProtocol::UDP,
262 _ => protocol,
263 }
264 } else {
265 protocol
266 }
267}
268
269fn create_socket_ops(
270 current_task: &CurrentTask,
271 domain: SocketDomain,
272 socket_type: SocketType,
273 protocol: SocketProtocol,
274) -> Result<Box<dyn SocketOps>, Errno> {
275 match domain {
276 SocketDomain::Unix => Ok(Box::new(UnixSocket::new(socket_type))),
277 SocketDomain::Vsock => Ok(Box::new(VsockSocket::new(socket_type))),
278 SocketDomain::Inet | SocketDomain::Inet6 => {
279 if socket_type == SocketType::Raw {
282 security::check_task_capable(current_task, CAP_NET_RAW)?;
283 }
284 Ok(Box::new(ZxioBackedSocket::new(current_task, domain, socket_type, protocol)?))
285 }
286 SocketDomain::Netlink => {
287 let netlink_family = NetlinkFamily::from_raw(protocol.as_raw());
288 new_netlink_socket(current_task.kernel(), socket_type, netlink_family)
289 }
290 SocketDomain::Packet => {
291 security::check_task_capable(current_task, CAP_NET_RAW)?;
294 Ok(Box::new(ZxioBackedSocket::new(current_task, domain, socket_type, protocol)?))
295 }
296 SocketDomain::Key => {
297 track_stub!(
298 TODO("https://fxbug.dev/323365389"),
299 "Returning a UnixSocket instead of a KeySocket"
300 );
301 Ok(Box::new(UnixSocket::new(SocketType::Datagram)))
302 }
303 SocketDomain::Qipcrtr => Ok(Box::new(QipcrtrSocket::new(socket_type))),
304 }
305}
306
307#[derive(Debug)]
308pub enum SockOptValue {
309 Value(Vec<u8>),
310 User(UserBuffer),
311}
312
313impl From<Vec<u8>> for SockOptValue {
314 fn from(buffer: Vec<u8>) -> Self {
315 Self::Value(buffer)
316 }
317}
318
319impl From<UserBuffer> for SockOptValue {
320 fn from(buffer: UserBuffer) -> Self {
321 Self::User(buffer)
322 }
323}
324
325impl SockOptValue {
326 pub fn len(&self) -> usize {
327 match self {
328 Self::Value(buffer) => buffer.len(),
329 Self::User(user_buffer) => user_buffer.length,
330 }
331 }
332
333 pub fn read<T: FromBytes>(&self, current_task: &CurrentTask) -> Result<T, Errno> {
334 match self {
335 Self::Value(buffer) => {
336 T::read_from_prefix(&buffer).map_err(|_| errno!(EINVAL)).map(|(v, _)| v)
337 }
338 Self::User(user_buffer) => {
339 current_task.read_object::<T>(user_buffer.clone().try_into()?)
340 }
341 }
342 }
343
344 pub fn read_bytes(
345 &self,
346 current_task: &CurrentTask,
347 max_bytes: usize,
348 ) -> Result<Vec<u8>, Errno> {
349 match self {
350 Self::Value(buffer) => {
351 let bytes = std::cmp::min(max_bytes, buffer.len());
352 Ok(buffer[..bytes].to_owned())
353 }
354 Self::User(user_buffer) => {
355 let bytes = std::cmp::min(max_bytes, user_buffer.length);
356 current_task
357 .read_buffer(&UserBuffer { address: user_buffer.address, length: bytes })
358 }
359 }
360 }
361
362 pub fn to_vec(self, current_task: &CurrentTask) -> Result<Vec<u8>, Errno> {
363 match self {
364 Self::Value(buffer) => Ok(buffer),
365 Self::User(user_buffer) => current_task.read_buffer(&user_buffer),
366 }
367 }
368}
369
370pub trait ReadFromSockOptValue {
372 type Result;
373 fn read_from_sockopt_value(
374 current_task: &CurrentTask,
375 buffer: &SockOptValue,
376 ) -> Result<Self::Result, Errno>;
377}
378
379impl<T, T64, T32> ReadFromSockOptValue for MappingMultiArchUserRef<T, T64, T32>
380where
381 T64: FromBytes + TryInto<T>,
382 T32: FromBytes + TryInto<T>,
383{
384 type Result = T;
385 fn read_from_sockopt_value(
386 current_task: &CurrentTask,
387 buffer: &SockOptValue,
388 ) -> Result<T, Errno> {
389 match buffer {
390 SockOptValue::Value(buffer) => {
391 Self::read_from_prefix(current_task, &buffer).map_err(|_| errno!(EINVAL))
392 }
393 SockOptValue::User(user_buffer) => {
394 let user_ref = Self::new_with_ref(current_task, user_buffer.clone())?;
395 current_task.read_multi_arch_object(user_ref)
396 }
397 }
398 }
399}
400
401impl Socket {
402 pub fn new(
407 current_task: &CurrentTask,
408 domain: SocketDomain,
409 socket_type: SocketType,
410 protocol: SocketProtocol,
411 kernel_private: bool,
412 ) -> Result<SocketHandle, Errno> {
413 let protocol = resolve_protocol(domain, socket_type, protocol);
414 security::check_socket_create_access(
418 current_task,
419 domain,
420 socket_type,
421 protocol,
422 kernel_private,
423 )?;
424 let ops = create_socket_ops(current_task, domain, socket_type, protocol)?;
425 Ok(Self::new_with_ops_and_info(ops, domain, socket_type, protocol))
426 }
427
428 pub fn new_with_ops(ops: Box<dyn SocketOps>) -> Result<SocketHandle, Errno> {
429 let (domain, socket_type, protocol) = ops.get_socket_info()?;
430 Ok(Self::new_with_ops_and_info(ops, domain, socket_type, protocol))
431 }
432
433 pub fn new_with_ops_and_info(
434 ops: Box<dyn SocketOps>,
435 domain: SocketDomain,
436 socket_type: SocketType,
437 protocol: SocketProtocol,
438 ) -> SocketHandle {
439 Arc::new(Socket {
440 ops,
441 domain,
442 socket_type,
443 protocol,
444 state: Default::default(),
445 security: security::SocketState::default(),
446 })
447 }
448
449 pub(super) fn set_fs_node(&self, node: &FsNodeHandle) {
450 let mut locked_state = self.state.lock();
451 assert!(locked_state.fs_node.is_none());
452 locked_state.fs_node = Some(node.clone());
453 }
454
455 pub fn get_from_file(file: &FileHandle) -> Result<&SocketHandle, Errno> {
458 let socket_file = file.downcast_file::<SocketFile>().ok_or_else(|| errno!(ENOTSOCK))?;
459 Ok(&socket_file.socket)
460 }
461
462 pub fn downcast_socket<T>(&self) -> Option<&T>
463 where
464 T: 'static,
465 {
466 let ops = &*self.ops;
467 ops.as_any().downcast_ref::<T>()
468 }
469
470 pub fn getsockname(&self) -> Result<SocketAddress, Errno> {
471 self.ops.getsockname(self)
472 }
473
474 pub fn getpeername(&self) -> Result<SocketAddress, Errno> {
475 self.ops.getpeername(self)
476 }
477
478 pub fn setsockopt(
479 &self,
480 current_task: &CurrentTask,
481 level: u32,
482 optname: u32,
483 optval: SockOptValue,
484 ) -> Result<(), Errno> {
485 let read_timeval = || {
486 let timeval = TimeValPtr::read_from_sockopt_value(current_task, &optval)?;
487 let duration = duration_from_timeval(timeval)?;
488 Ok(if duration == zx::MonotonicDuration::default() { None } else { Some(duration) })
489 };
490
491 security::check_socket_setsockopt_access(current_task, self, level, optname)?;
492 match (level, optname) {
493 (SOL_SOCKET, SO_RCVTIMEO) => self.state.lock().receive_timeout = read_timeval()?,
494 (SOL_SOCKET, SO_SNDTIMEO) => self.state.lock().send_timeout = read_timeval()?,
495 _ => self.ops.setsockopt(self, current_task, level, optname, optval)?,
496 }
497 Ok(())
498 }
499
500 pub fn getsockopt(
501 &self,
502 current_task: &CurrentTask,
503 level: u32,
504 optname: u32,
505 optlen: u32,
506 ) -> Result<Vec<u8>, Errno> {
507 security::check_socket_getsockopt_access(current_task, self, level, optname)?;
508 let value = match level {
509 SOL_SOCKET => match optname {
510 SO_TYPE => self.socket_type.as_raw().to_ne_bytes().to_vec(),
511 SO_DOMAIN => {
512 let domain = self.domain.as_raw() as u32;
513 domain.to_ne_bytes().to_vec()
514 }
515 SO_PROTOCOL => self.protocol.as_raw().to_ne_bytes().to_vec(),
516 SO_RCVTIMEO => {
517 let duration = self.receive_timeout().unwrap_or_default();
518 TimeValPtr::into_bytes(current_task, timeval_from_duration(duration))
519 .map_err(|_| errno!(EINVAL))?
520 }
521 SO_SNDTIMEO => {
522 let duration = self.send_timeout().unwrap_or_default();
523 TimeValPtr::into_bytes(current_task, timeval_from_duration(duration))
524 .map_err(|_| errno!(EINVAL))?
525 }
526 SO_ANDROID_DROP_REASON => {
527 track_stub!(
528 TODO("https://fxbug.dev/477273398"),
529 "Faking SO_ANDROID_DROP_REASON"
530 );
531 ANDROID_DROP_REASON_NONE.to_ne_bytes().to_vec()
532 }
533 _ => self.ops.getsockopt(self, current_task, level, optname, optlen)?,
534 },
535 _ => self.ops.getsockopt(self, current_task, level, optname, optlen)?,
536 };
537 Ok(value)
538 }
539
540 pub fn receive_timeout(&self) -> Option<zx::MonotonicDuration> {
541 self.state.lock().receive_timeout
542 }
543
544 pub fn send_timeout(&self) -> Option<zx::MonotonicDuration> {
545 self.state.lock().send_timeout
546 }
547
548 pub fn ioctl(
549 &self,
550 file: &FileObject,
551 current_task: &CurrentTask,
552 request: u32,
553 arg: SyscallArg,
554 ) -> Result<SyscallResult, Errno> {
555 let res = super::netlink_ioctl::netlink_ioctl(current_task, request, arg);
556 match &res {
557 Err(e) if e.code == ENOTTY => {}
558 _ => return res,
559 }
560 self.ops.ioctl(self, file, current_task, request, arg)
561 }
562
563 pub fn bind(
564 &self,
565 current_task: &CurrentTask,
566 socket_address: SocketAddress,
567 ) -> Result<(), Errno> {
568 self.ops.bind(self, current_task, socket_address)
569 }
570
571 pub fn listen(&self, current_task: &CurrentTask, backlog: i32) -> Result<(), Errno> {
572 security::check_socket_listen_access(current_task, self, backlog)?;
573 let max_connections =
574 current_task.kernel().system_limits.socket.max_connections.load(Ordering::Relaxed);
575 let backlog = std::cmp::min(backlog, max_connections);
576 let credentials = current_task.current_ucred();
577 self.ops.listen(self, backlog, credentials)
578 }
579
580 pub fn accept(&self, current_task: &CurrentTask) -> Result<SocketHandle, Errno> {
581 self.ops.accept(self, current_task)
582 }
583
584 pub fn read(
585 &self,
586 current_task: &CurrentTask,
587 data: &mut dyn OutputBuffer,
588 flags: SocketMessageFlags,
589 ) -> Result<MessageReadInfo, Errno> {
590 security::check_socket_recvmsg_access(current_task, self)?;
591 self.ops.read(self, current_task, data, flags)
592 }
593
594 pub fn write(
595 &self,
596 current_task: &CurrentTask,
597 data: &mut dyn InputBuffer,
598 dest_address: &mut Option<SocketAddress>,
599 ancillary_data: &mut Vec<AncillaryData>,
600 ) -> Result<usize, Errno> {
601 security::check_socket_sendmsg_access(current_task, self)?;
602 self.ops.write(self, current_task, data, dest_address, ancillary_data)
603 }
604
605 pub fn wait_async(
606 &self,
607 current_task: &CurrentTask,
608 waiter: &Waiter,
609 events: FdEvents,
610 handler: EventHandler,
611 ) -> WaitCanceler {
612 self.ops.wait_async(self, current_task, waiter, events, handler)
613 }
614
615 pub fn query_events(&self, current_task: &CurrentTask) -> Result<FdEvents, Errno> {
616 self.ops.query_events(self, current_task)
617 }
618
619 pub fn shutdown(
620 &self,
621 current_task: &CurrentTask,
622 how: SocketShutdownFlags,
623 ) -> Result<(), Errno> {
624 security::check_socket_shutdown_access(current_task, self, how)?;
625 self.ops.shutdown(self, how)
626 }
627
628 pub fn close(&self, current_task: &CurrentTask) {
629 self.ops.close(current_task, self)
630 }
631
632 pub fn to_handle(
633 &self,
634 _file: &FileObject,
635 current_task: &CurrentTask,
636 ) -> Result<Option<zx::NullableHandle>, Errno> {
637 self.ops.to_handle(self, current_task)
638 }
639
640 pub fn fs_node(&self) -> Option<FsNodeHandle> {
644 self.state.lock().fs_node.clone()
645 }
646}
647
648impl DowncastedFile<'_, SocketFile> {
649 pub fn connect(self, current_task: &CurrentTask, peer: SocketPeer) -> Result<(), Errno> {
650 security::check_socket_connect_access(current_task, self, &peer)?;
651 self.socket.ops.connect(&self.socket, current_task, peer)
652 }
653}
654
655pub struct AcceptQueue {
656 pub sockets: VecDeque<SocketHandle>,
657 pub backlog: usize,
658}
659
660impl AcceptQueue {
661 pub fn new(backlog: usize) -> AcceptQueue {
662 AcceptQueue { sockets: VecDeque::with_capacity(backlog), backlog }
663 }
664
665 pub fn set_backlog(&mut self, backlog: usize) -> Result<(), Errno> {
666 if self.sockets.len() > backlog {
667 return error!(EINVAL);
668 }
669 self.backlog = backlog;
670 Ok(())
671 }
672}
673
674#[cfg(test)]
675mod tests {
676 use super::*;
677 use crate::testing::{map_memory, spawn_kernel_and_run};
678 use crate::vfs::{UnixControlData, VecInputBuffer, VecOutputBuffer};
679 use starnix_uapi::SO_PASSCRED;
680 use starnix_uapi::user_address::{UserAddress, UserRef};
681
682 #[fuchsia::test]
683 async fn test_dgram_socket() {
684 spawn_kernel_and_run(async |current_task| {
685 let bind_address = SocketAddress::Unix(b"dgram_test".into());
686 let rec_dgram = Socket::new(
687 ¤t_task,
688 SocketDomain::Unix,
689 SocketType::Datagram,
690 SocketProtocol::default(),
691 false,
692 )
693 .expect("Failed to create socket.");
694 let passcred: u32 = 1;
695 let opt_size = std::mem::size_of::<u32>();
696 let user_address = map_memory(¤t_task, UserAddress::default(), opt_size as u64);
697 let opt_ref = UserRef::<u32>::new(user_address);
698 current_task.write_object(opt_ref, &passcred).unwrap();
699 let opt_buf = UserBuffer { address: user_address, length: opt_size };
700 rec_dgram.setsockopt(¤t_task, SOL_SOCKET, SO_PASSCRED, opt_buf.into()).unwrap();
701
702 rec_dgram.bind(¤t_task, bind_address).expect("failed to bind datagram socket");
703
704 let xfer_value: u64 = 1234567819;
705 let xfer_bytes = xfer_value.to_ne_bytes();
706
707 let send = Socket::new(
708 ¤t_task,
709 SocketDomain::Unix,
710 SocketType::Datagram,
711 SocketProtocol::default(),
712 false,
713 )
714 .expect("Failed to connect socket.");
715 send.ops.connect(&send, ¤t_task, SocketPeer::Handle(rec_dgram.clone())).unwrap();
716 let mut source_iter = VecInputBuffer::new(&xfer_bytes);
717 send.write(¤t_task, &mut source_iter, &mut None, &mut vec![]).unwrap();
718 assert_eq!(source_iter.available(), 0);
719 send.close(¤t_task);
722
723 let mut rec_buffer = VecOutputBuffer::new(8);
724 let read_info = rec_dgram
725 .read(¤t_task, &mut rec_buffer, SocketMessageFlags::empty())
726 .unwrap();
727 assert_eq!(read_info.bytes_read, xfer_bytes.len());
728 assert_eq!(rec_buffer.data(), xfer_bytes);
729 assert_eq!(1, read_info.ancillary_data.len());
730 assert_eq!(
731 read_info.ancillary_data[0],
732 AncillaryData::Unix(UnixControlData::Credentials(uapi::ucred {
733 pid: current_task.get_pid(),
734 uid: 0,
735 gid: 0
736 }))
737 );
738
739 rec_dgram.close(¤t_task);
740 })
741 .await;
742 }
743}