From 3adb423e9e5fe5d1fdf3e577cced747793edee54 Mon Sep 17 00:00:00 2001 From: Michael Baier Date: Thu, 9 Jul 2026 08:24:19 +0200 Subject: [PATCH 01/10] Added Testcase for bug1206 --- tests/rtlil/bug1206.ys | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 tests/rtlil/bug1206.ys diff --git a/tests/rtlil/bug1206.ys b/tests/rtlil/bug1206.ys new file mode 100644 index 000000000..0084bb0f4 --- /dev/null +++ b/tests/rtlil/bug1206.ys @@ -0,0 +1,6 @@ +logger -expect error "Wire width .* out of range" 1 +read_rtlil < Date: Thu, 9 Jul 2026 09:00:59 +0200 Subject: [PATCH 02/10] Adding Widht Limit --- kernel/rtlil.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index e55caf35a..3e9b4ae21 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -99,6 +99,9 @@ namespace RTLIL PD_INOUT = 3 }; + // Maximum width in bits of RTLIL::Wire or RTLIL::Const + constexpr int WIDTH_LIMIT = 1 << 30; + struct Const; struct AttrObject; struct NamedObject; From 42092cbc7720c49c0de0b8af437d82d3c2ecec6b Mon Sep 17 00:00:00 2001 From: Michael Baier Date: Thu, 9 Jul 2026 10:41:31 +0200 Subject: [PATCH 03/10] Adding width checks to frontend --- frontends/rtlil/rtlil_frontend.cc | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/frontends/rtlil/rtlil_frontend.cc b/frontends/rtlil/rtlil_frontend.cc index 4709c76ed..5ddee9c31 100644 --- a/frontends/rtlil/rtlil_frontend.cc +++ b/frontends/rtlil/rtlil_frontend.cc @@ -31,10 +31,6 @@ 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; @@ -283,7 +279,7 @@ struct RTLILFrontendWorker { ++idx; std::vector bits; - if (width > MAX_CONST_WIDTH) + if (width >= RTLIL::WIDTH_LIMIT) error("Constant width %lld out of range before `%s`.", width, error_token()); bits.reserve(width); int start_idx = idx; @@ -532,8 +528,11 @@ struct RTLILFrontendWorker { wire = current_module->addWire(std::move(*id)); break; } - if (try_parse_keyword("width")) + if (try_parse_keyword("width")){ width = parse_integer(); + if (width >= RTLIL::WIDTH_LIMIT) + error("Wire width %lld out of range before `%s`.", width, error_token()); + } else if (try_parse_keyword("upto")) upto = true; else if (try_parse_keyword("signed")) @@ -589,8 +588,11 @@ struct RTLILFrontendWorker { memory->name = std::move(*id); break; } - if (try_parse_keyword("width")) + if (try_parse_keyword("width")){ width = parse_integer(); + if (width >= RTLIL::WIDTH_LIMIT) + error("Memory width %lld out of range before `%s`.", width, error_token()); + } else if (try_parse_keyword("size")) size = parse_integer(); else if (try_parse_keyword("offset")) From 5cd9efefe3eb4af179f326515a9891badf34fd91 Mon Sep 17 00:00:00 2001 From: Michael Baier Date: Thu, 9 Jul 2026 10:41:42 +0200 Subject: [PATCH 04/10] Adding widht checks to backend --- kernel/rtlil.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index d7503d5e2..89cd1b244 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -379,6 +379,7 @@ RTLIL::Const::Const(long long val) // default width 32 RTLIL::Const::Const(long long val, int width) { + log_assert(width >= 0 && width < RTLIL::WIDTH_LIMIT); flags = RTLIL::CONST_FLAG_NONE; if ((width & 7) == 0) { new ((void*)&str_) std::string(); @@ -407,6 +408,7 @@ RTLIL::Const::Const(long long val, int width) RTLIL::Const::Const(RTLIL::State bit, int width) { + log_assert(width >= 0 && width < RTLIL::WIDTH_LIMIT); flags = RTLIL::CONST_FLAG_NONE; new ((void*)&bits_) bitvectype(); tag = backing_tag::bits; @@ -3170,6 +3172,7 @@ void RTLIL::Module::fixup_ports() RTLIL::Wire *RTLIL::Module::addWire(RTLIL::IdString name, int width) { + log_assert(width >= 0 && width < RTLIL::WIDTH_LIMIT); RTLIL::Wire *wire = new RTLIL::Wire; wire->name = std::move(name); wire->width = width; From eb4e29810e854cebd56331b9481ef8cdd723e6ff Mon Sep 17 00:00:00 2001 From: Michael Baier Date: Thu, 9 Jul 2026 11:56:21 +0200 Subject: [PATCH 05/10] Fixed Overflow error in checking width --- frontends/rtlil/rtlil_frontend.cc | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/frontends/rtlil/rtlil_frontend.cc b/frontends/rtlil/rtlil_frontend.cc index 5ddee9c31..4becf0ba0 100644 --- a/frontends/rtlil/rtlil_frontend.cc +++ b/frontends/rtlil/rtlil_frontend.cc @@ -529,9 +529,10 @@ struct RTLILFrontendWorker { break; } if (try_parse_keyword("width")){ - width = parse_integer(); - if (width >= RTLIL::WIDTH_LIMIT) - error("Wire width %lld out of range before `%s`.", width, error_token()); + long long width_val = parse_integer(); + if (width_val < 0 || width_val >= RTLIL::WIDTH_LIMIT) + error("Wire width %lld out of range before `%s`.", width_val, error_token()); + width = width_val; } else if (try_parse_keyword("upto")) upto = true; @@ -589,9 +590,10 @@ struct RTLILFrontendWorker { break; } if (try_parse_keyword("width")){ - width = parse_integer(); - if (width >= RTLIL::WIDTH_LIMIT) - error("Memory width %lld out of range before `%s`.", width, error_token()); + long long width_val = parse_integer(); + if (width_val < 0 || width_val >= RTLIL::WIDTH_LIMIT) + error("Memory width %lld out of range before `%s`.", width_val, error_token()); + width = width_val; } else if (try_parse_keyword("size")) size = parse_integer(); From 086c50763d64125a4ccc0c9a2f2727154b8e1e86 Mon Sep 17 00:00:00 2001 From: Michael Baier Date: Thu, 9 Jul 2026 11:58:07 +0200 Subject: [PATCH 06/10] Tescases for Width Limit, Resize and Overflow --- tests/rtlil/bug1206_memory.ys | 6 ++++++ tests/rtlil/bug1206_memory_overflow.ys | 6 ++++++ tests/rtlil/bug1206_overflow.ys | 6 ++++++ tests/unit/kernel/rtlilTest.cc | 22 ++++++++++++++++++++++ 4 files changed, 40 insertions(+) create mode 100644 tests/rtlil/bug1206_memory.ys create mode 100644 tests/rtlil/bug1206_memory_overflow.ys create mode 100644 tests/rtlil/bug1206_overflow.ys diff --git a/tests/rtlil/bug1206_memory.ys b/tests/rtlil/bug1206_memory.ys new file mode 100644 index 000000000..b747a195c --- /dev/null +++ b/tests/rtlil/bug1206_memory.ys @@ -0,0 +1,6 @@ +logger -expect error "Memory width .* out of range" 1 +read_rtlil < mod = std::make_unique(); + EXPECT_DEATH(mod->addWire(ID(test), RTLIL::WIDTH_LIMIT), ""); + EXPECT_NO_FATAL_FAILURE(mod->addWire(ID(test), RTLIL::WIDTH_LIMIT - 1)); + } + TEST_F(KernelRtlilTest, ConstEqualStr) { EXPECT_EQ(Const("abc"), Const("abc")); EXPECT_NE(Const("abc"), Const("def")); From 58fc67ee662da39f3bea0a2fd95f93c6e4258bc0 Mon Sep 17 00:00:00 2001 From: Michael Baier Date: Thu, 9 Jul 2026 12:24:55 +0200 Subject: [PATCH 07/10] Adding Width check to resize --- kernel/rtlil.h | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 3e9b4ae21..79466ac3b 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -1109,6 +1109,7 @@ public: bits_internal()[i] = state; } void resize(int size, RTLIL::State fill) { + log_assert(size >= 0 && size < RTLIL::WIDTH_LIMIT); bits_internal().resize(size, fill); } From 1dbefdbd4960dc4b2242ccb98fe57610480c2324 Mon Sep 17 00:00:00 2001 From: Michael Baier Date: Thu, 9 Jul 2026 16:32:01 +0200 Subject: [PATCH 08/10] Modified pyosys generator.py to support constexpr --- pyosys/generator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyosys/generator.py b/pyosys/generator.py index 091099742..3ee19cff0 100644 --- a/pyosys/generator.py +++ b/pyosys/generator.py @@ -631,7 +631,7 @@ class PyosysWrapperGenerator(object): self.register_containers(variable) definition_fn = ( - f"def_{'readonly' if variable.type.const else 'readwrite'}_static" + f"def_{'readonly' if (variable.type.const or variable.constexpr) else 'readwrite'}_static" ) variable_python_basename = keyword_aliases.get( From 8f0028652a270646eccb7972fbf6a69ee3fcaeba Mon Sep 17 00:00:00 2001 From: Michael Baier Date: Fri, 10 Jul 2026 14:36:39 +0200 Subject: [PATCH 09/10] long long to int truncation checks --- frontends/rtlil/rtlil_frontend.cc | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/frontends/rtlil/rtlil_frontend.cc b/frontends/rtlil/rtlil_frontend.cc index 4becf0ba0..418837cf9 100644 --- a/frontends/rtlil/rtlil_frontend.cc +++ b/frontends/rtlil/rtlil_frontend.cc @@ -538,8 +538,12 @@ struct RTLILFrontendWorker { upto = true; else if (try_parse_keyword("signed")) is_signed = true; - else if (try_parse_keyword("offset")) - start_offset = parse_integer(); + else if (try_parse_keyword("offset")) { + long long offset_val = parse_integer(); + if (offset_val < INT_MIN || offset_val > INT_MAX) + error("Wire offset %lld out of range before `%s`.", offset_val, error_token()); + start_offset = offset_val; + } else if (try_parse_keyword("input")) { port_id = parse_integer(); port_input = true; @@ -595,10 +599,18 @@ struct RTLILFrontendWorker { error("Memory width %lld out of range before `%s`.", width_val, error_token()); width = width_val; } - else if (try_parse_keyword("size")) - size = parse_integer(); - else if (try_parse_keyword("offset")) - start_offset = parse_integer(); + else if (try_parse_keyword("size")) { + long long size_val = parse_integer(); + if (size_val < INT_MIN || size_val > INT_MAX) + error("Memory size %lld out of range before `%s`.", size_val, error_token()); + size = size_val; + } + else if (try_parse_keyword("offset")) { + long long offset_val = parse_integer(); + if (offset_val < INT_MIN || offset_val > INT_MAX) + error("Memory offset %lld out of range before `%s`.", offset_val, error_token()); + start_offset = offset_val; + } else if (try_parse_eol()) error("Missing memory ID"); else From dca9234d86427faed88f6d139c925d6ae698bd4b Mon Sep 17 00:00:00 2001 From: Michael Baier Date: Fri, 10 Jul 2026 14:37:19 +0200 Subject: [PATCH 10/10] Testcases for new truncation checks --- tests/rtlil/bug1206_memory_offset_negative_overflow.ys | 6 ++++++ tests/rtlil/bug1206_memory_offset_overflow.ys | 6 ++++++ tests/rtlil/bug1206_memory_size_overflow.ys | 6 ++++++ tests/rtlil/bug1206_wire_offset_negative_overflow.ys | 6 ++++++ tests/rtlil/bug1206_wire_offset_overflow.ys | 6 ++++++ 5 files changed, 30 insertions(+) create mode 100644 tests/rtlil/bug1206_memory_offset_negative_overflow.ys create mode 100644 tests/rtlil/bug1206_memory_offset_overflow.ys create mode 100644 tests/rtlil/bug1206_memory_size_overflow.ys create mode 100644 tests/rtlil/bug1206_wire_offset_negative_overflow.ys create mode 100644 tests/rtlil/bug1206_wire_offset_overflow.ys diff --git a/tests/rtlil/bug1206_memory_offset_negative_overflow.ys b/tests/rtlil/bug1206_memory_offset_negative_overflow.ys new file mode 100644 index 000000000..480afd578 --- /dev/null +++ b/tests/rtlil/bug1206_memory_offset_negative_overflow.ys @@ -0,0 +1,6 @@ +logger -expect error "Memory offset .* out of range" 1 +read_rtlil <