network helpers: fix fd leak in get_network_interfaces

This one always leaked.

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
Wolfgang Bumiller 2020-11-30 11:10:32 +01:00
parent 935ee97b17
commit 99e98f605c
1 changed files with 22 additions and 4 deletions

View File

@ -1,14 +1,16 @@
use std::path::Path; use std::path::Path;
use std::process::Command; use std::process::Command;
use std::collections::HashMap; use std::collections::HashMap;
use std::os::unix::io::{AsRawFd, FromRawFd};
use anyhow::{Error, bail, format_err}; use anyhow::{Error, bail, format_err};
use lazy_static::lazy_static; use lazy_static::lazy_static;
use nix::sys::socket::{socket, AddressFamily, SockType, SockFlag};
use nix::ioctl_read_bad; use nix::ioctl_read_bad;
use nix::sys::socket::{socket, AddressFamily, SockType, SockFlag};
use regex::Regex; use regex::Regex;
use proxmox::*; // for IP macros use proxmox::*; // for IP macros
use proxmox::tools::fd::Fd;
pub static IPV4_REVERSE_MASK: &[&str] = &[ pub static IPV4_REVERSE_MASK: &[&str] = &[
"0.0.0.0", "0.0.0.0",
@ -133,8 +135,24 @@ pub fn get_network_interfaces() -> Result<HashMap<String, bool>, Error> {
let lines = raw.lines(); let lines = raw.lines();
let sock = socket(AddressFamily::Inet, SockType::Datagram, SockFlag::empty(), None) let sock = unsafe {
.or_else(|_| socket(AddressFamily::Inet6, SockType::Datagram, SockFlag::empty(), None))?; Fd::from_raw_fd(
socket(
AddressFamily::Inet,
SockType::Datagram,
SockFlag::empty(),
None,
)
.or_else(|_| {
socket(
AddressFamily::Inet6,
SockType::Datagram,
SockFlag::empty(),
None,
)
})?,
)
};
let mut interface_list = HashMap::new(); let mut interface_list = HashMap::new();
@ -146,7 +164,7 @@ pub fn get_network_interfaces() -> Result<HashMap<String, bool>, Error> {
for (i, b) in std::ffi::CString::new(ifname)?.as_bytes_with_nul().iter().enumerate() { for (i, b) in std::ffi::CString::new(ifname)?.as_bytes_with_nul().iter().enumerate() {
if i < (libc::IFNAMSIZ-1) { req.ifr_name[i] = *b as libc::c_uchar; } if i < (libc::IFNAMSIZ-1) { req.ifr_name[i] = *b as libc::c_uchar; }
} }
let res = unsafe { get_interface_flags(sock, &mut req)? }; let res = unsafe { get_interface_flags(sock.as_raw_fd(), &mut req)? };
if res != 0 { if res != 0 {
bail!("ioctl get_interface_flags for '{}' failed ({})", ifname, res); bail!("ioctl get_interface_flags for '{}' failed ({})", ifname, res);
} }