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