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