1use crate::bpf::context::EbpfRunContextImpl;
6use crate::bpf::fs::get_bpf_object;
7use crate::mm::MemoryAccessorExt;
8use crate::security;
9use crate::task::{CurrentTask, EventHandler, WaitCanceler, WaitQueue, Waiter};
10use crate::vfs::buffers::{
11 AncillaryData, InputBuffer, MessageQueue, MessageReadInfo, OutputBuffer, PasscredMode,
12 UnixControlData,
13};
14use crate::vfs::socket::{
15 AcceptQueue, DEFAULT_LISTEN_BACKLOG, SockOptValue, Socket, SocketAddress, SocketBpfState,
16 SocketDomain, SocketFile, SocketHandle, SocketMessageFlags, SocketOps, SocketPeer,
17 SocketProtocol, SocketShutdownFlags, SocketType,
18};
19use crate::vfs::{
20 AccessCheck, FdNumber, FileHandle, FileObject, FsNodeHandle, FsStr, LookupContext, Message,
21 UcredPtr,
22};
23use ebpf::{
24 BpfProgramContext, BpfValue, CbpfConfig, DataWidth, EbpfProgram, Packet, ProgramArgument, Type,
25};
26use ebpf_api::{
27 LoadBytesBase, PacketWithLoadBytes, PinnedMap, ProgramType, SOCKET_FILTER_CBPF_CONFIG,
28 SOCKET_FILTER_SK_BUF_TYPE, SocketFilterProgramContext, SocketRef,
29};
30use starnix_logging::track_stub;
31use starnix_sync::{LockDepGuard, LockDepMutex, UnixSocketInnerLock, allow_subclass};
32use starnix_syscalls::{SUCCESS, SyscallArg, SyscallResult};
33use starnix_uapi::errors::{EACCES, ECONNREFUSED, EINTR, EPERM, Errno};
34use starnix_uapi::file_mode::Access;
35use starnix_uapi::open_flags::OpenFlags;
36use starnix_uapi::user_address::{UserAddress, UserRef};
37use starnix_uapi::vfs::FdEvents;
38use starnix_uapi::{
39 __sk_buff, FIONREAD, SO_ACCEPTCONN, SO_ATTACH_BPF, SO_BROADCAST, SO_ERROR, SO_KEEPALIVE,
40 SO_LINGER, SO_NO_CHECK, SO_PASSCRED, SO_PASSSEC, SO_PEERCRED, SO_PEERSEC, SO_RCVBUF,
41 SO_REUSEADDR, SO_REUSEPORT, SO_SNDBUF, SOL_SOCKET, errno, error, gid_t, socklen_t, uapi, ucred,
42 uid_t,
43};
44use std::sync::Arc;
45use zerocopy::IntoBytes;
46
47const SOCKET_MIN_SIZE: usize = 4 << 10;
49const SOCKET_DEFAULT_SIZE: usize = 208 << 10;
50const SOCKET_MAX_SIZE: usize = 4 << 20;
51
52pub struct UnixSocket {
69 inner: LockDepMutex<UnixSocketInner, UnixSocketInnerLock>,
70 waiters: WaitQueue,
71}
72
73fn downcast_socket_to_unix(socket: &Socket) -> &UnixSocket {
74 socket.downcast_socket::<UnixSocket>().unwrap()
79}
80
81enum UnixSocketState {
82 Disconnected,
84
85 Listening(AcceptQueue),
87
88 Connected(SocketHandle),
90
91 Closed,
93}
94
95struct UnixSocketInner {
96 messages: MessageQueue,
98
99 address: Option<SocketAddress>,
101
102 fs_node: Option<FsNodeHandle>,
109
110 is_read_shutdown: bool,
113
114 is_write_shutdown: bool,
116
117 peer_closed_with_unread_data: bool,
120
121 linger: uapi::linger,
123
124 passcred: PasscredMode,
126
127 passsec: bool,
129
130 broadcast: bool,
132
133 no_check: bool,
135
136 reuseport: bool,
138
139 reuseaddr: bool,
141
142 keepalive: bool,
144
145 bpf_program: Option<UnixSocketFilter>,
147
148 credentials: Option<ucred>,
151
152 state: UnixSocketState,
155}
156
157impl UnixSocket {
158 pub fn new(_socket_type: SocketType) -> UnixSocket {
159 UnixSocket {
160 inner: UnixSocketInner {
161 messages: MessageQueue::new(SOCKET_DEFAULT_SIZE),
162 address: None,
163 fs_node: None,
164 is_read_shutdown: false,
165 is_write_shutdown: false,
166 peer_closed_with_unread_data: false,
167 linger: uapi::linger::default(),
168 passcred: PasscredMode::Disabled,
169 passsec: false,
170 broadcast: false,
171 no_check: false,
172 reuseaddr: false,
173 reuseport: false,
174 keepalive: false,
175 bpf_program: None,
176 credentials: None,
177 state: UnixSocketState::Disconnected,
178 }
179 .into(),
180 waiters: WaitQueue::default(),
181 }
182 }
183
184 pub fn new_pair(
190 current_task: &CurrentTask,
191 domain: SocketDomain,
192 socket_type: SocketType,
193 open_flags: OpenFlags,
194 ) -> Result<(FileHandle, FileHandle), Errno> {
195 let credentials = current_task.current_ucred();
196 let left = Socket::new(
197 current_task,
198 domain,
199 socket_type,
200 SocketProtocol::default(),
201 false,
202 )?;
203 let right = Socket::new(
204 current_task,
205 domain,
206 socket_type,
207 SocketProtocol::default(),
208 false,
209 )?;
210 downcast_socket_to_unix(&left).lock().state = UnixSocketState::Connected(right.clone());
211 downcast_socket_to_unix(&left).lock().credentials = Some(credentials.clone());
212 downcast_socket_to_unix(&right).lock().state = UnixSocketState::Connected(left.clone());
213 downcast_socket_to_unix(&right).lock().credentials = Some(credentials);
214 left.set_bpf_state(SocketBpfState::Established);
215 right.set_bpf_state(SocketBpfState::Established);
216 let left = SocketFile::from_socket(
217 current_task,
218 left,
219 open_flags,
220 false,
221 )?;
222 let right = SocketFile::from_socket(
223 current_task,
224 right,
225 open_flags,
226 false,
227 )?;
228 let left_socket = SocketFile::get_from_file(&left)?;
229 let right_socket = SocketFile::get_from_file(&right)?;
230
231 security::socket_socketpair(current_task, left_socket, right_socket)?;
232 Ok((left, right))
233 }
234
235 fn connect_stream(
236 &self,
237 socket: &SocketHandle,
238 current_task: &CurrentTask,
239 peer: &SocketHandle,
240 ) -> Result<(), Errno> {
241 match downcast_socket_to_unix(peer).lock().state {
244 UnixSocketState::Listening(_) => {}
245 _ => return error!(ECONNREFUSED),
246 }
247
248 let mut client = downcast_socket_to_unix(socket).lock();
249 match client.state {
250 UnixSocketState::Disconnected => {}
251 UnixSocketState::Connected(_) => return error!(EISCONN),
252 _ => return error!(EINVAL),
253 };
254
255 let unix_socket_peer = downcast_socket_to_unix(peer);
256 {
257 let _token = allow_subclass();
259 let mut listener = unix_socket_peer.lock();
260
261 let queue = match &listener.state {
263 UnixSocketState::Listening(queue) => queue,
264 _ => return error!(ECONNREFUSED),
265 };
266
267 self.check_type_for_connect(socket, peer, &listener.address)?;
268
269 if queue.sockets.len() > queue.backlog {
270 return error!(EAGAIN);
271 }
272
273 let server = Socket::new(
274 current_task,
275 peer.domain,
276 peer.socket_type,
277 SocketProtocol::default(),
278 true,
279 )?;
280 security::unix_stream_connect(current_task, socket, peer, &server)?;
281 client.state = UnixSocketState::Connected(server.clone());
282 client.credentials = listener.credentials.clone();
283 {
284 let _token = allow_subclass();
288 let mut server = downcast_socket_to_unix(&server).lock();
289 server.state = UnixSocketState::Connected(socket.clone());
290 server.address = listener.address.clone();
291 server.messages.set_capacity(listener.messages.capacity())?;
292 server.credentials = Some(current_task.current_ucred());
293 server.passcred = listener.passcred;
294 server.passsec = listener.passsec;
295 }
296
297 let queue = match listener.state {
300 UnixSocketState::Listening(ref mut queue) => queue,
301 _ => panic!("something changed the server socket state while I held a lock on it"),
302 };
303 queue.sockets.push_back(server);
304 }
305 unix_socket_peer.waiters.notify_fd_events(FdEvents::POLLIN);
306 Ok(())
307 }
308
309 fn connect_datagram(
310 &self,
311 socket: &SocketHandle,
312 current_task: &CurrentTask,
313 peer: &SocketHandle,
314 ) -> Result<(), Errno> {
315 {
316 let unix_socket = socket.downcast_socket::<UnixSocket>().unwrap();
317 let peer_inner = unix_socket.lock();
318 self.check_type_for_connect(socket, peer, &peer_inner.address)?;
319 }
320 security::unix_may_send(current_task, socket, peer)?;
321 let unix_socket = socket.downcast_socket::<UnixSocket>().unwrap();
322 unix_socket.lock().state = UnixSocketState::Connected(peer.clone());
323 Ok(())
324 }
325
326 pub fn check_type_for_connect(
327 &self,
328 socket: &Socket,
329 peer: &Socket,
330 peer_address: &Option<SocketAddress>,
331 ) -> Result<(), Errno> {
332 if socket.domain != peer.domain || socket.socket_type != peer.socket_type {
333 if let Some(address) = peer_address {
336 if address.is_abstract_unix() {
337 return error!(ECONNREFUSED);
338 }
339 }
340 return error!(EPROTOTYPE);
341 }
342 Ok(())
343 }
344
345 fn lock(&self) -> LockDepGuard<'_, UnixSocketInner> {
347 self.inner.lock()
348 }
349
350 fn is_listening(&self, _socket: &Socket) -> bool {
351 matches!(self.lock().state, UnixSocketState::Listening(_))
352 }
353
354 fn get_receive_capacity(&self) -> usize {
355 self.lock().messages.capacity()
356 }
357
358 fn set_receive_capacity(&self, requested_capacity: usize) {
359 self.lock().set_capacity(requested_capacity);
360 }
361
362 fn get_send_capacity(&self) -> usize {
363 let peer = {
364 if let Some(peer) = self.lock().peer() {
365 peer.clone()
366 } else {
367 return 0;
368 }
369 };
370 let unix_socket = downcast_socket_to_unix(&peer);
371 let capacity = unix_socket.lock().messages.capacity();
372 capacity
373 }
374
375 fn set_send_capacity(&self, requested_capacity: usize) {
376 let peer = {
377 if let Some(peer) = self.lock().peer() {
378 peer.clone()
379 } else {
380 return;
381 }
382 };
383 let unix_socket = downcast_socket_to_unix(&peer);
384 unix_socket.lock().set_capacity(requested_capacity);
385 }
386
387 fn get_linger(&self) -> uapi::linger {
388 let inner = self.lock();
389 inner.linger
390 }
391
392 fn set_linger(&self, linger: uapi::linger) {
393 let mut inner = self.lock();
394 inner.linger = linger;
395 }
396
397 fn get_passcred(&self) -> PasscredMode {
398 let inner = self.lock();
399 inner.passcred
400 }
401
402 fn set_passcred(&self, passcred: PasscredMode) {
403 let mut inner = self.lock();
404 inner.passcred = passcred;
405 }
406
407 fn get_passsec(&self) -> bool {
408 let inner = self.lock();
409 inner.passsec
410 }
411
412 fn set_passsec(&self, passsec: bool) {
413 let mut inner = self.lock();
414 inner.passsec = passsec;
415 }
416
417 fn get_broadcast(&self) -> bool {
418 let inner = self.lock();
419 inner.broadcast
420 }
421
422 fn set_broadcast(&self, broadcast: bool) {
423 let mut inner = self.lock();
424 inner.broadcast = broadcast;
425 }
426
427 fn get_no_check(&self) -> bool {
428 let inner = self.lock();
429 inner.no_check
430 }
431
432 fn set_no_check(&self, no_check: bool) {
433 let mut inner = self.lock();
434 inner.no_check = no_check;
435 }
436
437 fn get_reuseaddr(&self) -> bool {
438 let inner = self.lock();
439 inner.reuseaddr
440 }
441
442 fn set_reuseaddr(&self, reuseaddr: bool) {
443 let mut inner = self.lock();
444 inner.reuseaddr = reuseaddr;
445 }
446
447 fn get_reuseport(&self) -> bool {
448 let inner = self.lock();
449 inner.reuseport
450 }
451
452 fn set_reuseport(&self, reuseport: bool) {
453 let mut inner = self.lock();
454 inner.reuseport = reuseport;
455 }
456
457 fn get_keepalive(&self) -> bool {
458 let inner = self.lock();
459 inner.keepalive
460 }
461
462 fn set_keepalive(&self, keepalive: bool) {
463 let mut inner = self.lock();
464 inner.keepalive = keepalive;
465 }
466
467 fn set_bpf_program(&self, program: Option<UnixSocketFilter>) {
468 let mut inner = self.lock();
469 inner.bpf_program = program;
470 }
471
472 fn peer_cred(&self) -> Option<ucred> {
473 self.lock().credentials.clone()
474 }
475
476 pub fn bind_socket_to_node(
477 &self,
478 socket: &SocketHandle,
479 address: SocketAddress,
480 node: &FsNodeHandle,
481 ) -> Result<(), Errno> {
482 let unix_socket = downcast_socket_to_unix(socket);
483 let mut inner = unix_socket.lock();
484 inner.bind(address)?;
485 inner.fs_node = Some(node.clone());
486 node.set_bound_socket(socket.clone());
487 Ok(())
488 }
489
490 fn notify_shutdown(&self) {
491 self.waiters.notify_fd_events(FdEvents::POLLIN | FdEvents::POLLOUT | FdEvents::POLLHUP);
492 }
493}
494
495impl SocketOps for UnixSocket {
496 fn connect(
497 &self,
498 socket: &SocketHandle,
499 current_task: &CurrentTask,
500 peer: SocketPeer,
501 ) -> Result<(), Errno> {
502 let peer = match peer {
503 SocketPeer::Handle(handle) => handle,
504 SocketPeer::Address(SocketAddress::Unspecified) => {
505 if socket.socket_type == SocketType::Datagram {
506 let unix_socket = socket.downcast_socket::<UnixSocket>().unwrap();
507 unix_socket.lock().state = UnixSocketState::Disconnected;
508 return Ok(());
509 }
510 return error!(EINVAL);
511 }
512 SocketPeer::Address(_) => return error!(EINVAL),
513 };
514 match socket.socket_type {
515 SocketType::Stream | SocketType::SeqPacket => {
516 self.connect_stream(socket, current_task, &peer)
517 }
518 SocketType::Datagram | SocketType::Raw => {
519 self.connect_datagram(socket, current_task, &peer)
520 }
521 _ => error!(EINVAL),
522 }
523 }
524
525 fn listen(&self, socket: &Socket, backlog: i32, credentials: ucred) -> Result<(), Errno> {
526 match socket.socket_type {
527 SocketType::Stream | SocketType::SeqPacket => {}
528 _ => return error!(EOPNOTSUPP),
529 }
530 let mut inner = self.lock();
531 let is_bound = inner.address.is_some();
532 let backlog = if backlog < 0 { DEFAULT_LISTEN_BACKLOG } else { backlog as usize };
533 match &mut inner.state {
534 UnixSocketState::Disconnected if is_bound => {
535 inner.state = UnixSocketState::Listening(AcceptQueue::new(backlog));
536 }
537 UnixSocketState::Listening(queue) => {
538 queue.set_backlog(backlog)?;
539 }
540 _ => return error!(EINVAL),
541 }
542 inner.credentials = Some(credentials);
543 Ok(())
544 }
545
546 fn accept(&self, socket: &Socket, _current_task: &CurrentTask) -> Result<SocketHandle, Errno> {
547 match socket.socket_type {
548 SocketType::Stream | SocketType::SeqPacket => {}
549 _ => return error!(EOPNOTSUPP),
550 }
551 let mut inner = self.lock();
552 let queue = match &mut inner.state {
553 UnixSocketState::Listening(queue) => queue,
554 _ => return error!(EINVAL),
555 };
556 queue.sockets.pop_front().ok_or_else(|| errno!(EAGAIN))
557 }
558
559 fn bind(
560 &self,
561 _socket: &Socket,
562 _current_task: &CurrentTask,
563 socket_address: SocketAddress,
564 ) -> Result<(), Errno> {
565 match socket_address {
566 SocketAddress::Unix(_) => {}
567 _ => return error!(EINVAL),
568 }
569 self.lock().bind(socket_address)
570 }
571
572 fn read(
573 &self,
574 socket: &Socket,
575 current_task: &CurrentTask,
576 data: &mut dyn OutputBuffer,
577 flags: SocketMessageFlags,
578 ) -> Result<MessageReadInfo, Errno> {
579 let mut info = MessageReadInfo::default();
580 self.read_and_append(socket, current_task, &mut info, data, flags)?;
581 Ok(info)
582 }
583
584 fn read_and_append(
585 &self,
586 socket: &Socket,
587 _current_task: &CurrentTask,
588 read_info: &mut MessageReadInfo,
589 data: &mut dyn OutputBuffer,
590 flags: SocketMessageFlags,
591 ) -> Result<bool, Errno> {
592 let bytes_read_before = read_info.bytes_read;
593 let (can_coalesce, peer) = {
594 let mut inner = self.lock();
595 let can_coalesce = inner.read_and_append(read_info, data, socket.socket_type, flags)?;
596 let peer =
597 (read_info.bytes_read > bytes_read_before).then(|| inner.peer().cloned()).flatten();
598 (can_coalesce, peer)
599 };
600 if let Some(socket) = peer {
601 if let Some(socket) = socket.downcast_socket::<UnixSocket>() {
602 socket.waiters.notify_fd_events(FdEvents::POLLOUT);
603 }
604 }
605 Ok(can_coalesce)
606 }
607
608 fn write(
609 &self,
610 socket: &Socket,
611 current_task: &CurrentTask,
612 data: &mut dyn InputBuffer,
613 dest_address: &mut Option<SocketAddress>,
614 ancillary_data: &mut Vec<AncillaryData>,
615 ) -> Result<usize, Errno> {
616 let (connected_peer, local_address, local_passcred, is_write_shutdown) = {
617 let inner = self.lock();
618 (
619 inner.peer().map(|p| p.clone()),
620 inner.address.clone(),
621 inner.passcred,
622 inner.is_write_shutdown,
623 )
624 };
625
626 if is_write_shutdown {
627 return error!(EPIPE);
628 }
629
630 let peer = match (connected_peer, dest_address, socket.socket_type) {
631 (Some(peer), None, _) => peer,
632 (Some(peer), Some(_), SocketType::SeqPacket) => peer,
633 (None, Some(_), SocketType::Stream) => return error!(EOPNOTSUPP),
634 (None, Some(_), SocketType::SeqPacket) => return error!(ENOTCONN),
635 (Some(_), Some(_), _) => return error!(EISCONN),
636 (_, Some(SocketAddress::Unix(name)), _) => {
637 resolve_unix_socket_address(current_task, name.as_ref())?
638 }
639 (_, Some(_), _) => return error!(EINVAL),
640 (None, None, _) => return error!(ENOTCONN),
641 };
642
643 let dgram_security_context = if socket.socket_type == SocketType::Datagram {
644 security::unix_may_send(current_task, socket, &peer)?;
645 Some(security::socket_getpeersec_dgram(current_task, socket))
648 } else {
649 None
650 };
651
652 let peer_unaccepted = peer.fs_node().is_none();
653 let unix_socket = downcast_socket_to_unix(&peer);
654 let write_result = {
655 let mut peer = unix_socket.lock();
656 let default_creds =
657 (local_passcred.is_enabled() || peer.passcred.is_enabled() || peer_unaccepted)
658 .then(|| current_task.current_ucred());
659 peer.write(
660 current_task,
661 data,
662 local_address,
663 default_creds,
664 dgram_security_context,
665 ancillary_data,
666 socket,
667 )
668 };
669
670 if let Err(ref err) = write_result {
671 if err.code == ECONNREFUSED && socket.socket_type == SocketType::Datagram {
672 let mut inner = self.lock();
673 if let UnixSocketState::Connected(ref connected_peer) = inner.state {
674 if Arc::ptr_eq(connected_peer, &peer) {
675 inner.state = UnixSocketState::Disconnected;
676 self.waiters.notify_fd_events(FdEvents::POLLOUT | FdEvents::POLLHUP);
677 }
678 }
679 }
680 }
681
682 let bytes_written = write_result?;
683 if bytes_written > 0 {
684 unix_socket.waiters.notify_fd_events(FdEvents::POLLIN);
685 }
686 Ok(bytes_written)
687 }
688
689 fn wait_async(
690 &self,
691 _socket: &Socket,
692 _current_task: &CurrentTask,
693 waiter: &Waiter,
694 events: FdEvents,
695 handler: EventHandler,
696 ) -> WaitCanceler {
697 self.waiters.wait_async_fd_events(waiter, events, handler)
698 }
699
700 fn query_events(
701 &self,
702 socket: &Socket,
703 _current_task: &CurrentTask,
704 ) -> Result<FdEvents, Errno> {
705 let (
708 mut events,
709 peer,
710 local_is_read_shutdown,
711 local_is_write_shutdown,
712 is_closed,
713 is_disconnected,
714 ) = {
715 let inner = self.lock();
716
717 let mut events = FdEvents::empty();
718 let local_events = inner.messages.query_events();
719 if local_events.contains(FdEvents::POLLIN) {
720 events |= FdEvents::POLLIN;
721 }
722
723 if let UnixSocketState::Listening(queue) = &inner.state {
725 if !queue.sockets.is_empty() {
726 events |= FdEvents::POLLIN;
727 }
728 }
729
730 (
731 events,
732 inner.peer().cloned(),
733 inner.is_read_shutdown,
734 inner.is_write_shutdown,
735 matches!(inner.state, UnixSocketState::Closed),
736 matches!(inner.state, UnixSocketState::Disconnected),
737 )
738 };
739
740 let connection_oriented = socket.socket_type.is_connection_oriented();
741
742 let mut read_dead = local_is_read_shutdown || is_closed;
743 let mut write_dead = local_is_write_shutdown || is_closed;
744 let mut force_pollout = is_closed || is_disconnected;
745 let mut force_pollhup = false;
746
747 if connection_oriented && is_disconnected {
748 force_pollhup = true;
749 write_dead = true;
750 }
751
752 if let Some(peer) = peer {
753 let unix_socket = downcast_socket_to_unix(&peer);
754 let peer_inner = unix_socket.lock();
755
756 if peer_inner.is_read_shutdown {
757 write_dead = true;
758 }
759 if matches!(peer_inner.state, UnixSocketState::Closed) {
760 read_dead = true;
761 write_dead = true;
762 force_pollout = true;
763 }
764
765 let peer_events = peer_inner.messages.query_events();
766 if peer_events.contains(FdEvents::POLLOUT) {
767 events |= FdEvents::POLLOUT;
768 }
769 }
770
771 if force_pollout {
772 events |= FdEvents::POLLOUT;
773 }
774
775 if read_dead {
776 events |= FdEvents::POLLIN | FdEvents::POLLRDHUP;
777 }
778 if (read_dead && write_dead) || force_pollhup {
779 events |= FdEvents::POLLHUP;
780 }
781
782 Ok(events)
783 }
784
785 fn shutdown(&self, socket: &Socket, how: SocketShutdownFlags) -> Result<(), Errno> {
790 let (peer, self_notify_events) = {
793 let mut inner = self.lock();
794 let events = inner.shutdown(how);
795 (inner.peer().cloned(), events)
796 };
797 let mut peer_notify_events = FdEvents::empty();
798 if let Some(peer) = &peer {
799 if socket.socket_type.is_connection_oriented() {
800 let mut peer_how = SocketShutdownFlags::empty();
809 if how.contains(SocketShutdownFlags::WRITE) {
810 peer_how |= SocketShutdownFlags::READ;
811 }
812 if how.contains(SocketShutdownFlags::READ) {
813 peer_how |= SocketShutdownFlags::WRITE;
814 }
815 let peer_socket = downcast_socket_to_unix(peer);
816 peer_notify_events = peer_socket.lock().shutdown(peer_how);
817 }
818 }
819 if !self_notify_events.is_empty() {
820 self.waiters.notify_fd_events(self_notify_events);
821 }
822 if !peer_notify_events.is_empty() {
823 if let Some(peer) = &peer {
824 let peer_socket = downcast_socket_to_unix(peer);
825 peer_socket.waiters.notify_fd_events(peer_notify_events);
826 }
827 }
828 Ok(())
829 }
830
831 fn close(&self, _current_task: &CurrentTask, socket: &Socket) {
843 let (maybe_peer, has_unread, _maybe_fs_node) = {
845 let mut inner = self.lock();
846 let maybe_peer = inner.peer().map(Arc::clone);
847 inner.is_read_shutdown = true;
848 inner.state = UnixSocketState::Closed;
849 (maybe_peer, !inner.messages.is_empty(), inner.fs_node.take())
850 };
851 self.notify_shutdown();
852 if socket.socket_type.is_connection_oriented() {
854 if let Some(peer) = maybe_peer {
855 let unix_socket = downcast_socket_to_unix(&peer);
856
857 {
858 let mut peer_inner = unix_socket.lock();
859 if has_unread {
860 peer_inner.peer_closed_with_unread_data = true;
861 }
862 peer_inner.is_read_shutdown = true;
863 }
864 unix_socket.notify_shutdown();
865 }
866 }
867 }
868
869 fn getsockname(&self, socket: &Socket) -> Result<SocketAddress, Errno> {
874 let inner = self.lock();
875 if let Some(address) = &inner.address {
876 Ok(address.clone())
877 } else {
878 Ok(SocketAddress::default_for_domain(socket.domain))
879 }
880 }
881
882 fn getpeername(&self, _socket: &Socket) -> Result<SocketAddress, Errno> {
886 let peer = self.lock().peer().ok_or_else(|| errno!(ENOTCONN))?.clone();
887 peer.getsockname()
888 }
889
890 fn setsockopt(
891 &self,
892 _socket: &Socket,
893 current_task: &CurrentTask,
894 level: u32,
895 optname: u32,
896 optval: SockOptValue,
897 ) -> Result<(), Errno> {
898 match level {
899 SOL_SOCKET => match optname {
900 SO_SNDBUF => {
901 let requested_capacity: socklen_t = optval.read(current_task)?;
902 self.set_send_capacity(requested_capacity as usize * 2);
904 }
905 SO_RCVBUF => {
906 let requested_capacity: socklen_t = optval.read(current_task)?;
907 self.set_receive_capacity(requested_capacity as usize);
908 }
909 SO_LINGER => {
910 let mut linger: uapi::linger = optval.read(current_task)?;
911 if linger.l_onoff != 0 {
912 linger.l_onoff = 1;
913 }
914 self.set_linger(linger);
915 }
916 SO_PASSCRED => {
917 let passcred: u32 = optval.read(current_task)?;
918 self.set_passcred(PasscredMode::from(passcred != 0));
919 }
920 SO_PASSSEC => {
921 let passsec: u32 = optval.read(current_task)?;
922 self.set_passsec(passsec != 0);
923 }
924 SO_BROADCAST => {
925 let broadcast: u32 = optval.read(current_task)?;
926 self.set_broadcast(broadcast != 0);
927 }
928 SO_NO_CHECK => {
929 let no_check: u32 = optval.read(current_task)?;
930 self.set_no_check(no_check != 0);
931 }
932 SO_REUSEADDR => {
933 let reuseaddr: u32 = optval.read(current_task)?;
934 self.set_reuseaddr(reuseaddr != 0);
935 }
936 SO_REUSEPORT => {
937 let reuseport: u32 = optval.read(current_task)?;
938 self.set_reuseport(reuseport != 0);
939 }
940 SO_KEEPALIVE => {
941 let keepalive: u32 = optval.read(current_task)?;
942 self.set_keepalive(keepalive != 0);
943 }
944 SO_ATTACH_BPF => {
945 let fd: FdNumber = optval.read(current_task)?;
946 let object = get_bpf_object(current_task, fd)?;
947 let program = object.as_program()?;
948
949 let linked_program = program.link(ProgramType::SocketFilter)?;
950
951 self.set_bpf_program(Some(linked_program));
952 }
953 _ => return error!(ENOPROTOOPT),
954 },
955 _ => return error!(ENOPROTOOPT),
956 }
957 Ok(())
958 }
959
960 fn getsockopt(
961 &self,
962 socket: &Socket,
963 current_task: &CurrentTask,
964 level: u32,
965 optname: u32,
966 _optlen: u32,
967 ) -> Result<Vec<u8>, Errno> {
968 match level {
969 SOL_SOCKET => match optname {
970 SO_PEERCRED => Ok(UcredPtr::into_bytes(
971 current_task,
972 self.peer_cred().unwrap_or(ucred { pid: 0, uid: uid_t::MAX, gid: gid_t::MAX }),
973 )
974 .map_err(|_| errno!(EINVAL))?),
975 SO_PEERSEC => match socket.socket_type {
976 SocketType::Stream => security::socket_getpeersec_stream(current_task, socket),
977 _ => error!(ENOPROTOOPT),
978 },
979 SO_ACCEPTCONN =>
980 {
981 #[allow(clippy::bool_to_int_with_if)]
982 Ok(if self.is_listening(socket) { 1u32 } else { 0u32 }.to_ne_bytes().to_vec())
983 }
984 SO_SNDBUF => Ok((self.get_send_capacity() as socklen_t).to_ne_bytes().to_vec()),
985 SO_RCVBUF => Ok((self.get_receive_capacity() as socklen_t).to_ne_bytes().to_vec()),
986 SO_LINGER => Ok(self.get_linger().as_bytes().to_vec()),
987 SO_PASSCRED => Ok((self.get_passcred().is_enabled() as u32).as_bytes().to_vec()),
988 SO_PASSSEC => Ok((self.get_passsec() as u32).as_bytes().to_vec()),
989 SO_BROADCAST => Ok((self.get_broadcast() as u32).as_bytes().to_vec()),
990 SO_NO_CHECK => Ok((self.get_no_check() as u32).as_bytes().to_vec()),
991 SO_REUSEADDR => Ok((self.get_reuseaddr() as u32).as_bytes().to_vec()),
992 SO_REUSEPORT => Ok((self.get_reuseport() as u32).as_bytes().to_vec()),
993 SO_KEEPALIVE => Ok((self.get_keepalive() as u32).as_bytes().to_vec()),
994 SO_ERROR => Ok((0u32).as_bytes().to_vec()),
995 _ => error!(ENOPROTOOPT),
996 },
997 _ => error!(ENOPROTOOPT),
998 }
999 }
1000
1001 fn ioctl(
1002 &self,
1003 socket: &Socket,
1004 _file: &FileObject,
1005 current_task: &CurrentTask,
1006 request: u32,
1007 arg: SyscallArg,
1008 ) -> Result<SyscallResult, Errno> {
1009 let user_addr = UserAddress::from(arg);
1010 match request {
1011 FIONREAD if socket.socket_type == SocketType::Stream => {
1012 let length: i32 =
1013 self.lock().messages.len().try_into().map_err(|_| errno!(EINVAL))?;
1014 current_task.write_object(UserRef::<i32>::new(user_addr), &length)?;
1015 Ok(SUCCESS)
1016 }
1017 _ => error!(ENOTTY),
1018 }
1019 }
1020}
1021
1022impl UnixSocketInner {
1023 fn bind(&mut self, socket_address: SocketAddress) -> Result<(), Errno> {
1024 if self.address.is_some() {
1025 return error!(EINVAL);
1026 }
1027 self.address = Some(socket_address);
1028 Ok(())
1029 }
1030
1031 fn shutdown(&mut self, how: SocketShutdownFlags) -> FdEvents {
1048 let mut notify_events = FdEvents::empty();
1049 if how.contains(SocketShutdownFlags::READ) {
1050 self.is_read_shutdown = true;
1051 notify_events |= FdEvents::POLLIN | FdEvents::POLLRDHUP;
1052 }
1053 if how.contains(SocketShutdownFlags::WRITE) {
1054 self.is_write_shutdown = true;
1055 notify_events |= FdEvents::POLLOUT;
1056 }
1057 if self.is_read_shutdown && self.is_write_shutdown {
1058 notify_events |= FdEvents::POLLHUP;
1059 }
1060 notify_events
1061 }
1062
1063 fn set_capacity(&mut self, requested_capacity: usize) {
1064 let capacity = requested_capacity.clamp(SOCKET_MIN_SIZE, SOCKET_MAX_SIZE);
1065 let capacity = std::cmp::max(capacity, self.messages.len());
1066 self.messages.set_capacity(capacity).unwrap();
1068 }
1069
1070 fn peer(&self) -> Option<&SocketHandle> {
1073 match &self.state {
1074 UnixSocketState::Connected(peer) => Some(peer),
1075 _ => None,
1076 }
1077 }
1078
1079 fn read(
1090 &mut self,
1091 data: &mut dyn OutputBuffer,
1092 socket_type: SocketType,
1093 flags: SocketMessageFlags,
1094 ) -> Result<MessageReadInfo, Errno> {
1095 let (mut info, has_message) = if socket_type == SocketType::Stream {
1096 if flags.contains(SocketMessageFlags::PEEK) {
1097 self.messages.peek_stream(data, self.passcred)?
1098 } else {
1099 self.messages.read_stream_with_passcred(data, self.passcred)?
1100 }
1101 } else if flags.contains(SocketMessageFlags::PEEK) {
1102 self.messages.peek_datagram(data)?
1103 } else {
1104 self.messages.read_datagram(data)?
1105 };
1106 if !has_message {
1107 if self.peer_closed_with_unread_data {
1108 self.peer_closed_with_unread_data = false;
1110 return error!(ECONNRESET);
1111 }
1112 if !self.is_read_shutdown {
1113 return error!(EAGAIN);
1114 }
1115 }
1116
1117 if self.passcred.is_enabled() {
1118 let creds = info.credentials.unwrap_or_else(UnixControlData::unknown_ucred);
1119 info.credentials = Some(creds);
1120 info.ancillary_data.insert(0, AncillaryData::Unix(UnixControlData::Credentials(creds)));
1122 } else {
1123 info.credentials = None;
1124 }
1125
1126 if !self.passsec {
1128 info.ancillary_data
1129 .retain(|m| !matches!(m, AncillaryData::Unix(UnixControlData::Security(..))));
1130 }
1131
1132 Ok(info)
1133 }
1134
1135 fn read_and_append(
1136 &mut self,
1137 read_info: &mut MessageReadInfo,
1138 data: &mut dyn OutputBuffer,
1139 socket_type: SocketType,
1140 flags: SocketMessageFlags,
1141 ) -> Result<bool, Errno> {
1142 if socket_type == SocketType::Stream
1143 && !self.messages.can_coalesce_with(read_info, self.passcred)
1144 {
1145 return Ok(false);
1146 }
1147 let mut info = self.read(data, socket_type, flags)?;
1148 let bytes_read = info.bytes_read;
1149 read_info.append(&mut info);
1150 if socket_type != SocketType::Stream || bytes_read == 0 {
1151 return Ok(false);
1152 }
1153 Ok(self.messages.can_coalesce_with(read_info, self.passcred))
1154 }
1155
1156 fn write(
1165 &mut self,
1166 current_task: &CurrentTask,
1167 data: &mut dyn InputBuffer,
1168 address: Option<SocketAddress>,
1169 default_credentials: Option<ucred>,
1170 dgram_security_context: Option<Vec<u8>>,
1171 ancillary_data: &mut Vec<AncillaryData>,
1172 socket: &Socket,
1173 ) -> Result<usize, Errno> {
1174 if matches!(self.state, UnixSocketState::Closed) {
1175 if !socket.socket_type.is_connection_oriented() {
1176 return error!(ECONNREFUSED);
1177 } else {
1178 return error!(EPIPE);
1179 }
1180 }
1181 if self.is_read_shutdown {
1182 return error!(EPIPE);
1183 }
1184 let filter = |mut message: Message| {
1185 if let Some(context) = dgram_security_context {
1186 message
1187 .ancillary_data
1188 .push(AncillaryData::Unix(UnixControlData::Security(context.into())));
1189 }
1190 let Some(bpf_program) = self.bpf_program.as_ref() else {
1191 return Some(message);
1192 };
1193
1194 let mut sk_buf = SkBuf::default();
1196
1197 let mut context = EbpfRunContextImpl::<'_>::new(current_task);
1198 let s = bpf_program.run(&mut context, &mut sk_buf);
1199 if s == 0 {
1200 None
1201 } else {
1202 message.truncate(s as usize);
1203 Some(message)
1204 }
1205 };
1206 let bytes_written = if socket.socket_type == SocketType::Stream {
1207 self.messages.write_stream_with_filter(
1208 data,
1209 address,
1210 default_credentials,
1211 ancillary_data,
1212 filter,
1213 )?
1214 } else {
1215 self.messages.write_datagram_with_filter(
1216 data,
1217 address,
1218 default_credentials,
1219 ancillary_data,
1220 filter,
1221 )?
1222 };
1223 Ok(bytes_written)
1224 }
1225}
1226
1227pub fn resolve_unix_socket_address(
1228 current_task: &CurrentTask,
1229 name: &FsStr,
1230) -> Result<SocketHandle, Errno> {
1231 if name[0] == b'\0' {
1232 current_task.running_state().abstract_socket_namespace.lookup(name)
1233 } else {
1234 let mut context = LookupContext::default();
1235 let (parent, basename) =
1236 current_task.lookup_parent_at(&mut context, FdNumber::AT_FDCWD, name)?;
1237 let name = parent.lookup_child(current_task, &mut context, basename).map_err(|errno| {
1238 if matches!(errno.code, EACCES | EPERM | EINTR) { errno } else { errno!(ECONNREFUSED) }
1239 })?;
1240 name.check_access(current_task, AccessCheck::for_internal(Access::WRITE))?;
1241 name.entry.node.bound_socket().map(|s| s.clone()).ok_or_else(|| errno!(ECONNREFUSED))
1242 }
1243}
1244
1245#[repr(C)]
1247#[derive(Default)]
1248struct SkBuf {
1249 sk_buff: __sk_buff,
1250}
1251
1252impl Packet for &mut SkBuf {
1253 fn load(&self, _offset: i32, _width: DataWidth) -> Option<BpfValue> {
1254 None
1256 }
1257}
1258
1259impl<'a> PacketWithLoadBytes for &'a mut SkBuf {
1260 fn load_bytes_relative(
1261 &self,
1262 _base: LoadBytesBase,
1263 _offset: usize,
1264 _buf: ebpf::EbpfBufferPtr<'_>,
1265 ) -> i64 {
1266 track_stub!(TODO("https://fxbug.dev/385015056"), "bpf_load_bytes_relative");
1267 -1
1268 }
1269}
1270
1271impl ProgramArgument for &'_ mut SkBuf {
1272 fn get_type() -> &'static Type {
1273 &*SOCKET_FILTER_SK_BUF_TYPE
1274 }
1275}
1276
1277impl SocketRef for &'_ mut SkBuf {
1278 fn get_socket_cookie(&self) -> Option<u64> {
1279 track_stub!(TODO("https://fxbug.dev/385015056"), "bpf_get_socket_cookie");
1280 None
1281 }
1282
1283 fn get_socket_uid(&self) -> Option<uid_t> {
1284 track_stub!(TODO("https://fxbug.dev/385015056"), "bpf_get_socket_uid");
1285 None
1286 }
1287}
1288
1289struct UnixSocketEbpfContext {}
1290impl BpfProgramContext for UnixSocketEbpfContext {
1291 type RunContext<'a> = EbpfRunContextImpl<'a>;
1292 type Packet<'a> = &'a mut SkBuf;
1293 type Map = PinnedMap;
1294 const CBPF_CONFIG: &'static CbpfConfig = &SOCKET_FILTER_CBPF_CONFIG;
1295}
1296
1297ebpf_api::ebpf_program_context_type!(UnixSocketEbpfContext, SocketFilterProgramContext);
1298
1299type UnixSocketFilter = EbpfProgram<UnixSocketEbpfContext>;
1300
1301#[cfg(test)]
1302mod tests {
1303 use super::*;
1304 use crate::mm::MemoryAccessor;
1305 use crate::testing::{map_memory, spawn_kernel_and_run};
1306 use crate::vfs::{DirectoryMode, UnlinkKind};
1307 use starnix_types::user_buffer::UserBuffer;
1308 use starnix_uapi::file_mode::mode;
1309
1310 #[::fuchsia::test]
1311 async fn test_socket_send_capacity() {
1312 spawn_kernel_and_run(async |current_task| {
1313 let _kernel = current_task.kernel();
1314 let socket = Socket::new(
1315 ¤t_task,
1316 SocketDomain::Unix,
1317 SocketType::Stream,
1318 SocketProtocol::default(),
1319 false,
1320 )
1321 .expect("Failed to create socket.");
1322 socket
1323 .bind(¤t_task, SocketAddress::Unix(b"\0".into()))
1324 .expect("Failed to bind socket.");
1325 socket.listen(¤t_task, 10).expect("Failed to listen.");
1326 let connecting_socket = Socket::new(
1327 ¤t_task,
1328 SocketDomain::Unix,
1329 SocketType::Stream,
1330 SocketProtocol::default(),
1331 false,
1332 )
1333 .expect("Failed to connect socket.");
1334 connecting_socket
1335 .ops
1336 .connect(&connecting_socket, ¤t_task, SocketPeer::Handle(socket.clone()))
1337 .expect("Failed to connect socket.");
1338 assert_eq!(Ok(FdEvents::POLLIN), socket.query_events(¤t_task));
1339 let server_socket = socket.accept(¤t_task).unwrap();
1340
1341 let opt_size = std::mem::size_of::<socklen_t>();
1342 let user_address = map_memory(¤t_task, UserAddress::default(), opt_size as u64);
1343 let send_capacity: socklen_t = 4 * 4096;
1344 current_task.write_memory(user_address, &send_capacity.to_ne_bytes()).unwrap();
1345 let user_buffer = UserBuffer { address: user_address, length: opt_size };
1346 server_socket
1347 .setsockopt(¤t_task, SOL_SOCKET, SO_SNDBUF, user_buffer.into())
1348 .unwrap();
1349
1350 let opt_bytes =
1351 server_socket.getsockopt(¤t_task, SOL_SOCKET, SO_SNDBUF, 0).unwrap();
1352 let retrieved_capacity = socklen_t::from_ne_bytes(opt_bytes.try_into().unwrap());
1353 assert_eq!(2 * send_capacity, retrieved_capacity);
1355 })
1356 .await;
1357 }
1358
1359 #[::fuchsia::test]
1360 async fn test_datagram_socket_disconnect_af_unspec() {
1361 spawn_kernel_and_run(async |current_task| {
1362 let socket1 = Socket::new(
1363 ¤t_task,
1364 SocketDomain::Unix,
1365 SocketType::Datagram,
1366 SocketProtocol::default(),
1367 false,
1368 )
1369 .expect("Failed to create socket 1.");
1370 socket1
1371 .bind(¤t_task, SocketAddress::Unix(b"\0sock1".into()))
1372 .expect("Failed to bind socket 1.");
1373
1374 let socket2 = Socket::new(
1375 ¤t_task,
1376 SocketDomain::Unix,
1377 SocketType::Datagram,
1378 SocketProtocol::default(),
1379 false,
1380 )
1381 .expect("Failed to create socket 2.");
1382 socket2
1383 .bind(¤t_task, SocketAddress::Unix(b"\0sock2".into()))
1384 .expect("Failed to bind socket 2.");
1385
1386 socket1
1388 .ops
1389 .connect(&socket1, ¤t_task, SocketPeer::Handle(socket2.clone()))
1390 .expect("Failed to connect socket1 to socket2.");
1391
1392 socket1
1394 .ops
1395 .connect(&socket1, ¤t_task, SocketPeer::Address(SocketAddress::Unspecified))
1396 .expect("Failed to disconnect socket1 with AF_UNSPEC.");
1397 })
1398 .await;
1399 }
1400
1401 #[::fuchsia::test]
1402 async fn test_bind_socket_retains_fs_node_until_close() {
1403 spawn_kernel_and_run(async |current_task| {
1404 let socket = Socket::new(
1405 ¤t_task,
1406 SocketDomain::Unix,
1407 SocketType::Stream,
1408 SocketProtocol::default(),
1409 false,
1410 )
1411 .expect("Failed to create socket.");
1412
1413 let root = current_task.fs().root();
1414 let bound_node = root
1415 .bind_socket(
1416 ¤t_task,
1417 "test_sock".into(),
1418 socket.clone(),
1419 SocketAddress::Unix("test_sock".into()),
1420 mode!(IFSOCK, 0o777),
1421 )
1422 .expect("Failed to bind socket to node.");
1423 let weak_fs_node = Arc::downgrade(&bound_node.entry.node);
1424 std::mem::drop(bound_node);
1425
1426 root.unlink(
1430 ¤t_task,
1431 "test_sock".into(),
1432 UnlinkKind::NonDirectory,
1433 DirectoryMode::AllowAny,
1434 )
1435 .expect("Failed to unlink socket.");
1436 current_task.trigger_delayed_releaser();
1437
1438 let fs_node =
1441 weak_fs_node.upgrade().expect("FsNode should remain alive while socket is open");
1442 assert!(fs_node.bound_socket().is_some());
1443 std::mem::drop(fs_node);
1444
1445 let weak_socket = Arc::downgrade(&socket);
1448 socket.close(¤t_task);
1449 std::mem::drop(socket);
1450 current_task.trigger_delayed_releaser();
1451
1452 assert!(weak_fs_node.upgrade().is_none());
1453 assert!(weak_socket.upgrade().is_none());
1454 })
1455 .await;
1456 }
1457}