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(_), SocketType::Stream) => return error!(EISCONN),
636 (_, Some(SocketAddress::Unix(name)), _) => {
637 if name.is_empty() {
638 return error!(EINVAL);
639 }
640 resolve_unix_socket_address(current_task, name.as_ref())?
641 }
642 (_, Some(_), _) => return error!(EINVAL),
643 (None, None, _) => return error!(ENOTCONN),
644 };
645
646 let dgram_security_context = if socket.socket_type == SocketType::Datagram {
647 security::unix_may_send(current_task, socket, &peer)?;
648 Some(security::socket_getpeersec_dgram(current_task, socket))
651 } else {
652 None
653 };
654
655 let peer_unaccepted = peer.fs_node().is_none();
656 let unix_socket = downcast_socket_to_unix(&peer);
657 let write_result = {
658 let mut peer = unix_socket.lock();
659 let default_creds =
660 (local_passcred.is_enabled() || peer.passcred.is_enabled() || peer_unaccepted)
661 .then(|| current_task.current_ucred());
662 peer.write(
663 current_task,
664 data,
665 local_address,
666 default_creds,
667 dgram_security_context,
668 ancillary_data,
669 socket,
670 )
671 };
672
673 if let Err(ref err) = write_result {
674 if err.code == ECONNREFUSED && socket.socket_type == SocketType::Datagram {
675 let mut inner = self.lock();
676 if let UnixSocketState::Connected(ref connected_peer) = inner.state {
677 if Arc::ptr_eq(connected_peer, &peer) {
678 inner.state = UnixSocketState::Disconnected;
679 self.waiters.notify_fd_events(FdEvents::POLLOUT | FdEvents::POLLHUP);
680 }
681 }
682 }
683 }
684
685 let bytes_written = write_result?;
686 if bytes_written > 0 {
687 unix_socket.waiters.notify_fd_events(FdEvents::POLLIN);
688 }
689 Ok(bytes_written)
690 }
691
692 fn wait_async(
693 &self,
694 _socket: &Socket,
695 _current_task: &CurrentTask,
696 waiter: &Waiter,
697 events: FdEvents,
698 handler: EventHandler,
699 ) -> WaitCanceler {
700 self.waiters.wait_async_fd_events(waiter, events, handler)
701 }
702
703 fn query_events(
704 &self,
705 socket: &Socket,
706 _current_task: &CurrentTask,
707 ) -> Result<FdEvents, Errno> {
708 let (
711 mut events,
712 peer,
713 local_is_read_shutdown,
714 local_is_write_shutdown,
715 is_closed,
716 is_disconnected,
717 ) = {
718 let inner = self.lock();
719
720 let mut events = FdEvents::empty();
721 let local_events = inner.messages.query_events();
722 if local_events.contains(FdEvents::POLLIN) {
723 events |= FdEvents::POLLIN;
724 }
725
726 if let UnixSocketState::Listening(queue) = &inner.state {
728 if !queue.sockets.is_empty() {
729 events |= FdEvents::POLLIN;
730 }
731 }
732
733 (
734 events,
735 inner.peer().cloned(),
736 inner.is_read_shutdown,
737 inner.is_write_shutdown,
738 matches!(inner.state, UnixSocketState::Closed),
739 matches!(inner.state, UnixSocketState::Disconnected),
740 )
741 };
742
743 let connection_oriented = socket.socket_type.is_connection_oriented();
744
745 let mut read_dead = local_is_read_shutdown || is_closed;
746 let mut write_dead = local_is_write_shutdown || is_closed;
747 let mut force_pollout = is_closed || is_disconnected;
748 let mut force_pollhup = false;
749
750 if connection_oriented && is_disconnected {
751 force_pollhup = true;
752 write_dead = true;
753 }
754
755 if let Some(peer) = peer {
756 let unix_socket = downcast_socket_to_unix(&peer);
757 let peer_inner = unix_socket.lock();
758
759 if peer_inner.is_read_shutdown {
760 write_dead = true;
761 }
762 if matches!(peer_inner.state, UnixSocketState::Closed) {
763 read_dead = true;
764 write_dead = true;
765 force_pollout = true;
766 }
767
768 let peer_events = peer_inner.messages.query_events();
769 if peer_events.contains(FdEvents::POLLOUT) {
770 events |= FdEvents::POLLOUT;
771 }
772 }
773
774 if force_pollout {
775 events |= FdEvents::POLLOUT;
776 }
777
778 if read_dead {
779 events |= FdEvents::POLLIN | FdEvents::POLLRDHUP;
780 }
781 if (read_dead && write_dead) || force_pollhup {
782 events |= FdEvents::POLLHUP;
783 }
784
785 Ok(events)
786 }
787
788 fn shutdown(&self, socket: &Socket, how: SocketShutdownFlags) -> Result<(), Errno> {
793 let (peer, self_notify_events) = {
796 let mut inner = self.lock();
797 let events = inner.shutdown(how);
798 (inner.peer().cloned(), events)
799 };
800 let mut peer_notify_events = FdEvents::empty();
801 if let Some(peer) = &peer {
802 if socket.socket_type.is_connection_oriented() {
803 let mut peer_how = SocketShutdownFlags::empty();
812 if how.contains(SocketShutdownFlags::WRITE) {
813 peer_how |= SocketShutdownFlags::READ;
814 }
815 if how.contains(SocketShutdownFlags::READ) {
816 peer_how |= SocketShutdownFlags::WRITE;
817 }
818 let peer_socket = downcast_socket_to_unix(peer);
819 peer_notify_events = peer_socket.lock().shutdown(peer_how);
820 }
821 }
822 if !self_notify_events.is_empty() {
823 self.waiters.notify_fd_events(self_notify_events);
824 }
825 if !peer_notify_events.is_empty() {
826 if let Some(peer) = &peer {
827 let peer_socket = downcast_socket_to_unix(peer);
828 peer_socket.waiters.notify_fd_events(peer_notify_events);
829 }
830 }
831 Ok(())
832 }
833
834 fn close(&self, _current_task: &CurrentTask, socket: &Socket) {
846 let (maybe_peer, has_unread, _maybe_fs_node) = {
848 let mut inner = self.lock();
849 let maybe_peer = inner.peer().map(Arc::clone);
850 inner.is_read_shutdown = true;
851 inner.state = UnixSocketState::Closed;
852 (maybe_peer, !inner.messages.is_empty(), inner.fs_node.take())
853 };
854 self.notify_shutdown();
855 if socket.socket_type.is_connection_oriented() {
857 if let Some(peer) = maybe_peer {
858 let unix_socket = downcast_socket_to_unix(&peer);
859
860 {
861 let mut peer_inner = unix_socket.lock();
862 if has_unread {
863 peer_inner.peer_closed_with_unread_data = true;
864 }
865 peer_inner.is_read_shutdown = true;
866 }
867 unix_socket.notify_shutdown();
868 }
869 }
870 }
871
872 fn getsockname(&self, socket: &Socket) -> Result<SocketAddress, Errno> {
877 let inner = self.lock();
878 if let Some(address) = &inner.address {
879 Ok(address.clone())
880 } else {
881 Ok(SocketAddress::default_for_domain(socket.domain))
882 }
883 }
884
885 fn getpeername(&self, _socket: &Socket) -> Result<SocketAddress, Errno> {
889 let peer = self.lock().peer().ok_or_else(|| errno!(ENOTCONN))?.clone();
890 peer.getsockname()
891 }
892
893 fn setsockopt(
894 &self,
895 _socket: &Socket,
896 current_task: &CurrentTask,
897 level: u32,
898 optname: u32,
899 optval: SockOptValue,
900 ) -> Result<(), Errno> {
901 match level {
902 SOL_SOCKET => match optname {
903 SO_SNDBUF => {
904 let requested_capacity: socklen_t = optval.read(current_task)?;
905 self.set_send_capacity(requested_capacity as usize * 2);
907 }
908 SO_RCVBUF => {
909 let requested_capacity: socklen_t = optval.read(current_task)?;
910 self.set_receive_capacity(requested_capacity as usize);
911 }
912 SO_LINGER => {
913 let mut linger: uapi::linger = optval.read(current_task)?;
914 if linger.l_onoff != 0 {
915 linger.l_onoff = 1;
916 }
917 self.set_linger(linger);
918 }
919 SO_PASSCRED => {
920 let passcred: u32 = optval.read(current_task)?;
921 self.set_passcred(PasscredMode::from(passcred != 0));
922 }
923 SO_PASSSEC => {
924 let passsec: u32 = optval.read(current_task)?;
925 self.set_passsec(passsec != 0);
926 }
927 SO_BROADCAST => {
928 let broadcast: u32 = optval.read(current_task)?;
929 self.set_broadcast(broadcast != 0);
930 }
931 SO_NO_CHECK => {
932 let no_check: u32 = optval.read(current_task)?;
933 self.set_no_check(no_check != 0);
934 }
935 SO_REUSEADDR => {
936 let reuseaddr: u32 = optval.read(current_task)?;
937 self.set_reuseaddr(reuseaddr != 0);
938 }
939 SO_REUSEPORT => {
940 let reuseport: u32 = optval.read(current_task)?;
941 self.set_reuseport(reuseport != 0);
942 }
943 SO_KEEPALIVE => {
944 let keepalive: u32 = optval.read(current_task)?;
945 self.set_keepalive(keepalive != 0);
946 }
947 SO_ATTACH_BPF => {
948 let fd: FdNumber = optval.read(current_task)?;
949 let object = get_bpf_object(current_task, fd)?;
950 let program = object.as_program()?;
951
952 let linked_program = program.link(ProgramType::SocketFilter)?;
953
954 self.set_bpf_program(Some(linked_program));
955 }
956 _ => return error!(ENOPROTOOPT),
957 },
958 _ => return error!(ENOPROTOOPT),
959 }
960 Ok(())
961 }
962
963 fn getsockopt(
964 &self,
965 socket: &Socket,
966 current_task: &CurrentTask,
967 level: u32,
968 optname: u32,
969 _optlen: u32,
970 ) -> Result<Vec<u8>, Errno> {
971 match level {
972 SOL_SOCKET => match optname {
973 SO_PEERCRED => Ok(UcredPtr::into_bytes(
974 current_task,
975 self.peer_cred().unwrap_or(ucred { pid: 0, uid: uid_t::MAX, gid: gid_t::MAX }),
976 )
977 .map_err(|_| errno!(EINVAL))?),
978 SO_PEERSEC => match socket.socket_type {
979 SocketType::Stream => security::socket_getpeersec_stream(current_task, socket),
980 _ => error!(ENOPROTOOPT),
981 },
982 SO_ACCEPTCONN =>
983 {
984 #[allow(clippy::bool_to_int_with_if)]
985 Ok(if self.is_listening(socket) { 1u32 } else { 0u32 }.to_ne_bytes().to_vec())
986 }
987 SO_SNDBUF => Ok((self.get_send_capacity() as socklen_t).to_ne_bytes().to_vec()),
988 SO_RCVBUF => Ok((self.get_receive_capacity() as socklen_t).to_ne_bytes().to_vec()),
989 SO_LINGER => Ok(self.get_linger().as_bytes().to_vec()),
990 SO_PASSCRED => Ok((self.get_passcred().is_enabled() as u32).as_bytes().to_vec()),
991 SO_PASSSEC => Ok((self.get_passsec() as u32).as_bytes().to_vec()),
992 SO_BROADCAST => Ok((self.get_broadcast() as u32).as_bytes().to_vec()),
993 SO_NO_CHECK => Ok((self.get_no_check() as u32).as_bytes().to_vec()),
994 SO_REUSEADDR => Ok((self.get_reuseaddr() as u32).as_bytes().to_vec()),
995 SO_REUSEPORT => Ok((self.get_reuseport() as u32).as_bytes().to_vec()),
996 SO_KEEPALIVE => Ok((self.get_keepalive() as u32).as_bytes().to_vec()),
997 SO_ERROR => Ok((0u32).as_bytes().to_vec()),
998 _ => error!(ENOPROTOOPT),
999 },
1000 _ => error!(ENOPROTOOPT),
1001 }
1002 }
1003
1004 fn ioctl(
1005 &self,
1006 socket: &Socket,
1007 _file: &FileObject,
1008 current_task: &CurrentTask,
1009 request: u32,
1010 arg: SyscallArg,
1011 ) -> Result<SyscallResult, Errno> {
1012 let user_addr = UserAddress::from(arg);
1013 match request {
1014 FIONREAD if socket.socket_type == SocketType::Stream => {
1015 let length: i32 =
1016 self.lock().messages.len().try_into().map_err(|_| errno!(EINVAL))?;
1017 current_task.write_object(UserRef::<i32>::new(user_addr), &length)?;
1018 Ok(SUCCESS)
1019 }
1020 _ => error!(ENOTTY),
1021 }
1022 }
1023}
1024
1025impl UnixSocketInner {
1026 fn bind(&mut self, socket_address: SocketAddress) -> Result<(), Errno> {
1027 if self.address.is_some() {
1028 return error!(EINVAL);
1029 }
1030 self.address = Some(socket_address);
1031 Ok(())
1032 }
1033
1034 fn shutdown(&mut self, how: SocketShutdownFlags) -> FdEvents {
1051 let mut notify_events = FdEvents::empty();
1052 if how.contains(SocketShutdownFlags::READ) {
1053 self.is_read_shutdown = true;
1054 notify_events |= FdEvents::POLLIN | FdEvents::POLLRDHUP;
1055 }
1056 if how.contains(SocketShutdownFlags::WRITE) {
1057 self.is_write_shutdown = true;
1058 notify_events |= FdEvents::POLLOUT;
1059 }
1060 if self.is_read_shutdown && self.is_write_shutdown {
1061 notify_events |= FdEvents::POLLHUP;
1062 }
1063 notify_events
1064 }
1065
1066 fn set_capacity(&mut self, requested_capacity: usize) {
1067 let capacity = requested_capacity.clamp(SOCKET_MIN_SIZE, SOCKET_MAX_SIZE);
1068 let capacity = std::cmp::max(capacity, self.messages.len());
1069 self.messages.set_capacity(capacity).unwrap();
1071 }
1072
1073 fn peer(&self) -> Option<&SocketHandle> {
1076 match &self.state {
1077 UnixSocketState::Connected(peer) => Some(peer),
1078 _ => None,
1079 }
1080 }
1081
1082 fn read(
1093 &mut self,
1094 data: &mut dyn OutputBuffer,
1095 socket_type: SocketType,
1096 flags: SocketMessageFlags,
1097 ) -> Result<MessageReadInfo, Errno> {
1098 let (mut info, has_message) = if socket_type == SocketType::Stream {
1099 if flags.contains(SocketMessageFlags::PEEK) {
1100 self.messages.peek_stream(data, self.passcred)?
1101 } else {
1102 self.messages.read_stream_with_passcred(data, self.passcred)?
1103 }
1104 } else if flags.contains(SocketMessageFlags::PEEK) {
1105 self.messages.peek_datagram(data)?
1106 } else {
1107 self.messages.read_datagram(data)?
1108 };
1109 if !has_message {
1110 if self.peer_closed_with_unread_data {
1111 self.peer_closed_with_unread_data = false;
1113 return error!(ECONNRESET);
1114 }
1115 if !self.is_read_shutdown {
1116 return error!(EAGAIN);
1117 }
1118 }
1119
1120 if self.passcred.is_enabled() {
1121 let creds = info.credentials.unwrap_or_else(UnixControlData::unknown_ucred);
1122 info.credentials = Some(creds);
1123 info.ancillary_data.insert(0, AncillaryData::Unix(UnixControlData::Credentials(creds)));
1125 } else {
1126 info.credentials = None;
1127 }
1128
1129 if !self.passsec {
1131 info.ancillary_data
1132 .retain(|m| !matches!(m, AncillaryData::Unix(UnixControlData::Security(..))));
1133 }
1134
1135 Ok(info)
1136 }
1137
1138 fn read_and_append(
1139 &mut self,
1140 read_info: &mut MessageReadInfo,
1141 data: &mut dyn OutputBuffer,
1142 socket_type: SocketType,
1143 flags: SocketMessageFlags,
1144 ) -> Result<bool, Errno> {
1145 if socket_type == SocketType::Stream
1146 && !self.messages.can_coalesce_with(read_info, self.passcred)
1147 {
1148 return Ok(false);
1149 }
1150 let mut info = self.read(data, socket_type, flags)?;
1151 let bytes_read = info.bytes_read;
1152 read_info.append(&mut info);
1153 if socket_type != SocketType::Stream || bytes_read == 0 {
1154 return Ok(false);
1155 }
1156 Ok(self.messages.can_coalesce_with(read_info, self.passcred))
1157 }
1158
1159 fn write(
1168 &mut self,
1169 current_task: &CurrentTask,
1170 data: &mut dyn InputBuffer,
1171 address: Option<SocketAddress>,
1172 default_credentials: Option<ucred>,
1173 dgram_security_context: Option<Vec<u8>>,
1174 ancillary_data: &mut Vec<AncillaryData>,
1175 socket: &Socket,
1176 ) -> Result<usize, Errno> {
1177 if matches!(self.state, UnixSocketState::Closed) {
1178 if !socket.socket_type.is_connection_oriented() {
1179 return error!(ECONNREFUSED);
1180 } else {
1181 return error!(EPIPE);
1182 }
1183 }
1184 if self.is_read_shutdown {
1185 return error!(EPIPE);
1186 }
1187 let filter = |mut message: Message| {
1188 if let Some(context) = dgram_security_context {
1189 message
1190 .ancillary_data
1191 .push(AncillaryData::Unix(UnixControlData::Security(context.into())));
1192 }
1193 let Some(bpf_program) = self.bpf_program.as_ref() else {
1194 return Some(message);
1195 };
1196
1197 let mut sk_buf = SkBuf::default();
1199
1200 let mut context = EbpfRunContextImpl::<'_>::new(current_task);
1201 let s = bpf_program.run(&mut context, &mut sk_buf);
1202 if s == 0 {
1203 None
1204 } else {
1205 message.truncate(s as usize);
1206 Some(message)
1207 }
1208 };
1209 let bytes_written = if socket.socket_type == SocketType::Stream {
1210 self.messages.write_stream_with_filter(
1211 data,
1212 address,
1213 default_credentials,
1214 ancillary_data,
1215 filter,
1216 )?
1217 } else {
1218 self.messages.write_datagram_with_filter(
1219 data,
1220 address,
1221 default_credentials,
1222 ancillary_data,
1223 filter,
1224 )?
1225 };
1226 Ok(bytes_written)
1227 }
1228}
1229
1230pub fn resolve_unix_socket_address(
1231 current_task: &CurrentTask,
1232 name: &FsStr,
1233) -> Result<SocketHandle, Errno> {
1234 if name[0] == b'\0' {
1235 current_task.running_state().abstract_socket_namespace.lookup(name)
1236 } else {
1237 let mut context = LookupContext::default();
1238 let (parent, basename) =
1239 current_task.lookup_parent_at(&mut context, FdNumber::AT_FDCWD, name)?;
1240 let name = parent.lookup_child(current_task, &mut context, basename).map_err(|errno| {
1241 if matches!(errno.code, EACCES | EPERM | EINTR) { errno } else { errno!(ECONNREFUSED) }
1242 })?;
1243 name.check_access(current_task, AccessCheck::for_internal(Access::WRITE))?;
1244 name.entry.node.bound_socket().map(|s| s.clone()).ok_or_else(|| errno!(ECONNREFUSED))
1245 }
1246}
1247
1248#[repr(C)]
1250#[derive(Default)]
1251struct SkBuf {
1252 sk_buff: __sk_buff,
1253}
1254
1255impl Packet for &mut SkBuf {
1256 fn load(&self, _offset: i32, _width: DataWidth) -> Option<BpfValue> {
1257 None
1259 }
1260}
1261
1262impl<'a> PacketWithLoadBytes for &'a mut SkBuf {
1263 fn load_bytes_relative(
1264 &self,
1265 _base: LoadBytesBase,
1266 _offset: usize,
1267 _buf: ebpf::EbpfBufferPtr<'_>,
1268 ) -> i64 {
1269 track_stub!(TODO("https://fxbug.dev/385015056"), "bpf_load_bytes_relative");
1270 -1
1271 }
1272}
1273
1274impl ProgramArgument for &'_ mut SkBuf {
1275 fn get_type() -> &'static Type {
1276 &*SOCKET_FILTER_SK_BUF_TYPE
1277 }
1278}
1279
1280impl SocketRef for &'_ mut SkBuf {
1281 fn get_socket_cookie(&self) -> Option<u64> {
1282 track_stub!(TODO("https://fxbug.dev/385015056"), "bpf_get_socket_cookie");
1283 None
1284 }
1285
1286 fn get_socket_uid(&self) -> Option<uid_t> {
1287 track_stub!(TODO("https://fxbug.dev/385015056"), "bpf_get_socket_uid");
1288 None
1289 }
1290}
1291
1292struct UnixSocketEbpfContext {}
1293impl BpfProgramContext for UnixSocketEbpfContext {
1294 type RunContext<'a> = EbpfRunContextImpl<'a>;
1295 type Packet<'a> = &'a mut SkBuf;
1296 type Map = PinnedMap;
1297 const CBPF_CONFIG: &'static CbpfConfig = &SOCKET_FILTER_CBPF_CONFIG;
1298}
1299
1300ebpf_api::ebpf_program_context_type!(UnixSocketEbpfContext, SocketFilterProgramContext);
1301
1302type UnixSocketFilter = EbpfProgram<UnixSocketEbpfContext>;
1303
1304#[cfg(test)]
1305mod tests {
1306 use super::*;
1307 use crate::mm::MemoryAccessor;
1308 use crate::testing::{map_memory, spawn_kernel_and_run};
1309 use crate::vfs::{DirectoryMode, UnlinkKind};
1310 use starnix_types::user_buffer::UserBuffer;
1311 use starnix_uapi::file_mode::mode;
1312
1313 #[::fuchsia::test]
1314 async fn test_socket_send_capacity() {
1315 spawn_kernel_and_run(async |current_task| {
1316 let _kernel = current_task.kernel();
1317 let socket = Socket::new(
1318 ¤t_task,
1319 SocketDomain::Unix,
1320 SocketType::Stream,
1321 SocketProtocol::default(),
1322 false,
1323 )
1324 .expect("Failed to create socket.");
1325 socket
1326 .bind(¤t_task, SocketAddress::Unix(b"\0".into()))
1327 .expect("Failed to bind socket.");
1328 socket.listen(¤t_task, 10).expect("Failed to listen.");
1329 let connecting_socket = Socket::new(
1330 ¤t_task,
1331 SocketDomain::Unix,
1332 SocketType::Stream,
1333 SocketProtocol::default(),
1334 false,
1335 )
1336 .expect("Failed to connect socket.");
1337 connecting_socket
1338 .ops
1339 .connect(&connecting_socket, ¤t_task, SocketPeer::Handle(socket.clone()))
1340 .expect("Failed to connect socket.");
1341 assert_eq!(Ok(FdEvents::POLLIN), socket.query_events(¤t_task));
1342 let server_socket = socket.accept(¤t_task).unwrap();
1343
1344 let opt_size = std::mem::size_of::<socklen_t>();
1345 let user_address = map_memory(¤t_task, UserAddress::default(), opt_size as u64);
1346 let send_capacity: socklen_t = 4 * 4096;
1347 current_task.write_memory(user_address, &send_capacity.to_ne_bytes()).unwrap();
1348 let user_buffer = UserBuffer { address: user_address, length: opt_size };
1349 server_socket
1350 .setsockopt(¤t_task, SOL_SOCKET, SO_SNDBUF, user_buffer.into())
1351 .unwrap();
1352
1353 let opt_bytes =
1354 server_socket.getsockopt(¤t_task, SOL_SOCKET, SO_SNDBUF, 0).unwrap();
1355 let retrieved_capacity = socklen_t::from_ne_bytes(opt_bytes.try_into().unwrap());
1356 assert_eq!(2 * send_capacity, retrieved_capacity);
1358 })
1359 .await;
1360 }
1361
1362 #[::fuchsia::test]
1363 async fn test_datagram_socket_disconnect_af_unspec() {
1364 spawn_kernel_and_run(async |current_task| {
1365 let socket1 = Socket::new(
1366 ¤t_task,
1367 SocketDomain::Unix,
1368 SocketType::Datagram,
1369 SocketProtocol::default(),
1370 false,
1371 )
1372 .expect("Failed to create socket 1.");
1373 socket1
1374 .bind(¤t_task, SocketAddress::Unix(b"\0sock1".into()))
1375 .expect("Failed to bind socket 1.");
1376
1377 let socket2 = Socket::new(
1378 ¤t_task,
1379 SocketDomain::Unix,
1380 SocketType::Datagram,
1381 SocketProtocol::default(),
1382 false,
1383 )
1384 .expect("Failed to create socket 2.");
1385 socket2
1386 .bind(¤t_task, SocketAddress::Unix(b"\0sock2".into()))
1387 .expect("Failed to bind socket 2.");
1388
1389 socket1
1391 .ops
1392 .connect(&socket1, ¤t_task, SocketPeer::Handle(socket2.clone()))
1393 .expect("Failed to connect socket1 to socket2.");
1394
1395 socket1
1397 .ops
1398 .connect(&socket1, ¤t_task, SocketPeer::Address(SocketAddress::Unspecified))
1399 .expect("Failed to disconnect socket1 with AF_UNSPEC.");
1400 })
1401 .await;
1402 }
1403
1404 #[::fuchsia::test]
1405 async fn test_bind_socket_retains_fs_node_until_close() {
1406 spawn_kernel_and_run(async |current_task| {
1407 let socket = Socket::new(
1408 ¤t_task,
1409 SocketDomain::Unix,
1410 SocketType::Stream,
1411 SocketProtocol::default(),
1412 false,
1413 )
1414 .expect("Failed to create socket.");
1415
1416 let root = current_task.fs().root();
1417 let bound_node = root
1418 .bind_socket(
1419 ¤t_task,
1420 "test_sock".into(),
1421 socket.clone(),
1422 SocketAddress::Unix("test_sock".into()),
1423 mode!(IFSOCK, 0o777),
1424 )
1425 .expect("Failed to bind socket to node.");
1426 let weak_fs_node = Arc::downgrade(&bound_node.entry.node);
1427 std::mem::drop(bound_node);
1428
1429 root.unlink(
1433 ¤t_task,
1434 "test_sock".into(),
1435 UnlinkKind::NonDirectory,
1436 DirectoryMode::AllowAny,
1437 )
1438 .expect("Failed to unlink socket.");
1439 current_task.trigger_delayed_releaser();
1440
1441 let fs_node =
1444 weak_fs_node.upgrade().expect("FsNode should remain alive while socket is open");
1445 assert!(fs_node.bound_socket().is_some());
1446 std::mem::drop(fs_node);
1447
1448 let weak_socket = Arc::downgrade(&socket);
1451 socket.close(¤t_task);
1452 std::mem::drop(socket);
1453 current_task.trigger_delayed_releaser();
1454
1455 assert!(weak_fs_node.upgrade().is_none());
1456 assert!(weak_socket.upgrade().is_none());
1457 })
1458 .await;
1459 }
1460}