From 915ad949f9fb0dd9286da8e052c9cbb5233348e3 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Tue, 16 Sep 2025 01:17:45 +0000 Subject: [PATCH] Limit the maximum size of parsed RTLIL constants to 1 Gb. Without this check it's trivially easy to crash Yosys with a tiny RTLIL input by specifying a constant with very large width. Fuzz testers love hitting this over and over again. --- frontends/rtlil/rtlil_frontend.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/frontends/rtlil/rtlil_frontend.cc b/frontends/rtlil/rtlil_frontend.cc index d7511055b..b54cd8f14 100644 --- a/frontends/rtlil/rtlil_frontend.cc +++ b/frontends/rtlil/rtlil_frontend.cc @@ -31,6 +31,10 @@ YOSYS_NAMESPACE_BEGIN struct RTLILFrontendWorker { + // Forbid constants of more than 1 Gb. + // This will help us not explode on malicious RTLIL. + static constexpr int MAX_CONST_WIDTH = 1024 * 1024 * 1024; + std::istream *f = nullptr; RTLIL::Design *design; bool flag_nooverwrite = false; @@ -267,7 +271,7 @@ struct RTLILFrontendWorker { // Can't test value<0 here because we need to stop parsing after '-0' if (negative_value || line[0] != '\'') { if (width < INT_MIN || width > INT_MAX) - error("Integer %lld out of range in `%s'.", width, error_token()); + error("Integer %lld out of range before `%s'.", width, error_token()); consume_whitespace_and_comments(); return RTLIL::Const(width); } @@ -278,6 +282,8 @@ struct RTLILFrontendWorker { ++idx; std::vector bits; + if (width > MAX_CONST_WIDTH) + error("Constant width %lld out of range before `%s`.", width, error_token()); bits.reserve(width); while (true) { RTLIL::State bit;