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