From 9a641bb03e6b5318a09eff4cd08b2aa00ec92e97 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Fri, 20 Sep 2024 04:06:38 -0700 Subject: [PATCH] Validate Zvl ISA string correctly See #1810 for explanation of how this can go wrong. Resolves #1810 --- disasm/isa_parser.cc | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/disasm/isa_parser.cc b/disasm/isa_parser.cc index 1c0a0c470e..b5c8b801d6 100644 --- a/disasm/isa_parser.cc +++ b/disasm/isa_parser.cc @@ -9,6 +9,26 @@ static std::string strtolower(const char* str) return res; } +static unsigned long safe_stoul(const std::string& s) +{ + int old_errno = errno; + errno = 0; + + char* endp; + unsigned long ret = strtoul(s.c_str(), &endp, 10); + + int new_errno = errno; + errno = old_errno; + + if (endp == s.c_str() || *endp) + throw std::invalid_argument("stoul"); + + if (new_errno) + throw std::out_of_range("stoul"); + + return ret; +} + static void bad_option_string(const char *option, const char *value, const char *msg) { @@ -327,7 +347,7 @@ isa_parser_t::isa_parser_t(const char* str, const char *priv) } else if (ext_str.substr(0, 3) == "zvl") { reg_t new_vlen; try { - new_vlen = std::stol(ext_str.substr(3, ext_str.size() - 4)); + new_vlen = safe_stoul(ext_str.substr(3, ext_str.size() - 4)); } catch (std::logic_error& e) { new_vlen = 0; } @@ -337,7 +357,7 @@ isa_parser_t::isa_parser_t(const char* str, const char *priv) } else if (ext_str.substr(0, 3) == "zve") { reg_t new_elen; try { - new_elen = std::stol(ext_str.substr(3, ext_str.size() - 4)); + new_elen = safe_stoul(ext_str.substr(3, ext_str.size() - 4)); } catch (std::logic_error& e) { new_elen = 0; }