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, UnixControlData,
12};
13use crate::vfs::socket::{
14 AcceptQueue, DEFAULT_LISTEN_BACKLOG, SockOptValue, Socket, SocketAddress, SocketDomain,
15 SocketFile, SocketHandle, SocketMessageFlags, SocketOps, SocketPeer, SocketProtocol,
16 SocketShutdownFlags, SocketType,
17};
18use crate::vfs::{
19 CheckAccessReason, FdNumber, FileHandle, FileObject, FsNodeHandle, FsStr, LookupContext,
20 Message, UcredPtr,
21};
22use ebpf::{
23 BpfProgramContext, BpfValue, CbpfConfig, DataWidth, EbpfProgram, Packet, ProgramArgument, Type,
24};
25use ebpf_api::{
26 LoadBytesBase, PacketWithLoadBytes, PinnedMap, ProgramType, SOCKET_FILTER_CBPF_CONFIG,
27 SOCKET_FILTER_SK_BUF_TYPE, SocketFilterProgramContext, SocketRef,
28};
29use starnix_logging::track_stub;
30use starnix_sync::{LockDepGuard, LockDepMutex, UnixSocketInnerLock, allow_subclass};
31use starnix_syscalls::{SUCCESS, SyscallArg, SyscallResult};
32use starnix_uapi::errors::{EACCES, EINTR, EPERM, Errno};
33use starnix_uapi::file_mode::Access;
34use starnix_uapi::open_flags::OpenFlags;
35use starnix_uapi::user_address::{UserAddress, UserRef};
36use starnix_uapi::vfs::FdEvents;
37use starnix_uapi::{
38 __sk_buff, FIONREAD, SO_ACCEPTCONN, SO_ATTACH_BPF, SO_BROADCAST, SO_ERROR, SO_KEEPALIVE,
39 SO_LINGER, SO_NO_CHECK, SO_PASSCRED, SO_PASSSEC, SO_PEERCRED, SO_PEERSEC, SO_RCVBUF,
40 SO_REUSEADDR, SO_REUSEPORT, SO_SNDBUF, SOL_SOCKET, errno, error, gid_t, socklen_t, uapi, ucred,
41 uid_t,
42};
43use std::sync::Arc;
44use zerocopy::IntoBytes;
45
46const SOCKET_MIN_SIZE: usize = 4 << 10;
48const SOCKET_DEFAULT_SIZE: usize = 208 << 10;
49const SOCKET_MAX_SIZE: usize = 4 << 20;
50
51pub struct UnixSocket {
68 inner: LockDepMutex<UnixSocketInner, UnixSocketInnerLock>,
69 waiters: WaitQueue,
70}
71
72fn downcast_socket_to_unix(socket: &Socket) -> &UnixSocket {
73 socket.downcast_socket::<UnixSocket>().unwrap()
78}
79
80enum UnixSocketState {
81 Disconnected,
83
84 Listening(AcceptQueue),
86
87 Connected(SocketHandle),
89
90 Closed,
92}
93
94struct UnixSocketInner {
95 messages: MessageQueue,
97
98 address: Option<SocketAddress>,
100
101 is_shutdown: bool,
104
105 peer_closed_with_unread_data: bool,
108
109 linger: uapi::linger,
111
112 passcred: bool,
114
115 passsec: bool,
117
118 broadcast: bool,
120
121 no_check: bool,
123
124 reuseport: bool,
126
127 reuseaddr: bool,
129
130 keepalive: bool,
132
133 bpf_program: Option<UnixSocketFilter>,
135
136 credentials: Option<ucred>,
138
139 state: UnixSocketState,
142}
143
144impl UnixSocket {
145 pub fn new(_socket_type: SocketType) -> UnixSocket {
146 UnixSocket {
147 inner: UnixSocketInner {
148 messages: MessageQueue::new(SOCKET_DEFAULT_SIZE),
149 address: None,
150 is_shutdown: false,
151 peer_closed_with_unread_data: false,
152 linger: uapi::linger::default(),
153 passcred: false,
154 passsec: false,
155 broadcast: false,
156 no_check: false,
157 reuseaddr: false,
158 reuseport: false,
159 keepalive: false,
160 bpf_program: None,
161 credentials: None,
162 state: UnixSocketState::Disconnected,
163 }
164 .into(),
165 waiters: WaitQueue::default(),
166 }
167 }
168
169 pub fn new_pair(
175 current_task: &CurrentTask,
176 domain: SocketDomain,
177 socket_type: SocketType,
178 open_flags: OpenFlags,
179 ) -> Result<(FileHandle, FileHandle), Errno> {
180 let credentials = current_task.current_ucred();
181 let left = Socket::new(
182 current_task,
183 domain,
184 socket_type,
185 SocketProtocol::default(),
186 false,
187 )?;
188 let right = Socket::new(
189 current_task,
190 domain,
191 socket_type,
192 SocketProtocol::default(),
193 false,
194 )?;
195 downcast_socket_to_unix(&left).lock().state = UnixSocketState::Connected(right.clone());
196 downcast_socket_to_unix(&left).lock().credentials = Some(credentials.clone());
197 downcast_socket_to_unix(&right).lock().state = UnixSocketState::Connected(left.clone());
198 downcast_socket_to_unix(&right).lock().credentials = Some(credentials);
199 let left = SocketFile::from_socket(
200 current_task,
201 left,
202 open_flags,
203 false,
204 )?;
205 let right = SocketFile::from_socket(
206 current_task,
207 right,
208 open_flags,
209 false,
210 )?;
211 let left_socket = SocketFile::get_from_file(&left)?;
212 let right_socket = SocketFile::get_from_file(&right)?;
213
214 security::socket_socketpair(current_task, left_socket, right_socket)?;
215 Ok((left, right))
216 }
217
218 fn connect_stream(
219 &self,
220 socket: &SocketHandle,
221 current_task: &CurrentTask,
222 peer: &SocketHandle,
223 ) -> Result<(), Errno> {
224 match downcast_socket_to_unix(peer).lock().state {
227 UnixSocketState::Listening(_) => {}
228 _ => return error!(ECONNREFUSED),
229 }
230
231 let mut client = downcast_socket_to_unix(socket).lock();
232 match client.state {
233 UnixSocketState::Disconnected => {}
234 UnixSocketState::Connected(_) => return error!(EISCONN),
235 _ => return error!(EINVAL),
236 };
237
238 let unix_socket_peer = downcast_socket_to_unix(peer);
239 {
240 let _token = allow_subclass();
242 let mut listener = unix_socket_peer.lock();
243
244 let queue = match &listener.state {
246 UnixSocketState::Listening(queue) => queue,
247 _ => return error!(ECONNREFUSED),
248 };
249
250 self.check_type_for_connect(socket, peer, &listener.address)?;
251
252 if queue.sockets.len() > queue.backlog {
253 return error!(EAGAIN);
254 }
255
256 let server = Socket::new(
257 current_task,
258 peer.domain,
259 peer.socket_type,
260 SocketProtocol::default(),
261 true,
262 )?;
263 security::unix_stream_connect(current_task, socket, peer, &server)?;
264 client.state = UnixSocketState::Connected(server.clone());
265 client.credentials = Some(current_task.current_ucred());
266 {
267 let _token = allow_subclass();
271 let mut server = downcast_socket_to_unix(&server).lock();
272 server.state = UnixSocketState::Connected(socket.clone());
273 server.address = listener.address.clone();
274 server.messages.set_capacity(listener.messages.capacity())?;
275 server.credentials = listener.credentials.clone();
276 server.passcred = listener.passcred;
277 server.passsec = listener.passsec;
278 }
279
280 let queue = match listener.state {
283 UnixSocketState::Listening(ref mut queue) => queue,
284 _ => panic!("something changed the server socket state while I held a lock on it"),
285 };
286 queue.sockets.push_back(server);
287 }
288 unix_socket_peer.waiters.notify_fd_events(FdEvents::POLLIN);
289 Ok(())
290 }
291
292 fn connect_datagram(&self, socket: &SocketHandle, peer: &SocketHandle) -> Result<(), Errno> {
293 {
294 let unix_socket = socket.downcast_socket::<UnixSocket>().unwrap();
295 let peer_inner = unix_socket.lock();
296 self.check_type_for_connect(socket, peer, &peer_inner.address)?;
297 }
298 let unix_socket = socket.downcast_socket::<UnixSocket>().unwrap();
299 unix_socket.lock().state = UnixSocketState::Connected(peer.clone());
300 Ok(())
301 }
302
303 pub fn check_type_for_connect(
304 &self,
305 socket: &Socket,
306 peer: &Socket,
307 peer_address: &Option<SocketAddress>,
308 ) -> Result<(), Errno> {
309 if socket.domain != peer.domain || socket.socket_type != peer.socket_type {
310 if let Some(address) = peer_address {
313 if address.is_abstract_unix() {
314 return error!(ECONNREFUSED);
315 }
316 }
317 return error!(EPROTOTYPE);
318 }
319 Ok(())
320 }
321
322 fn lock(&self) -> LockDepGuard<'_, UnixSocketInner> {
324 self.inner.lock()
325 }
326
327 fn is_listening(&self, _socket: &Socket) -> bool {
328 matches!(self.lock().state, UnixSocketState::Listening(_))
329 }
330
331 fn get_receive_capacity(&self) -> usize {
332 self.lock().messages.capacity()
333 }
334
335 fn set_receive_capacity(&self, requested_capacity: usize) {
336 self.lock().set_capacity(requested_capacity);
337 }
338
339 fn get_send_capacity(&self) -> usize {
340 let peer = {
341 if let Some(peer) = self.lock().peer() {
342 peer.clone()
343 } else {
344 return 0;
345 }
346 };
347 let unix_socket = downcast_socket_to_unix(&peer);
348 let capacity = unix_socket.lock().messages.capacity();
349 capacity
350 }
351
352 fn set_send_capacity(&self, requested_capacity: usize) {
353 let peer = {
354 if let Some(peer) = self.lock().peer() {
355 peer.clone()
356 } else {
357 return;
358 }
359 };
360 let unix_socket = downcast_socket_to_unix(&peer);
361 unix_socket.lock().set_capacity(requested_capacity);
362 }
363
364 fn get_linger(&self) -> uapi::linger {
365 let inner = self.lock();
366 inner.linger
367 }
368
369 fn set_linger(&self, linger: uapi::linger) {
370 let mut inner = self.lock();
371 inner.linger = linger;
372 }
373
374 fn get_passcred(&self) -> bool {
375 let inner = self.lock();
376 inner.passcred
377 }
378
379 fn set_passcred(&self, passcred: bool) {
380 let mut inner = self.lock();
381 inner.passcred = passcred;
382 }
383
384 fn get_passsec(&self) -> bool {
385 let inner = self.lock();
386 inner.passsec
387 }
388
389 fn set_passsec(&self, passsec: bool) {
390 let mut inner = self.lock();
391 inner.passsec = passsec;
392 }
393
394 fn get_broadcast(&self) -> bool {
395 let inner = self.lock();
396 inner.broadcast
397 }
398
399 fn set_broadcast(&self, broadcast: bool) {
400 let mut inner = self.lock();
401 inner.broadcast = broadcast;
402 }
403
404 fn get_no_check(&self) -> bool {
405 let inner = self.lock();
406 inner.no_check
407 }
408
409 fn set_no_check(&self, no_check: bool) {
410 let mut inner = self.lock();
411 inner.no_check = no_check;
412 }
413
414 fn get_reuseaddr(&self) -> bool {
415 let inner = self.lock();
416 inner.reuseaddr
417 }
418
419 fn set_reuseaddr(&self, reuseaddr: bool) {
420 let mut inner = self.lock();
421 inner.reuseaddr = reuseaddr;
422 }
423
424 fn get_reuseport(&self) -> bool {
425 let inner = self.lock();
426 inner.reuseport
427 }
428
429 fn set_reuseport(&self, reuseport: bool) {
430 let mut inner = self.lock();
431 inner.reuseport = reuseport;
432 }
433
434 fn get_keepalive(&self) -> bool {
435 let inner = self.lock();
436 inner.keepalive
437 }
438
439 fn set_keepalive(&self, keepalive: bool) {
440 let mut inner = self.lock();
441 inner.keepalive = keepalive;
442 }
443
444 fn set_bpf_program(&self, program: Option<UnixSocketFilter>) {
445 let mut inner = self.lock();
446 inner.bpf_program = program;
447 }
448
449 fn peer_cred(&self) -> Option<ucred> {
450 let peer = {
451 let inner = self.lock();
452 inner.peer().cloned()
453 };
454 if let Some(peer) = peer {
455 let unix_socket = downcast_socket_to_unix(&peer);
456 let unix_socket = unix_socket.lock();
457 unix_socket.credentials.clone()
458 } else {
459 None
460 }
461 }
462
463 pub fn bind_socket_to_node(
464 &self,
465 socket: &SocketHandle,
466 address: SocketAddress,
467 node: &FsNodeHandle,
468 ) -> Result<(), Errno> {
469 let unix_socket = downcast_socket_to_unix(socket);
470 let mut inner = unix_socket.lock();
471 inner.bind(address)?;
472 node.set_bound_socket(socket.clone());
473 Ok(())
474 }
475
476 fn notify_shutdown(&self) {
477 self.waiters.notify_fd_events(FdEvents::POLLIN | FdEvents::POLLOUT | FdEvents::POLLHUP);
478 }
479}
480
481impl SocketOps for UnixSocket {
482 fn connect(
483 &self,
484 socket: &SocketHandle,
485 current_task: &CurrentTask,
486 peer: SocketPeer,
487 ) -> Result<(), Errno> {
488 let peer = match peer {
489 SocketPeer::Handle(handle) => handle,
490 SocketPeer::Address(_) => return error!(EINVAL),
491 };
492 match socket.socket_type {
493 SocketType::Stream | SocketType::SeqPacket => {
494 self.connect_stream(socket, current_task, &peer)
495 }
496 SocketType::Datagram | SocketType::Raw => self.connect_datagram(socket, &peer),
497 _ => error!(EINVAL),
498 }
499 }
500
501 fn listen(&self, socket: &Socket, backlog: i32, credentials: ucred) -> Result<(), Errno> {
502 match socket.socket_type {
503 SocketType::Stream | SocketType::SeqPacket => {}
504 _ => return error!(EOPNOTSUPP),
505 }
506 let mut inner = self.lock();
507 inner.credentials = Some(credentials);
508 let is_bound = inner.address.is_some();
509 let backlog = if backlog < 0 { DEFAULT_LISTEN_BACKLOG } else { backlog as usize };
510 match &mut inner.state {
511 UnixSocketState::Disconnected if is_bound => {
512 inner.state = UnixSocketState::Listening(AcceptQueue::new(backlog));
513 Ok(())
514 }
515 UnixSocketState::Listening(queue) => {
516 queue.set_backlog(backlog)?;
517 Ok(())
518 }
519 _ => error!(EINVAL),
520 }
521 }
522
523 fn accept(&self, socket: &Socket, _current_task: &CurrentTask) -> Result<SocketHandle, Errno> {
524 match socket.socket_type {
525 SocketType::Stream | SocketType::SeqPacket => {}
526 _ => return error!(EOPNOTSUPP),
527 }
528 let mut inner = self.lock();
529 let queue = match &mut inner.state {
530 UnixSocketState::Listening(queue) => queue,
531 _ => return error!(EINVAL),
532 };
533 queue.sockets.pop_front().ok_or_else(|| errno!(EAGAIN))
534 }
535
536 fn bind(
537 &self,
538 _socket: &Socket,
539 _current_task: &CurrentTask,
540 socket_address: SocketAddress,
541 ) -> Result<(), Errno> {
542 match socket_address {
543 SocketAddress::Unix(_) => {}
544 _ => return error!(EINVAL),
545 }
546 self.lock().bind(socket_address)
547 }
548
549 fn read(
550 &self,
551 socket: &Socket,
552 _current_task: &CurrentTask,
553 data: &mut dyn OutputBuffer,
554 flags: SocketMessageFlags,
555 ) -> Result<MessageReadInfo, Errno> {
556 let info = self.lock().read(data, socket.socket_type, flags)?;
557 if info.bytes_read > 0 {
558 let peer = {
559 let inner = self.lock();
560 inner.peer().cloned()
561 };
562 if let Some(socket) = peer {
563 let unix_socket_peer = socket.downcast_socket::<UnixSocket>();
564 if let Some(socket) = unix_socket_peer {
565 socket.waiters.notify_fd_events(FdEvents::POLLOUT);
566 }
567 }
568 }
569 Ok(info)
570 }
571
572 fn write(
573 &self,
574 socket: &Socket,
575 current_task: &CurrentTask,
576 data: &mut dyn InputBuffer,
577 dest_address: &mut Option<SocketAddress>,
578 ancillary_data: &mut Vec<AncillaryData>,
579 ) -> Result<usize, Errno> {
580 let (connected_peer, local_address, creds) = {
581 let inner = self.lock();
582 (inner.peer().map(|p| p.clone()), inner.address.clone(), inner.credentials.clone())
583 };
584
585 let peer = match (connected_peer, dest_address, socket.socket_type) {
586 (Some(peer), None, _) => peer,
587 (None, Some(_), SocketType::Stream) => return error!(EOPNOTSUPP),
588 (None, Some(_), SocketType::SeqPacket) => return error!(ENOTCONN),
589 (Some(_), Some(_), _) => return error!(EISCONN),
590 (_, Some(SocketAddress::Unix(name)), _) => {
591 resolve_unix_socket_address(current_task, name.as_ref())?
592 }
593 (_, Some(_), _) => return error!(EINVAL),
594 (None, None, _) => return error!(ENOTCONN),
595 };
596
597 if socket.socket_type == SocketType::Datagram {
598 security::unix_may_send(current_task, socket, &peer)?;
599 }
600
601 let unix_socket = downcast_socket_to_unix(&peer);
602 let bytes_written = {
603 let mut peer = unix_socket.lock();
604 if peer.passcred {
605 let creds = creds.unwrap_or_else(|| current_task.current_ucred());
606 ancillary_data.push(AncillaryData::Unix(UnixControlData::Credentials(creds)));
607 }
608 if peer.passsec {
609 let context = security::socket_getpeersec_dgram(current_task, socket);
612 ancillary_data.push(AncillaryData::Unix(UnixControlData::Security(context.into())));
613 }
614 peer.write(current_task, data, local_address, ancillary_data, socket.socket_type)?
615 };
616 if bytes_written > 0 {
617 unix_socket.waiters.notify_fd_events(FdEvents::POLLIN);
618 }
619 Ok(bytes_written)
620 }
621
622 fn wait_async(
623 &self,
624 _socket: &Socket,
625 _current_task: &CurrentTask,
626 waiter: &Waiter,
627 events: FdEvents,
628 handler: EventHandler,
629 ) -> WaitCanceler {
630 self.waiters.wait_async_fd_events(waiter, events, handler)
631 }
632
633 fn query_events(
634 &self,
635 _socket: &Socket,
636 _current_task: &CurrentTask,
637 ) -> Result<FdEvents, Errno> {
638 let (mut events, peer) = {
641 let inner = self.lock();
642
643 let mut events = FdEvents::empty();
644 let local_events = inner.messages.query_events();
645 if local_events.contains(FdEvents::POLLIN) {
648 events = FdEvents::POLLIN;
649 }
650
651 if inner.is_shutdown {
652 events |= FdEvents::POLLIN | FdEvents::POLLOUT | FdEvents::POLLHUP;
653 }
654
655 match &inner.state {
656 UnixSocketState::Listening(queue) => {
657 if !queue.sockets.is_empty() {
658 events |= FdEvents::POLLIN;
659 }
660 }
661 UnixSocketState::Closed => {
662 events |= FdEvents::POLLHUP;
663 }
664 _ => {}
665 }
666
667 (events, inner.peer().cloned())
668 };
669
670 if let Some(peer) = peer {
672 let unix_socket = downcast_socket_to_unix(&peer);
673 let peer_inner = unix_socket.lock();
674 let peer_events = peer_inner.messages.query_events();
675 if peer_events.contains(FdEvents::POLLOUT) {
676 events |= FdEvents::POLLOUT;
677 }
678 }
679
680 Ok(events)
681 }
682
683 fn shutdown(&self, _socket: &Socket, how: SocketShutdownFlags) -> Result<(), Errno> {
687 let mut should_notify_self = false;
688 let mut should_notify_peer = false;
689 let peer = {
690 let mut inner = self.lock();
691 let peer = inner.peer().ok_or_else(|| errno!(ENOTCONN))?.clone();
692 if how.contains(SocketShutdownFlags::READ) {
693 inner.is_shutdown = true;
694 should_notify_self = true;
695 }
696 peer
697 };
698 if how.contains(SocketShutdownFlags::WRITE) {
699 let unix_socket = downcast_socket_to_unix(&peer);
700 unix_socket.lock().is_shutdown = true;
701 should_notify_peer = true;
702 }
703 if should_notify_self {
704 self.waiters.notify_fd_events(FdEvents::POLLIN | FdEvents::POLLOUT | FdEvents::POLLHUP);
705 }
706 if should_notify_peer {
707 let unix_socket = downcast_socket_to_unix(&peer);
708 unix_socket
709 .waiters
710 .notify_fd_events(FdEvents::POLLIN | FdEvents::POLLOUT | FdEvents::POLLHUP);
711 }
712 Ok(())
713 }
714
715 fn close(&self, _current_task: &CurrentTask, socket: &Socket) {
726 let (maybe_peer, has_unread) = {
727 let mut inner = self.lock();
728 let maybe_peer = inner.peer().map(Arc::clone);
729 inner.is_shutdown = true;
730 inner.state = UnixSocketState::Closed;
731 (maybe_peer, !inner.messages.is_empty())
732 };
733 self.notify_shutdown();
734 if socket.socket_type == SocketType::Stream || socket.socket_type == SocketType::SeqPacket {
736 if let Some(peer) = maybe_peer {
737 let unix_socket = downcast_socket_to_unix(&peer);
738
739 {
740 let mut peer_inner = unix_socket.lock();
741 if has_unread {
742 peer_inner.peer_closed_with_unread_data = true;
743 }
744 peer_inner.is_shutdown = true;
745 }
746 unix_socket.notify_shutdown();
747 }
748 }
749 }
750
751 fn getsockname(&self, socket: &Socket) -> Result<SocketAddress, Errno> {
756 let inner = self.lock();
757 if let Some(address) = &inner.address {
758 Ok(address.clone())
759 } else {
760 Ok(SocketAddress::default_for_domain(socket.domain))
761 }
762 }
763
764 fn getpeername(&self, _socket: &Socket) -> Result<SocketAddress, Errno> {
768 let peer = self.lock().peer().ok_or_else(|| errno!(ENOTCONN))?.clone();
769 peer.getsockname()
770 }
771
772 fn setsockopt(
773 &self,
774 _socket: &Socket,
775 current_task: &CurrentTask,
776 level: u32,
777 optname: u32,
778 optval: SockOptValue,
779 ) -> Result<(), Errno> {
780 match level {
781 SOL_SOCKET => match optname {
782 SO_SNDBUF => {
783 let requested_capacity: socklen_t = optval.read(current_task)?;
784 self.set_send_capacity(requested_capacity as usize * 2);
786 }
787 SO_RCVBUF => {
788 let requested_capacity: socklen_t = optval.read(current_task)?;
789 self.set_receive_capacity(requested_capacity as usize);
790 }
791 SO_LINGER => {
792 let mut linger: uapi::linger = optval.read(current_task)?;
793 if linger.l_onoff != 0 {
794 linger.l_onoff = 1;
795 }
796 self.set_linger(linger);
797 }
798 SO_PASSCRED => {
799 let passcred: u32 = optval.read(current_task)?;
800 self.set_passcred(passcred != 0);
801 }
802 SO_PASSSEC => {
803 let passsec: u32 = optval.read(current_task)?;
804 self.set_passsec(passsec != 0);
805 }
806 SO_BROADCAST => {
807 let broadcast: u32 = optval.read(current_task)?;
808 self.set_broadcast(broadcast != 0);
809 }
810 SO_NO_CHECK => {
811 let no_check: u32 = optval.read(current_task)?;
812 self.set_no_check(no_check != 0);
813 }
814 SO_REUSEADDR => {
815 let reuseaddr: u32 = optval.read(current_task)?;
816 self.set_reuseaddr(reuseaddr != 0);
817 }
818 SO_REUSEPORT => {
819 let reuseport: u32 = optval.read(current_task)?;
820 self.set_reuseport(reuseport != 0);
821 }
822 SO_KEEPALIVE => {
823 let keepalive: u32 = optval.read(current_task)?;
824 self.set_keepalive(keepalive != 0);
825 }
826 SO_ATTACH_BPF => {
827 let fd: FdNumber = optval.read(current_task)?;
828 let object = get_bpf_object(current_task, fd)?;
829 let program = object.as_program()?;
830
831 let linked_program = program.link(ProgramType::SocketFilter)?;
832
833 self.set_bpf_program(Some(linked_program));
834 }
835 _ => return error!(ENOPROTOOPT),
836 },
837 _ => return error!(ENOPROTOOPT),
838 }
839 Ok(())
840 }
841
842 fn getsockopt(
843 &self,
844 socket: &Socket,
845 current_task: &CurrentTask,
846 level: u32,
847 optname: u32,
848 _optlen: u32,
849 ) -> Result<Vec<u8>, Errno> {
850 match level {
851 SOL_SOCKET => match optname {
852 SO_PEERCRED => Ok(UcredPtr::into_bytes(
853 current_task,
854 self.peer_cred().unwrap_or(ucred { pid: 0, uid: uid_t::MAX, gid: gid_t::MAX }),
855 )
856 .map_err(|_| errno!(EINVAL))?),
857 SO_PEERSEC => match socket.socket_type {
858 SocketType::Stream => security::socket_getpeersec_stream(current_task, socket),
859 _ => error!(ENOPROTOOPT),
860 },
861 SO_ACCEPTCONN =>
862 {
863 #[allow(clippy::bool_to_int_with_if)]
864 Ok(if self.is_listening(socket) { 1u32 } else { 0u32 }.to_ne_bytes().to_vec())
865 }
866 SO_SNDBUF => Ok((self.get_send_capacity() as socklen_t).to_ne_bytes().to_vec()),
867 SO_RCVBUF => Ok((self.get_receive_capacity() as socklen_t).to_ne_bytes().to_vec()),
868 SO_LINGER => Ok(self.get_linger().as_bytes().to_vec()),
869 SO_PASSCRED => Ok((self.get_passcred() as u32).as_bytes().to_vec()),
870 SO_PASSSEC => Ok((self.get_passsec() as u32).as_bytes().to_vec()),
871 SO_BROADCAST => Ok((self.get_broadcast() as u32).as_bytes().to_vec()),
872 SO_NO_CHECK => Ok((self.get_no_check() as u32).as_bytes().to_vec()),
873 SO_REUSEADDR => Ok((self.get_reuseaddr() as u32).as_bytes().to_vec()),
874 SO_REUSEPORT => Ok((self.get_reuseport() as u32).as_bytes().to_vec()),
875 SO_KEEPALIVE => Ok((self.get_keepalive() as u32).as_bytes().to_vec()),
876 SO_ERROR => Ok((0u32).as_bytes().to_vec()),
877 _ => error!(ENOPROTOOPT),
878 },
879 _ => error!(ENOPROTOOPT),
880 }
881 }
882
883 fn ioctl(
884 &self,
885 socket: &Socket,
886 _file: &FileObject,
887 current_task: &CurrentTask,
888 request: u32,
889 arg: SyscallArg,
890 ) -> Result<SyscallResult, Errno> {
891 let user_addr = UserAddress::from(arg);
892 match request {
893 FIONREAD if socket.socket_type == SocketType::Stream => {
894 let length: i32 =
895 self.lock().messages.len().try_into().map_err(|_| errno!(EINVAL))?;
896 current_task.write_object(UserRef::<i32>::new(user_addr), &length)?;
897 Ok(SUCCESS)
898 }
899 _ => error!(ENOTTY),
900 }
901 }
902}
903
904impl UnixSocketInner {
905 fn bind(&mut self, socket_address: SocketAddress) -> Result<(), Errno> {
906 if self.address.is_some() {
907 return error!(EINVAL);
908 }
909 self.address = Some(socket_address);
910 Ok(())
911 }
912
913 fn set_capacity(&mut self, requested_capacity: usize) {
914 let capacity = requested_capacity.clamp(SOCKET_MIN_SIZE, SOCKET_MAX_SIZE);
915 let capacity = std::cmp::max(capacity, self.messages.len());
916 self.messages.set_capacity(capacity).unwrap();
918 }
919
920 fn peer(&self) -> Option<&SocketHandle> {
923 match &self.state {
924 UnixSocketState::Connected(peer) => Some(peer),
925 _ => None,
926 }
927 }
928
929 fn read(
940 &mut self,
941 data: &mut dyn OutputBuffer,
942 socket_type: SocketType,
943 flags: SocketMessageFlags,
944 ) -> Result<MessageReadInfo, Errno> {
945 let mut info = if socket_type == SocketType::Stream {
946 if data.available() == 0 {
947 return Ok(MessageReadInfo::default());
948 }
949
950 if flags.contains(SocketMessageFlags::PEEK) {
951 self.messages.peek_stream(data)?
952 } else {
953 self.messages.read_stream(data)?
954 }
955 } else if flags.contains(SocketMessageFlags::PEEK) {
956 self.messages.peek_datagram(data)?
957 } else {
958 self.messages.read_datagram(data)?
959 };
960 if info.message_length == 0 {
961 if self.peer_closed_with_unread_data {
962 self.peer_closed_with_unread_data = false;
964 return error!(ECONNRESET);
965 }
966 if !self.is_shutdown {
967 return error!(EAGAIN);
968 }
969 }
970
971 let creds_message;
974 if let Some(index) = info
975 .ancillary_data
976 .iter()
977 .position(|m| matches!(m, AncillaryData::Unix(UnixControlData::Credentials { .. })))
978 {
979 creds_message = info.ancillary_data.remove(index)
980 } else {
981 creds_message = AncillaryData::Unix(UnixControlData::unknown_creds());
983 }
984 if self.passcred {
985 info.ancillary_data.insert(0, creds_message);
987 }
988
989 Ok(info)
990 }
991
992 fn write(
1001 &mut self,
1002 current_task: &CurrentTask,
1003 data: &mut dyn InputBuffer,
1004 address: Option<SocketAddress>,
1005 ancillary_data: &mut Vec<AncillaryData>,
1006 socket_type: SocketType,
1007 ) -> Result<usize, Errno> {
1008 if self.is_shutdown {
1009 return error!(EPIPE);
1010 }
1011 let filter = |mut message: Message| {
1012 let Some(bpf_program) = self.bpf_program.as_ref() else {
1013 return Some(message);
1014 };
1015
1016 let mut sk_buf = SkBuf::default();
1018
1019 let mut context = EbpfRunContextImpl::<'_>::new(current_task);
1020 let s = bpf_program.run(&mut context, &mut sk_buf);
1021 if s == 0 {
1022 None
1023 } else {
1024 message.truncate(s as usize);
1025 Some(message)
1026 }
1027 };
1028 let bytes_written = if socket_type == SocketType::Stream {
1029 self.messages.write_stream_with_filter(data, address, ancillary_data, filter)?
1030 } else {
1031 self.messages.write_datagram_with_filter(data, address, ancillary_data, filter)?
1032 };
1033 Ok(bytes_written)
1034 }
1035}
1036
1037pub fn resolve_unix_socket_address(
1038 current_task: &CurrentTask,
1039 name: &FsStr,
1040) -> Result<SocketHandle, Errno> {
1041 if name[0] == b'\0' {
1042 current_task.running_state().abstract_socket_namespace.lookup(name)
1043 } else {
1044 let mut context = LookupContext::default();
1045 let (parent, basename) =
1046 current_task.lookup_parent_at(&mut context, FdNumber::AT_FDCWD, name)?;
1047 let name = parent.lookup_child(current_task, &mut context, basename).map_err(|errno| {
1048 if matches!(errno.code, EACCES | EPERM | EINTR) { errno } else { errno!(ECONNREFUSED) }
1049 })?;
1050 name.check_access(
1051 current_task,
1052 Access::WRITE,
1053 CheckAccessReason::InternalPermissionChecks,
1054 )?;
1055 name.entry.node.bound_socket().map(|s| s.clone()).ok_or_else(|| errno!(ECONNREFUSED))
1056 }
1057}
1058
1059#[repr(C)]
1061#[derive(Default)]
1062struct SkBuf {
1063 sk_buff: __sk_buff,
1064}
1065
1066impl Packet for &mut SkBuf {
1067 fn load(&self, _offset: i32, _width: DataWidth) -> Option<BpfValue> {
1068 None
1070 }
1071}
1072
1073impl<'a> PacketWithLoadBytes for &'a mut SkBuf {
1074 fn load_bytes_relative(
1075 &self,
1076 _base: LoadBytesBase,
1077 _offset: usize,
1078 _buf: ebpf::EbpfBufferPtr<'_>,
1079 ) -> i64 {
1080 track_stub!(TODO("https://fxbug.dev/385015056"), "bpf_load_bytes_relative");
1081 -1
1082 }
1083}
1084
1085impl ProgramArgument for &'_ mut SkBuf {
1086 fn get_type() -> &'static Type {
1087 &*SOCKET_FILTER_SK_BUF_TYPE
1088 }
1089}
1090
1091impl SocketRef for &'_ mut SkBuf {
1092 fn get_socket_cookie(&self) -> Option<u64> {
1093 track_stub!(TODO("https://fxbug.dev/385015056"), "bpf_get_socket_cookie");
1094 None
1095 }
1096
1097 fn get_socket_uid(&self) -> Option<uid_t> {
1098 track_stub!(TODO("https://fxbug.dev/385015056"), "bpf_get_socket_uid");
1099 None
1100 }
1101}
1102
1103struct UnixSocketEbpfContext {}
1104impl BpfProgramContext for UnixSocketEbpfContext {
1105 type RunContext<'a> = EbpfRunContextImpl<'a>;
1106 type Packet<'a> = &'a mut SkBuf;
1107 type Map = PinnedMap;
1108 const CBPF_CONFIG: &'static CbpfConfig = &SOCKET_FILTER_CBPF_CONFIG;
1109}
1110
1111ebpf_api::ebpf_program_context_type!(UnixSocketEbpfContext, SocketFilterProgramContext);
1112
1113type UnixSocketFilter = EbpfProgram<UnixSocketEbpfContext>;
1114
1115#[cfg(test)]
1116mod tests {
1117 use super::*;
1118 use crate::mm::MemoryAccessor;
1119 use crate::testing::{map_memory, spawn_kernel_and_run};
1120 use starnix_types::user_buffer::UserBuffer;
1121
1122 #[::fuchsia::test]
1123 async fn test_socket_send_capacity() {
1124 spawn_kernel_and_run(async |current_task| {
1125 let _kernel = current_task.kernel();
1126 let socket = Socket::new(
1127 ¤t_task,
1128 SocketDomain::Unix,
1129 SocketType::Stream,
1130 SocketProtocol::default(),
1131 false,
1132 )
1133 .expect("Failed to create socket.");
1134 socket
1135 .bind(¤t_task, SocketAddress::Unix(b"\0".into()))
1136 .expect("Failed to bind socket.");
1137 socket.listen(¤t_task, 10).expect("Failed to listen.");
1138 let connecting_socket = Socket::new(
1139 ¤t_task,
1140 SocketDomain::Unix,
1141 SocketType::Stream,
1142 SocketProtocol::default(),
1143 false,
1144 )
1145 .expect("Failed to connect socket.");
1146 connecting_socket
1147 .ops
1148 .connect(&connecting_socket, ¤t_task, SocketPeer::Handle(socket.clone()))
1149 .expect("Failed to connect socket.");
1150 assert_eq!(Ok(FdEvents::POLLIN), socket.query_events(¤t_task));
1151 let server_socket = socket.accept(¤t_task).unwrap();
1152
1153 let opt_size = std::mem::size_of::<socklen_t>();
1154 let user_address = map_memory(¤t_task, UserAddress::default(), opt_size as u64);
1155 let send_capacity: socklen_t = 4 * 4096;
1156 current_task.write_memory(user_address, &send_capacity.to_ne_bytes()).unwrap();
1157 let user_buffer = UserBuffer { address: user_address, length: opt_size };
1158 server_socket
1159 .setsockopt(¤t_task, SOL_SOCKET, SO_SNDBUF, user_buffer.into())
1160 .unwrap();
1161
1162 let opt_bytes =
1163 server_socket.getsockopt(¤t_task, SOL_SOCKET, SO_SNDBUF, 0).unwrap();
1164 let retrieved_capacity = socklen_t::from_ne_bytes(opt_bytes.try_into().unwrap());
1165 assert_eq!(2 * send_capacity, retrieved_capacity);
1167 })
1168 .await;
1169 }
1170}