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::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::{
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(new_route_socket(kernel)?),
82 NetlinkFamily::Generic => Box::new(GenericNetlinkSocket::new(kernel)?),
83 NetlinkFamily::SockDiag => Box::new(new_sock_diag_socket(kernel)?),
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 Permission::NetlinkSockDiagRead => false,
949 Permission::NetlinkSockDiagDestroy => true,
950 };
951 if !need_cap_net_admin {
952 return Ok(());
953 }
954
955 self.current_task.override_creds(creds.clone(), || {
956 security::check_task_capable(self.current_task, CAP_NET_ADMIN).map_err(|error| {
957 netlink::Errno::new(error.code.error_code() as i32)
958 .expect("Errno::error_code() is expected to be in range [1..max_i32]")
959 })
960 })
961 }
962}
963pub struct NetlinkContextImpl;
964
965impl NetlinkContext for NetlinkContextImpl {
966 type Creds = FullCredentials;
967 type Sender<M: Clone + NetlinkSerializable + Send> = NetlinkToClientSender<M>;
968 type Receiver<
969 M: Send + MessageWithPermission + NetlinkDeserializable<Error: Into<DecodeError>>,
970 > = UnboundedReceiver<NetlinkMessageWithCreds<UnparsedNetlinkMessage<Vec<u8>, M>, Self::Creds>>;
971 type AccessControl<'a> = NetlinkAccessControl<'a>;
972}
973
974fn new_route_socket(kernel: &Arc<Kernel>) -> Result<NetlinkSocket<NetlinkRouteClient>, Errno> {
975 let inner = Arc::new(Mutex::new(NetlinkSocketInner::new(NetlinkFamily::Route)));
976 let (message_sender, message_receiver) = mpsc::unbounded();
977 let client = match kernel
978 .network_netlink()
979 .new_route_client(NetlinkToClientSender::new(inner.clone()), message_receiver)
980 {
981 Ok(client) => client,
982 Err(NewClientError::Disconnected) => {
983 log_error!(
984 tag = NETLINK_LOG_TAG;
985 "Netlink async worker is unexpectedly disconnected"
986 );
987 return error!(EPIPE);
988 }
989 };
990 Ok(NetlinkSocket { inner, client, message_sender })
991}
992
993fn new_sock_diag_socket(
994 kernel: &Arc<Kernel>,
995) -> Result<NetlinkSocket<NetlinkSockDiagClient>, Errno> {
996 let inner = Arc::new(Mutex::new(NetlinkSocketInner::new(NetlinkFamily::SockDiag)));
997 let (message_sender, message_receiver) = mpsc::unbounded();
998 let client = match kernel
999 .network_netlink()
1000 .new_sock_diag_client(NetlinkToClientSender::new(inner.clone()), message_receiver)
1001 {
1002 Ok(client) => client,
1003 Err(NewClientError::Disconnected) => {
1004 log_error!(
1005 tag = NETLINK_LOG_TAG;
1006 "Netlink async worker is unexpectedly disconnected"
1007 );
1008 return error!(EPIPE);
1009 }
1010 };
1011 Ok(NetlinkSocket { inner, client, message_sender })
1012}
1013
1014struct NetlinkSocket<C: NetlinkClient> {
1016 inner: Arc<Mutex<NetlinkSocketInner>>,
1018 client: C,
1020 message_sender: UnboundedSender<
1024 NetlinkMessageWithCreds<UnparsedNetlinkMessage<Vec<u8>, C::Request>, FullCredentials>,
1025 >,
1026}
1027
1028impl<C: NetlinkClient + 'static> SocketOps for NetlinkSocket<C> {
1029 fn connect(
1030 &self,
1031 _locked: &mut Locked<FileOpsCore>,
1032 _socket: &SocketHandle,
1033 current_task: &CurrentTask,
1034 peer: SocketPeer,
1035 ) -> Result<(), Errno> {
1036 let NetlinkSocket { inner, client: _, message_sender: _ } = self;
1037 inner.lock().connect(current_task, peer)
1038 }
1039
1040 fn listen(
1041 &self,
1042 _locked: &mut Locked<FileOpsCore>,
1043 _socket: &Socket,
1044 _backlog: i32,
1045 _credentials: ucred,
1046 ) -> Result<(), Errno> {
1047 error!(EOPNOTSUPP)
1048 }
1049
1050 fn accept(
1051 &self,
1052 _locked: &mut Locked<FileOpsCore>,
1053 _socket: &Socket,
1054 _current_task: &CurrentTask,
1055 ) -> Result<SocketHandle, Errno> {
1056 error!(EOPNOTSUPP)
1057 }
1058
1059 fn bind(
1060 &self,
1061 _locked: &mut Locked<FileOpsCore>,
1062 _socket: &Socket,
1063 current_task: &CurrentTask,
1064 socket_address: SocketAddress,
1065 ) -> Result<(), Errno> {
1066 let NetlinkSocket { inner, client, message_sender: _ } = self;
1067
1068 let multicast_groups = match &socket_address {
1069 SocketAddress::Netlink(NetlinkAddress { pid: _, groups }) => *groups,
1070 _ => return error!(EINVAL),
1071 };
1072 let pid = {
1073 let mut inner = inner.lock();
1074 inner.bind(current_task, socket_address)?;
1075 inner
1076 .address
1077 .as_ref()
1078 .and_then(|NetlinkAddress { pid, groups: _ }| NonZeroU32::new(*pid))
1079 };
1080 if let Some(pid) = pid {
1081 client.set_pid(pid);
1082 }
1083 client
1088 .set_legacy_memberships(LegacyGroups(multicast_groups))
1089 .map_err(|InvalidLegacyGroupsError {}| errno!(EPERM))?
1090 .wait_until_complete();
1091 Ok(())
1092 }
1093
1094 fn read(
1095 &self,
1096 _locked: &mut Locked<FileOpsCore>,
1097 _socket: &Socket,
1098 _current_task: &CurrentTask,
1099 data: &mut dyn OutputBuffer,
1100 flags: SocketMessageFlags,
1101 ) -> Result<MessageReadInfo, Errno> {
1102 let NetlinkSocket { inner, client: _, message_sender: _ } = self;
1103 inner.lock().read_datagram(data, flags)
1104 }
1105
1106 fn write(
1107 &self,
1108 _locked: &mut Locked<FileOpsCore>,
1109 socket: &Socket,
1110 current_task: &CurrentTask,
1111 data: &mut dyn InputBuffer,
1112 _dest_address: &mut Option<SocketAddress>,
1113 _ancillary_data: &mut Vec<AncillaryData>,
1114 ) -> Result<usize, Errno> {
1115 let NetlinkSocket { inner: _, client: _, message_sender } = self;
1116
1117 let bytes = data.peek_all()?;
1118 let bytes_len = bytes.len();
1119
1120 match NetlinkBuffer::new(&bytes) {
1122 Ok(buffer) => {
1123 security::check_netlink_send_access(current_task, socket, buffer.message_type())?;
1124 }
1125 Err(e) => {
1126 log_warn!(tag = NETLINK_LOG_TAG;
1132 "Failed to parse netlink header {e:?}"
1133 );
1134 data.drain();
1135 return Ok(bytes_len);
1136 }
1137 }
1138
1139 let msg = NetlinkMessageWithCreds::new(
1140 UnparsedNetlinkMessage::new(bytes),
1141 current_task.full_current_creds(),
1142 );
1143 message_sender.unbounded_send(msg).map_err(|e| {
1144 log_warn!(
1145 tag = NETLINK_LOG_TAG;
1146 "Netlink receiver unexpectedly disconnected for socket: {:?}",
1147 e
1148 );
1149 errno!(EPIPE)
1150 })?;
1151 data.drain();
1152 Ok(bytes_len)
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 NetlinkSocket { 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 NetlinkSocket { 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 NetlinkSocket { 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 NetlinkSocket { 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 NetlinkSocket { 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 GenericNetlinkSocket {
1264 inner: Arc<Mutex<NetlinkSocketInner>>,
1265 client: GenericNetlinkClientHandle<NetlinkToClientSender<GenericMessage>>,
1266 message_sender: mpsc::UnboundedSender<NetlinkMessage<GenericMessage>>,
1267}
1268
1269impl GenericNetlinkSocket {
1270 pub fn new(kernel: &Kernel) -> Result<Self, Errno> {
1271 let inner = Arc::new(Mutex::new(NetlinkSocketInner::new(NetlinkFamily::Generic)));
1272 let (message_sender, message_receiver) = mpsc::unbounded();
1273 match kernel
1274 .generic_netlink()
1275 .new_generic_client(NetlinkToClientSender::new(inner.clone()), message_receiver)
1276 {
1277 Ok(client) => Ok(Self { inner, client, message_sender }),
1278 Err(e) => {
1279 log_warn!(
1280 tag = NETLINK_LOG_TAG;
1281 "Failed to connect to generic netlink server. Errno: {:?}",
1282 e
1283 );
1284 error!(EPIPE)
1285 }
1286 }
1287 }
1288
1289 fn lock(&self) -> starnix_sync::MutexGuard<'_, NetlinkSocketInner> {
1291 self.inner.lock()
1292 }
1293}
1294
1295impl SocketOps for GenericNetlinkSocket {
1296 fn connect(
1297 &self,
1298 _locked: &mut Locked<FileOpsCore>,
1299 _socket: &SocketHandle,
1300 current_task: &CurrentTask,
1301 peer: SocketPeer,
1302 ) -> Result<(), Errno> {
1303 let mut state = self.lock();
1304 state.connect(current_task, peer)
1305 }
1306
1307 fn listen(
1308 &self,
1309 _locked: &mut Locked<FileOpsCore>,
1310 _socket: &Socket,
1311 _backlog: i32,
1312 _credentials: ucred,
1313 ) -> Result<(), Errno> {
1314 error!(EOPNOTSUPP)
1315 }
1316
1317 fn accept(
1318 &self,
1319 _locked: &mut Locked<FileOpsCore>,
1320 _socket: &Socket,
1321 _current_task: &CurrentTask,
1322 ) -> Result<SocketHandle, Errno> {
1323 error!(EOPNOTSUPP)
1324 }
1325
1326 fn bind(
1327 &self,
1328 _locked: &mut Locked<FileOpsCore>,
1329 _socket: &Socket,
1330 current_task: &CurrentTask,
1331 socket_address: SocketAddress,
1332 ) -> Result<(), Errno> {
1333 let mut state = self.lock();
1334 state.bind(current_task, socket_address)
1335 }
1336
1337 fn read(
1338 &self,
1339 _locked: &mut Locked<FileOpsCore>,
1340 _socket: &Socket,
1341 _current_task: &CurrentTask,
1342 data: &mut dyn OutputBuffer,
1343 flags: SocketMessageFlags,
1344 ) -> Result<MessageReadInfo, Errno> {
1345 self.lock().read_datagram(data, flags)
1346 }
1347
1348 fn write(
1349 &self,
1350 _locked: &mut Locked<FileOpsCore>,
1351 _socket: &Socket,
1352 _current_task: &CurrentTask,
1353 data: &mut dyn InputBuffer,
1354 _dest_address: &mut Option<SocketAddress>,
1355 _ancillary_data: &mut Vec<AncillaryData>,
1356 ) -> Result<usize, Errno> {
1357 let bytes = data.read_all()?;
1358 match NetlinkMessage::<GenericMessage>::deserialize(&bytes) {
1359 Err(e) => {
1360 log_warn!("Failed to process write; data could not be deserialized: {:?}", e);
1361 error!(EINVAL)
1362 }
1363 Ok(msg) => match self.message_sender.unbounded_send(msg) {
1364 Ok(()) => Ok(bytes.len()),
1365 Err(e) => {
1366 log_warn!("Netlink receiver unexpectedly disconnected for socket: {:?}", e);
1367 error!(EPIPE)
1368 }
1369 },
1370 }
1371 }
1372
1373 fn wait_async(
1374 &self,
1375 _locked: &mut Locked<FileOpsCore>,
1376 _socket: &Socket,
1377 _current_task: &CurrentTask,
1378 waiter: &Waiter,
1379 events: FdEvents,
1380 handler: EventHandler,
1381 ) -> WaitCanceler {
1382 self.lock().wait_async(waiter, events, handler)
1383 }
1384
1385 fn query_events(
1386 &self,
1387 _locked: &mut Locked<FileOpsCore>,
1388 _socket: &Socket,
1389 _current_task: &CurrentTask,
1390 ) -> Result<FdEvents, Errno> {
1391 Ok(self.lock().query_events() & FdEvents::POLLIN)
1392 }
1393
1394 fn shutdown(
1395 &self,
1396 _locked: &mut Locked<FileOpsCore>,
1397 _socket: &Socket,
1398 _how: SocketShutdownFlags,
1399 ) -> Result<(), Errno> {
1400 track_stub!(TODO("https://fxbug.dev/322875507"), "GenericNetlinkSocket::shutdown");
1401 Ok(())
1402 }
1403
1404 fn close(
1405 &self,
1406 _locked: &mut Locked<FileOpsCore>,
1407 _current_task: &CurrentTask,
1408 _socket: &Socket,
1409 ) {
1410 }
1411
1412 fn getsockname(
1413 &self,
1414 _locked: &mut Locked<FileOpsCore>,
1415 _socket: &Socket,
1416 ) -> Result<SocketAddress, Errno> {
1417 self.lock().getsockname()
1418 }
1419
1420 fn getpeername(
1421 &self,
1422 _locked: &mut Locked<FileOpsCore>,
1423 _socket: &Socket,
1424 ) -> Result<SocketAddress, Errno> {
1425 self.lock().getpeername()
1426 }
1427
1428 fn getsockopt(
1429 &self,
1430 _locked: &mut Locked<FileOpsCore>,
1431 _socket: &Socket,
1432 _current_task: &CurrentTask,
1433 level: u32,
1434 optname: u32,
1435 _optlen: u32,
1436 ) -> Result<Vec<u8>, Errno> {
1437 self.lock().getsockopt(level, optname)
1438 }
1439
1440 fn setsockopt(
1441 &self,
1442 _locked: &mut Locked<FileOpsCore>,
1443 _socket: &Socket,
1444 current_task: &CurrentTask,
1445 level: u32,
1446 optname: u32,
1447 optval: SockOptValue,
1448 ) -> Result<(), Errno> {
1449 match (level, optname) {
1450 (SOL_NETLINK, NETLINK_ADD_MEMBERSHIP) => {
1451 let group_id: u32 = optval.read(current_task)?;
1452 self.client.add_membership(ModernGroup(group_id))
1453 }
1454 _ => self.lock().setsockopt(current_task, level, optname, optval),
1455 }
1456 }
1457}
1458
1459pub struct AuditNetlinkClient {
1461 audit_logger: Arc<AuditLogger>,
1463 waiters: WaitQueue,
1465 audit_response: Mutex<Option<NetlinkMessage<GenericMessage>>>,
1467}
1468
1469impl AuditNetlinkClient {
1470 fn new(audit_logger: Arc<AuditLogger>) -> Self {
1471 Self { audit_logger, waiters: Default::default(), audit_response: Mutex::new(None) }
1472 }
1473
1474 pub fn notify(&self) {
1475 self.waiters.notify_fd_events(FdEvents::POLLIN);
1476 }
1477
1478 fn check_audit_access(
1480 &self,
1481 current_task: &CurrentTask,
1482 request_type: &AuditRequest,
1483 ) -> Result<(), Errno> {
1484 match request_type {
1485 AuditRequest::AuditGet | AuditRequest::AuditSet => {
1486 security::check_task_capable(current_task, CAP_AUDIT_CONTROL)
1487 }
1488 AuditRequest::AuditUser => security::check_task_capable(current_task, CAP_AUDIT_WRITE),
1489 }
1490 }
1491
1492 fn process_request(
1494 self: &Arc<Self>,
1495 current_task: &CurrentTask,
1496 nl_message: NetlinkMessage<GenericMessage>,
1497 ) -> Result<NetlinkMessage<GenericMessage>, Errno> {
1498 let (nl_header, nl_payload) = nl_message.into_parts();
1499 let audit_request_type = AuditRequest::try_from(nl_header.message_type as u32)?;
1500 self.check_audit_access(current_task, &audit_request_type)?;
1501
1502 let NetlinkPayload::InnerMessage(GenericMessage::Other { payload, .. }) = nl_payload else {
1504 return error!(EINVAL);
1505 };
1506 match audit_request_type {
1507 AuditRequest::AuditGet => self.process_get_status(nl_header.sequence_number),
1508 AuditRequest::AuditSet => self.process_set_status(current_task, nl_header, payload),
1509 AuditRequest::AuditUser => self.process_user_audit(nl_header, payload),
1510 }
1511 }
1512
1513 fn get_nl_response(&self, flags: SocketMessageFlags) -> Option<Vec<u8>> {
1514 if flags.contains(SocketMessageFlags::PEEK) {
1515 if let Some(message) = self.audit_response.lock().as_ref() {
1516 return Some(AuditNetlinkClient::serialize_nlmsg(message.clone()));
1517 }
1518 } else if let Some(message) = self.audit_response.lock().take() {
1519 return Some(AuditNetlinkClient::serialize_nlmsg(message));
1520 }
1521 None
1522 }
1523
1524 fn read_audit_log(self: &Arc<Self>) -> Option<Vec<u8>> {
1526 if let Some(AuditMessage { audit_type, message }) = self.audit_logger.read_audit_log(self) {
1527 return Some(AuditNetlinkClient::serialize_nlmsg(
1528 AuditNetlinkClient::build_audit_nlmsg(0, audit_type, message),
1529 ));
1530 }
1531 None
1532 }
1533
1534 fn read_nlmsg(self: &Arc<Self>, flags: SocketMessageFlags) -> Result<Vec<u8>, Errno> {
1536 self.get_nl_response(flags).or_else(|| self.read_audit_log()).ok_or_else(|| errno!(EAGAIN))
1539 }
1540
1541 fn process_get_status(
1542 &self,
1543 sequence_number: u32,
1544 ) -> Result<NetlinkMessage<GenericMessage>, Errno> {
1545 Ok(AuditNetlinkClient::build_audit_nlmsg(
1546 sequence_number,
1547 AUDIT_GET as u16,
1548 self.audit_logger.get_status().as_bytes().to_vec(),
1549 ))
1550 }
1551
1552 fn process_set_status(
1553 self: &Arc<Self>,
1554 current_task: &CurrentTask,
1555 nl_hdr: NetlinkHeader,
1556 nl_payload: Vec<u8>,
1557 ) -> Result<NetlinkMessage<GenericMessage>, Errno> {
1558 let Some(status) = audit_status::read_from_bytes(nl_payload.as_bytes()).ok() else {
1559 return error!(EINVAL);
1560 };
1561 self.audit_logger.set_status(current_task, status, self)?;
1562 Ok(AuditNetlinkClient::build_audit_ack(Ok(()), nl_hdr))
1563 }
1564
1565 fn process_user_audit(
1566 &self,
1567 nl_hdr: NetlinkHeader,
1568 nl_payload: Vec<u8>,
1569 ) -> Result<NetlinkMessage<GenericMessage>, Errno> {
1570 let audit_msg = String::from_utf8_lossy(nl_payload.as_bytes());
1571 self.audit_logger.audit_log(nl_hdr.message_type, move || audit_msg);
1572 Ok(AuditNetlinkClient::build_audit_ack(Ok(()), nl_hdr))
1573 }
1574
1575 fn query_events(self: &Arc<Self>) -> FdEvents {
1576 if self.audit_response.lock().is_some() || self.audit_logger.get_backlog_count(self) != 0 {
1577 return FdEvents::POLLIN;
1578 }
1579 FdEvents::empty()
1580 }
1581
1582 fn detach(self: &Arc<Self>) {
1583 self.audit_logger.detach_client(self);
1584 }
1585
1586 fn build_audit_nlmsg(
1587 seq_number: u32,
1588 msg_type: u16,
1589 payload: Vec<u8>,
1590 ) -> NetlinkMessage<GenericMessage> {
1591 let nl_payload =
1594 NetlinkPayload::InnerMessage(GenericMessage::Other { family: msg_type, payload });
1595 let mut nl_header = NetlinkHeader::default();
1596 nl_header.sequence_number = seq_number;
1597 let mut message = NetlinkMessage::new(nl_header, nl_payload);
1598 message.finalize();
1599 message
1600 }
1601
1602 fn build_audit_ack(
1603 error: Result<(), Errno>,
1604 req_header: NetlinkHeader,
1605 ) -> NetlinkMessage<GenericMessage> {
1606 let error = {
1607 assert_eq!(req_header.buffer_len(), NETLINK_HEADER_LEN);
1608 let mut buffer = vec![0; NETLINK_HEADER_LEN];
1609 req_header.emit(&mut buffer);
1610
1611 let code = match error {
1612 Ok(()) => None,
1613 Err(e) => Some(
1614 NonZeroI32::new(-(e.code.error_code() as i32))
1616 .expect("Errno's code must be non-zero"),
1617 ),
1618 };
1619
1620 let mut error = ErrorMessage::default();
1621 error.code = code;
1622 error.header = buffer;
1623 error
1624 };
1625
1626 let payload = NetlinkPayload::<GenericMessage>::Error(error);
1627 let mut resp_header = NetlinkHeader::default();
1628 resp_header.message_type = NLMSG_ERROR;
1629 resp_header.sequence_number = req_header.sequence_number;
1630 let mut message = NetlinkMessage::new(resp_header, payload);
1631 message.finalize();
1632 message
1633 }
1634
1635 fn serialize_nlmsg(message: NetlinkMessage<GenericMessage>) -> Vec<u8> {
1636 let mut buf = vec![0; message.buffer_len()];
1637 message.serialize(&mut buf);
1638 buf
1639 }
1640}
1641
1642pub struct AuditNetlinkSocket {
1644 audit_client: Arc<AuditNetlinkClient>,
1646}
1647
1648impl AuditNetlinkSocket {
1649 pub fn new(kernel: &Kernel) -> Result<Self, Errno> {
1650 if kernel.audit_logger().is_disabled() {
1651 return error!(EPROTONOSUPPORT);
1652 }
1653 Ok(Self { audit_client: Arc::new(AuditNetlinkClient::new(kernel.audit_logger())) })
1654 }
1655}
1656
1657impl SocketOps for AuditNetlinkSocket {
1658 fn read(
1659 &self,
1660 _locked: &mut Locked<FileOpsCore>,
1661 _socket: &Socket,
1662 _current_task: &CurrentTask,
1663 data: &mut dyn OutputBuffer,
1664 flags: SocketMessageFlags,
1665 ) -> Result<MessageReadInfo, Errno> {
1666 let buf = self.audit_client.read_nlmsg(flags)?;
1667
1668 let size = data.write_all(buf.as_bytes())?;
1669 Ok(MessageReadInfo {
1670 bytes_read: size,
1671 message_length: size,
1672 address: Some(SocketAddress::Netlink(NetlinkAddress::default())),
1673 ancillary_data: vec![],
1674 })
1675 }
1676
1677 fn write(
1678 &self,
1679 _locked: &mut Locked<FileOpsCore>,
1680 socket: &Socket,
1681 current_task: &CurrentTask,
1682 data: &mut dyn InputBuffer,
1683 _dest_address: &mut Option<SocketAddress>,
1684 _ancillary_data: &mut Vec<AncillaryData>,
1685 ) -> Result<usize, Errno> {
1686 match NetlinkMessage::<GenericMessage>::deserialize(&(data.peek_all()?)) {
1687 Ok(nl_message) => {
1688 let header = nl_message.header;
1689 security::check_netlink_send_access(current_task, socket, header.message_type)?;
1690
1691 let audit_ack = self
1693 .audit_client
1694 .process_request(current_task, nl_message)
1695 .map_err(|e| AuditNetlinkClient::build_audit_ack(Err(e), header))
1696 .unwrap_or_else(|nlerr| nlerr);
1697 *self.audit_client.audit_response.lock() = Some(audit_ack);
1698 data.drain();
1699 Ok(header.length as usize)
1700 }
1701 Err(e) => {
1702 log_warn!("Failed to process write; data could not be deserialized: {:?}", e);
1703 error!(EINVAL)
1704 }
1705 }
1706 }
1707
1708 fn wait_async(
1709 &self,
1710 _locked: &mut Locked<FileOpsCore>,
1711 _socket: &Socket,
1712 _current_task: &CurrentTask,
1713 waiter: &Waiter,
1714 events: FdEvents,
1715 handler: EventHandler,
1716 ) -> WaitCanceler {
1717 self.audit_client.waiters.wait_async_fd_events(waiter, events, handler)
1718 }
1719
1720 fn query_events(
1721 &self,
1722 _locked: &mut Locked<FileOpsCore>,
1723 _socket: &Socket,
1724 _current_task: &CurrentTask,
1725 ) -> Result<FdEvents, Errno> {
1726 Ok(self.audit_client.query_events() & FdEvents::POLLIN)
1727 }
1728
1729 fn close(
1730 &self,
1731 _locked: &mut Locked<FileOpsCore>,
1732 _current_task: &CurrentTask,
1733 _socket: &Socket,
1734 ) {
1735 self.audit_client.detach();
1737 }
1738
1739 fn shutdown(
1740 &self,
1741 _locked: &mut Locked<FileOpsCore>,
1742 _socket: &Socket,
1743 _how: SocketShutdownFlags,
1744 ) -> Result<(), Errno> {
1745 error!(EOPNOTSUPP)
1746 }
1747
1748 fn connect(
1749 &self,
1750 _locked: &mut Locked<FileOpsCore>,
1751 _socket: &SocketHandle,
1752 _current_task: &CurrentTask,
1753 _peer: SocketPeer,
1754 ) -> Result<(), Errno> {
1755 error!(EOPNOTSUPP)
1756 }
1757
1758 fn listen(
1759 &self,
1760 _locked: &mut Locked<FileOpsCore>,
1761 _socket: &Socket,
1762 _backlog: i32,
1763 _credentials: ucred,
1764 ) -> Result<(), Errno> {
1765 error!(EOPNOTSUPP)
1766 }
1767
1768 fn accept(
1769 &self,
1770 _locked: &mut Locked<FileOpsCore>,
1771 _socket: &Socket,
1772 _current_task: &CurrentTask,
1773 ) -> Result<SocketHandle, Errno> {
1774 error!(EOPNOTSUPP)
1775 }
1776
1777 fn bind(
1778 &self,
1779 _locked: &mut Locked<FileOpsCore>,
1780 _socket: &Socket,
1781 _current_task: &CurrentTask,
1782 _socket_address: SocketAddress,
1783 ) -> Result<(), Errno> {
1784 error!(EOPNOTSUPP)
1785 }
1786
1787 fn getsockname(
1788 &self,
1789 _locked: &mut Locked<FileOpsCore>,
1790 _socket: &Socket,
1791 ) -> Result<SocketAddress, Errno> {
1792 error!(EOPNOTSUPP)
1793 }
1794
1795 fn getpeername(
1796 &self,
1797 _locked: &mut Locked<FileOpsCore>,
1798 _socket: &Socket,
1799 ) -> Result<SocketAddress, Errno> {
1800 error!(EOPNOTSUPP)
1801 }
1802
1803 fn getsockopt(
1804 &self,
1805 _locked: &mut Locked<FileOpsCore>,
1806 _socket: &Socket,
1807 _current_task: &CurrentTask,
1808 _level: u32,
1809 _optname: u32,
1810 _optlen: u32,
1811 ) -> Result<Vec<u8>, Errno> {
1812 error!(EOPNOTSUPP)
1813 }
1814
1815 fn setsockopt(
1816 &self,
1817 _locked: &mut Locked<FileOpsCore>,
1818 _socket: &Socket,
1819 _current_task: &CurrentTask,
1820 _level: u32,
1821 _optname: u32,
1822 _optval: SockOptValue,
1823 ) -> Result<(), Errno> {
1824 error!(EOPNOTSUPP)
1825 }
1826}
1827
1828#[cfg(test)]
1829mod tests {
1830 use super::*;
1831
1832 use netlink_packet_route::RouteNetlinkMessage;
1833 use netlink_packet_route::route::RouteMessage;
1834 use test_case::test_case;
1835
1836 #[test_case(true; "sufficient_capacity")]
1838 #[test_case(false; "insufficient_capacity")]
1841 fn test_netlink_to_client_sender(sufficient_capacity: bool) {
1842 const MODERN_GROUP: u32 = 5;
1843
1844 let mut message: NetlinkMessage<RouteNetlinkMessage> =
1845 RouteNetlinkMessage::NewRoute(RouteMessage::default()).into();
1846 message.finalize();
1847
1848 let (initial_queue_size, final_queue_size) = if sufficient_capacity {
1849 (SOCKET_DEFAULT_SIZE, SOCKET_DEFAULT_SIZE)
1850 } else {
1851 (0, message.buffer_len())
1852 };
1853
1854 let socket_inner = Arc::new(Mutex::new(NetlinkSocketInner {
1855 receive_buffer: MessageQueue::new(initial_queue_size),
1856 ..NetlinkSocketInner::new(NetlinkFamily::Route)
1857 }));
1858
1859 let mut sender = NetlinkToClientSender::<RouteNetlinkMessage>::new(socket_inner.clone());
1860 sender.send(message.clone(), Some(ModernGroup(MODERN_GROUP)));
1861 let Message { data, address, ancillary_data: _ } =
1862 socket_inner.lock().read_message().expect("should read message");
1863
1864 assert_eq!(
1865 address,
1866 Some(SocketAddress::Netlink(NetlinkAddress { pid: 0, groups: 1 << MODERN_GROUP }))
1867 );
1868 let actual_message = NetlinkMessage::<RouteNetlinkMessage>::deserialize(&data)
1869 .expect("message should deserialize into RtnlMessage");
1870 assert_eq!(actual_message, message);
1871 assert_eq!(socket_inner.lock().receive_buffer.capacity(), final_queue_size);
1872 }
1873
1874 fn getsockopt_u32(socket: &NetlinkSocketInner, level: u32, optname: u32) -> u32 {
1875 let byte_vec = socket.getsockopt(level, optname).expect("getsockopt should succeed");
1876 let bytes: [u8; 4] = byte_vec.as_slice().try_into().expect("expected 4 bytes");
1877 u32::from_ne_bytes(bytes)
1878 }
1879
1880 fn sock_opt_value(val: u32) -> SockOptValue {
1881 SockOptValue::Value(val.to_ne_bytes().to_vec())
1882 }
1883
1884 #[::fuchsia::test]
1885 async fn test_set_get_snd_rcv_buf() {
1886 crate::testing::spawn_kernel_and_run_sync(|_locked, current_task| {
1887 let mut socket = NetlinkSocketInner::new(NetlinkFamily::Route);
1888
1889 let expected_default = u32::try_from(SOCKET_DEFAULT_SIZE).unwrap();
1891 assert_eq!(getsockopt_u32(&socket, SOL_SOCKET, SO_SNDBUF), expected_default);
1892 assert_eq!(getsockopt_u32(&socket, SOL_SOCKET, SO_RCVBUF), expected_default);
1893
1894 const SNDBUF_SIZE: u32 = 12345;
1897 const RCVBUF_SIZE: u32 = 54321;
1898 socket
1899 .setsockopt(current_task, SOL_SOCKET, SO_SNDBUF, sock_opt_value(SNDBUF_SIZE))
1900 .expect("setsockopt should succeed");
1901 socket
1902 .setsockopt(current_task, SOL_SOCKET, SO_RCVBUF, sock_opt_value(RCVBUF_SIZE))
1903 .expect("setsockopt should succeed");
1904 assert_eq!(getsockopt_u32(&socket, SOL_SOCKET, SO_SNDBUF), SNDBUF_SIZE * 2);
1905 assert_eq!(getsockopt_u32(&socket, SOL_SOCKET, SO_RCVBUF), RCVBUF_SIZE * 2);
1906 })
1907 .await;
1908 }
1909
1910 #[::fuchsia::test]
1911 async fn test_snd_rcv_buf_limits() {
1912 crate::testing::spawn_kernel_and_run_sync(|_locked, current_task| {
1913 let mut socket = NetlinkSocketInner::new(NetlinkFamily::Route);
1914 let too_big = u32::try_from(SOCKET_MAX_SIZE).unwrap() + 1;
1915
1916 socket
1918 .setsockopt(current_task, SOL_SOCKET, SO_SNDBUF, sock_opt_value(too_big))
1919 .expect("setsockopt should succeed");
1920 socket
1921 .setsockopt(current_task, SOL_SOCKET, SO_RCVBUF, sock_opt_value(too_big))
1922 .expect("setsockopt should succeed");
1923 let expected_max = u32::try_from(SOCKET_MAX_SIZE).unwrap();
1924 assert_eq!(getsockopt_u32(&socket, SOL_SOCKET, SO_SNDBUF), expected_max);
1925 assert_eq!(getsockopt_u32(&socket, SOL_SOCKET, SO_RCVBUF), expected_max);
1926
1927 socket
1930 .setsockopt(current_task, SOL_SOCKET, SO_SNDBUFFORCE, sock_opt_value(too_big))
1931 .expect("setsockopt should succeed");
1932 socket
1933 .setsockopt(current_task, SOL_SOCKET, SO_RCVBUFFORCE, sock_opt_value(too_big))
1934 .expect("setsockopt should succeed");
1935 assert_eq!(getsockopt_u32(&socket, SOL_SOCKET, SO_SNDBUF), too_big * 2);
1936 assert_eq!(getsockopt_u32(&socket, SOL_SOCKET, SO_RCVBUF), too_big * 2);
1937 })
1938 .await;
1939 }
1940}