1#![allow(non_upper_case_globals)]
7
8use crate::bpf::attachments::{BpfAttachAttr, bpf_prog_attach, bpf_prog_detach};
9use crate::bpf::fs::{BpfFsDir, BpfHandle, get_bpf_object, resolve_pinned_bpf_object};
10use crate::bpf::map::{self, BpfMap, BpfMapHandle};
11use crate::bpf::program::{Program, ProgramInfo};
12use crate::mm::{MemoryAccessor, MemoryAccessorExt};
13use crate::security;
14use crate::task::CurrentTask;
15use crate::vfs::socket::{Socket, ZxioBackedSocket};
16use crate::vfs::{Anon, FdFlags, FdNumber, LookupContext, OutputBuffer, UserBuffersOutputBuffer};
17use ebpf::{EbpfInstruction, MapFlags, MapSchema};
18use ebpf_api::{MapKey, ProgramType};
19use smallvec::smallvec;
20use starnix_logging::{log_error, log_trace, log_warn, track_stub};
21use starnix_sync::{Locked, Unlocked};
22use starnix_syscalls::{SUCCESS, SyscallResult};
23use starnix_types::user_buffer::UserBuffer;
24use starnix_uapi::auth::CAP_SYS_ADMIN;
25use starnix_uapi::errors::Errno;
26use starnix_uapi::open_flags::OpenFlags;
27use starnix_uapi::user_address::{UserAddress, UserCString, UserRef};
28use starnix_uapi::{
29 BPF_F_RDONLY, BPF_F_WRONLY, bpf_attr__bindgen_ty_1, bpf_attr__bindgen_ty_2,
30 bpf_attr__bindgen_ty_4, bpf_attr__bindgen_ty_5, bpf_attr__bindgen_ty_8, bpf_attr__bindgen_ty_9,
31 bpf_attr__bindgen_ty_10, bpf_attr__bindgen_ty_12, bpf_cmd, bpf_cmd_BPF_BTF_GET_FD_BY_ID,
32 bpf_cmd_BPF_BTF_GET_NEXT_ID, bpf_cmd_BPF_BTF_LOAD, bpf_cmd_BPF_ENABLE_STATS,
33 bpf_cmd_BPF_ITER_CREATE, bpf_cmd_BPF_LINK_CREATE, bpf_cmd_BPF_LINK_DETACH,
34 bpf_cmd_BPF_LINK_GET_FD_BY_ID, bpf_cmd_BPF_LINK_GET_NEXT_ID, bpf_cmd_BPF_LINK_UPDATE,
35 bpf_cmd_BPF_MAP_CREATE, bpf_cmd_BPF_MAP_DELETE_BATCH, bpf_cmd_BPF_MAP_DELETE_ELEM,
36 bpf_cmd_BPF_MAP_FREEZE, bpf_cmd_BPF_MAP_GET_FD_BY_ID, bpf_cmd_BPF_MAP_GET_NEXT_ID,
37 bpf_cmd_BPF_MAP_GET_NEXT_KEY, bpf_cmd_BPF_MAP_LOOKUP_AND_DELETE_BATCH,
38 bpf_cmd_BPF_MAP_LOOKUP_AND_DELETE_ELEM, bpf_cmd_BPF_MAP_LOOKUP_BATCH,
39 bpf_cmd_BPF_MAP_LOOKUP_ELEM, bpf_cmd_BPF_MAP_UPDATE_BATCH, bpf_cmd_BPF_MAP_UPDATE_ELEM,
40 bpf_cmd_BPF_OBJ_GET, bpf_cmd_BPF_OBJ_GET_INFO_BY_FD, bpf_cmd_BPF_OBJ_PIN,
41 bpf_cmd_BPF_PROG_ATTACH, bpf_cmd_BPF_PROG_BIND_MAP, bpf_cmd_BPF_PROG_DETACH,
42 bpf_cmd_BPF_PROG_GET_FD_BY_ID, bpf_cmd_BPF_PROG_GET_NEXT_ID, bpf_cmd_BPF_PROG_LOAD,
43 bpf_cmd_BPF_PROG_QUERY, bpf_cmd_BPF_PROG_RUN, bpf_cmd_BPF_RAW_TRACEPOINT_OPEN,
44 bpf_cmd_BPF_TASK_FD_QUERY, bpf_cmd_BPF_TOKEN_CREATE, bpf_map_info,
45 bpf_map_type_BPF_MAP_TYPE_DEVMAP, bpf_map_type_BPF_MAP_TYPE_DEVMAP_HASH,
46 bpf_map_type_BPF_MAP_TYPE_SK_STORAGE, bpf_prog_info, errno, error,
47};
48use zerocopy::{FromBytes, IntoBytes};
49
50fn read_attr<Attr: FromBytes>(
55 current_task: &CurrentTask,
56 attr_addr: UserAddress,
57 attr_size: u32,
58) -> Result<Attr, Errno> {
59 let mut attr_size = attr_size as usize;
60 let sizeof_attr = std::mem::size_of::<Attr>();
61
62 if attr_size > sizeof_attr {
64 let tail_addr = attr_addr.checked_add(sizeof_attr).ok_or_else(|| errno!(EFAULT))?;
65 let tail = current_task.read_memory_to_vec(tail_addr, attr_size - sizeof_attr)?;
66 if tail.into_iter().any(|byte| byte != 0) {
67 return error!(E2BIG);
68 }
69
70 attr_size = sizeof_attr;
71 }
72
73 current_task.read_object_partial(UserRef::new(attr_addr), attr_size)
76}
77
78fn reopen_bpf_fd(
79 locked: &mut Locked<Unlocked>,
80 current_task: &CurrentTask,
81 handle: BpfHandle,
82 open_flags: OpenFlags,
83) -> Result<SyscallResult, Errno> {
84 let name = handle.type_name();
87 let file = Anon::new_private_file(
88 locked,
89 current_task,
90 Box::new(handle),
91 open_flags | OpenFlags::CLOEXEC,
92 name,
93 );
94 Ok(current_task.add_file(locked, file, FdFlags::CLOEXEC)?.into())
95}
96
97fn install_bpf_fd(
98 locked: &mut Locked<Unlocked>,
99 current_task: &CurrentTask,
100 obj: impl Into<BpfHandle>,
101) -> Result<SyscallResult, Errno> {
102 let handle: BpfHandle = obj.into();
103 handle.security_check_open_fd(current_task, None)?;
104 let name = handle.type_name();
105
106 let file = Anon::new_private_file(
108 locked,
109 current_task,
110 Box::new(handle),
111 OpenFlags::RDWR | OpenFlags::CLOEXEC,
112 name,
113 );
114 Ok(current_task.add_file(locked, file, FdFlags::CLOEXEC)?.into())
115}
116
117#[derive(Debug, Clone)]
118pub struct BpfTypeFormat {
119 #[allow(dead_code)]
120 data: Vec<u8>,
121}
122
123fn read_map_key(
124 current_task: &CurrentTask,
125 addr: UserAddress,
126 map: &BpfMapHandle,
127) -> Result<MapKey, Errno> {
128 let key_size = map.schema.key_size as usize;
129 let mut key = current_task.read_objects_to_smallvec(UserRef::<u8>::new(addr), key_size)?;
130
131 if map.schema.map_type == bpf_map_type_BPF_MAP_TYPE_SK_STORAGE {
133 let fd = FdNumber::from_raw(
134 i32::read_from_bytes(&key[..]).expect("invalid key size in sk_storage map"),
135 );
136 let file = current_task.get_file(fd)?;
137 let socket = Socket::get_from_file(&file)?;
138 let socket = socket.downcast_socket::<ZxioBackedSocket>().ok_or_else(|| errno!(EINVAL))?;
139 let cookie = socket.get_socket_cookie()?;
140 key = MapKey::from_slice(cookie.as_bytes());
141 }
142
143 Ok(key)
144}
145
146fn validate_bpf_name(name: &[u8]) -> Result<&str, Errno> {
147 let name = std::ffi::CStr::from_bytes_until_nul(name)
148 .map_err(|_| errno!(EINVAL))?
149 .to_str()
150 .map_err(|_| errno!(EINVAL))?;
151 if !name.chars().all(|c| c.is_ascii_alphanumeric() || c == '_' || c == '.') {
154 return error!(EINVAL);
155 }
156 Ok(name)
157}
158
159pub fn sys_bpf(
160 locked: &mut Locked<Unlocked>,
161 current_task: &CurrentTask,
162 cmd: bpf_cmd,
163 attr_addr: UserAddress,
164 attr_size: u32,
165) -> Result<SyscallResult, Errno> {
166 match cmd {
174 bpf_cmd_BPF_MAP_CREATE => {
176 let map_attr: bpf_attr__bindgen_ty_1 = read_attr(current_task, attr_addr, attr_size)?;
177 log_trace!("BPF_MAP_CREATE {:?}", map_attr);
178 security::check_bpf_access(current_task, cmd, &map_attr, attr_size)?;
179
180 let map_type = map_attr.map_type;
181 let mut flags =
182 MapFlags::from_bits(map_attr.map_flags).ok_or_else(|| errno!(EINVAL))?;
183 if map_type == bpf_map_type_BPF_MAP_TYPE_DEVMAP
188 || map_type == bpf_map_type_BPF_MAP_TYPE_DEVMAP_HASH
189 {
190 flags |= MapFlags::ProgReadOnly;
191 }
192
193 let schema = MapSchema {
194 map_type,
195 key_size: map_attr.key_size,
196 value_size: map_attr.value_size,
197 max_entries: map_attr.max_entries,
198 flags,
199 };
200
201 let name = validate_bpf_name(map_attr.map_name.as_bytes())?;
202 let map = BpfMap::new(
203 locked,
204 current_task,
205 schema,
206 name,
207 security::bpf_map_alloc(current_task),
208 )?;
209 install_bpf_fd(locked, current_task, map)
210 }
211
212 bpf_cmd_BPF_MAP_LOOKUP_ELEM => {
213 let elem_attr: bpf_attr__bindgen_ty_2 = read_attr(current_task, attr_addr, attr_size)?;
214 log_trace!("BPF_MAP_LOOKUP_ELEM");
215 security::check_bpf_access(current_task, cmd, &elem_attr, attr_size)?;
216 let map_fd = FdNumber::from_raw(elem_attr.map_fd as i32);
217 let map = get_bpf_object(current_task, map_fd)?;
218 let map = map.as_map()?;
219
220 if map.schema.flags.contains(MapFlags::SyscallWriteOnly) {
221 return error!(EPERM);
222 }
223
224 let key = read_map_key(current_task, UserAddress::from(elem_attr.key), map)?;
225
226 let user_value = UserAddress::from(unsafe { elem_attr.__bindgen_anon_1.value });
229
230 let _suspend_lock =
231 current_task.kernel().suspend_resume_manager.acquire_ebpf_suspend_lock(locked);
232
233 let value = map.load(&key).ok_or_else(|| errno!(ENOENT))?;
234 current_task.write_memory(user_value, &value)?;
235
236 Ok(SUCCESS)
237 }
238
239 bpf_cmd_BPF_MAP_UPDATE_ELEM => {
241 let elem_attr: bpf_attr__bindgen_ty_2 = read_attr(current_task, attr_addr, attr_size)?;
242 log_trace!("BPF_MAP_UPDATE_ELEM");
243 security::check_bpf_access(current_task, cmd, &elem_attr, attr_size)?;
244 let map_fd = FdNumber::from_raw(elem_attr.map_fd as i32);
245 let map = get_bpf_object(current_task, map_fd)?;
246 let map = map.as_map()?;
247
248 let (frozen, locked) = map.frozen(locked);
250
251 if *frozen || map.schema.flags.contains(MapFlags::SyscallReadOnly) {
252 return error!(EPERM);
253 }
254
255 let flags = elem_attr.flags;
256 let key = read_map_key(current_task, UserAddress::from(elem_attr.key), map)?;
257
258 let user_value = UserAddress::from(unsafe { elem_attr.__bindgen_anon_1.value });
261 let mut value =
262 current_task.read_memory_to_vec(user_value, map.schema.value_size as usize)?;
263
264 let _suspend_lock =
265 current_task.kernel().suspend_resume_manager.acquire_ebpf_suspend_lock(locked);
266
267 map.update(&key[..], value.as_mut_bytes().into(), flags)
268 .map_err(map::map_error_to_errno)?;
269 Ok(SUCCESS)
270 }
271
272 bpf_cmd_BPF_MAP_DELETE_ELEM => {
273 let elem_attr: bpf_attr__bindgen_ty_2 = read_attr(current_task, attr_addr, attr_size)?;
274 log_trace!("BPF_MAP_DELETE_ELEM");
275 security::check_bpf_access(current_task, cmd, &elem_attr, attr_size)?;
276 let map_fd = FdNumber::from_raw(elem_attr.map_fd as i32);
277 let map = get_bpf_object(current_task, map_fd)?;
278 let map = map.as_map()?;
279
280 let (frozen, locked) = map.frozen(locked);
282
283 if *frozen || map.schema.flags.contains(MapFlags::SyscallReadOnly) {
284 return error!(EPERM);
285 }
286
287 let key = read_map_key(current_task, UserAddress::from(elem_attr.key), map)?;
288
289 let _suspend_lock =
290 current_task.kernel().suspend_resume_manager.acquire_ebpf_suspend_lock(locked);
291
292 map.delete(&key).map_err(map::map_error_to_errno)?;
293 Ok(SUCCESS)
294 }
295
296 bpf_cmd_BPF_MAP_GET_NEXT_KEY => {
299 let elem_attr: bpf_attr__bindgen_ty_2 = read_attr(current_task, attr_addr, attr_size)?;
300 log_trace!("BPF_MAP_GET_NEXT_KEY");
301 security::check_bpf_access(current_task, cmd, &elem_attr, attr_size)?;
302 let map_fd = FdNumber::from_raw(elem_attr.map_fd as i32);
303 let map = get_bpf_object(current_task, map_fd)?;
304 let map = map.as_map()?;
305
306 if map.schema.flags.contains(MapFlags::SyscallWriteOnly) {
307 return error!(EPERM);
308 }
309
310 let key = if elem_attr.key != 0 {
311 Some(read_map_key(current_task, UserAddress::from(elem_attr.key), map)?)
312 } else {
313 None
314 };
315
316 let next_key =
317 map.get_next_key(key.as_ref().map(|k| &k[..])).map_err(map::map_error_to_errno)?;
318
319 let user_next_key = UserAddress::from(unsafe { elem_attr.__bindgen_anon_1.next_key });
322 current_task.write_memory(user_next_key, &next_key)?;
323
324 Ok(SUCCESS)
325 }
326
327 bpf_cmd_BPF_PROG_LOAD => {
330 let prog_attr: bpf_attr__bindgen_ty_4 = read_attr(current_task, attr_addr, attr_size)?;
331 log_trace!("BPF_PROG_LOAD");
332 security::check_bpf_access(current_task, cmd, &prog_attr, attr_size)?;
333
334 let user_code = UserRef::<EbpfInstruction>::new(UserAddress::from(prog_attr.insns));
335 let code = current_task.read_objects_to_vec(user_code, prog_attr.insn_cnt as usize)?;
336
337 let mut log_buffer = if prog_attr.log_buf != 0 && prog_attr.log_size > 1 {
338 UserBuffersOutputBuffer::unified_new(
339 current_task,
340 smallvec![UserBuffer {
341 address: prog_attr.log_buf.into(),
342 length: (prog_attr.log_size - 1) as usize
343 }],
344 )?
345 } else {
346 UserBuffersOutputBuffer::unified_new(current_task, smallvec![])?
347 };
348 let name = validate_bpf_name(prog_attr.prog_name.as_bytes())?;
349 let info = ProgramInfo::try_from(&prog_attr)?;
350 let program_type = info.program_type;
351 let program = Program::new(locked, current_task, info, &mut log_buffer, code);
352 let program_or_stub = match (program, program_type) {
353 (Ok(program), _) => BpfHandle::Program(program),
354
355 (Err(e), ProgramType::SockOps | ProgramType::SchedCls | ProgramType::Kprobe)
358 if !current_task.kernel().features.bpf_v2 =>
359 {
360 log_warn!(
361 "Creating a stub for eBPF program {name}, type={program_type:?}: {e:?}"
362 );
363 BpfHandle::ProgramStub(prog_attr.prog_type)
364 }
365
366 (Err(e), _) => {
367 log_error!("Unable to load eBPF program {name}, type={program_type:?}: {e:?}");
368 return Err(e.into());
369 }
370 };
371 log_buffer.write(b"\0")?;
373 install_bpf_fd(locked, current_task, program_or_stub)
374 }
375
376 bpf_cmd_BPF_PROG_ATTACH => {
378 let attach_attr: BpfAttachAttr = read_attr(current_task, attr_addr, attr_size)?;
379 security::check_bpf_access(current_task, cmd, &attach_attr, attr_size)?;
380 bpf_prog_attach(locked, current_task, attach_attr)
381 }
382
383 bpf_cmd_BPF_PROG_QUERY => {
385 let mut prog_attr: bpf_attr__bindgen_ty_10 =
386 read_attr(current_task, attr_addr, attr_size)?;
387 log_trace!("BPF_PROG_QUERY");
388 security::check_bpf_access(current_task, cmd, &prog_attr, attr_size)?;
389 track_stub!(TODO("https://fxbug.dev/322873416"), "Bpf::BPF_PROG_QUERY");
390 current_task.write_memory(UserAddress::from(prog_attr.prog_ids), 1.as_bytes())?;
391 prog_attr.__bindgen_anon_2.prog_cnt = std::mem::size_of::<u64>() as u32;
392 current_task.write_memory(attr_addr, prog_attr.as_bytes())?;
393 Ok(SUCCESS)
394 }
395
396 bpf_cmd_BPF_OBJ_PIN => {
399 let pin_attr: bpf_attr__bindgen_ty_5 = read_attr(current_task, attr_addr, attr_size)?;
400 log_trace!("BPF_OBJ_PIN {:?}", pin_attr);
401 security::check_bpf_access(current_task, cmd, &pin_attr, attr_size)?;
402 let bpf_fd = FdNumber::from_raw(pin_attr.bpf_fd as i32);
403 let object = get_bpf_object(current_task, bpf_fd)?;
404 let path_addr = UserCString::new(current_task, UserAddress::from(pin_attr.pathname));
405 let pathname = current_task.read_path(path_addr)?;
406 let (parent, basename) = current_task.lookup_parent_at(
407 locked,
408 &mut LookupContext::default(),
409 FdNumber::AT_FDCWD,
410 pathname.as_ref(),
411 )?;
412 let bpf_dir =
413 parent.entry.node.downcast_ops::<BpfFsDir>().ok_or_else(|| errno!(EINVAL))?;
414 bpf_dir.register_pin(locked, current_task, &parent, basename, object)?;
415 Ok(SUCCESS)
416 }
417
418 bpf_cmd_BPF_OBJ_GET => {
420 let path_attr: bpf_attr__bindgen_ty_5 = read_attr(current_task, attr_addr, attr_size)?;
421 log_trace!("BPF_OBJ_GET {:?}", path_attr);
422 security::check_bpf_access(current_task, cmd, &path_attr, attr_size)?;
423 let path_addr = UserCString::new(current_task, UserAddress::from(path_attr.pathname));
424 let open_flags = match path_attr.file_flags {
425 BPF_F_RDONLY => OpenFlags::RDONLY,
426 BPF_F_WRONLY => OpenFlags::WRONLY,
427 0 => OpenFlags::RDWR,
428 _ => return error!(EINVAL),
429 };
430 let pathname = current_task.read_path(path_addr)?;
431 let handle =
432 resolve_pinned_bpf_object(locked, current_task, pathname.as_ref(), open_flags)?;
433 reopen_bpf_fd(locked, current_task, handle, open_flags)
434 }
435
436 bpf_cmd_BPF_OBJ_GET_INFO_BY_FD => {
438 let mut get_info_attr: bpf_attr__bindgen_ty_9 =
439 read_attr(current_task, attr_addr, attr_size)?;
440 log_trace!("BPF_OBJ_GET_INFO_BY_FD {:?}", get_info_attr);
441 security::check_bpf_access(current_task, cmd, &get_info_attr, attr_size)?;
442 let bpf_fd = FdNumber::from_raw(get_info_attr.bpf_fd as i32);
443 let object = get_bpf_object(current_task, bpf_fd)?;
444
445 let mut info = match object {
446 BpfHandle::Map(map) => bpf_map_info {
447 type_: map.schema.map_type,
448 id: map.id(),
449 key_size: map.schema.key_size,
450 value_size: map.schema.value_size,
451 max_entries: map.schema.max_entries,
452 map_flags: map.schema.flags.bits(),
453 ..Default::default()
454 }
455 .as_bytes()
456 .to_owned(),
457 BpfHandle::Program(prog) => {
458 #[allow(unknown_lints, clippy::unnecessary_struct_initialization)]
459 bpf_prog_info {
460 type_: prog.info.program_type.into(),
461 id: prog.id(),
462 jited_prog_len: 1,
464 ..Default::default()
465 }
466 .as_bytes()
467 .to_owned()
468 }
469 BpfHandle::ProgramStub(type_) => {
470 #[allow(unknown_lints, clippy::unnecessary_struct_initialization)]
471 bpf_prog_info {
472 type_,
473 jited_prog_len: 1,
475 ..Default::default()
476 }
477 .as_bytes()
478 .to_owned()
479 }
480 _ => {
481 return error!(EINVAL);
482 }
483 };
484
485 info.truncate(get_info_attr.info_len as usize);
490 get_info_attr.info_len = info.len() as u32;
491 current_task.write_memory(UserAddress::from(get_info_attr.info), &info)?;
492 current_task.write_memory(attr_addr, get_info_attr.as_bytes())?;
493 Ok(SUCCESS)
494 }
495
496 bpf_cmd_BPF_BTF_LOAD => {
500 let btf_attr: bpf_attr__bindgen_ty_12 = read_attr(current_task, attr_addr, attr_size)?;
501 log_trace!("BPF_BTF_LOAD {:?}", btf_attr);
502 security::check_bpf_access(current_task, cmd, &btf_attr, attr_size)?;
503 let data = current_task
504 .read_memory_to_vec(UserAddress::from(btf_attr.btf), btf_attr.btf_size as usize)?;
505 install_bpf_fd(locked, current_task, BpfTypeFormat { data })
506 }
507 bpf_cmd_BPF_PROG_DETACH => {
508 let attach_attr: BpfAttachAttr = read_attr(current_task, attr_addr, attr_size)?;
509 security::check_bpf_access(current_task, cmd, &attach_attr, attr_size)?;
510 bpf_prog_detach(locked, current_task, attach_attr)
511 }
512 bpf_cmd_BPF_PROG_RUN => {
513 track_stub!(TODO("https://fxbug.dev/322874055"), "BPF_PROG_RUN");
514 error!(EINVAL)
515 }
516 bpf_cmd_BPF_PROG_GET_NEXT_ID => {
517 security::check_task_capable(current_task, CAP_SYS_ADMIN)?;
518 let mut get_next_attr: bpf_attr__bindgen_ty_8 =
519 read_attr(current_task, attr_addr, attr_size)?;
520 let start_id = unsafe { get_next_attr.__bindgen_anon_1.start_id };
522 get_next_attr.next_id = current_task
523 .kernel()
524 .ebpf_state
525 .get_next_program_id(locked, start_id)
526 .ok_or_else(|| errno!(ENOENT))?;
527 current_task.write_object(UserRef::new(attr_addr), &get_next_attr)?;
528 Ok(SUCCESS)
529 }
530 bpf_cmd_BPF_MAP_GET_NEXT_ID => {
531 security::check_task_capable(current_task, CAP_SYS_ADMIN)?;
532 let mut get_next_attr: bpf_attr__bindgen_ty_8 =
533 read_attr(current_task, attr_addr, attr_size)?;
534 let start_id = unsafe { get_next_attr.__bindgen_anon_1.start_id };
536 get_next_attr.next_id = current_task
537 .kernel()
538 .ebpf_state
539 .get_next_map_id(locked, start_id)
540 .ok_or_else(|| errno!(ENOENT))?;
541 current_task.write_object(UserRef::new(attr_addr), &get_next_attr)?;
542 Ok(SUCCESS)
543 }
544 bpf_cmd_BPF_PROG_GET_FD_BY_ID => {
545 security::check_task_capable(current_task, CAP_SYS_ADMIN)?;
546 let get_by_id_attr: bpf_attr__bindgen_ty_8 =
547 read_attr(current_task, attr_addr, attr_size)?;
548 let prog_id = unsafe { get_by_id_attr.__bindgen_anon_1.prog_id };
550 let prog = current_task
551 .kernel()
552 .ebpf_state
553 .get_program_by_id(locked, prog_id)
554 .ok_or_else(|| errno!(ENOENT))?;
555 install_bpf_fd(locked, current_task, prog)
556 }
557 bpf_cmd_BPF_MAP_GET_FD_BY_ID => {
558 security::check_task_capable(current_task, CAP_SYS_ADMIN)?;
559 let get_by_id_attr: bpf_attr__bindgen_ty_8 =
560 read_attr(current_task, attr_addr, attr_size)?;
561 let map_id = unsafe { get_by_id_attr.__bindgen_anon_1.map_id };
563 let map = current_task
564 .kernel()
565 .ebpf_state
566 .get_map_by_id(locked, map_id)
567 .ok_or_else(|| errno!(ENOENT))?;
568 install_bpf_fd(locked, current_task, map)
569 }
570 bpf_cmd_BPF_RAW_TRACEPOINT_OPEN => {
571 track_stub!(TODO("https://fxbug.dev/322874055"), "BPF_RAW_TRACEPOINT_OPEN");
572 error!(EINVAL)
573 }
574 bpf_cmd_BPF_BTF_GET_FD_BY_ID => {
575 track_stub!(TODO("https://fxbug.dev/322874055"), "BPF_BTF_GET_FD_BY_ID");
576 error!(EINVAL)
577 }
578 bpf_cmd_BPF_TASK_FD_QUERY => {
579 track_stub!(TODO("https://fxbug.dev/322874055"), "BPF_TASK_FD_QUERY");
580 error!(EINVAL)
581 }
582 bpf_cmd_BPF_MAP_LOOKUP_AND_DELETE_ELEM => {
583 track_stub!(TODO("https://fxbug.dev/322874055"), "BPF_MAP_LOOKUP_AND_DELETE_ELEM");
584 error!(EINVAL)
585 }
586 bpf_cmd_BPF_MAP_FREEZE => {
587 let elem_attr: bpf_attr__bindgen_ty_2 = read_attr(current_task, attr_addr, attr_size)?;
588 log_trace!("BPF_MAP_FREEZE");
589 let map_fd = FdNumber::from_raw(elem_attr.map_fd as i32);
590 let map = get_bpf_object(current_task, map_fd)?;
591 let map = map.as_map()?;
592 map.freeze(locked)?;
593 Ok(SUCCESS)
594 }
595 bpf_cmd_BPF_BTF_GET_NEXT_ID => {
596 track_stub!(TODO("https://fxbug.dev/322874055"), "BPF_BTF_GET_NEXT_ID");
597 error!(EINVAL)
598 }
599 bpf_cmd_BPF_MAP_LOOKUP_BATCH => {
600 track_stub!(TODO("https://fxbug.dev/322874055"), "BPF_MAP_LOOKUP_BATCH");
601 error!(EINVAL)
602 }
603 bpf_cmd_BPF_MAP_LOOKUP_AND_DELETE_BATCH => {
604 track_stub!(TODO("https://fxbug.dev/322874055"), "BPF_MAP_LOOKUP_AND_DELETE_BATCH");
605 error!(EINVAL)
606 }
607 bpf_cmd_BPF_MAP_UPDATE_BATCH => {
608 track_stub!(TODO("https://fxbug.dev/322874055"), "BPF_MAP_UPDATE_BATCH");
609 error!(EINVAL)
610 }
611 bpf_cmd_BPF_MAP_DELETE_BATCH => {
612 track_stub!(TODO("https://fxbug.dev/322874055"), "BPF_MAP_DELETE_BATCH");
613 error!(EINVAL)
614 }
615 bpf_cmd_BPF_LINK_CREATE => {
616 track_stub!(TODO("https://fxbug.dev/322874055"), "BPF_LINK_CREATE");
617 error!(EINVAL)
618 }
619 bpf_cmd_BPF_LINK_UPDATE => {
620 track_stub!(TODO("https://fxbug.dev/322874055"), "BPF_LINK_UPDATE");
621 error!(EINVAL)
622 }
623 bpf_cmd_BPF_LINK_GET_FD_BY_ID => {
624 track_stub!(TODO("https://fxbug.dev/322874055"), "BPF_LINK_GET_FD_BY_ID");
625 error!(EINVAL)
626 }
627 bpf_cmd_BPF_LINK_GET_NEXT_ID => {
628 track_stub!(TODO("https://fxbug.dev/322874055"), "BPF_LINK_GET_NEXT_ID");
629 error!(EINVAL)
630 }
631 bpf_cmd_BPF_ENABLE_STATS => {
632 track_stub!(TODO("https://fxbug.dev/322874055"), "BPF_ENABLE_STATS");
633 error!(EINVAL)
634 }
635 bpf_cmd_BPF_ITER_CREATE => {
636 track_stub!(TODO("https://fxbug.dev/322874055"), "BPF_ITER_CREATE");
637 error!(EINVAL)
638 }
639 bpf_cmd_BPF_LINK_DETACH => {
640 track_stub!(TODO("https://fxbug.dev/322874055"), "BPF_LINK_DETACH");
641 error!(EINVAL)
642 }
643 bpf_cmd_BPF_PROG_BIND_MAP => {
644 track_stub!(TODO("https://fxbug.dev/322874055"), "BPF_PROG_BIND_MAP");
645 error!(EINVAL)
646 }
647 bpf_cmd_BPF_TOKEN_CREATE => {
648 track_stub!(TODO("https://fxbug.dev/322874055"), "BPF_TOKEN_CREATE");
649 error!(EINVAL)
650 }
651 _ => {
652 track_stub!(TODO("https://fxbug.dev/322874055"), "bpf", cmd);
653 error!(EINVAL)
654 }
655 }
656}
657
658#[cfg(target_arch = "aarch64")]
660mod arch32 {
661 pub use super::sys_bpf as sys_arch32_bpf;
662}
663
664#[cfg(target_arch = "aarch64")]
665pub use arch32::*;