From 92f717d825d598b1f149a9b65590f1b50421ccea Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 31 May 2026 21:17:41 -0700 Subject: [PATCH 1/2] Fix out-of-bounds write for missing queue method arguments When a method argument is missing, the error path stores a nullptr in the argument vector for that missing slot. The vector was sized from the number of arguments that were present in the source, so calls such as `q.push_back()` or `q.insert(0)` wrote those nullptr placeholders past the end of the vector. Size the vector from the number of arguments required by the queue method instead. This gives the error path slots for the missing arguments while leaving valid calls unchanged. Signed-off-by: Lars-Peter Clausen --- elaborate.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/elaborate.cc b/elaborate.cc index 03a9f4a18..ba327a815 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -4101,7 +4101,8 @@ NetProc* PCallTask::elaborate_queue_method_(Design*des, NetScope*scope, des->errors += 1; } ivl_type_t element_type = net->queue_type()->element_type(); - vectorargv (nparms+1); + unsigned expected_nparms = method_name == "insert" ? 2 : 1; + vectorargv (expected_nparms+1); argv[0] = sig; auto args = map_named_args(des, parm_names, parms_); From d18cb1b298e8373c40739db1ce07d241b0f59973 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 31 May 2026 21:18:01 -0700 Subject: [PATCH 2/2] Add regression tests for queue method argument count errors Check that queue push_back(), push_front() and insert() report errors when called with too few or too many arguments. These tests are expected to fail as compile/elaboration errors. They also make sure the invalid calls do not crash during elaboration while reporting the argument count error. Signed-off-by: Lars-Peter Clausen --- .../ivltests/sv_queue_method_insert_too_few_arg_fail.v | 9 +++++++++ .../ivltests/sv_queue_method_insert_too_many_arg_fail.v | 9 +++++++++ .../sv_queue_method_push_back_too_few_arg_fail.v | 9 +++++++++ .../sv_queue_method_push_back_too_many_arg_fail.v | 9 +++++++++ .../sv_queue_method_push_front_too_few_arg_fail.v | 9 +++++++++ .../sv_queue_method_push_front_too_many_arg_fail.v | 9 +++++++++ ivtest/regress-vvp.list | 6 ++++++ .../sv_queue_method_insert_too_few_arg_fail.json | 5 +++++ .../sv_queue_method_insert_too_many_arg_fail.json | 5 +++++ .../sv_queue_method_push_back_too_few_arg_fail.json | 5 +++++ .../sv_queue_method_push_back_too_many_arg_fail.json | 5 +++++ .../sv_queue_method_push_front_too_few_arg_fail.json | 5 +++++ .../sv_queue_method_push_front_too_many_arg_fail.json | 5 +++++ 13 files changed, 90 insertions(+) create mode 100644 ivtest/ivltests/sv_queue_method_insert_too_few_arg_fail.v create mode 100644 ivtest/ivltests/sv_queue_method_insert_too_many_arg_fail.v create mode 100644 ivtest/ivltests/sv_queue_method_push_back_too_few_arg_fail.v create mode 100644 ivtest/ivltests/sv_queue_method_push_back_too_many_arg_fail.v create mode 100644 ivtest/ivltests/sv_queue_method_push_front_too_few_arg_fail.v create mode 100644 ivtest/ivltests/sv_queue_method_push_front_too_many_arg_fail.v create mode 100644 ivtest/vvp_tests/sv_queue_method_insert_too_few_arg_fail.json create mode 100644 ivtest/vvp_tests/sv_queue_method_insert_too_many_arg_fail.json create mode 100644 ivtest/vvp_tests/sv_queue_method_push_back_too_few_arg_fail.json create mode 100644 ivtest/vvp_tests/sv_queue_method_push_back_too_many_arg_fail.json create mode 100644 ivtest/vvp_tests/sv_queue_method_push_front_too_few_arg_fail.json create mode 100644 ivtest/vvp_tests/sv_queue_method_push_front_too_many_arg_fail.json diff --git a/ivtest/ivltests/sv_queue_method_insert_too_few_arg_fail.v b/ivtest/ivltests/sv_queue_method_insert_too_few_arg_fail.v new file mode 100644 index 000000000..b2cb9efe6 --- /dev/null +++ b/ivtest/ivltests/sv_queue_method_insert_too_few_arg_fail.v @@ -0,0 +1,9 @@ +// Check that queue insert() rejects too few arguments. + +module test; + int q[$]; + + initial begin + q.insert(0); + end +endmodule diff --git a/ivtest/ivltests/sv_queue_method_insert_too_many_arg_fail.v b/ivtest/ivltests/sv_queue_method_insert_too_many_arg_fail.v new file mode 100644 index 000000000..ceade7d15 --- /dev/null +++ b/ivtest/ivltests/sv_queue_method_insert_too_many_arg_fail.v @@ -0,0 +1,9 @@ +// Check that queue insert() rejects too many arguments. + +module test; + int q[$]; + + initial begin + q.insert(0, 1, 2); + end +endmodule diff --git a/ivtest/ivltests/sv_queue_method_push_back_too_few_arg_fail.v b/ivtest/ivltests/sv_queue_method_push_back_too_few_arg_fail.v new file mode 100644 index 000000000..374e03edc --- /dev/null +++ b/ivtest/ivltests/sv_queue_method_push_back_too_few_arg_fail.v @@ -0,0 +1,9 @@ +// Check that queue push_back() rejects too few arguments. + +module test; + int q[$]; + + initial begin + q.push_back(); + end +endmodule diff --git a/ivtest/ivltests/sv_queue_method_push_back_too_many_arg_fail.v b/ivtest/ivltests/sv_queue_method_push_back_too_many_arg_fail.v new file mode 100644 index 000000000..276004280 --- /dev/null +++ b/ivtest/ivltests/sv_queue_method_push_back_too_many_arg_fail.v @@ -0,0 +1,9 @@ +// Check that queue push_back() rejects too many arguments. + +module test; + int q[$]; + + initial begin + q.push_back(1, 2); + end +endmodule diff --git a/ivtest/ivltests/sv_queue_method_push_front_too_few_arg_fail.v b/ivtest/ivltests/sv_queue_method_push_front_too_few_arg_fail.v new file mode 100644 index 000000000..a82bcb3cd --- /dev/null +++ b/ivtest/ivltests/sv_queue_method_push_front_too_few_arg_fail.v @@ -0,0 +1,9 @@ +// Check that queue push_front() rejects too few arguments. + +module test; + int q[$]; + + initial begin + q.push_front(); + end +endmodule diff --git a/ivtest/ivltests/sv_queue_method_push_front_too_many_arg_fail.v b/ivtest/ivltests/sv_queue_method_push_front_too_many_arg_fail.v new file mode 100644 index 000000000..f7862a21a --- /dev/null +++ b/ivtest/ivltests/sv_queue_method_push_front_too_many_arg_fail.v @@ -0,0 +1,9 @@ +// Check that queue push_front() rejects too many arguments. + +module test; + int q[$]; + + initial begin + q.push_front(1, 2); + end +endmodule diff --git a/ivtest/regress-vvp.list b/ivtest/regress-vvp.list index 2475c4d3a..0a5ad95c7 100644 --- a/ivtest/regress-vvp.list +++ b/ivtest/regress-vvp.list @@ -351,6 +351,12 @@ sv_package_lifetime_fail vvp_tests/sv_package_lifetime_fail.json sv_parameter_type vvp_tests/sv_parameter_type.json sv_queue_ap_method vvp_tests/sv_queue_ap_method.json sv_queue_assign_op vvp_tests/sv_queue_assign_op.json +sv_queue_method_insert_too_few_arg_fail vvp_tests/sv_queue_method_insert_too_few_arg_fail.json +sv_queue_method_insert_too_many_arg_fail vvp_tests/sv_queue_method_insert_too_many_arg_fail.json +sv_queue_method_push_back_too_few_arg_fail vvp_tests/sv_queue_method_push_back_too_few_arg_fail.json +sv_queue_method_push_back_too_many_arg_fail vvp_tests/sv_queue_method_push_back_too_many_arg_fail.json +sv_queue_method_push_front_too_few_arg_fail vvp_tests/sv_queue_method_push_front_too_few_arg_fail.json +sv_queue_method_push_front_too_many_arg_fail vvp_tests/sv_queue_method_push_front_too_many_arg_fail.json sv_soft_packed_union vvp_tests/sv_soft_packed_union.json sv_soft_packed_union_fail1 vvp_tests/sv_soft_packed_union_fail1.json sv_super_member_fail vvp_tests/sv_super_member_fail.json diff --git a/ivtest/vvp_tests/sv_queue_method_insert_too_few_arg_fail.json b/ivtest/vvp_tests/sv_queue_method_insert_too_few_arg_fail.json new file mode 100644 index 000000000..98191069a --- /dev/null +++ b/ivtest/vvp_tests/sv_queue_method_insert_too_few_arg_fail.json @@ -0,0 +1,5 @@ +{ + "type" : "CE", + "source" : "sv_queue_method_insert_too_few_arg_fail.v", + "iverilog-args" : [ "-g2005-sv" ] +} diff --git a/ivtest/vvp_tests/sv_queue_method_insert_too_many_arg_fail.json b/ivtest/vvp_tests/sv_queue_method_insert_too_many_arg_fail.json new file mode 100644 index 000000000..751dc11d1 --- /dev/null +++ b/ivtest/vvp_tests/sv_queue_method_insert_too_many_arg_fail.json @@ -0,0 +1,5 @@ +{ + "type" : "CE", + "source" : "sv_queue_method_insert_too_many_arg_fail.v", + "iverilog-args" : [ "-g2005-sv" ] +} diff --git a/ivtest/vvp_tests/sv_queue_method_push_back_too_few_arg_fail.json b/ivtest/vvp_tests/sv_queue_method_push_back_too_few_arg_fail.json new file mode 100644 index 000000000..e75cf2d2b --- /dev/null +++ b/ivtest/vvp_tests/sv_queue_method_push_back_too_few_arg_fail.json @@ -0,0 +1,5 @@ +{ + "type" : "CE", + "source" : "sv_queue_method_push_back_too_few_arg_fail.v", + "iverilog-args" : [ "-g2005-sv" ] +} diff --git a/ivtest/vvp_tests/sv_queue_method_push_back_too_many_arg_fail.json b/ivtest/vvp_tests/sv_queue_method_push_back_too_many_arg_fail.json new file mode 100644 index 000000000..e66971bc9 --- /dev/null +++ b/ivtest/vvp_tests/sv_queue_method_push_back_too_many_arg_fail.json @@ -0,0 +1,5 @@ +{ + "type" : "CE", + "source" : "sv_queue_method_push_back_too_many_arg_fail.v", + "iverilog-args" : [ "-g2005-sv" ] +} diff --git a/ivtest/vvp_tests/sv_queue_method_push_front_too_few_arg_fail.json b/ivtest/vvp_tests/sv_queue_method_push_front_too_few_arg_fail.json new file mode 100644 index 000000000..c3118f197 --- /dev/null +++ b/ivtest/vvp_tests/sv_queue_method_push_front_too_few_arg_fail.json @@ -0,0 +1,5 @@ +{ + "type" : "CE", + "source" : "sv_queue_method_push_front_too_few_arg_fail.v", + "iverilog-args" : [ "-g2005-sv" ] +} diff --git a/ivtest/vvp_tests/sv_queue_method_push_front_too_many_arg_fail.json b/ivtest/vvp_tests/sv_queue_method_push_front_too_many_arg_fail.json new file mode 100644 index 000000000..644c6c99a --- /dev/null +++ b/ivtest/vvp_tests/sv_queue_method_push_front_too_many_arg_fail.json @@ -0,0 +1,5 @@ +{ + "type" : "CE", + "source" : "sv_queue_method_push_front_too_many_arg_fail.v", + "iverilog-args" : [ "-g2005-sv" ] +}