fix(net): Check if interface is valid first. (#2497)

Fixes #2496
This commit is contained in:
Patrick Ziegler 2021-09-09 21:47:23 +02:00 committed by GitHub
parent 9f828800fb
commit 5011e66346
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 20 additions and 9 deletions

View File

@ -37,6 +37,7 @@ class file_descriptor;
namespace net { namespace net {
DEFINE_ERROR(network_error); DEFINE_ERROR(network_error);
bool is_interface_valid(const string& ifname);
bool is_wireless_interface(const string& ifname); bool is_wireless_interface(const string& ifname);
std::string find_wireless_interface(); std::string find_wireless_interface();
std::string find_wired_interface(); std::string find_wired_interface();

View File

@ -12,8 +12,7 @@
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/types.h> #include <sys/types.h>
#include <iomanip> #include <cassert>
#include <iomanip> #include <iomanip>
#include "common.hpp" #include "common.hpp"
@ -37,6 +36,11 @@ namespace net {
static bool is_virtual(const std::string& ifname) { static bool is_virtual(const std::string& ifname) {
char* target = realpath((NET_PATH + ifname).c_str(), nullptr); char* target = realpath((NET_PATH + ifname).c_str(), nullptr);
if (!target) {
throw system_error("realpath");
}
const std::string real_path{target}; const std::string real_path{target};
free(target); free(target);
return real_path.rfind(VIRTUAL_PATH, 0) == 0; return real_path.rfind(VIRTUAL_PATH, 0) == 0;
@ -54,6 +58,10 @@ namespace net {
return NetType::ETHERNET; return NetType::ETHERNET;
} }
bool is_interface_valid(const string& ifname) {
return if_nametoindex(ifname.c_str()) != 0;
}
/** /**
* Test if interface with given name is a wireless device * Test if interface with given name is a wireless device
*/ */
@ -91,9 +99,7 @@ namespace net {
* Construct network interface * Construct network interface
*/ */
network::network(string interface) : m_log(logger::make()), m_interface(move(interface)) { network::network(string interface) : m_log(logger::make()), m_interface(move(interface)) {
if (if_nametoindex(m_interface.c_str()) == 0) { assert(is_virtual(interface));
throw network_error("Invalid network interface \"" + m_interface + "\"");
}
m_socketfd = file_util::make_file_descriptor(socket(AF_INET, SOCK_DGRAM, 0)); m_socketfd = file_util::make_file_descriptor(socket(AF_INET, SOCK_DGRAM, 0));
if (!*m_socketfd) { if (!*m_socketfd) {
@ -294,8 +300,8 @@ namespace net {
units.pop_back(); units.pop_back();
} }
return sstream() << std::setw(minwidth) << std::setfill(' ') << std::setprecision(precision) << std::fixed << speedrate return sstream() << std::setw(minwidth) << std::setfill(' ') << std::setprecision(precision) << std::fixed
<< " " << suffix << unit; << speedrate << " " << suffix << unit;
} }
// }}} // }}}

View File

@ -38,7 +38,11 @@ namespace modules {
} }
if (m_interface.empty()) { if (m_interface.empty()) {
throw module_error("missing 'interface' or 'interface-type'"); throw module_error("Missing 'interface' or 'interface-type'");
}
if (!net::is_interface_valid(m_interface)) {
throw module_error("Invalid network interface \"" + m_interface + "\"");
} }
m_ping_nth_update = m_conf.get(name(), "ping-interval", m_ping_nth_update); m_ping_nth_update = m_conf.get(name(), "ping-interval", m_ping_nth_update);