1use super::{
6 NetlinkFamily, QipcrtrSocket, SocketAddress, SocketBpfState, SocketDomain, SocketFile,
7 SocketMessageFlags, SocketProtocol, SocketShutdownFlags, SocketType, UnixSocket, VsockSocket,
8 ZxioBackedSocket, 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 bpf_state: SocketBpfState,
245}
246
247pub type SocketHandle = Arc<Socket>;
248
249#[derive(Clone)]
250pub enum SocketPeer {
251 Handle(SocketHandle),
252 Address(SocketAddress),
253}
254
255fn resolve_protocol(
259 domain: SocketDomain,
260 socket_type: SocketType,
261 protocol: SocketProtocol,
262) -> SocketProtocol {
263 if domain.is_inet() && protocol.as_raw() == 0 {
264 match socket_type {
265 SocketType::Stream => SocketProtocol::TCP,
266 SocketType::Datagram => SocketProtocol::UDP,
267 _ => protocol,
268 }
269 } else {
270 protocol
271 }
272}
273
274fn create_socket_ops(
275 current_task: &CurrentTask,
276 domain: SocketDomain,
277 socket_type: SocketType,
278 protocol: SocketProtocol,
279) -> Result<Box<dyn SocketOps>, Errno> {
280 match domain {
281 SocketDomain::Unix => Ok(Box::new(UnixSocket::new(socket_type))),
282 SocketDomain::Vsock => Ok(Box::new(VsockSocket::new(socket_type))),
283 SocketDomain::Inet | SocketDomain::Inet6 => {
284 if socket_type == SocketType::Raw {
287 security::check_task_capable(current_task, CAP_NET_RAW)?;
288 }
289 Ok(Box::new(ZxioBackedSocket::new(current_task, domain, socket_type, protocol)?))
290 }
291 SocketDomain::Netlink => {
292 let netlink_family = NetlinkFamily::from_raw(protocol.as_raw());
293 new_netlink_socket(current_task.kernel(), socket_type, netlink_family)
294 }
295 SocketDomain::Packet => {
296 security::check_task_capable(current_task, CAP_NET_RAW)?;
299 Ok(Box::new(ZxioBackedSocket::new(current_task, domain, socket_type, protocol)?))
300 }
301 SocketDomain::Key => {
302 track_stub!(
303 TODO("https://fxbug.dev/323365389"),
304 "Returning a UnixSocket instead of a KeySocket"
305 );
306 Ok(Box::new(UnixSocket::new(SocketType::Datagram)))
307 }
308 SocketDomain::Qipcrtr => Ok(Box::new(QipcrtrSocket::new(socket_type))),
309 }
310}
311
312#[derive(Debug)]
313pub enum SockOptValue {
314 Value(Vec<u8>),
315 User(UserBuffer),
316}
317
318impl From<Vec<u8>> for SockOptValue {
319 fn from(buffer: Vec<u8>) -> Self {
320 Self::Value(buffer)
321 }
322}
323
324impl From<UserBuffer> for SockOptValue {
325 fn from(buffer: UserBuffer) -> Self {
326 Self::User(buffer)
327 }
328}
329
330impl SockOptValue {
331 pub fn len(&self) -> usize {
332 match self {
333 Self::Value(buffer) => buffer.len(),
334 Self::User(user_buffer) => user_buffer.length,
335 }
336 }
337
338 pub fn read<T: FromBytes>(&self, current_task: &CurrentTask) -> Result<T, Errno> {
339 match self {
340 Self::Value(buffer) => {
341 T::read_from_prefix(&buffer).map_err(|_| errno!(EINVAL)).map(|(v, _)| v)
342 }
343 Self::User(user_buffer) => {
344 current_task.read_object::<T>(user_buffer.clone().try_into()?)
345 }
346 }
347 }
348
349 pub fn read_bytes(
350 &self,
351 current_task: &CurrentTask,
352 max_bytes: usize,
353 ) -> Result<Vec<u8>, Errno> {
354 match self {
355 Self::Value(buffer) => {
356 let bytes = std::cmp::min(max_bytes, buffer.len());
357 Ok(buffer[..bytes].to_owned())
358 }
359 Self::User(user_buffer) => {
360 let bytes = std::cmp::min(max_bytes, user_buffer.length);
361 current_task
362 .read_buffer(&UserBuffer { address: user_buffer.address, length: bytes })
363 }
364 }
365 }
366
367 pub fn to_vec(self, current_task: &CurrentTask) -> Result<Vec<u8>, Errno> {
368 match self {
369 Self::Value(buffer) => Ok(buffer),
370 Self::User(user_buffer) => current_task.read_buffer(&user_buffer),
371 }
372 }
373}
374
375pub trait ReadFromSockOptValue {
377 type Result;
378 fn read_from_sockopt_value(
379 current_task: &CurrentTask,
380 buffer: &SockOptValue,
381 ) -> Result<Self::Result, Errno>;
382}
383
384impl<T, T64, T32> ReadFromSockOptValue for MappingMultiArchUserRef<T, T64, T32>
385where
386 T64: FromBytes + TryInto<T>,
387 T32: FromBytes + TryInto<T>,
388{
389 type Result = T;
390 fn read_from_sockopt_value(
391 current_task: &CurrentTask,
392 buffer: &SockOptValue,
393 ) -> Result<T, Errno> {
394 match buffer {
395 SockOptValue::Value(buffer) => {
396 Self::read_from_prefix(current_task, &buffer).map_err(|_| errno!(EINVAL))
397 }
398 SockOptValue::User(user_buffer) => {
399 let user_ref = Self::new_with_ref(current_task, user_buffer.clone())?;
400 current_task.read_multi_arch_object(user_ref)
401 }
402 }
403 }
404}
405
406impl Socket {
407 pub fn new(
412 current_task: &CurrentTask,
413 domain: SocketDomain,
414 socket_type: SocketType,
415 protocol: SocketProtocol,
416 kernel_private: bool,
417 ) -> Result<SocketHandle, Errno> {
418 let protocol = resolve_protocol(domain, socket_type, protocol);
419 security::check_socket_create_access(
423 current_task,
424 domain,
425 socket_type,
426 protocol,
427 kernel_private,
428 )?;
429 let ops = create_socket_ops(current_task, domain, socket_type, protocol)?;
430 Ok(Self::new_with_ops_and_info(ops, domain, socket_type, protocol))
431 }
432
433 pub fn new_with_ops(ops: Box<dyn SocketOps>) -> Result<SocketHandle, Errno> {
434 let (domain, socket_type, protocol) = ops.get_socket_info()?;
435 Ok(Self::new_with_ops_and_info(ops, domain, socket_type, protocol))
436 }
437
438 pub fn new_with_ops_and_info(
439 ops: Box<dyn SocketOps>,
440 domain: SocketDomain,
441 socket_type: SocketType,
442 protocol: SocketProtocol,
443 ) -> SocketHandle {
444 Arc::new(Socket {
445 ops,
446 domain,
447 socket_type,
448 protocol,
449 state: Default::default(),
450 security: security::SocketState::default(),
451 })
452 }
453
454 pub(super) fn set_fs_node(&self, node: &FsNodeHandle) {
455 let mut locked_state = self.state.lock();
456 assert!(locked_state.fs_node.is_none());
457 locked_state.fs_node = Some(node.clone());
458 }
459
460 pub fn get_from_file(file: &FileHandle) -> Result<&SocketHandle, Errno> {
463 let socket_file = file.downcast_file::<SocketFile>().ok_or_else(|| errno!(ENOTSOCK))?;
464 Ok(&socket_file.socket)
465 }
466
467 pub fn downcast_socket<T>(&self) -> Option<&T>
468 where
469 T: 'static,
470 {
471 let ops = &*self.ops;
472 ops.as_any().downcast_ref::<T>()
473 }
474
475 pub fn getsockname(&self) -> Result<SocketAddress, Errno> {
476 self.ops.getsockname(self)
477 }
478
479 pub fn getpeername(&self) -> Result<SocketAddress, Errno> {
480 self.ops.getpeername(self)
481 }
482
483 pub fn setsockopt(
484 &self,
485 current_task: &CurrentTask,
486 level: u32,
487 optname: u32,
488 optval: SockOptValue,
489 ) -> Result<(), Errno> {
490 let read_timeval = || {
491 let timeval = TimeValPtr::read_from_sockopt_value(current_task, &optval)?;
492 let duration = duration_from_timeval(timeval)?;
493 Ok(if duration == zx::MonotonicDuration::default() { None } else { Some(duration) })
494 };
495
496 security::check_socket_setsockopt_access(current_task, self, level, optname)?;
497 match (level, optname) {
498 (SOL_SOCKET, SO_RCVTIMEO) => self.state.lock().receive_timeout = read_timeval()?,
499 (SOL_SOCKET, SO_SNDTIMEO) => self.state.lock().send_timeout = read_timeval()?,
500 _ => self.ops.setsockopt(self, current_task, level, optname, optval)?,
501 }
502 Ok(())
503 }
504
505 pub fn getsockopt(
506 &self,
507 current_task: &CurrentTask,
508 level: u32,
509 optname: u32,
510 optlen: u32,
511 ) -> Result<Vec<u8>, Errno> {
512 security::check_socket_getsockopt_access(current_task, self, level, optname)?;
513 let value = match level {
514 SOL_SOCKET => match optname {
515 SO_TYPE => self.socket_type.as_raw().to_ne_bytes().to_vec(),
516 SO_DOMAIN => {
517 let domain = self.domain.as_raw() as u32;
518 domain.to_ne_bytes().to_vec()
519 }
520 SO_PROTOCOL => self.protocol.as_raw().to_ne_bytes().to_vec(),
521 SO_RCVTIMEO => {
522 let duration = self.receive_timeout().unwrap_or_default();
523 TimeValPtr::into_bytes(current_task, timeval_from_duration(duration))
524 .map_err(|_| errno!(EINVAL))?
525 }
526 SO_SNDTIMEO => {
527 let duration = self.send_timeout().unwrap_or_default();
528 TimeValPtr::into_bytes(current_task, timeval_from_duration(duration))
529 .map_err(|_| errno!(EINVAL))?
530 }
531 SO_ANDROID_DROP_REASON => {
532 track_stub!(
533 TODO("https://fxbug.dev/477273398"),
534 "Faking SO_ANDROID_DROP_REASON"
535 );
536 ANDROID_DROP_REASON_NONE.to_ne_bytes().to_vec()
537 }
538 _ => self.ops.getsockopt(self, current_task, level, optname, optlen)?,
539 },
540 _ => self.ops.getsockopt(self, current_task, level, optname, optlen)?,
541 };
542 Ok(value)
543 }
544
545 pub fn receive_timeout(&self) -> Option<zx::MonotonicDuration> {
546 self.state.lock().receive_timeout
547 }
548
549 pub fn send_timeout(&self) -> Option<zx::MonotonicDuration> {
550 self.state.lock().send_timeout
551 }
552
553 pub fn ioctl(
554 &self,
555 file: &FileObject,
556 current_task: &CurrentTask,
557 request: u32,
558 arg: SyscallArg,
559 ) -> Result<SyscallResult, Errno> {
560 let res = super::netlink_ioctl::netlink_ioctl(current_task, request, arg);
561 match &res {
562 Err(e) if e.code == ENOTTY => {}
563 _ => return res,
564 }
565 self.ops.ioctl(self, file, current_task, request, arg)
566 }
567
568 pub fn bind(
569 &self,
570 current_task: &CurrentTask,
571 socket_address: SocketAddress,
572 ) -> Result<(), Errno> {
573 self.ops.bind(self, current_task, socket_address)
574 }
575
576 pub fn listen(&self, current_task: &CurrentTask, backlog: i32) -> Result<(), Errno> {
577 security::check_socket_listen_access(current_task, self, backlog)?;
578 let max_connections =
579 current_task.kernel().system_limits.socket.max_connections.load(Ordering::Relaxed);
580 let backlog = std::cmp::min(backlog, max_connections);
581 let credentials = current_task.current_ucred();
582 self.ops.listen(self, backlog, credentials)?;
583 self.state.lock().bpf_state = SocketBpfState::Listen;
584 Ok(())
585 }
586
587 pub fn accept(&self, current_task: &CurrentTask) -> Result<SocketHandle, Errno> {
588 let new_socket = self.ops.accept(self, current_task)?;
589 new_socket.state.lock().bpf_state = SocketBpfState::Established;
590 Ok(new_socket)
591 }
592
593 pub fn read(
594 &self,
595 current_task: &CurrentTask,
596 data: &mut dyn OutputBuffer,
597 flags: SocketMessageFlags,
598 ) -> Result<MessageReadInfo, Errno> {
599 security::check_socket_recvmsg_access(current_task, self)?;
600 self.ops.read(self, current_task, data, flags)
601 }
602
603 pub fn write(
604 &self,
605 current_task: &CurrentTask,
606 data: &mut dyn InputBuffer,
607 dest_address: &mut Option<SocketAddress>,
608 ancillary_data: &mut Vec<AncillaryData>,
609 ) -> Result<usize, Errno> {
610 security::check_socket_sendmsg_access(current_task, self)?;
611 self.ops.write(self, current_task, data, dest_address, ancillary_data)
612 }
613
614 pub fn wait_async(
615 &self,
616 current_task: &CurrentTask,
617 waiter: &Waiter,
618 events: FdEvents,
619 handler: EventHandler,
620 ) -> WaitCanceler {
621 self.ops.wait_async(self, current_task, waiter, events, handler)
622 }
623
624 pub fn query_events(&self, current_task: &CurrentTask) -> Result<FdEvents, Errno> {
625 self.ops.query_events(self, current_task)
626 }
627
628 pub fn shutdown(
629 &self,
630 current_task: &CurrentTask,
631 how: SocketShutdownFlags,
632 ) -> Result<(), Errno> {
633 security::check_socket_shutdown_access(current_task, self, how)?;
634 self.ops.shutdown(self, how)
635 }
636
637 pub fn close(&self, current_task: &CurrentTask) {
638 self.state.lock().bpf_state = SocketBpfState::Close;
639 self.ops.close(current_task, self)
640 }
641
642 pub fn to_handle(
643 &self,
644 _file: &FileObject,
645 current_task: &CurrentTask,
646 ) -> Result<Option<zx::NullableHandle>, Errno> {
647 self.ops.to_handle(self, current_task)
648 }
649
650 pub fn fs_node(&self) -> Option<FsNodeHandle> {
654 self.state.lock().fs_node.clone()
655 }
656
657 pub fn bpf_state(&self) -> SocketBpfState {
658 self.state.lock().bpf_state
659 }
660
661 pub fn set_bpf_state(&self, state: SocketBpfState) {
662 self.state.lock().bpf_state = state;
663 }
664}
665
666impl DowncastedFile<'_, SocketFile> {
667 pub fn connect(self, current_task: &CurrentTask, peer: SocketPeer) -> Result<(), Errno> {
668 security::check_socket_connect_access(current_task, self, &peer)?;
669 let res = self.socket.ops.connect(&self.socket, current_task, peer);
670 if res.is_ok() || res == error!(EINPROGRESS) {
671 self.socket.state.lock().bpf_state = SocketBpfState::Established;
672 }
673 res
674 }
675}
676
677pub struct AcceptQueue {
678 pub sockets: VecDeque<SocketHandle>,
679 pub backlog: usize,
680}
681
682impl AcceptQueue {
683 pub fn new(backlog: usize) -> AcceptQueue {
684 AcceptQueue { sockets: VecDeque::with_capacity(backlog), backlog }
685 }
686
687 pub fn set_backlog(&mut self, backlog: usize) -> Result<(), Errno> {
688 if self.sockets.len() > backlog {
689 return error!(EINVAL);
690 }
691 self.backlog = backlog;
692 Ok(())
693 }
694}
695
696#[cfg(test)]
697mod tests {
698 use super::*;
699 use crate::testing::{map_memory, spawn_kernel_and_run};
700 use crate::vfs::{UnixControlData, VecInputBuffer, VecOutputBuffer};
701 use starnix_uapi::SO_PASSCRED;
702 use starnix_uapi::user_address::{UserAddress, UserRef};
703
704 #[fuchsia::test]
705 async fn test_dgram_socket() {
706 spawn_kernel_and_run(async |current_task| {
707 let bind_address = SocketAddress::Unix(b"dgram_test".into());
708 let rec_dgram = Socket::new(
709 ¤t_task,
710 SocketDomain::Unix,
711 SocketType::Datagram,
712 SocketProtocol::default(),
713 false,
714 )
715 .expect("Failed to create socket.");
716 let passcred: u32 = 1;
717 let opt_size = std::mem::size_of::<u32>();
718 let user_address = map_memory(¤t_task, UserAddress::default(), opt_size as u64);
719 let opt_ref = UserRef::<u32>::new(user_address);
720 current_task.write_object(opt_ref, &passcred).unwrap();
721 let opt_buf = UserBuffer { address: user_address, length: opt_size };
722 rec_dgram.setsockopt(¤t_task, SOL_SOCKET, SO_PASSCRED, opt_buf.into()).unwrap();
723
724 rec_dgram.bind(¤t_task, bind_address).expect("failed to bind datagram socket");
725
726 let xfer_value: u64 = 1234567819;
727 let xfer_bytes = xfer_value.to_ne_bytes();
728
729 let send = Socket::new(
730 ¤t_task,
731 SocketDomain::Unix,
732 SocketType::Datagram,
733 SocketProtocol::default(),
734 false,
735 )
736 .expect("Failed to connect socket.");
737 send.ops.connect(&send, ¤t_task, SocketPeer::Handle(rec_dgram.clone())).unwrap();
738 let mut source_iter = VecInputBuffer::new(&xfer_bytes);
739 send.write(¤t_task, &mut source_iter, &mut None, &mut vec![]).unwrap();
740 assert_eq!(source_iter.available(), 0);
741 send.close(¤t_task);
744
745 let mut rec_buffer = VecOutputBuffer::new(8);
746 let read_info = rec_dgram
747 .read(¤t_task, &mut rec_buffer, SocketMessageFlags::empty())
748 .unwrap();
749 assert_eq!(read_info.bytes_read, xfer_bytes.len());
750 assert_eq!(rec_buffer.data(), xfer_bytes);
751 assert_eq!(1, read_info.ancillary_data.len());
752 assert_eq!(
753 read_info.ancillary_data[0],
754 AncillaryData::Unix(UnixControlData::Credentials(uapi::ucred {
755 pid: current_task.get_pid(),
756 uid: 0,
757 gid: 0
758 }))
759 );
760
761 rec_dgram.close(¤t_task);
762 })
763 .await;
764 }
765}