8000 Stack buffer overflow in `_vl_moddiv_w` due to unchecked `words` exceeding `VL_MULS_MAX_WORDS` · Issue #6003 · verilator/verilator · GitHub
[go: up one dir, main page]

Skip to content

Stack buffer overflow in _vl_moddiv_w due to unchecked words exceeding VL_MULS_MAX_WORDS #6003

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
sdjasj opened this issue May 14, 2025 · 3 comments · Fixed by #6006
Closed

Comments

@sdjasj
Copy link
Contributor
sdjasj commented May 14, 2025

Hi, I recently encountered a new issue, which I’m quite confident is different from the previous one. So I’m opening a new issue to make it easier to track—hope this hasn't caused you any inconvenience.

Here is the code that triggers the problem, test.v:

`timescale 1ns/1ps
module top (out81);

    reg [2:0] in2;
    output wire  [24:23] out81;

    assign out81 = {3000{in2[1:0]}} / {2000{1'b1}}; // `%` works the same way.

    initial begin
        in2 = 3;
        #10;
        $display(out81);
    end

endmodule

I compiled and ran it using ASan instrumentation:

CXXFLAGS="-g -O0 -fsanitize=address" verilator --binary -Wno-lint --timing test.v
./obj_dir/Vtest

During execution, I received the following error log, indicating a stack overflow:

=================================================================
==2385719==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffc53f65e94 at pc 0x555b6eac05ad bp 0x7ffc53f65920 sp 0x7ffc53f65910
WRITE of size 4 at 0x7ffc53f65e94 thread T0
    #0 0x555b6eac05ac in _vl_moddiv_w(int, unsigned int*, unsigned int const*, unsigned int const*, bool) /usr/local/share/verilator/include/verilated.cpp:500
    #1 0x555b6eb42e44 in Vtest___024root___act_sequent__TOP__0(Vtest___024root*) /root/diff_fuzz/min/min38/obj_dir/Vtest___024root__DepSet_hc07518e4__0.cpp:57
    #2 0x555b6eb448dc in Vtest___024root___eval_stl(Vtest___024root*) /root/diff_fuzz/min/min38/obj_dir/Vtest___024root__DepSet_hc07518e4__0__Slow.cpp:75
    #3 0x555b6eb44a95 in Vtest___024root___eval_phase__stl(Vtest___024root*) /root/diff_fuzz/min/min38/obj_dir/Vtest___024root__DepSet_hc07518e4__0__Slow.cpp:91
    #4 0x555b6eb446d1 in Vtest___024root___eval_settle(Vtest___024root*) /root/diff_fuzz/min/min38/obj_dir/Vtest___024root__DepSet_hc07518e4__0__Slow.cpp:45
    #5 0x555b6eb413c8 in Vtest::eval_step() /root/diff_fuzz/min/min38/obj_dir/Vtest.cpp:54
    #6 0x555b6eb45267 in Vtest::eval() /root/diff_fuzz/min/min38/obj_dir/Vtest.h:56
    #7 0x555b6eb43d4d in main /root/diff_fuzz/min/min38/obj_dir/Vtest__main.cpp:21
    #8 0x7fa852d85d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #9 0x7fa852d85e3f in __libc_start_main_impl ../csu/libc-start.c:392
    #10 0x555b6eabad84 in _start (/root/diff_fuzz/min/min38/obj_dir/Vtest+0xcd84)

Address 0x7ffc53f65e94 is located in stack of thread T0 at offset 1204 in frame
    #0 0x555b6eac0066 in _vl_moddiv_w(int, unsigned int*, unsigned int const*, unsigned int const*, bool) /usr/local/share/verilator/include/verilated.cpp:460

  This frame has 2 object(s):
    [32, 548) 'un' (line 495)
    [688, 1204) 'vn' (line 496) <== Memory access at offset 1204 overflows this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow /usr/local/share/verilator/include/verilated.cpp:500 in _vl_moddiv_w(int, unsigned int*, unsigned int const*, unsigned int const*, bool)
Shadow bytes around the buggy address:
  0x10000a7e4b80: 04 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2
  0x10000a7e4b90: f2 f2 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10000a7e4ba0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10000a7e4bb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10000a7e4bc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x10000a7e4bd0: 00 00[04]f3 f3 f3 f3 f3 f3 f3 f3 f3 f3 f3 f3 f3
  0x10000a7e4be0: f3 f3 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00
  0x10000a7e4bf0: 00 00 f1 f1 f1 f1 f8 f2 f2 f2 00 00 00 00 00 00
  0x10000a7e4c00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10000a7e4c10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10000a7e4c20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==2385719==ABORTING

It eventually points to this line in:

_vl_moddiv_w(...) at /usr/local/share/verilator/include/verilated.cpp:500

I noticed that the following code does not check whether words exceeds VL_MULS_MAX_WORDS, which causes the overflow:

// +1 word as we may shift during normalization
uint32_t un[VL_MULS_MAX_WORDS + 1];  // Fixed size, as MSVC++ doesn't allow [words] here
uint32_t vn[VL_MULS_MAX_WORDS + 1];  // v normalized

// Zero for ease of debugging and to save having to zero for shifts
// Note +1 as loop will use extra word
for (int i = 0; i < words + 1; ++i) un[i] = vn[i] = 0;

System details:

  • Verilator version: Verilator 5.037 devel rev v5.036-44-ga80aa07de
  • OS: Ubuntu 22.04.5 LTS (Jammy), Kernel/Release: 22.04
@sdjasj sdjasj added the new New issue not seen by maintainers label May 14, 2025
@wsnyder
Copy link
Member
wsnyder commented May 14, 2025

There is an assertion, run with --runtime-debug to hit it.

This should have been checked at compile time, see the t_math_wide_bad.v test.

This is likely an easy one to debug, perhaps you'd attempt to find out why that test prints an assertion and yours doesn't and make a pull?

@sdjasj
Copy link
Contributor Author
sdjasj commented May 14, 2025

This should have been checked at compile time, see the t_math_wide_bad.v test.

I tried it, and indeed the t_math_wide_bad.v test fails as expected during compile-time checks, but test.v compiles successfully. After adding --runtime-debug, test.v triggers an assertion at runtime. I’ll try to fix this and submit a pull request.

@wsnyder
Copy link
Member
wsnyder commented May 15, 2025

Thanks for fixing!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants
0