Skip to content

Commit

Permalink
util: Fix mac truncation (openbmc#58)
Browse files Browse the repository at this point in the history
We don't want to allow MACs to be silently truncated.

Change-Id: I1d2771c481bccb30e957b829fd1db1e4db0dc051

Signed-off-by: William A. Kennington III <[email protected]>
Co-authored-by: William A. Kennington III <[email protected]>
  • Loading branch information
2 people authored and rfrandse committed Feb 21, 2023
1 parent 2067354 commit 363a2ad
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 10 deletions.
39 changes: 34 additions & 5 deletions src/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include <algorithm>
#include <cctype>
#include <charconv>
#include <cstdlib>
#include <cstring>
#include <filesystem>
Expand All @@ -23,6 +24,7 @@
#include <stdexcept>
#include <stdplus/raw.hpp>
#include <string>
#include <string_view>
#include <variant>
#include <xyz/openbmc_project/Common/error.hpp>

Expand Down Expand Up @@ -633,14 +635,41 @@ ether_addr getfromInventory(sdbusplus::bus::bus& bus,
return fromString(std::get<std::string>(value));
}

ether_addr fromString(const char* str)
uint8_t decodeHex(std::string_view str)
{
struct ether_addr* mac = ether_aton(str);
if (mac == nullptr)
uint8_t ret;
auto res = std::from_chars(str.begin(), str.end(), ret, 16);
if (res.ptr != str.end() || res.ec != std::errc())
{
throw std::invalid_argument("Invalid MAC Address");
throw std::invalid_argument("Not hex");
}
return *mac;
return ret;
}
ether_addr fromString(std::string_view str)
{
ether_addr ret;
if (str.size() == 12 && str.find(":") == str.npos)
{
for (size_t i = 0; i < 6; ++i)
{
ret.ether_addr_octet[i] = decodeHex(str.substr(i * 2, 2));
}
}
else
{
for (size_t i = 0; i < 5; ++i)
{
auto loc = str.find(":");
ret.ether_addr_octet[i] = decodeHex(str.substr(0, loc));
str.remove_prefix(loc == str.npos ? str.size() : loc + 1);
if (str.empty())
{
throw std::invalid_argument("Missing mac data");
}
}
ret.ether_addr_octet[5] = decodeHex(str);
}
return ret;
}

std::string toString(const ether_addr& mac)
Expand Down
6 changes: 1 addition & 5 deletions src/util.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,7 @@ ether_addr getfromInventory(sdbusplus::bus::bus& bus,
* @returns A mac address in network byte order
* @throws std::runtime_error for bad mac
*/
ether_addr fromString(const char* str);
inline ether_addr fromString(const std::string& str)
{
return fromString(str.c_str());
}
ether_addr fromString(std::string_view str);

/** @brief Converts the given mac address bytes into a string
* @param[in] mac - The mac address
Expand Down
7 changes: 7 additions & 0 deletions test/test_util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,13 @@ TEST(MacFromString, Bad)
{
EXPECT_THROW(fromString("0x:00:00:00:00:00"), std::invalid_argument);
EXPECT_THROW(fromString("00:00:00:00:00"), std::invalid_argument);
EXPECT_THROW(fromString("00:00:00:00:00:"), std::invalid_argument);
EXPECT_THROW(fromString("00:00:00:00::00"), std::invalid_argument);
EXPECT_THROW(fromString(":00:00:00:00:00"), std::invalid_argument);
EXPECT_THROW(fromString("00::00:00:00:00"), std::invalid_argument);
EXPECT_THROW(fromString(":::::"), std::invalid_argument);
EXPECT_THROW(fromString("00:0:0:0:0"), std::invalid_argument);
EXPECT_THROW(fromString("00:00:00:00:00:00:00"), std::invalid_argument);
EXPECT_THROW(fromString(""), std::invalid_argument);
}

Expand Down

0 comments on commit 363a2ad

Please sign in to comment.