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