Skip to main content

starnix_core/vfs/socket/
socket_netlink.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::security::{self, AuditLogger, AuditMessage, AuditRequest};
6use crate::vfs::socket::{SockOptValue, SocketDomain};
7use futures::channel::mpsc::{
8    UnboundedReceiver, UnboundedSender, {self},
9};
10use linux_uapi::{AUDIT_GET, audit_status};
11use netlink::messaging::{
12    AccessControl, MessageWithPermission, NetlinkContext, NetlinkMessageWithCreds, Permission,
13    Sender, UnparsedNetlinkMessage,
14};
15use netlink::multicast_groups::{
16    InvalidLegacyGroupsError, InvalidModernGroupError, LegacyGroups, ModernGroup,
17    NoMappingFromModernToLegacyGroupError, SingleLegacyGroup,
18};
19use netlink::protocol_family::NetlinkClient;
20use netlink::protocol_family::route::NetlinkRouteClient;
21use netlink::protocol_family::sock_diag::NetlinkSockDiagClient;
22use netlink::{NETLINK_LOG_TAG, NewClientError};
23use netlink_packet_core::{
24    ErrorMessage, NETLINK_HEADER_LEN, NLMSG_ERROR, NetlinkBuffer, NetlinkDeserializable,
25    NetlinkHeader, NetlinkMessage, NetlinkPayload, NetlinkSerializable,
26};
27use netlink_packet_utils::{DecodeError, Emitable as _};
28use starnix_sync::{FileOpsCore, LockEqualOrBefore, Locked, Mutex};
29use std::marker::PhantomData;
30use std::num::{NonZeroI32, NonZeroU32};
31use std::sync::Arc;
32use zerocopy::{FromBytes, IntoBytes};
33
34use crate::device::kobject::{Device, UEventAction, UEventContext};
35use crate::device::{DeviceListener, DeviceListenerKey};
36use crate::task::{CurrentTask, EventHandler, Kernel, WaitCanceler, WaitQueue, Waiter};
37use crate::vfs::buffers::{
38    AncillaryData, InputBuffer, Message, MessageQueue, MessageReadInfo, OutputBuffer,
39    UnixControlData, VecInputBuffer,
40};
41use crate::vfs::socket::{
42    GenericMessage, GenericNetlinkClientHandle, Socket, SocketAddress, SocketHandle,
43    SocketMessageFlags, SocketOps, SocketPeer, SocketShutdownFlags, SocketType,
44};
45use starnix_logging::{log_debug, log_error, log_warn, track_stub};
46use starnix_uapi::auth::{CAP_AUDIT_CONTROL, CAP_AUDIT_WRITE, CAP_NET_ADMIN, Credentials};
47use starnix_uapi::errors::Errno;
48use starnix_uapi::vfs::FdEvents;
49use starnix_uapi::{
50    AF_NETLINK, NETLINK_ADD_MEMBERSHIP, NETLINK_AUDIT, NETLINK_CONNECTOR, NETLINK_CRYPTO,
51    NETLINK_DNRTMSG, NETLINK_DROP_MEMBERSHIP, NETLINK_ECRYPTFS, NETLINK_FIB_LOOKUP,
52    NETLINK_FIREWALL, NETLINK_GENERIC, NETLINK_IP6_FW, NETLINK_ISCSI, NETLINK_KOBJECT_UEVENT,
53    NETLINK_NETFILTER, NETLINK_NFLOG, NETLINK_RDMA, NETLINK_ROUTE, NETLINK_SCSITRANSPORT,
54    NETLINK_SELINUX, NETLINK_SMC, NETLINK_SOCK_DIAG, NETLINK_USERSOCK, NETLINK_XFRM, NLM_F_MULTI,
55    NLMSG_DONE, SO_PASSCRED, SO_PROTOCOL, SO_RCVBUF, SO_RCVBUFFORCE, SO_SNDBUF, SO_SNDBUFFORCE,
56    SO_TIMESTAMP, SOL_SOCKET, errno, error, nlmsghdr, sockaddr_nl, socklen_t, ucred,
57};
58
59// From netlink/socket.go in gVisor.
60pub const SOCKET_MIN_SIZE: usize = 4 << 10;
61pub const SOCKET_DEFAULT_SIZE: usize = 16 * 1024;
62pub const SOCKET_MAX_SIZE: usize = 4 << 20;
63
64// From linux/socket.go in gVisor.
65const SOL_NETLINK: u32 = 270;
66
67pub fn new_netlink_socket(
68    kernel: &Arc<Kernel>,
69    socket_type: SocketType,
70    family: NetlinkFamily,
71) -> Result<Box<dyn SocketOps>, Errno> {
72    log_debug!(tag = NETLINK_LOG_TAG; "Creating {:?} Netlink Socket", family);
73    if socket_type != SocketType::Datagram && socket_type != SocketType::Raw {
74        return error!(ESOCKTNOSUPPORT);
75    }
76
77    let ops: Box<dyn SocketOps> = match family {
78        NetlinkFamily::KobjectUevent => Box::new(UEventNetlinkSocket::default()),
79        NetlinkFamily::Route => Box::new(new_route_socket(kernel)?),
80        NetlinkFamily::Generic => Box::new(GenericNetlinkSocket::new(kernel)?),
81        NetlinkFamily::SockDiag => Box::new(new_sock_diag_socket(kernel)?),
82        NetlinkFamily::Audit => Box::new(AuditNetlinkSocket::new(kernel)?),
83        NetlinkFamily::Usersock
84        | NetlinkFamily::Firewall
85        | NetlinkFamily::Nflog
86        | NetlinkFamily::Xfrm
87        | NetlinkFamily::Selinux
88        | NetlinkFamily::Iscsi
89        | NetlinkFamily::FibLookup
90        | NetlinkFamily::Connector
91        | NetlinkFamily::Netfilter
92        | NetlinkFamily::Ip6Fw
93        | NetlinkFamily::Dnrtmsg
94        | NetlinkFamily::Scsitransport
95        | NetlinkFamily::Ecryptfs
96        | NetlinkFamily::Rdma
97        | NetlinkFamily::Crypto
98        | NetlinkFamily::Smc => Box::new(StubbedNetlinkSocket::new(family)),
99        NetlinkFamily::Invalid => return error!(EINVAL),
100    };
101    Ok(ops)
102}
103
104#[derive(Default, Debug, Clone, PartialEq, Eq)]
105#[repr(C)]
106pub struct NetlinkAddress {
107    pid: u32,
108    groups: u32,
109}
110
111impl NetlinkAddress {
112    pub fn new(pid: u32, groups: u32) -> Self {
113        NetlinkAddress { pid, groups }
114    }
115
116    pub fn set_pid_if_zero(&mut self, pid: i32) {
117        if self.pid == 0 {
118            self.pid = pid as u32;
119        }
120    }
121
122    pub fn to_bytes(&self) -> Vec<u8> {
123        sockaddr_nl { nl_family: AF_NETLINK, nl_pid: self.pid, nl_pad: 0, nl_groups: self.groups }
124            .as_bytes()
125            .to_vec()
126    }
127}
128
129#[derive(Debug, Hash, Eq, PartialEq, Clone)]
130pub enum NetlinkFamily {
131    Invalid,
132    Route,
133    Usersock,
134    Firewall,
135    SockDiag,
136    Nflog,
137    Xfrm,
138    Selinux,
139    Iscsi,
140    Audit,
141    FibLookup,
142    Connector,
143    Netfilter,
144    Ip6Fw,
145    Dnrtmsg,
146    KobjectUevent,
147    Generic,
148    Scsitransport,
149    Ecryptfs,
150    Rdma,
151    Crypto,
152    Smc,
153}
154
155impl NetlinkFamily {
156    pub fn from_raw(family: u32) -> Self {
157        match family {
158            NETLINK_ROUTE => NetlinkFamily::Route,
159            NETLINK_USERSOCK => NetlinkFamily::Usersock,
160            NETLINK_FIREWALL => NetlinkFamily::Firewall,
161            NETLINK_SOCK_DIAG => NetlinkFamily::SockDiag,
162            NETLINK_NFLOG => NetlinkFamily::Nflog,
163            NETLINK_XFRM => NetlinkFamily::Xfrm,
164            NETLINK_SELINUX => NetlinkFamily::Selinux,
165            NETLINK_ISCSI => NetlinkFamily::Iscsi,
166            NETLINK_AUDIT => NetlinkFamily::Audit,
167            NETLINK_FIB_LOOKUP => NetlinkFamily::FibLookup,
168            NETLINK_CONNECTOR => NetlinkFamily::Connector,
169            NETLINK_NETFILTER => NetlinkFamily::Netfilter,
170            NETLINK_IP6_FW => NetlinkFamily::Ip6Fw,
171            NETLINK_DNRTMSG => NetlinkFamily::Dnrtmsg,
172            NETLINK_KOBJECT_UEVENT => NetlinkFamily::KobjectUevent,
173            NETLINK_GENERIC => NetlinkFamily::Generic,
174            NETLINK_SCSITRANSPORT => NetlinkFamily::Scsitransport,
175            NETLINK_ECRYPTFS => NetlinkFamily::Ecryptfs,
176            NETLINK_RDMA => NetlinkFamily::Rdma,
177            NETLINK_CRYPTO => NetlinkFamily::Crypto,
178            NETLINK_SMC => NetlinkFamily::Smc,
179            _ => NetlinkFamily::Invalid,
180        }
181    }
182
183    pub fn as_raw(&self) -> u32 {
184        match self {
185            NetlinkFamily::Route => NETLINK_ROUTE,
186            NetlinkFamily::KobjectUevent => NETLINK_KOBJECT_UEVENT,
187            NetlinkFamily::Audit => NETLINK_AUDIT,
188            _ => 0,
189        }
190    }
191}
192
193struct NetlinkSocketInner {
194    /// The specific type of netlink socket.
195    family: NetlinkFamily,
196
197    /// The [`MessageQueue`] that contains messages from netlink to the client.
198    receive_buffer: MessageQueue,
199
200    /// The socket's send buffer size. Note, This value is only used
201    /// to serve getsockopt calls for `SO_SNDBUF`. It does not yet enforce a
202    /// limit on the number of messages netlink will buffer from the client.
203    /// TODO(https://fxbug.dev/285880057): Limit the size of the send buffer.
204    send_buf_size: usize,
205
206    /// This queue will be notified on reads, writes, disconnects etc.
207    waiters: WaitQueue,
208
209    /// The address of this socket.
210    address: Option<NetlinkAddress>,
211
212    /// See SO_PASSCRED.
213    pub passcred: bool,
214
215    /// See SO_TIMESTAMP.
216    pub timestamp: bool,
217}
218
219impl NetlinkSocketInner {
220    fn new(family: NetlinkFamily) -> Self {
221        Self {
222            family,
223            receive_buffer: MessageQueue::new(SOCKET_DEFAULT_SIZE),
224            send_buf_size: SOCKET_DEFAULT_SIZE,
225            waiters: WaitQueue::default(),
226            address: None,
227            passcred: false,
228            timestamp: false,
229        }
230    }
231
232    fn bind(
233        &mut self,
234        current_task: &CurrentTask,
235        socket_address: SocketAddress,
236    ) -> Result<(), Errno> {
237        if self.address.is_some() {
238            return error!(EINVAL);
239        }
240
241        let netlink_address = match socket_address {
242            SocketAddress::Netlink(mut netlink_address) => {
243                // TODO: Support distinct IDs for processes with multiple netlink sockets.
244                netlink_address.set_pid_if_zero(current_task.get_pid());
245                netlink_address
246            }
247            _ => return error!(EINVAL),
248        };
249
250        self.address = Some(netlink_address);
251        Ok(())
252    }
253
254    fn connect(&mut self, current_task: &CurrentTask, peer: SocketPeer) -> Result<(), Errno> {
255        let address = match peer {
256            SocketPeer::Address(address) => address,
257            _ => return error!(EINVAL),
258        };
259        // Connect is equivalent to bind, but error are ignored.
260        let _ = self.bind(current_task, address);
261        Ok(())
262    }
263
264    fn read_message(&mut self) -> Option<Message> {
265        let message = self.receive_buffer.read_message();
266        if message.is_some() {
267            self.waiters.notify_fd_events(FdEvents::POLLOUT);
268        }
269        message
270    }
271
272    fn read_datagram(
273        &mut self,
274        data: &mut dyn OutputBuffer,
275        flags: SocketMessageFlags,
276    ) -> Result<MessageReadInfo, Errno> {
277        let mut info = if flags.contains(SocketMessageFlags::PEEK) {
278            self.receive_buffer.peek_datagram(data)
279        } else {
280            self.receive_buffer.read_datagram(data)
281        }?;
282        if info.message_length == 0 {
283            return error!(EAGAIN);
284        }
285
286        if self.passcred {
287            track_stub!(TODO("https://fxbug.dev/297373991"), "SCM_CREDENTIALS/SO_PASSCRED");
288            info.ancillary_data.push(AncillaryData::Unix(UnixControlData::unknown_creds()));
289        }
290
291        Ok(info)
292    }
293
294    fn write_to_queue(
295        &mut self,
296        data: &mut dyn InputBuffer,
297        address: Option<NetlinkAddress>,
298        ancillary_data: &mut Vec<AncillaryData>,
299    ) -> Result<usize, Errno> {
300        let socket_address = match address {
301            Some(addr) => Some(SocketAddress::Netlink(addr)),
302            None => self.address.as_ref().map(|addr| SocketAddress::Netlink(addr.clone())),
303        };
304        let bytes_written =
305            self.receive_buffer.write_datagram(data, socket_address, ancillary_data)?;
306        if bytes_written > 0 {
307            self.waiters.notify_fd_events(FdEvents::POLLIN);
308        }
309        Ok(bytes_written)
310    }
311
312    fn wait_async(
313        &mut self,
314        waiter: &Waiter,
315        events: FdEvents,
316        handler: EventHandler,
317    ) -> WaitCanceler {
318        self.waiters.wait_async_fd_events(waiter, events, handler)
319    }
320
321    fn query_events(&self) -> FdEvents {
322        self.receive_buffer.query_events()
323    }
324
325    fn getsockname(&self) -> Result<SocketAddress, Errno> {
326        match &self.address {
327            Some(addr) => Ok(SocketAddress::Netlink(addr.clone())),
328            _ => Ok(SocketAddress::default_for_domain(SocketDomain::Netlink)),
329        }
330    }
331
332    fn getpeername(&self) -> Result<SocketAddress, Errno> {
333        match &self.address {
334            Some(addr) => Ok(SocketAddress::Netlink(addr.clone())),
335            _ => Ok(SocketAddress::default_for_domain(SocketDomain::Netlink)),
336        }
337    }
338
339    fn getsockopt(&self, level: u32, optname: u32) -> Result<Vec<u8>, Errno> {
340        let opt_value = match level {
341            SOL_SOCKET => match optname {
342                SO_PASSCRED => (self.passcred as u32).as_bytes().to_vec(),
343                SO_TIMESTAMP => (self.timestamp as u32).as_bytes().to_vec(),
344                SO_SNDBUF => (self.send_buf_size as socklen_t).to_ne_bytes().to_vec(),
345                SO_RCVBUF => (self.receive_buffer.capacity() as socklen_t).to_ne_bytes().to_vec(),
346                SO_SNDBUFFORCE => (self.send_buf_size as socklen_t).to_ne_bytes().to_vec(),
347                SO_RCVBUFFORCE => {
348                    (self.receive_buffer.capacity() as socklen_t).to_ne_bytes().to_vec()
349                }
350                SO_PROTOCOL => self.family.as_raw().as_bytes().to_vec(),
351                _ => return error!(ENOSYS),
352            },
353            _ => vec![],
354        };
355
356        Ok(opt_value)
357    }
358
359    fn setsockopt(
360        &mut self,
361        current_task: &CurrentTask,
362        level: u32,
363        optname: u32,
364        optval: SockOptValue,
365    ) -> Result<(), Errno> {
366        match level {
367            SOL_SOCKET => match optname {
368                SO_SNDBUF => {
369                    let requested_capacity: socklen_t = optval.read(current_task)?;
370                    // SO_SNDBUF doubles the requested capacity to leave space for bookkeeping.
371                    // See https://man7.org/linux/man-pages/man7/socket.7.html
372                    let capacity = usize::try_from(requested_capacity * 2).unwrap_or(usize::MAX);
373                    // TODO(https://fxbug.dev/322907334): Clamp to `wmem_max`.
374                    let capacity = capacity.clamp(SOCKET_MIN_SIZE, SOCKET_MAX_SIZE);
375                    self.send_buf_size = capacity;
376                }
377                SO_SNDBUFFORCE => {
378                    security::check_task_capable(current_task, CAP_NET_ADMIN)?;
379                    let requested_capacity: socklen_t = optval.read(current_task)?;
380                    // SO_SNDBUFFORE doubles the requested capacity to leave space for bookkeeping.
381                    // See https://man7.org/linux/man-pages/man7/socket.7.html
382                    let capacity = usize::try_from(requested_capacity * 2).unwrap_or(usize::MAX);
383                    self.send_buf_size = capacity;
384                }
385                SO_RCVBUF => {
386                    let requested_capacity: socklen_t = optval.read(current_task)?;
387                    // SO_RCVBUF doubles the requested capacity to leave space for bookkeeping.
388                    // See https://man7.org/linux/man-pages/man7/socket.7.html
389                    let capacity = usize::try_from(requested_capacity * 2).unwrap_or(usize::MAX);
390                    // TODO(https://fxbug.dev/322906968): Clamp to `rmem_max`.
391                    let capacity = capacity.clamp(SOCKET_MIN_SIZE, SOCKET_MAX_SIZE);
392                    self.receive_buffer.set_capacity(capacity)?;
393                }
394                SO_RCVBUFFORCE => {
395                    security::check_task_capable(current_task, CAP_NET_ADMIN)?;
396                    let requested_capacity: socklen_t = optval.read(current_task)?;
397                    // SO_RCVBUFFORE doubles the requested capacity to leave space for bookkeeping.
398                    // See https://man7.org/linux/man-pages/man7/socket.7.html
399                    let capacity = usize::try_from(requested_capacity * 2).unwrap_or(usize::MAX);
400                    self.receive_buffer.set_capacity(capacity)?;
401                }
402                SO_PASSCRED => {
403                    let passcred: u32 = optval.read(current_task)?;
404                    self.passcred = passcred != 0;
405                }
406                SO_TIMESTAMP => {
407                    let timestamp: u32 = optval.read(current_task)?;
408                    self.timestamp = timestamp != 0;
409                }
410                _ => return error!(ENOSYS),
411            },
412            _ => return error!(ENOSYS),
413        }
414
415        Ok(())
416    }
417}
418
419/// A fake Netlink socket that loops messages back to the client.
420///
421/// Used as a placeholder implementation for protocol families that lack a real
422/// implementation.
423struct StubbedNetlinkSocket {
424    inner: Mutex<NetlinkSocketInner>,
425}
426
427impl StubbedNetlinkSocket {
428    pub fn new(family: NetlinkFamily) -> Self {
429        track_stub!(
430            TODO("https://fxbug.dev/278565021"),
431            format!("Creating StubbedNetlinkSocket: {:?}", family).as_str()
432        );
433        StubbedNetlinkSocket { inner: Mutex::new(NetlinkSocketInner::new(family)) }
434    }
435
436    /// Locks and returns the inner state of the Socket.
437    fn lock(&self) -> starnix_sync::MutexGuard<'_, NetlinkSocketInner> {
438        self.inner.lock()
439    }
440}
441
442impl SocketOps for StubbedNetlinkSocket {
443    fn connect(
444        &self,
445        _locked: &mut Locked<FileOpsCore>,
446        _socket: &SocketHandle,
447        current_task: &CurrentTask,
448        peer: SocketPeer,
449    ) -> Result<(), Errno> {
450        self.lock().connect(current_task, peer)
451    }
452
453    fn listen(
454        &self,
455        _locked: &mut Locked<FileOpsCore>,
456        _socket: &Socket,
457        _backlog: i32,
458        _credentials: ucred,
459    ) -> Result<(), Errno> {
460        error!(EOPNOTSUPP)
461    }
462
463    fn accept(
464        &self,
465        _locked: &mut Locked<FileOpsCore>,
466        _socket: &Socket,
467        _current_task: &CurrentTask,
468    ) -> Result<SocketHandle, Errno> {
469        error!(EOPNOTSUPP)
470    }
471
472    fn bind(
473        &self,
474        _locked: &mut Locked<FileOpsCore>,
475        _socket: &Socket,
476        current_task: &CurrentTask,
477        socket_address: SocketAddress,
478    ) -> Result<(), Errno> {
479        self.lock().bind(current_task, socket_address)
480    }
481
482    fn read(
483        &self,
484        _locked: &mut Locked<FileOpsCore>,
485        _socket: &Socket,
486        _current_task: &CurrentTask,
487        data: &mut dyn OutputBuffer,
488        _flags: SocketMessageFlags,
489    ) -> Result<MessageReadInfo, Errno> {
490        let msg = self.lock().read_message();
491        match msg {
492            Some(message) => {
493                // Mark the message as complete and return it.
494                let (mut nl_msg, _) =
495                    nlmsghdr::read_from_prefix(&message.data).map_err(|_| errno!(EINVAL))?;
496                nl_msg.nlmsg_type = NLMSG_DONE as u16;
497                nl_msg.nlmsg_flags &= NLM_F_MULTI as u16;
498                let msg_bytes = nl_msg.as_bytes();
499                let bytes_read = data.write(msg_bytes)?;
500
501                let info = MessageReadInfo {
502                    bytes_read,
503                    message_length: msg_bytes.len(),
504                    address: Some(SocketAddress::Netlink(NetlinkAddress::default())),
505                    ancillary_data: vec![],
506                };
507                Ok(info)
508            }
509            None => Ok(MessageReadInfo::default()),
510        }
511    }
512
513    fn write(
514        &self,
515        _locked: &mut Locked<FileOpsCore>,
516        _socket: &Socket,
517        _current_task: &CurrentTask,
518        data: &mut dyn InputBuffer,
519        dest_address: &mut Option<SocketAddress>,
520        ancillary_data: &mut Vec<AncillaryData>,
521    ) -> Result<usize, Errno> {
522        let mut local_address = self.lock().address.clone();
523
524        let destination = match dest_address {
525            Some(SocketAddress::Netlink(addr)) => addr,
526            _ => match &mut local_address {
527                Some(addr) => addr,
528                _ => return Ok(data.drain()),
529            },
530        };
531
532        if destination.groups != 0 {
533            track_stub!(TODO("https://fxbug.dev/322874956"), "StubbedNetlinkSockets multicasting");
534            return Ok(data.drain());
535        }
536
537        self.lock().write_to_queue(data, Some(NetlinkAddress::default()), ancillary_data)
538    }
539
540    fn wait_async(
541        &self,
542        _locked: &mut Locked<FileOpsCore>,
543        _socket: &Socket,
544        _current_task: &CurrentTask,
545        waiter: &Waiter,
546        events: FdEvents,
547        handler: EventHandler,
548    ) -> WaitCanceler {
549        self.lock().wait_async(waiter, events, handler)
550    }
551
552    fn query_events(
553        &self,
554        _locked: &mut Locked<FileOpsCore>,
555        _socket: &Socket,
556        _current_task: &CurrentTask,
557    ) -> Result<FdEvents, Errno> {
558        Ok(self.lock().query_events() & FdEvents::POLLIN)
559    }
560
561    fn shutdown(
562        &self,
563        _locked: &mut Locked<FileOpsCore>,
564        _socket: &Socket,
565        _how: SocketShutdownFlags,
566    ) -> Result<(), Errno> {
567        track_stub!(TODO("https://fxbug.dev/322875507"), "StubbedNetlinkSocket::shutdown");
568        Ok(())
569    }
570
571    fn close(
572        &self,
573        _locked: &mut Locked<FileOpsCore>,
574        _current_task: &CurrentTask,
575        _socket: &Socket,
576    ) {
577    }
578
579    fn getsockname(
580        &self,
581        _locked: &mut Locked<FileOpsCore>,
582        _socket: &Socket,
583    ) -> Result<SocketAddress, Errno> {
584        self.lock().getsockname()
585    }
586
587    fn getpeername(
588        &self,
589        _locked: &mut Locked<FileOpsCore>,
590        _socket: &Socket,
591    ) -> Result<SocketAddress, Errno> {
592        self.lock().getpeername()
593    }
594
595    fn getsockopt(
596        &self,
597        _locked: &mut Locked<FileOpsCore>,
598        _socket: &Socket,
599        _current_task: &CurrentTask,
600        level: u32,
601        optname: u32,
602        _optlen: u32,
603    ) -> Result<Vec<u8>, Errno> {
604        self.lock().getsockopt(level, optname)
605    }
606
607    fn setsockopt(
608        &self,
609        _locked: &mut Locked<FileOpsCore>,
610        _socket: &Socket,
611        current_task: &CurrentTask,
612        level: u32,
613        optname: u32,
614        optval: SockOptValue,
615    ) -> Result<(), Errno> {
616        self.lock().setsockopt(current_task, level, optname, optval)
617    }
618}
619
620/// Socket implementation for the NETLINK_KOBJECT_UEVENT family of netlink sockets.
621struct UEventNetlinkSocket {
622    inner: Arc<Mutex<NetlinkSocketInner>>,
623    device_listener_key: Mutex<Option<DeviceListenerKey>>,
624}
625
626impl Default for UEventNetlinkSocket {
627    #[allow(clippy::let_and_return)]
628    fn default() -> Self {
629        let result = Self {
630            inner: Arc::new(Mutex::new(NetlinkSocketInner::new(NetlinkFamily::KobjectUevent))),
631            device_listener_key: Default::default(),
632        };
633        #[cfg(any(test, debug_assertions))]
634        {
635            let _l1 = result.device_listener_key.lock();
636            let _l2 = result.lock();
637        }
638        result
639    }
640}
641
642impl UEventNetlinkSocket {
643    /// Locks and returns the inner state of the Socket.
644    fn lock(&self) -> starnix_sync::MutexGuard<'_, NetlinkSocketInner> {
645        self.inner.lock()
646    }
647
648    fn register_listener<L>(
649        &self,
650        locked: &mut Locked<L>,
651        current_task: &CurrentTask,
652        state: starnix_sync::MutexGuard<'_, NetlinkSocketInner>,
653    ) where
654        L: LockEqualOrBefore<FileOpsCore>,
655    {
656        if state.address.is_none() {
657            return;
658        }
659        std::mem::drop(state);
660        let mut key_state = self.device_listener_key.lock();
661        if key_state.is_none() {
662            *key_state = Some(
663                current_task.kernel().device_registry.register_listener(locked, self.inner.clone()),
664            );
665        }
666    }
667}
668
669impl SocketOps for UEventNetlinkSocket {
670    fn connect(
671        &self,
672        locked: &mut Locked<FileOpsCore>,
673        _socket: &SocketHandle,
674        current_task: &CurrentTask,
675        peer: SocketPeer,
676    ) -> Result<(), Errno> {
677        let mut state = self.lock();
678        state.connect(current_task, peer)?;
679        self.register_listener(locked, current_task, state);
680        Ok(())
681    }
682
683    fn listen(
684        &self,
685        _locked: &mut Locked<FileOpsCore>,
686        _socket: &Socket,
687        _backlog: i32,
688        _credentials: ucred,
689    ) -> Result<(), Errno> {
690        error!(EOPNOTSUPP)
691    }
692
693    fn accept(
694        &self,
695        _locked: &mut Locked<FileOpsCore>,
696        _socket: &Socket,
697        _current_task: &CurrentTask,
698    ) -> Result<SocketHandle, Errno> {
699        error!(EOPNOTSUPP)
700    }
701
702    fn bind(
703        &self,
704        locked: &mut Locked<FileOpsCore>,
705        _socket: &Socket,
706        current_task: &CurrentTask,
707        socket_address: SocketAddress,
708    ) -> Result<(), Errno> {
709        let mut state = self.lock();
710        state.bind(current_task, socket_address)?;
711        self.register_listener(locked, current_task, state);
712        Ok(())
713    }
714
715    fn read(
716        &self,
717        _locked: &mut Locked<FileOpsCore>,
718        _socket: &Socket,
719        _current_task: &CurrentTask,
720        data: &mut dyn OutputBuffer,
721        flags: SocketMessageFlags,
722    ) -> Result<MessageReadInfo, Errno> {
723        self.lock().read_datagram(data, flags)
724    }
725
726    fn write(
727        &self,
728        _locked: &mut Locked<FileOpsCore>,
729        _socket: &Socket,
730        _current_task: &CurrentTask,
731        _data: &mut dyn InputBuffer,
732        _dest_address: &mut Option<SocketAddress>,
733        _ancillary_data: &mut Vec<AncillaryData>,
734    ) -> Result<usize, Errno> {
735        error!(EOPNOTSUPP)
736    }
737
738    fn wait_async(
739        &self,
740        _locked: &mut Locked<FileOpsCore>,
741        _socket: &Socket,
742        _current_task: &CurrentTask,
743        waiter: &Waiter,
744        events: FdEvents,
745        handler: EventHandler,
746    ) -> WaitCanceler {
747        self.lock().wait_async(waiter, events, handler)
748    }
749
750    fn query_events(
751        &self,
752        _locked: &mut Locked<FileOpsCore>,
753        _socket: &Socket,
754        _current_task: &CurrentTask,
755    ) -> Result<FdEvents, Errno> {
756        Ok(self.lock().query_events() & FdEvents::POLLIN)
757    }
758
759    fn shutdown(
760        &self,
761        _locked: &mut Locked<FileOpsCore>,
762        _socket: &Socket,
763        _how: SocketShutdownFlags,
764    ) -> Result<(), Errno> {
765        track_stub!(TODO("https://fxbug.dev/322875507"), "UEventNetlinkSocket::shutdown");
766        Ok(())
767    }
768
769    fn close(
770        &self,
771        locked: &mut Locked<FileOpsCore>,
772        current_task: &CurrentTask,
773        _socket: &Socket,
774    ) {
775        let id = self.device_listener_key.lock().take();
776        if let Some(id) = id {
777            current_task.kernel().device_registry.unregister_listener(locked, &id);
778        }
779    }
780
781    fn getsockname(
782        &self,
783        _locked: &mut Locked<FileOpsCore>,
784        _socket: &Socket,
785    ) -> Result<SocketAddress, Errno> {
786        self.lock().getsockname()
787    }
788
789    fn getpeername(
790        &self,
791        _locked: &mut Locked<FileOpsCore>,
792        _socket: &Socket,
793    ) -> Result<SocketAddress, Errno> {
794        self.lock().getpeername()
795    }
796
797    fn getsockopt(
798        &self,
799        _locked: &mut Locked<FileOpsCore>,
800        _socket: &Socket,
801        _current_task: &CurrentTask,
802        level: u32,
803        optname: u32,
804        _optlen: u32,
805    ) -> Result<Vec<u8>, Errno> {
806        self.lock().getsockopt(level, optname)
807    }
808
809    fn setsockopt(
810        &self,
811        _locked: &mut Locked<FileOpsCore>,
812        _socket: &Socket,
813        current_task: &CurrentTask,
814        level: u32,
815        optname: u32,
816        optval: SockOptValue,
817    ) -> Result<(), Errno> {
818        self.lock().setsockopt(current_task, level, optname, optval)
819    }
820}
821
822impl DeviceListener for Arc<Mutex<NetlinkSocketInner>> {
823    fn on_device_event(&self, action: UEventAction, device: Device, context: UEventContext) {
824        let path = device.path_from_depth(0);
825        let message = format!(
826            "{action}@/{path}\0\
827                            ACTION={action}\0\
828                            SEQNUM={seqnum}\0\
829                            {other_props}",
830            seqnum = context.seqnum,
831            other_props = device.uevent_properties('\0'),
832        );
833        let ancillary_data = AncillaryData::Unix(UnixControlData::Credentials(Default::default()));
834        let mut ancillary_data = vec![ancillary_data];
835        // Ignore write errors
836        let _ = self.lock().write_to_queue(
837            &mut VecInputBuffer::new(message.as_bytes()),
838            Some(NetlinkAddress { pid: 0, groups: 1 }),
839            &mut ancillary_data,
840        );
841    }
842}
843
844/// Type for sending messages from [`netlink::Netlink`] to an individual socket.
845#[derive(Clone)]
846pub struct NetlinkToClientSender<M> {
847    /// The inner socket implementation, which holds a message queue.
848    inner: Arc<Mutex<NetlinkSocketInner>>,
849
850    /// `PhantomData<fn(M) -> M>` is used instead of `PhantomData<M>` in order
851    /// to ensure that the type is invariant over `M` and that it implements
852    /// `Sync` even if `M` is not `Sync`.
853    _message_type: PhantomData<fn(M) -> M>,
854}
855
856impl<M> NetlinkToClientSender<M> {
857    fn new(inner: Arc<Mutex<NetlinkSocketInner>>) -> Self {
858        NetlinkToClientSender { _message_type: Default::default(), inner }
859    }
860}
861
862impl<M: Clone + NetlinkSerializable + Send> Sender<M> for NetlinkToClientSender<M> {
863    fn send(&mut self, message: NetlinkMessage<M>, group: Option<ModernGroup>) {
864        // Serialize the message
865        let mut buf = vec![0; message.buffer_len()];
866        message.emit(&mut buf);
867        let mut buf: VecInputBuffer = buf.into();
868        // Write the message into the inner socket buffer.
869        let NetlinkToClientSender { _message_type: _, inner } = self;
870        let mut guard = inner.lock();
871
872        // To avoid dropping messages when the receive buffer is
873        // full, grow the buffer on behalf of the client.
874        // This is a stop gap measure to avoid dropping messages
875        // when netlink produces a large response to a
876        // NLM_F_DUMP request.
877        //
878        // TODO(https://fxbug.dev/459883760): The memory
879        // implications of this may be problematic. It should be
880        // replaced with a proper mechanism to handle a backlog
881        // of NLM_F_DUMP responses.
882        let available = guard.receive_buffer.available_capacity();
883        let required = buf.available();
884        if available < required {
885            let delta = required - available;
886            let current_capacity = guard.receive_buffer.capacity();
887            let new_capacity = (current_capacity + delta).min(SOCKET_MAX_SIZE);
888            match guard.receive_buffer.set_capacity(new_capacity) {
889                Ok(()) => {}
890                Err(e) => {
891                    log_error!(
892                        tag = NETLINK_LOG_TAG;
893                        "Failed to increase receive buffer size: {:?}",
894                        e
895                    );
896                }
897            }
898        }
899
900        let _bytes_written: usize = guard
901            .write_to_queue(
902                &mut buf,
903                Some(NetlinkAddress {
904                    // All messages come from the "kernel" which has PID of 0.
905                    pid: 0,
906                    // If this is a multicast message, set the group the multicast
907                    // message is from.
908                    groups: group
909                        .map(SingleLegacyGroup::try_from)
910                        .and_then(Result::<_, NoMappingFromModernToLegacyGroupError>::ok)
911                        .map_or(0, |g| g.inner()),
912                }),
913                &mut Vec::new(),
914            )
915            .unwrap_or_else(|e| {
916                log_error!(
917                    tag = NETLINK_LOG_TAG;
918                    "Failed to write message into buffer for socket. Errno: {:?}",
919                    e
920                );
921                0
922            });
923    }
924}
925
926#[derive(Clone)]
927pub struct NetlinkAccessControl<'a> {
928    current_task: &'a CurrentTask,
929}
930
931impl<'a> NetlinkAccessControl<'a> {
932    pub fn new(current_task: &'a CurrentTask) -> Self {
933        Self { current_task }
934    }
935}
936
937impl<'a> AccessControl<Arc<Credentials>> for NetlinkAccessControl<'a> {
938    fn grant_assess(
939        &self,
940        creds: &Arc<Credentials>,
941        permission: Permission,
942    ) -> Result<(), netlink::Errno> {
943        let need_cap_net_admin = match permission {
944            Permission::NetlinkRouteRead => false,
945            Permission::NetlinkRouteWrite => true,
946            Permission::NetlinkSockDiagRead => false,
947            Permission::NetlinkSockDiagDestroy => true,
948        };
949        if !need_cap_net_admin {
950            return Ok(());
951        }
952
953        self.current_task.override_creds(creds.clone(), || {
954            security::check_task_capable(self.current_task, CAP_NET_ADMIN).map_err(|error| {
955                netlink::Errno::new(error.code.error_code() as i32)
956                    .expect("Errno::error_code() is expected to be in range [1..max_i32]")
957            })
958        })
959    }
960}
961pub struct NetlinkContextImpl;
962
963impl NetlinkContext for NetlinkContextImpl {
964    type Creds = Arc<Credentials>;
965    type Sender<M: Clone + NetlinkSerializable + Send> = NetlinkToClientSender<M>;
966    type Receiver<
967        M: Send + MessageWithPermission + NetlinkDeserializable<Error: Into<DecodeError>>,
968    > = UnboundedReceiver<NetlinkMessageWithCreds<UnparsedNetlinkMessage<Vec<u8>, M>, Self::Creds>>;
969    type AccessControl<'a> = NetlinkAccessControl<'a>;
970}
971
972fn new_route_socket(kernel: &Arc<Kernel>) -> Result<NetlinkSocket<NetlinkRouteClient>, Errno> {
973    let inner = Arc::new(Mutex::new(NetlinkSocketInner::new(NetlinkFamily::Route)));
974    let (message_sender, message_receiver) = mpsc::unbounded();
975    let client = match kernel
976        .network_netlink()
977        .new_route_client(NetlinkToClientSender::new(inner.clone()), message_receiver)
978    {
979        Ok(client) => client,
980        Err(NewClientError::Disconnected) => {
981            log_error!(
982                tag = NETLINK_LOG_TAG;
983                "Netlink async worker is unexpectedly disconnected"
984            );
985            return error!(EPIPE);
986        }
987    };
988    Ok(NetlinkSocket { inner, client, message_sender })
989}
990
991fn new_sock_diag_socket(
992    kernel: &Arc<Kernel>,
993) -> Result<NetlinkSocket<NetlinkSockDiagClient>, Errno> {
994    let inner = Arc::new(Mutex::new(NetlinkSocketInner::new(NetlinkFamily::SockDiag)));
995    let (message_sender, message_receiver) = mpsc::unbounded();
996    let client = match kernel
997        .network_netlink()
998        .new_sock_diag_client(NetlinkToClientSender::new(inner.clone()), message_receiver)
999    {
1000        Ok(client) => client,
1001        Err(NewClientError::Disconnected) => {
1002            log_error!(
1003                tag = NETLINK_LOG_TAG;
1004                "Netlink async worker is unexpectedly disconnected"
1005            );
1006            return error!(EPIPE);
1007        }
1008    };
1009    Ok(NetlinkSocket { inner, client, message_sender })
1010}
1011
1012/// An abstraction over common networking-specific netlink sockets.
1013struct NetlinkSocket<C: NetlinkClient> {
1014    /// The inner Netlink socket implementation
1015    inner: Arc<Mutex<NetlinkSocketInner>>,
1016    /// The implementation of a client (socket connection) to NETLINK_ROUTE.
1017    client: C,
1018    /// The sender of messages from this socket to Netlink.
1019    // TODO(https://issuetracker.google.com/285880057): Bound the capacity of
1020    // the "send buffer".
1021    message_sender: UnboundedSender<
1022        NetlinkMessageWithCreds<UnparsedNetlinkMessage<Vec<u8>, C::Request>, Arc<Credentials>>,
1023    >,
1024}
1025
1026impl<C: NetlinkClient + 'static> SocketOps for NetlinkSocket<C> {
1027    fn connect(
1028        &self,
1029        _locked: &mut Locked<FileOpsCore>,
1030        _socket: &SocketHandle,
1031        current_task: &CurrentTask,
1032        peer: SocketPeer,
1033    ) -> Result<(), Errno> {
1034        let NetlinkSocket { inner, client: _, message_sender: _ } = self;
1035        inner.lock().connect(current_task, peer)
1036    }
1037
1038    fn listen(
1039        &self,
1040        _locked: &mut Locked<FileOpsCore>,
1041        _socket: &Socket,
1042        _backlog: i32,
1043        _credentials: ucred,
1044    ) -> Result<(), Errno> {
1045        error!(EOPNOTSUPP)
1046    }
1047
1048    fn accept(
1049        &self,
1050        _locked: &mut Locked<FileOpsCore>,
1051        _socket: &Socket,
1052        _current_task: &CurrentTask,
1053    ) -> Result<SocketHandle, Errno> {
1054        error!(EOPNOTSUPP)
1055    }
1056
1057    fn bind(
1058        &self,
1059        _locked: &mut Locked<FileOpsCore>,
1060        _socket: &Socket,
1061        current_task: &CurrentTask,
1062        socket_address: SocketAddress,
1063    ) -> Result<(), Errno> {
1064        let NetlinkSocket { inner, client, message_sender: _ } = self;
1065
1066        let multicast_groups = match &socket_address {
1067            SocketAddress::Netlink(NetlinkAddress { pid: _, groups }) => *groups,
1068            _ => return error!(EINVAL),
1069        };
1070        let pid = {
1071            let mut inner = inner.lock();
1072            inner.bind(current_task, socket_address)?;
1073            inner
1074                .address
1075                .as_ref()
1076                .and_then(|NetlinkAddress { pid, groups: _ }| NonZeroU32::new(*pid))
1077        };
1078        if let Some(pid) = pid {
1079            client.set_pid(pid);
1080        }
1081        // This "blocks" in order to synchronize with the internal
1082        // state of the netlink worker, but we're not blocking on
1083        // the completion of any i/o or any expensive computation,
1084        // so there's no need to support interrupts here.
1085        client
1086            .set_legacy_memberships(LegacyGroups(multicast_groups))
1087            .map_err(|InvalidLegacyGroupsError {}| errno!(EPERM))?
1088            .wait_until_complete();
1089        Ok(())
1090    }
1091
1092    fn read(
1093        &self,
1094        _locked: &mut Locked<FileOpsCore>,
1095        _socket: &Socket,
1096        _current_task: &CurrentTask,
1097        data: &mut dyn OutputBuffer,
1098        flags: SocketMessageFlags,
1099    ) -> Result<MessageReadInfo, Errno> {
1100        let NetlinkSocket { inner, client: _, message_sender: _ } = self;
1101        inner.lock().read_datagram(data, flags)
1102    }
1103
1104    fn write(
1105        &self,
1106        _locked: &mut Locked<FileOpsCore>,
1107        socket: &Socket,
1108        current_task: &CurrentTask,
1109        data: &mut dyn InputBuffer,
1110        _dest_address: &mut Option<SocketAddress>,
1111        _ancillary_data: &mut Vec<AncillaryData>,
1112    ) -> Result<usize, Errno> {
1113        let NetlinkSocket { inner: _, client: _, message_sender } = self;
1114
1115        let bytes = data.peek_all()?;
1116        let bytes_len = bytes.len();
1117
1118        // Parse only the netlink header to send it through security check.
1119        match NetlinkBuffer::new(&bytes) {
1120            Ok(buffer) => {
1121                security::check_netlink_send_access(current_task, socket, buffer.message_type())?;
1122            }
1123            Err(e) => {
1124                // If we can't even decode the header of the netlink message,
1125                // then return early here as a stronger statement that we're not
1126                // going to accidentally operate on it and violate the security
1127                // check. The netlink crate would end up dropping this with no
1128                // response as well.
1129                log_warn!(tag = NETLINK_LOG_TAG;
1130                    "Failed to parse netlink header {e:?}"
1131                );
1132                data.drain();
1133                return Ok(bytes_len);
1134            }
1135        }
1136
1137        let msg = NetlinkMessageWithCreds::new(
1138            UnparsedNetlinkMessage::new(bytes),
1139            current_task.current_creds().clone(),
1140        );
1141        message_sender.unbounded_send(msg).map_err(|e| {
1142            log_warn!(
1143                tag = NETLINK_LOG_TAG;
1144                "Netlink receiver unexpectedly disconnected for socket: {:?}",
1145                e
1146            );
1147            errno!(EPIPE)
1148        })?;
1149        data.drain();
1150        Ok(bytes_len)
1151    }
1152
1153    fn wait_async(
1154        &self,
1155        _locked: &mut Locked<FileOpsCore>,
1156        _socket: &Socket,
1157        _current_task: &CurrentTask,
1158        waiter: &Waiter,
1159        events: FdEvents,
1160        handler: EventHandler,
1161    ) -> WaitCanceler {
1162        let NetlinkSocket { inner, client: _, message_sender: _ } = self;
1163        inner.lock().wait_async(waiter, events, handler)
1164    }
1165
1166    fn query_events(
1167        &self,
1168        _locked: &mut Locked<FileOpsCore>,
1169        _socket: &Socket,
1170        _current_task: &CurrentTask,
1171    ) -> Result<FdEvents, Errno> {
1172        let NetlinkSocket { inner, client: _, message_sender: _ } = self;
1173        Ok(inner.lock().query_events() & FdEvents::POLLIN)
1174    }
1175
1176    fn shutdown(
1177        &self,
1178        _locked: &mut Locked<FileOpsCore>,
1179        _socket: &Socket,
1180        _how: SocketShutdownFlags,
1181    ) -> Result<(), Errno> {
1182        error!(EOPNOTSUPP)
1183    }
1184
1185    fn close(
1186        &self,
1187        _locked: &mut Locked<FileOpsCore>,
1188        _current_task: &CurrentTask,
1189        _socket: &Socket,
1190    ) {
1191        // Close the underlying channel to the Netlink worker.
1192        self.message_sender.close_channel();
1193    }
1194
1195    fn getsockname(
1196        &self,
1197        _locked: &mut Locked<FileOpsCore>,
1198        _socket: &Socket,
1199    ) -> Result<SocketAddress, Errno> {
1200        let NetlinkSocket { inner, client: _, message_sender: _ } = self;
1201        inner.lock().getsockname()
1202    }
1203
1204    fn getpeername(
1205        &self,
1206        _locked: &mut Locked<FileOpsCore>,
1207        _socket: &Socket,
1208    ) -> Result<SocketAddress, Errno> {
1209        self.inner.lock().getpeername()
1210    }
1211
1212    fn getsockopt(
1213        &self,
1214        _locked: &mut Locked<FileOpsCore>,
1215        _socket: &Socket,
1216        _current_task: &CurrentTask,
1217        level: u32,
1218        optname: u32,
1219        _optlen: u32,
1220    ) -> Result<Vec<u8>, Errno> {
1221        self.inner.lock().getsockopt(level, optname)
1222    }
1223
1224    fn setsockopt(
1225        &self,
1226        _locked: &mut Locked<FileOpsCore>,
1227        _socket: &Socket,
1228        current_task: &CurrentTask,
1229        level: u32,
1230        optname: u32,
1231        optval: SockOptValue,
1232    ) -> Result<(), Errno> {
1233        match (level, optname) {
1234            (SOL_NETLINK, NETLINK_ADD_MEMBERSHIP) => {
1235                let NetlinkSocket { inner: _, client, message_sender: _ } = self;
1236                let group: u32 = optval.read(current_task)?;
1237                let async_work = client
1238                    .add_membership(ModernGroup(group))
1239                    .map_err(|InvalidModernGroupError| errno!(EINVAL))?;
1240                // This "blocks" in order to synchronize with the internal
1241                // state of the rtnetlink worker, but we're not blocking on
1242                // the completion of any i/o or any expensive computation,
1243                // so there's no need to support interrupts here.
1244                async_work.wait_until_complete();
1245                Ok(())
1246            }
1247            (SOL_NETLINK, NETLINK_DROP_MEMBERSHIP) => {
1248                let NetlinkSocket { inner: _, client, message_sender: _ } = self;
1249                let group: u32 = optval.read(current_task)?;
1250                client
1251                    .del_membership(ModernGroup(group))
1252                    .map_err(|InvalidModernGroupError| errno!(EINVAL))?;
1253                Ok(())
1254            }
1255            _ => self.inner.lock().setsockopt(current_task, level, optname, optval),
1256        }
1257    }
1258}
1259
1260/// Socket implementation for the NETLINK_GENERIC family of netlink sockets.
1261struct GenericNetlinkSocket {
1262    inner: Arc<Mutex<NetlinkSocketInner>>,
1263    client: GenericNetlinkClientHandle<NetlinkToClientSender<GenericMessage>>,
1264    message_sender: mpsc::UnboundedSender<NetlinkMessage<GenericMessage>>,
1265}
1266
1267impl GenericNetlinkSocket {
1268    pub fn new(kernel: &Kernel) -> Result<Self, Errno> {
1269        let inner = Arc::new(Mutex::new(NetlinkSocketInner::new(NetlinkFamily::Generic)));
1270        let (message_sender, message_receiver) = mpsc::unbounded();
1271        match kernel
1272            .generic_netlink()
1273            .new_generic_client(NetlinkToClientSender::new(inner.clone()), message_receiver)
1274        {
1275            Ok(client) => Ok(Self { inner, client, message_sender }),
1276            Err(e) => {
1277                log_warn!(
1278                    tag = NETLINK_LOG_TAG;
1279                    "Failed to connect to generic netlink server. Errno: {:?}",
1280                    e
1281                );
1282                error!(EPIPE)
1283            }
1284        }
1285    }
1286
1287    /// Locks and returns the inner state of the Socket.
1288    fn lock(&self) -> starnix_sync::MutexGuard<'_, NetlinkSocketInner> {
1289        self.inner.lock()
1290    }
1291}
1292
1293impl SocketOps for GenericNetlinkSocket {
1294    fn connect(
1295        &self,
1296        _locked: &mut Locked<FileOpsCore>,
1297        _socket: &SocketHandle,
1298        current_task: &CurrentTask,
1299        peer: SocketPeer,
1300    ) -> Result<(), Errno> {
1301        let mut state = self.lock();
1302        state.connect(current_task, peer)
1303    }
1304
1305    fn listen(
1306        &self,
1307        _locked: &mut Locked<FileOpsCore>,
1308        _socket: &Socket,
1309        _backlog: i32,
1310        _credentials: ucred,
1311    ) -> Result<(), Errno> {
1312        error!(EOPNOTSUPP)
1313    }
1314
1315    fn accept(
1316        &self,
1317        _locked: &mut Locked<FileOpsCore>,
1318        _socket: &Socket,
1319        _current_task: &CurrentTask,
1320    ) -> Result<SocketHandle, Errno> {
1321        error!(EOPNOTSUPP)
1322    }
1323
1324    fn bind(
1325        &self,
1326        _locked: &mut Locked<FileOpsCore>,
1327        _socket: &Socket,
1328        current_task: &CurrentTask,
1329        socket_address: SocketAddress,
1330    ) -> Result<(), Errno> {
1331        let mut state = self.lock();
1332        state.bind(current_task, socket_address)
1333    }
1334
1335    fn read(
1336        &self,
1337        _locked: &mut Locked<FileOpsCore>,
1338        _socket: &Socket,
1339        _current_task: &CurrentTask,
1340        data: &mut dyn OutputBuffer,
1341        flags: SocketMessageFlags,
1342    ) -> Result<MessageReadInfo, Errno> {
1343        self.lock().read_datagram(data, flags)
1344    }
1345
1346    fn write(
1347        &self,
1348        _locked: &mut Locked<FileOpsCore>,
1349        _socket: &Socket,
1350        _current_task: &CurrentTask,
1351        data: &mut dyn InputBuffer,
1352        _dest_address: &mut Option<SocketAddress>,
1353        _ancillary_data: &mut Vec<AncillaryData>,
1354    ) -> Result<usize, Errno> {
1355        let bytes = data.read_all()?;
1356        match NetlinkMessage::<GenericMessage>::deserialize(&bytes) {
1357            Err(e) => {
1358                log_warn!("Failed to process write; data could not be deserialized: {:?}", e);
1359                error!(EINVAL)
1360            }
1361            Ok(msg) => match self.message_sender.unbounded_send(msg) {
1362                Ok(()) => Ok(bytes.len()),
1363                Err(e) => {
1364                    log_warn!("Netlink receiver unexpectedly disconnected for socket: {:?}", e);
1365                    error!(EPIPE)
1366                }
1367            },
1368        }
1369    }
1370
1371    fn wait_async(
1372        &self,
1373        _locked: &mut Locked<FileOpsCore>,
1374        _socket: &Socket,
1375        _current_task: &CurrentTask,
1376        waiter: &Waiter,
1377        events: FdEvents,
1378        handler: EventHandler,
1379    ) -> WaitCanceler {
1380        self.lock().wait_async(waiter, events, handler)
1381    }
1382
1383    fn query_events(
1384        &self,
1385        _locked: &mut Locked<FileOpsCore>,
1386        _socket: &Socket,
1387        _current_task: &CurrentTask,
1388    ) -> Result<FdEvents, Errno> {
1389        Ok(self.lock().query_events() & FdEvents::POLLIN)
1390    }
1391
1392    fn shutdown(
1393        &self,
1394        _locked: &mut Locked<FileOpsCore>,
1395        _socket: &Socket,
1396        _how: SocketShutdownFlags,
1397    ) -> Result<(), Errno> {
1398        track_stub!(TODO("https://fxbug.dev/322875507"), "GenericNetlinkSocket::shutdown");
1399        Ok(())
1400    }
1401
1402    fn close(
1403        &self,
1404        _locked: &mut Locked<FileOpsCore>,
1405        _current_task: &CurrentTask,
1406        _socket: &Socket,
1407    ) {
1408    }
1409
1410    fn getsockname(
1411        &self,
1412        _locked: &mut Locked<FileOpsCore>,
1413        _socket: &Socket,
1414    ) -> Result<SocketAddress, Errno> {
1415        self.lock().getsockname()
1416    }
1417
1418    fn getpeername(
1419        &self,
1420        _locked: &mut Locked<FileOpsCore>,
1421        _socket: &Socket,
1422    ) -> Result<SocketAddress, Errno> {
1423        self.lock().getpeername()
1424    }
1425
1426    fn getsockopt(
1427        &self,
1428        _locked: &mut Locked<FileOpsCore>,
1429        _socket: &Socket,
1430        _current_task: &CurrentTask,
1431        level: u32,
1432        optname: u32,
1433        _optlen: u32,
1434    ) -> Result<Vec<u8>, Errno> {
1435        self.lock().getsockopt(level, optname)
1436    }
1437
1438    fn setsockopt(
1439        &self,
1440        _locked: &mut Locked<FileOpsCore>,
1441        _socket: &Socket,
1442        current_task: &CurrentTask,
1443        level: u32,
1444        optname: u32,
1445        optval: SockOptValue,
1446    ) -> Result<(), Errno> {
1447        match (level, optname) {
1448            (SOL_NETLINK, NETLINK_ADD_MEMBERSHIP) => {
1449                let group_id: u32 = optval.read(current_task)?;
1450                self.client.add_membership(ModernGroup(group_id))
1451            }
1452            _ => self.lock().setsockopt(current_task, level, optname, optval),
1453        }
1454    }
1455}
1456
1457/// Audit client that can be attached to the `AuditLogger`.
1458pub struct AuditNetlinkClient {
1459    /// Reference to the `AuditLogger`.
1460    audit_logger: Arc<AuditLogger>,
1461    /// The waiters queue present in `AuditNetlinkSocket`.
1462    waiters: WaitQueue,
1463    /// Optional response from the `AuditLogger`.
1464    audit_response: Mutex<Option<NetlinkMessage<GenericMessage>>>,
1465}
1466
1467impl AuditNetlinkClient {
1468    fn new(audit_logger: Arc<AuditLogger>) -> Self {
1469        Self { audit_logger, waiters: Default::default(), audit_response: Mutex::new(None) }
1470    }
1471
1472    pub fn notify(&self) {
1473        self.waiters.notify_fd_events(FdEvents::POLLIN);
1474    }
1475
1476    /// Function to check the capabilities of the current task against CAP_AUDIT_*
1477    fn check_audit_access(
1478        &self,
1479        current_task: &CurrentTask,
1480        request_type: &AuditRequest,
1481    ) -> Result<(), Errno> {
1482        match request_type {
1483            AuditRequest::AuditGet | AuditRequest::AuditSet => {
1484                security::check_task_capable(current_task, CAP_AUDIT_CONTROL)
1485            }
1486            AuditRequest::AuditUser => security::check_task_capable(current_task, CAP_AUDIT_WRITE),
1487        }
1488    }
1489
1490    /// Function to process request coming from userspace, it returns the response after processing
1491    fn process_request(
1492        self: &Arc<Self>,
1493        current_task: &CurrentTask,
1494        nl_message: NetlinkMessage<GenericMessage>,
1495    ) -> Result<NetlinkMessage<GenericMessage>, Errno> {
1496        let (nl_header, nl_payload) = nl_message.into_parts();
1497        let audit_request_type = AuditRequest::try_from(nl_header.message_type as u32)?;
1498        self.check_audit_access(current_task, &audit_request_type)?;
1499
1500        // If there is no GenericMessage, return an ErrorMessage.
1501        let NetlinkPayload::InnerMessage(GenericMessage::Other { payload, .. }) = nl_payload else {
1502            return error!(EINVAL);
1503        };
1504        match audit_request_type {
1505            AuditRequest::AuditGet => self.process_get_status(nl_header.sequence_number),
1506            AuditRequest::AuditSet => self.process_set_status(current_task, nl_header, payload),
1507            AuditRequest::AuditUser => self.process_user_audit(nl_header, payload),
1508        }
1509    }
1510
1511    fn get_nl_response(&self, flags: SocketMessageFlags) -> Option<Vec<u8>> {
1512        if flags.contains(SocketMessageFlags::PEEK) {
1513            if let Some(message) = self.audit_response.lock().as_ref() {
1514                return Some(AuditNetlinkClient::serialize_nlmsg(message.clone()));
1515            }
1516        } else if let Some(message) = self.audit_response.lock().take() {
1517            return Some(AuditNetlinkClient::serialize_nlmsg(message));
1518        }
1519        None
1520    }
1521
1522    /// Function to read an audit message from `AuditLogger`.
1523    fn read_audit_log(self: &Arc<Self>) -> Option<Vec<u8>> {
1524        if let Some(AuditMessage { audit_type, message }) = self.audit_logger.read_audit_log(self) {
1525            return Some(AuditNetlinkClient::serialize_nlmsg(
1526                AuditNetlinkClient::build_audit_nlmsg(0, audit_type, message),
1527            ));
1528        }
1529        None
1530    }
1531
1532    /// Function to read the optional response if present or an audit message.
1533    fn read_nlmsg(self: &Arc<Self>, flags: SocketMessageFlags) -> Result<Vec<u8>, Errno> {
1534        // First check if there is a response and send it if present.
1535        // Send an audit message otherwise or return EAGAIN.
1536        self.get_nl_response(flags).or_else(|| self.read_audit_log()).ok_or_else(|| errno!(EAGAIN))
1537    }
1538
1539    fn process_get_status(
1540        &self,
1541        sequence_number: u32,
1542    ) -> Result<NetlinkMessage<GenericMessage>, Errno> {
1543        Ok(AuditNetlinkClient::build_audit_nlmsg(
1544            sequence_number,
1545            AUDIT_GET as u16,
1546            self.audit_logger.get_status().as_bytes().to_vec(),
1547        ))
1548    }
1549
1550    fn process_set_status(
1551        self: &Arc<Self>,
1552        current_task: &CurrentTask,
1553        nl_hdr: NetlinkHeader,
1554        nl_payload: Vec<u8>,
1555    ) -> Result<NetlinkMessage<GenericMessage>, Errno> {
1556        let Some(status) = audit_status::read_from_bytes(nl_payload.as_bytes()).ok() else {
1557            return error!(EINVAL);
1558        };
1559        self.audit_logger.set_status(current_task, status, self)?;
1560        Ok(AuditNetlinkClient::build_audit_ack(Ok(()), nl_hdr))
1561    }
1562
1563    fn process_user_audit(
1564        &self,
1565        nl_hdr: NetlinkHeader,
1566        nl_payload: Vec<u8>,
1567    ) -> Result<NetlinkMessage<GenericMessage>, Errno> {
1568        let audit_msg = String::from_utf8_lossy(nl_payload.as_bytes());
1569        self.audit_logger.audit_log(nl_hdr.message_type, move || audit_msg);
1570        Ok(AuditNetlinkClient::build_audit_ack(Ok(()), nl_hdr))
1571    }
1572
1573    fn query_events(self: &Arc<Self>) -> FdEvents {
1574        if self.audit_response.lock().is_some() || self.audit_logger.get_backlog_count(self) != 0 {
1575            return FdEvents::POLLIN;
1576        }
1577        FdEvents::empty()
1578    }
1579
1580    fn detach(self: &Arc<Self>) {
1581        self.audit_logger.detach_client(self);
1582    }
1583
1584    fn build_audit_nlmsg(
1585        seq_number: u32,
1586        msg_type: u16,
1587        payload: Vec<u8>,
1588    ) -> NetlinkMessage<GenericMessage> {
1589        // The family in GenericMessage can be used for message type, not only for the Netlink Family,
1590        // because after finalizing the message, the message type is equal to family.
1591        let nl_payload =
1592            NetlinkPayload::InnerMessage(GenericMessage::Other { family: msg_type, payload });
1593        let mut nl_header = NetlinkHeader::default();
1594        nl_header.sequence_number = seq_number;
1595        let mut message = NetlinkMessage::new(nl_header, nl_payload);
1596        message.finalize();
1597        message
1598    }
1599
1600    fn build_audit_ack(
1601        error: Result<(), Errno>,
1602        req_header: NetlinkHeader,
1603    ) -> NetlinkMessage<GenericMessage> {
1604        let error = {
1605            assert_eq!(req_header.buffer_len(), NETLINK_HEADER_LEN);
1606            let mut buffer = vec![0; NETLINK_HEADER_LEN];
1607            req_header.emit(&mut buffer);
1608
1609            let code = match error {
1610                Ok(()) => None,
1611                Err(e) => Some(
1612                    // Audit netlink errors are negative.
1613                    NonZeroI32::new(-(e.code.error_code() as i32))
1614                        .expect("Errno's code must be non-zero"),
1615                ),
1616            };
1617
1618            let mut error = ErrorMessage::default();
1619            error.code = code;
1620            error.header = buffer;
1621            error
1622        };
1623
1624        let payload = NetlinkPayload::<GenericMessage>::Error(error);
1625        let mut resp_header = NetlinkHeader::default();
1626        resp_header.message_type = NLMSG_ERROR;
1627        resp_header.sequence_number = req_header.sequence_number;
1628        let mut message = NetlinkMessage::new(resp_header, payload);
1629        message.finalize();
1630        message
1631    }
1632
1633    fn serialize_nlmsg(message: NetlinkMessage<GenericMessage>) -> Vec<u8> {
1634        let mut buf = vec![0; message.buffer_len()];
1635        message.serialize(&mut buf);
1636        buf
1637    }
1638}
1639
1640/// Audit Netlink Socket structure.
1641pub struct AuditNetlinkSocket {
1642    /// Reference to the `AuditNetlinkClient` associated with self.
1643    audit_client: Arc<AuditNetlinkClient>,
1644}
1645
1646impl AuditNetlinkSocket {
1647    pub fn new(kernel: &Kernel) -> Result<Self, Errno> {
1648        if kernel.audit_logger().is_disabled() {
1649            return error!(EPROTONOSUPPORT);
1650        }
1651        Ok(Self { audit_client: Arc::new(AuditNetlinkClient::new(kernel.audit_logger())) })
1652    }
1653}
1654
1655impl SocketOps for AuditNetlinkSocket {
1656    fn read(
1657        &self,
1658        _locked: &mut Locked<FileOpsCore>,
1659        _socket: &Socket,
1660        _current_task: &CurrentTask,
1661        data: &mut dyn OutputBuffer,
1662        flags: SocketMessageFlags,
1663    ) -> Result<MessageReadInfo, Errno> {
1664        let buf = self.audit_client.read_nlmsg(flags)?;
1665
1666        let size = data.write_all(buf.as_bytes())?;
1667        Ok(MessageReadInfo {
1668            bytes_read: size,
1669            message_length: size,
1670            address: Some(SocketAddress::Netlink(NetlinkAddress::default())),
1671            ancillary_data: vec![],
1672        })
1673    }
1674
1675    fn write(
1676        &self,
1677        _locked: &mut Locked<FileOpsCore>,
1678        socket: &Socket,
1679        current_task: &CurrentTask,
1680        data: &mut dyn InputBuffer,
1681        _dest_address: &mut Option<SocketAddress>,
1682        _ancillary_data: &mut Vec<AncillaryData>,
1683    ) -> Result<usize, Errno> {
1684        match NetlinkMessage::<GenericMessage>::deserialize(&(data.peek_all()?)) {
1685            Ok(nl_message) => {
1686                let header = nl_message.header;
1687                security::check_netlink_send_access(current_task, socket, header.message_type)?;
1688
1689                // Send request to the `AuditNetlinkClient`.
1690                let audit_ack = self
1691                    .audit_client
1692                    .process_request(current_task, nl_message)
1693                    .map_err(|e| AuditNetlinkClient::build_audit_ack(Err(e), header))
1694                    .unwrap_or_else(|nlerr| nlerr);
1695                *self.audit_client.audit_response.lock() = Some(audit_ack);
1696                data.drain();
1697                Ok(header.length as usize)
1698            }
1699            Err(e) => {
1700                log_warn!("Failed to process write; data could not be deserialized: {:?}", e);
1701                error!(EINVAL)
1702            }
1703        }
1704    }
1705
1706    fn wait_async(
1707        &self,
1708        _locked: &mut Locked<FileOpsCore>,
1709        _socket: &Socket,
1710        _current_task: &CurrentTask,
1711        waiter: &Waiter,
1712        events: FdEvents,
1713        handler: EventHandler,
1714    ) -> WaitCanceler {
1715        self.audit_client.waiters.wait_async_fd_events(waiter, events, handler)
1716    }
1717
1718    fn query_events(
1719        &self,
1720        _locked: &mut Locked<FileOpsCore>,
1721        _socket: &Socket,
1722        _current_task: &CurrentTask,
1723    ) -> Result<FdEvents, Errno> {
1724        Ok(self.audit_client.query_events() & FdEvents::POLLIN)
1725    }
1726
1727    fn close(
1728        &self,
1729        _locked: &mut Locked<FileOpsCore>,
1730        _current_task: &CurrentTask,
1731        _socket: &Socket,
1732    ) {
1733        // If the `AuditNetlinkClient` disconnects, detach it.
1734        self.audit_client.detach();
1735    }
1736
1737    fn shutdown(
1738        &self,
1739        _locked: &mut Locked<FileOpsCore>,
1740        _socket: &Socket,
1741        _how: SocketShutdownFlags,
1742    ) -> Result<(), Errno> {
1743        error!(EOPNOTSUPP)
1744    }
1745
1746    fn connect(
1747        &self,
1748        _locked: &mut Locked<FileOpsCore>,
1749        _socket: &SocketHandle,
1750        _current_task: &CurrentTask,
1751        _peer: SocketPeer,
1752    ) -> Result<(), Errno> {
1753        error!(EOPNOTSUPP)
1754    }
1755
1756    fn listen(
1757        &self,
1758        _locked: &mut Locked<FileOpsCore>,
1759        _socket: &Socket,
1760        _backlog: i32,
1761        _credentials: ucred,
1762    ) -> Result<(), Errno> {
1763        error!(EOPNOTSUPP)
1764    }
1765
1766    fn accept(
1767        &self,
1768        _locked: &mut Locked<FileOpsCore>,
1769        _socket: &Socket,
1770        _current_task: &CurrentTask,
1771    ) -> Result<SocketHandle, Errno> {
1772        error!(EOPNOTSUPP)
1773    }
1774
1775    fn bind(
1776        &self,
1777        _locked: &mut Locked<FileOpsCore>,
1778        _socket: &Socket,
1779        _current_task: &CurrentTask,
1780        _socket_address: SocketAddress,
1781    ) -> Result<(), Errno> {
1782        error!(EOPNOTSUPP)
1783    }
1784
1785    fn getsockname(
1786        &self,
1787        _locked: &mut Locked<FileOpsCore>,
1788        _socket: &Socket,
1789    ) -> Result<SocketAddress, Errno> {
1790        error!(EOPNOTSUPP)
1791    }
1792
1793    fn getpeername(
1794        &self,
1795        _locked: &mut Locked<FileOpsCore>,
1796        _socket: &Socket,
1797    ) -> Result<SocketAddress, Errno> {
1798        error!(EOPNOTSUPP)
1799    }
1800
1801    fn getsockopt(
1802        &self,
1803        _locked: &mut Locked<FileOpsCore>,
1804        _socket: &Socket,
1805        _current_task: &CurrentTask,
1806        _level: u32,
1807        _optname: u32,
1808        _optlen: u32,
1809    ) -> Result<Vec<u8>, Errno> {
1810        error!(EOPNOTSUPP)
1811    }
1812
1813    fn setsockopt(
1814        &self,
1815        _locked: &mut Locked<FileOpsCore>,
1816        _socket: &Socket,
1817        _current_task: &CurrentTask,
1818        _level: u32,
1819        _optname: u32,
1820        _optval: SockOptValue,
1821    ) -> Result<(), Errno> {
1822        error!(EOPNOTSUPP)
1823    }
1824}
1825
1826#[cfg(test)]
1827mod tests {
1828    use super::*;
1829
1830    use netlink_packet_route::RouteNetlinkMessage;
1831    use netlink_packet_route::route::RouteMessage;
1832    use test_case::test_case;
1833
1834    // Successfully send the message and observe it's stored in the queue.
1835    #[test_case(true; "sufficient_capacity")]
1836    // Attempting to send when the queue is full should succeed by increasing
1837    // the size of the queue.
1838    #[test_case(false; "insufficient_capacity")]
1839    fn test_netlink_to_client_sender(sufficient_capacity: bool) {
1840        const MODERN_GROUP: u32 = 5;
1841
1842        let mut message: NetlinkMessage<RouteNetlinkMessage> =
1843            RouteNetlinkMessage::NewRoute(RouteMessage::default()).into();
1844        message.finalize();
1845
1846        let (initial_queue_size, final_queue_size) = if sufficient_capacity {
1847            (SOCKET_DEFAULT_SIZE, SOCKET_DEFAULT_SIZE)
1848        } else {
1849            (0, message.buffer_len())
1850        };
1851
1852        let socket_inner = Arc::new(Mutex::new(NetlinkSocketInner {
1853            receive_buffer: MessageQueue::new(initial_queue_size),
1854            ..NetlinkSocketInner::new(NetlinkFamily::Route)
1855        }));
1856
1857        let mut sender = NetlinkToClientSender::<RouteNetlinkMessage>::new(socket_inner.clone());
1858        sender.send(message.clone(), Some(ModernGroup(MODERN_GROUP)));
1859        let Message { data, address, ancillary_data: _ } =
1860            socket_inner.lock().read_message().expect("should read message");
1861
1862        assert_eq!(
1863            address,
1864            Some(SocketAddress::Netlink(NetlinkAddress { pid: 0, groups: 1 << MODERN_GROUP }))
1865        );
1866        let actual_message = NetlinkMessage::<RouteNetlinkMessage>::deserialize(&data)
1867            .expect("message should deserialize into RtnlMessage");
1868        assert_eq!(actual_message, message);
1869        assert_eq!(socket_inner.lock().receive_buffer.capacity(), final_queue_size);
1870    }
1871
1872    fn getsockopt_u32(socket: &NetlinkSocketInner, level: u32, optname: u32) -> u32 {
1873        let byte_vec = socket.getsockopt(level, optname).expect("getsockopt should succeed");
1874        let bytes: [u8; 4] = byte_vec.as_slice().try_into().expect("expected 4 bytes");
1875        u32::from_ne_bytes(bytes)
1876    }
1877
1878    fn sock_opt_value(val: u32) -> SockOptValue {
1879        SockOptValue::Value(val.to_ne_bytes().to_vec())
1880    }
1881
1882    #[::fuchsia::test]
1883    async fn test_set_get_snd_rcv_buf() {
1884        crate::testing::spawn_kernel_and_run_sync(|_locked, current_task| {
1885            let mut socket = NetlinkSocketInner::new(NetlinkFamily::Route);
1886
1887            // Verify initialization uses the default value.
1888            let expected_default = u32::try_from(SOCKET_DEFAULT_SIZE).unwrap();
1889            assert_eq!(getsockopt_u32(&socket, SOL_SOCKET, SO_SNDBUF), expected_default);
1890            assert_eq!(getsockopt_u32(&socket, SOL_SOCKET, SO_RCVBUF), expected_default);
1891
1892            // Set new values and observe that they were applied.
1893            // Note that applied value is 2 times the requested value.
1894            const SNDBUF_SIZE: u32 = 12345;
1895            const RCVBUF_SIZE: u32 = 54321;
1896            socket
1897                .setsockopt(current_task, SOL_SOCKET, SO_SNDBUF, sock_opt_value(SNDBUF_SIZE))
1898                .expect("setsockopt should succeed");
1899            socket
1900                .setsockopt(current_task, SOL_SOCKET, SO_RCVBUF, sock_opt_value(RCVBUF_SIZE))
1901                .expect("setsockopt should succeed");
1902            assert_eq!(getsockopt_u32(&socket, SOL_SOCKET, SO_SNDBUF), SNDBUF_SIZE * 2);
1903            assert_eq!(getsockopt_u32(&socket, SOL_SOCKET, SO_RCVBUF), RCVBUF_SIZE * 2);
1904        })
1905        .await;
1906    }
1907
1908    #[::fuchsia::test]
1909    async fn test_snd_rcv_buf_limits() {
1910        crate::testing::spawn_kernel_and_run_sync(|_locked, current_task| {
1911            let mut socket = NetlinkSocketInner::new(NetlinkFamily::Route);
1912            let too_big = u32::try_from(SOCKET_MAX_SIZE).unwrap() + 1;
1913
1914            // SO_SNDBUF and SO_RCVBUF clamp the size to the limit.
1915            socket
1916                .setsockopt(current_task, SOL_SOCKET, SO_SNDBUF, sock_opt_value(too_big))
1917                .expect("setsockopt should succeed");
1918            socket
1919                .setsockopt(current_task, SOL_SOCKET, SO_RCVBUF, sock_opt_value(too_big))
1920                .expect("setsockopt should succeed");
1921            let expected_max = u32::try_from(SOCKET_MAX_SIZE).unwrap();
1922            assert_eq!(getsockopt_u32(&socket, SOL_SOCKET, SO_SNDBUF), expected_max);
1923            assert_eq!(getsockopt_u32(&socket, SOL_SOCKET, SO_RCVBUF), expected_max);
1924
1925            // SO_SNDBUFFORCE and SO_RCVBUFFORCE do not.
1926            // Note that the applied value is two times the requested value.
1927            socket
1928                .setsockopt(current_task, SOL_SOCKET, SO_SNDBUFFORCE, sock_opt_value(too_big))
1929                .expect("setsockopt should succeed");
1930            socket
1931                .setsockopt(current_task, SOL_SOCKET, SO_RCVBUFFORCE, sock_opt_value(too_big))
1932                .expect("setsockopt should succeed");
1933            assert_eq!(getsockopt_u32(&socket, SOL_SOCKET, SO_SNDBUF), too_big * 2);
1934            assert_eq!(getsockopt_u32(&socket, SOL_SOCKET, SO_RCVBUF), too_big * 2);
1935        })
1936        .await;
1937    }
1938}