From abde6e10a36c4574327b8eb5b5777a8ce7761fc9 Mon Sep 17 00:00:00 2001
From: Andrew Stoycos <astoycos@redhat.com>
Date: Mon, 3 Jul 2023 15:17:27 -0400
Subject: [PATCH] add map_ids field to bpf_prog_get_info_by_fd

Add an optional field (map_ids) to the syscall, this allows a pointer to
a buffer to be filled with the map_ids in use by the program.

Signed-off-by: Andrew Stoycos <astoycos@redhat.com>
---
 aya/src/programs/extension.rs  |  7 ++++---
 aya/src/programs/lirc_mode2.rs |  2 +-
 aya/src/programs/mod.rs        | 20 +++++++++++---------
 aya/src/sys/bpf.rs             | 12 ++++++++----
 4 files changed, 24 insertions(+), 17 deletions(-)

diff --git a/aya/src/programs/extension.rs b/aya/src/programs/extension.rs
index 682d14ad..21043888 100644
--- a/aya/src/programs/extension.rs
+++ b/aya/src/programs/extension.rs
@@ -151,11 +151,12 @@ impl Extension {
 /// with the name `func_name` within that BTF object.
 fn get_btf_info(prog_fd: i32, func_name: &str) -> Result<(RawFd, u32), ProgramError> {
     // retrieve program information
-    let info =
-        sys::bpf_prog_get_info_by_fd(prog_fd).map_err(|io_error| ProgramError::SyscallError {
+    let info = sys::bpf_prog_get_info_by_fd(prog_fd, &[]).map_err(|io_error| {
+        ProgramError::SyscallError {
             call: "bpf_prog_get_info_by_fd",
             io_error,
-        })?;
+        }
+    })?;
 
     // btf_id refers to the ID of the program btf that was loaded with bpf(BPF_BTF_LOAD)
     if info.btf_id == 0 {
diff --git a/aya/src/programs/lirc_mode2.rs b/aya/src/programs/lirc_mode2.rs
index ce40eaaa..bc435ce2 100644
--- a/aya/src/programs/lirc_mode2.rs
+++ b/aya/src/programs/lirc_mode2.rs
@@ -132,7 +132,7 @@ impl LircLink {
 
     /// Get ProgramInfo from this link
     pub fn info(&self) -> Result<ProgramInfo, ProgramError> {
-        match bpf_prog_get_info_by_fd(self.prog_fd) {
+        match bpf_prog_get_info_by_fd(self.prog_fd, &[]) {
             Ok(info) => Ok(ProgramInfo(info)),
             Err(io_error) => Err(ProgramError::SyscallError {
                 call: "bpf_prog_get_info_by_fd",
diff --git a/aya/src/programs/mod.rs b/aya/src/programs/mod.rs
index 1ea52b7c..5e4d1f4a 100644
--- a/aya/src/programs/mod.rs
+++ b/aya/src/programs/mod.rs
@@ -495,10 +495,11 @@ impl<T: Link> ProgramData<T> {
                 io_error,
             })? as RawFd;
 
-        let info = bpf_prog_get_info_by_fd(fd).map_err(|io_error| ProgramError::SyscallError {
-            call: "bpf_prog_get_info_by_fd",
-            io_error,
-        })?;
+        let info =
+            bpf_prog_get_info_by_fd(fd, &[]).map_err(|io_error| ProgramError::SyscallError {
+                call: "bpf_prog_get_info_by_fd",
+                io_error,
+            })?;
 
         let name = ProgramInfo(info).name_as_str().map(|s| s.to_string());
         ProgramData::from_bpf_prog_info(name, fd, path.as_ref(), info, verifier_log_level)
@@ -968,10 +969,11 @@ impl ProgramInfo {
                 io_error,
             })? as RawFd;
 
-        let info = bpf_prog_get_info_by_fd(fd).map_err(|io_error| ProgramError::SyscallError {
-            call: "bpf_prog_get_info_by_fd",
-            io_error,
-        })?;
+        let info =
+            bpf_prog_get_info_by_fd(fd, &[]).map_err(|io_error| ProgramError::SyscallError {
+                call: "bpf_prog_get_info_by_fd",
+                io_error,
+            })?;
         unsafe {
             libc::close(fd);
         }
@@ -1004,7 +1006,7 @@ impl Iterator for ProgramsIter {
                             io_error,
                         })
                         .and_then(|fd| {
-                            bpf_prog_get_info_by_fd(fd.as_raw_fd())
+                            bpf_prog_get_info_by_fd(fd.as_raw_fd(), &[])
                                 .map_err(|io_error| ProgramError::SyscallError {
                                     call: "bpf_prog_get_info_by_fd",
                                     io_error,
diff --git a/aya/src/sys/bpf.rs b/aya/src/sys/bpf.rs
index 9f7e11c6..565c21f1 100644
--- a/aya/src/sys/bpf.rs
+++ b/aya/src/sys/bpf.rs
@@ -468,17 +468,21 @@ pub(crate) fn bpf_prog_get_fd_by_id(prog_id: u32) -> Result<OwnedFd, io::Error>
     unsafe { fd_sys_bpf(bpf_cmd::BPF_PROG_GET_FD_BY_ID, &attr).map_err(|(_, e)| e) }
 }
 
-pub(crate) fn bpf_prog_get_info_by_fd(prog_fd: RawFd) -> Result<bpf_prog_info, io::Error> {
+pub(crate) fn bpf_prog_get_info_by_fd(
+    prog_fd: RawFd,
+    map_ids: &[u32],
+) -> Result<bpf_prog_info, io::Error> {
     let mut attr = unsafe { mem::zeroed::<bpf_attr>() };
-    // info gets entirely populated by the kernel
-    let info = MaybeUninit::zeroed();
+    let mut info = unsafe { mem::zeroed::<bpf_prog_info>() };
+    info.map_ids = map_ids.as_ptr() as u64;
+    info.nr_map_ids = map_ids.len() as u32;
 
     attr.info.bpf_fd = prog_fd as u32;
     attr.info.info = &info as *const _ as u64;
     attr.info.info_len = mem::size_of::<bpf_prog_info>() as u32;
 
     match sys_bpf(bpf_cmd::BPF_OBJ_GET_INFO_BY_FD, &attr) {
-        Ok(_) => Ok(unsafe { info.assume_init() }),
+        Ok(_) => Ok(info),
         Err((_, err)) => Err(err),
     }
 }