Skip to main content

starnix_core/vfs/socket/
socket_unix.rs

1// Copyright 2022 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use 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
46// From unix.go in gVisor.
47const SOCKET_MIN_SIZE: usize = 4 << 10;
48const SOCKET_DEFAULT_SIZE: usize = 208 << 10;
49const SOCKET_MAX_SIZE: usize = 4 << 20;
50
51/// The data of a socket is stored in the "Inner" struct. Because both ends have separate locks,
52/// care must be taken to avoid taking both locks since there is no way to tell what order to
53/// take them in.
54///
55/// When writing, data is buffered in the "other" end of the socket's Inner.MessageQueue:
56///
57///            UnixSocket end #1          UnixSocket end #2
58///            +---------------+          +---------------+
59///            |               |          |   +-------+   |
60///   Writes -------------------------------->| Inner |------> Reads
61///            |               |          |   +-------+   |
62///            |   +-------+   |          |               |
63///   Reads <------| Inner |<-------------------------------- Writes
64///            |   +-------+   |          |               |
65///            +---------------+          +---------------+
66///
67pub struct UnixSocket {
68    inner: LockDepMutex<UnixSocketInner, UnixSocketInnerLock>,
69    waiters: WaitQueue,
70}
71
72fn downcast_socket_to_unix(socket: &Socket) -> &UnixSocket {
73    // It is a programing error if we are downcasting
74    // a different type of socket as sockets from different families
75    // should not communicate, so unwrapping here
76    // will let us know that.
77    socket.downcast_socket::<UnixSocket>().unwrap()
78}
79
80enum UnixSocketState {
81    /// The socket has not been connected.
82    Disconnected,
83
84    /// The socket has had `listen` called and can accept incoming connections.
85    Listening(AcceptQueue),
86
87    /// The socket is connected to a peer.
88    Connected(SocketHandle),
89
90    /// The socket is closed.
91    Closed,
92}
93
94struct UnixSocketInner {
95    /// The `MessageQueue` that contains messages sent to this socket.
96    messages: MessageQueue,
97
98    /// The address that this socket has been bound to, if it has been bound.
99    address: Option<SocketAddress>,
100
101    /// Whether this end of the socket has been shut down and can no longer receive message. It is
102    /// still possible to send messages to the peer, if it exists and hasn't also been shut down.
103    is_shutdown: bool,
104
105    /// Whether the peer had unread data when it was closed. In this case, reads should return
106    /// ECONNRESET instead of 0 (eof).
107    peer_closed_with_unread_data: bool,
108
109    /// See SO_LINGER.
110    linger: uapi::linger,
111
112    /// See SO_PASSCRED.
113    passcred: bool,
114
115    /// See SO_PASSSEC.
116    passsec: bool,
117
118    /// See SO_BROADCAST.
119    broadcast: bool,
120
121    /// See SO_NO_CHECK.
122    no_check: bool,
123
124    /// See SO_REUSEPORT.
125    reuseport: bool,
126
127    /// See SO_REUSEADDR.
128    reuseaddr: bool,
129
130    /// See SO_KEEPALIVE.
131    keepalive: bool,
132
133    /// See SO_ATTACH_BPF.
134    bpf_program: Option<UnixSocketFilter>,
135
136    /// Unix credentials of the owner of this socket, for SO_PEERCRED.
137    credentials: Option<ucred>,
138
139    /// Socket state: a queue if this is a listening socket, or a peer if this is a connected
140    /// socket.
141    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    /// Creates a pair of connected sockets.
170    ///
171    /// # Parameters
172    /// - `domain`: The domain of the socket (e.g., `AF_UNIX`).
173    /// - `socket_type`: The type of the socket (e.g., `SOCK_STREAM`).
174    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            /* kernel_private = */ false,
187        )?;
188        let right = Socket::new(
189            current_task,
190            domain,
191            socket_type,
192            SocketProtocol::default(),
193            /* kernel_private = */ 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            /* kernel_private= */ false,
204        )?;
205        let right = SocketFile::from_socket(
206            current_task,
207            right,
208            open_flags,
209            /* kernel_private= */ 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        // Only hold one lock at a time until we make sure the lock ordering
225        // is right: client before listener
226        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            // Lock ordering is client before listener.
241            let _token = allow_subclass();
242            let mut listener = unix_socket_peer.lock();
243
244            // Must check this again because we released the listener lock for a moment
245            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                /* kernel_private = */ 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                // This allow_subclass is safe because `server` is a newly created socket
268                // that hasn't been added to any public table or returned to the user yet.
269                // It is unreachable by other threads, making lock ordering cycles impossible.
270                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            // We already checked that the socket is in Listening state...but the borrow checker cannot
281            // be convinced that it's ok to combine these checks
282            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            // According to ConnectWithWrongType in accept_bind_test, abstract
311            // UNIX domain sockets return ECONNREFUSED rather than EPROTOTYPE.
312            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    /// Locks and returns the inner state of the Socket.
323    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                // TODO: https://fxbug.dev/364568855 - Store the opaque LSM property value, and expand
610                // it to a string upon readmsg.
611                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        // Note that self.lock() must be dropped before acquiring peer.inner.lock() to avoid
639        // potential deadlocks.
640        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            // From our end's message queue we only care about POLLIN (whether we have data stored
646            // that's readable). POLLOUT is based on whether the peer end has room in its buffer.
647            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        // Check the peer (outside of our lock) to see if it can accept data written from our end.
671        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    /// Shuts down this socket according to how, preventing any future reads and/or writes.
684    ///
685    /// Used by the shutdown syscalls.
686    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    /// Close this socket.
716    ///
717    /// Called by SocketFile when the file descriptor that is holding this
718    /// socket is closed.
719    ///
720    /// Close differs from shutdown in two ways. First, close will call
721    /// mark_peer_closed_with_unread_data if this socket has unread data,
722    /// which changes how read() behaves on that socket. Second, close
723    /// transitions the internal state of this socket to Closed, which breaks
724    /// the reference cycle that exists in the connected state.
725    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 this is a connected socket type, also shut down the connected peer.
735        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    /// Returns the name of this socket.
752    ///
753    /// The name is derived from the address and domain. A socket
754    /// will always have a name, even if it is not bound to an address.
755    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    /// Returns the name of the peer of this socket, if such a peer exists.
765    ///
766    /// Returns an error if the socket is not connected.
767    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                    // See StreamUnixSocketPairTest.SetSocketSendBuf for why we multiply by 2 here.
785                    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        // We have validated capacity sufficiently that set_capacity should always succeed.
917        self.messages.set_capacity(capacity).unwrap();
918    }
919
920    /// Returns the socket that is connected to this socket, if such a peer exists. Returns
921    /// ENOTCONN otherwise.
922    fn peer(&self) -> Option<&SocketHandle> {
923        match &self.state {
924            UnixSocketState::Connected(peer) => Some(peer),
925            _ => None,
926        }
927    }
928
929    /// Reads the the contents of this socket into `InputBuffer`.
930    ///
931    /// Will stop reading if a message with ancillary data is encountered (after the message with
932    /// ancillary data has been read).
933    ///
934    /// # Parameters
935    /// - `data`: The `OutputBuffer` to write the data to.
936    ///
937    /// Returns the number of bytes that were read into the buffer, and any ancillary data that was
938    /// read from the socket.
939    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                // Reset the flag
963                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        // Remove any credentials message, so that it can be moved to the front if passcred is
972        // enabled, or simply be removed if passcred is not enabled.
973        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            // If passcred is enabled credentials are returned even if they were not sent.
982            creds_message = AncillaryData::Unix(UnixControlData::unknown_creds());
983        }
984        if self.passcred {
985            // Allow credentials to take priority if they are enabled, so insert at 0.
986            info.ancillary_data.insert(0, creds_message);
987        }
988
989        Ok(info)
990    }
991
992    /// Writes the the contents of `InputBuffer` into this socket.
993    ///
994    /// # Parameters
995    /// - `data`: The `InputBuffer` to read the data from.
996    /// - `ancillary_data`: Any ancillary data to write to the socket. Note that the ancillary data
997    ///                     will only be written if the entirety of the requested write completes.
998    ///
999    /// Returns the number of bytes that were written to the socket.
1000    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            // TODO(https://fxbug.dev/385015056): Fill in SkBuf.
1017            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// Packet buffer representation used for eBPF filters.
1060#[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        // TODO(https://fxbug.dev/385015056): Implement packet access.
1069        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                &current_task,
1128                SocketDomain::Unix,
1129                SocketType::Stream,
1130                SocketProtocol::default(),
1131                /* kernel_private = */ false,
1132            )
1133            .expect("Failed to create socket.");
1134            socket
1135                .bind(&current_task, SocketAddress::Unix(b"\0".into()))
1136                .expect("Failed to bind socket.");
1137            socket.listen(&current_task, 10).expect("Failed to listen.");
1138            let connecting_socket = Socket::new(
1139                &current_task,
1140                SocketDomain::Unix,
1141                SocketType::Stream,
1142                SocketProtocol::default(),
1143                /* kernel_private = */ false,
1144            )
1145            .expect("Failed to connect socket.");
1146            connecting_socket
1147                .ops
1148                .connect(&connecting_socket, &current_task, SocketPeer::Handle(socket.clone()))
1149                .expect("Failed to connect socket.");
1150            assert_eq!(Ok(FdEvents::POLLIN), socket.query_events(&current_task));
1151            let server_socket = socket.accept(&current_task).unwrap();
1152
1153            let opt_size = std::mem::size_of::<socklen_t>();
1154            let user_address = map_memory(&current_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(&current_task, SOL_SOCKET, SO_SNDBUF, user_buffer.into())
1160                .unwrap();
1161
1162            let opt_bytes =
1163                server_socket.getsockopt(&current_task, SOL_SOCKET, SO_SNDBUF, 0).unwrap();
1164            let retrieved_capacity = socklen_t::from_ne_bytes(opt_bytes.try_into().unwrap());
1165            // Setting SO_SNDBUF actually sets it to double the size
1166            assert_eq!(2 * send_capacity, retrieved_capacity);
1167        })
1168        .await;
1169    }
1170}