Fix some leaked file descriptors in programs

Also added some todos for the switch to OwnedFd

Signed-off-by: Ayrton Sparling <ayrton@sparling.us>
pull/474/head
Ayrton Sparling 3 years ago
parent 9f5d157628
commit 04f269b13c
No known key found for this signature in database
GPG Key ID: 36C6BC444BECABA3

@ -407,6 +407,7 @@ impl Drop for Program {
pub(crate) struct ProgramData<T: Link> { pub(crate) struct ProgramData<T: Link> {
pub(crate) name: Option<String>, pub(crate) name: Option<String>,
pub(crate) obj: obj::Program, pub(crate) obj: obj::Program,
// TODO: replace with OwnedFd, then we don't need to manually impl Drop for ProgramData
pub(crate) fd: Option<RawFd>, pub(crate) fd: Option<RawFd>,
pub(crate) links: LinkMap<T>, pub(crate) links: LinkMap<T>,
pub(crate) expected_attach_type: Option<bpf_attach_type>, pub(crate) expected_attach_type: Option<bpf_attach_type>,
@ -449,6 +450,12 @@ impl<T: Link> ProgramData<T> {
} }
} }
impl<T: Link> Drop for ProgramData<T> {
fn drop(&mut self) {
self.fd.map(|fd| unsafe { libc::close(fd) });
}
}
fn unload_program<T: Link>(data: &mut ProgramData<T>) -> Result<(), ProgramError> { fn unload_program<T: Link>(data: &mut ProgramData<T>) -> Result<(), ProgramError> {
data.links.remove_all()?; data.links.remove_all()?;
let fd = data.fd.take().ok_or(ProgramError::NotLoaded)?; let fd = data.fd.take().ok_or(ProgramError::NotLoaded)?;
@ -830,6 +837,7 @@ impl ProgramInfo {
} }
/// Loads a program from a pinned path in bpffs. /// Loads a program from a pinned path in bpffs.
// TODO: Switch RawFd to OwnedFd
pub fn from_pin<P: AsRef<Path>>(path: P) -> Result<ProgramInfo, ProgramError> { pub fn from_pin<P: AsRef<Path>>(path: P) -> Result<ProgramInfo, ProgramError> {
let path_string = CString::new(path.as_ref().to_str().unwrap()).unwrap(); let path_string = CString::new(path.as_ref().to_str().unwrap()).unwrap();
let fd = let fd =
@ -838,14 +846,23 @@ impl ProgramInfo {
io_error, io_error,
})? as RawFd; })? as RawFd;
let info = bpf_prog_get_info_by_fd(fd).map_err(|io_error| ProgramError::SyscallError { let info = Self::from_fd(&fd);
call: "bpf_prog_get_info_by_fd".to_owned(),
io_error, // Ensure RawFd is closed independent of the result of Self::from_fd
})?;
unsafe { unsafe {
libc::close(fd); libc::close(fd);
} }
info
}
/// Create ProgramInfo from the file descriptor of a program.
pub fn from_fd(fd: &RawFd) -> Result<ProgramInfo, ProgramError> {
let info = bpf_prog_get_info_by_fd(*fd).map_err(|io_error| ProgramError::SyscallError {
call: "bpf_prog_get_info_by_fd".to_owned(),
io_error,
})?;
Ok(ProgramInfo(info)) Ok(ProgramInfo(info))
} }
} }

@ -425,6 +425,7 @@ pub(crate) fn bpf_prog_query(
ret ret
} }
// TODO: Replace RawFd with OwnedFd
pub(crate) fn bpf_prog_get_fd_by_id(prog_id: u32) -> Result<RawFd, io::Error> { pub(crate) fn bpf_prog_get_fd_by_id(prog_id: u32) -> Result<RawFd, io::Error> {
let mut attr = unsafe { mem::zeroed::<bpf_attr>() }; let mut attr = unsafe { mem::zeroed::<bpf_attr>() };

Loading…
Cancel
Save