Skip to content

Use after free in opt_dff #5164

Closed
Closed
@georgerennie

Description

@georgerennie

Version

Yosys 0.53+81 (git sha1 378add3, sccache clang++ 19.1.7 -fPIC -O3 -O1 -fno-omit-frame-pointer -fno-optimize-sibling-calls -fsanitize=address,undefined)

On which OS did this happen?

Linux

Reproduction Steps

I was trying to see if #4010 still reproduces on main and found that it now SIGSEGVs. This seems to be separate from the potential misoptimization so I'm opening a new issue. Minimized reproducer below

read_rtlil <<EOT
module \module137
  wire \clk
  wire width 1 output 1 \qa
  wire width 1 \qb
  cell $dff \dffa
    parameter \CLK_POLARITY 1
    parameter \WIDTH 1
    connect \CLK \clk
    connect \D \qb
    connect \Q \qa
  end
  cell $dff \dffb
    parameter \CLK_POLARITY 1
    parameter \WIDTH 1
    connect \CLK \clk
    connect \D 1'x
    connect \Q \qb
  end
end
EOT
opt_dff -sat

Expected Behavior

Completion without error

Actual Behavior

Using ASAN, reports a heap-use-after-free in the IdString copy constructor. Looks like a cell is being deleted when a reference still remains?

 /----------------------------------------------------------------------------\
 |  yosys -- Yosys Open SYnthesis Suite                                       |
 |  Copyright (C) 2012 - 2025  Claire Xenia Wolf <claire@yosyshq.com>         |
 |  Distributed under an ISC-like license, type "license" to see terms        |
 \----------------------------------------------------------------------------/
 Yosys 0.53+81 (git sha1 378add372, sccache clang++ 19.1.7 -fPIC -O3 -O1 -fno-omit-frame-pointer -fno-optimize-sibling-calls -fsanitize=address,undefined)

-- Executing script file `bug.ys' --

1. Executing RTLIL frontend.
Input filename: <<EOT

2. Executing OPT_DFF pass (perform DFF optimizations).
=================================================================
==790124==ERROR: AddressSanitizer: heap-use-after-free on address 0x510000002a78 at pc 0x55df051ebb36 bp 0x7fff4d6c13f0 sp 0x7fff4d6c13e8
READ of size 4 at 0x510000002a78 thread T0
    #0 0x55df051ebb35 in Yosys::RTLIL::IdString::IdString(Yosys::RTLIL::IdString const&) <yosys>/./kernel/rtlil.h:297:66
    #1 0x55df051ebb35 in void Yosys::hashlib::HasherDJB32::eat<Yosys::RTLIL::IdString&>(Yosys::RTLIL::IdString&) <yosys>/./kernel/hashlib.h:122:77
    #2 0x55df0521b0ba in Yosys::ModWalker::PortBit::hash_into(Yosys::hashlib::HasherDJB32) const <yosys>/./kernel/modtools.h:325:6
    #3 0x55df0521b5b4 in Yosys::hashlib::hash_ops<Yosys::ModWalker::PortBit>::hash_into(Yosys::ModWalker::PortBit const&, Yosys::hashlib::HasherDJB32) <yosys>/./kernel/hashlib.h:173:13
    #4 0x55df0521b5b4 in Yosys::hashlib::hash_ops<Yosys::ModWalker::PortBit>::hash(Yosys::ModWalker::PortBit const&) <yosys>/./kernel/hashlib.h:176:33
    #5 0x55df0521b5b4 in Yosys::hashlib::pool<Yosys::ModWalker::PortBit, Yosys::hashlib::hash_ops<Yosys::ModWalker::PortBit>>::do_hash(Yosys::ModWalker::PortBit const&) const <yosys>/./kernel/hashlib.h:847:11
    #6 0x55df0521b5b4 in Yosys::hashlib::pool<Yosys::ModWalker::PortBit, Yosys::hashlib::hash_ops<Yosys::ModWalker::PortBit>>::do_rehash() <yosys>/./kernel/hashlib.h:858:26
    #7 0x55df0521ad13 in Yosys::hashlib::pool<Yosys::ModWalker::PortBit, Yosys::hashlib::hash_ops<Yosys::ModWalker::PortBit>>::do_insert(Yosys::ModWalker::PortBit const&, unsigned int&) <yosys>/./kernel/hashlib.h:933:4
    #8 0x55df0521a052 in Yosys::hashlib::pool<Yosys::ModWalker::PortBit, Yosys::hashlib::hash_ops<Yosys::ModWalker::PortBit>>::insert(Yosys::ModWalker::PortBit const&) <yosys>/./kernel/hashlib.h:1053:7
    #9 0x55df060c0332 in void Yosys::hashlib::pool<Yosys::ModWalker::PortBit, Yosys::hashlib::hash_ops<Yosys::ModWalker::PortBit>>::insert<Yosys::hashlib::pool<Yosys::ModWalker::PortBit, Yosys::hashlib::hash_ops<Yosys::ModWalker::PortBit>>::const_iterator>(Yosys::hashlib::pool<Yosys::ModWalker::PortBit, Yosys::hashlib::hash_ops<Yosys::ModWalker::PortBit>>::const_iterator, Yosys::hashlib::pool<Yosys::ModWalker::PortBit, Yosys::hashlib::hash_ops<Yosys::ModWalker::PortBit>>::const_iterator) <yosys>/./kernel/hashlib.h:1044:4
    #10 0x55df060c0332 in bool Yosys::ModWalker::get_drivers<std::vector<Yosys::RTLIL::SigBit, std::allocator<Yosys::RTLIL::SigBit>>>(Yosys::hashlib::pool<Yosys::ModWalker::PortBit, Yosys::hashlib::hash_ops<Yosys::ModWalker::PortBit>>&, std::vector<Yosys::RTLIL::SigBit, std::allocator<Yosys::RTLIL::SigBit>> const&) const <yosys>/./kernel/modtools.h:466:12
    #11 0x55df060bfef2 in Yosys::ModWalker::get_drivers(Yosys::hashlib::pool<Yosys::ModWalker::PortBit, Yosys::hashlib::hash_ops<Yosys::ModWalker::PortBit>>&, Yosys::RTLIL::SigSpec) const <yosys>/./kernel/modtools.h:510:10
    #12 0x55df060bf98a in Yosys::ModWalker::has_drivers(Yosys::RTLIL::SigSpec) const <yosys>/./kernel/modtools.h:561:10
    #13 0x55df06094780 in (anonymous namespace)::OptDffWorker::run_constbits() <yosys>/passes/opt/opt_dff.cc:773:22
    #14 0x55df06094780 in (anonymous namespace)::OptDffPass::execute(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>, Yosys::RTLIL::Design*) <yosys>/passes/opt/opt_dff.cc:924:15
    #15 0x55df04de80f8 in Yosys::Pass::call(Yosys::RTLIL::Design*, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>) <yosys>/kernel/register.cc:260:26
    #16 0x55df04de704d in Yosys::Pass::call(Yosys::RTLIL::Design*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>) <yosys>/kernel/register.cc:237:2
    #17 0x55df0508838a in Yosys::run_frontend(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, Yosys::RTLIL::Design*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*) <yosys>/kernel/yosys.cc:762:6
    #18 0x55df04d2e07d in main <yosys>/kernel/driver.cc:543:7
    #19 0x7fd5be8556b4 in __libc_start_call_main /usr/src/debug/glibc/glibc/csu/../sysdeps/nptl/libc_start_call_main.h:58:16
    #20 0x7fd5be855768 in __libc_start_main /usr/src/debug/glibc/glibc/csu/../csu/libc-start.c:360:3
    #21 0x55df04bdc7e4 in _start (<yosys>/yosys+0x12a77e4) (BuildId: 95d502b0a92c0260f38d79ff6f081325acd5572f)

0x510000002a78 is located 56 bytes inside of 192-byte region [0x510000002a40,0x510000002b00)
freed by thread T0 here:
    #0 0x55df04d1c372 in operator delete(void*, unsigned long) (<yosys>/yosys+0x13e7372) (BuildId: 95d502b0a92c0260f38d79ff6f081325acd5572f)
    #1 0x55df04ef5e3d in Yosys::RTLIL::Module::remove(Yosys::RTLIL::Cell*) <yosys>/kernel/rtlil.cc:2683:2
    #2 0x55df060968e4 in (anonymous namespace)::OptDffWorker::run_constbits() <yosys>/passes/opt/opt_dff.cc:833:14
    #3 0x55df060968e4 in (anonymous namespace)::OptDffPass::execute(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>, Yosys::RTLIL::Design*) <yosys>/passes/opt/opt_dff.cc:924:15
    #4 0x55df04de80f8 in Yosys::Pass::call(Yosys::RTLIL::Design*, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>) <yosys>/kernel/register.cc:260:26
    #5 0x55df04de704d in Yosys::Pass::call(Yosys::RTLIL::Design*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>) <yosys>/kernel/register.cc:237:2
    #6 0x55df0508838a in Yosys::run_frontend(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, Yosys::RTLIL::Design*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*) <yosys>/kernel/yosys.cc:762:6
    #7 0x55df04d2e07d in main <yosys>/kernel/driver.cc:543:7
    #8 0x7fd5be8556b4 in __libc_start_call_main /usr/src/debug/glibc/glibc/csu/../sysdeps/nptl/libc_start_call_main.h:58:16
    #9 0x7fd5be855768 in __libc_start_main /usr/src/debug/glibc/glibc/csu/../csu/libc-start.c:360:3
    #10 0x55df04bdc7e4 in _start (<yosys>/yosys+0x12a77e4) (BuildId: 95d502b0a92c0260f38d79ff6f081325acd5572f)

previously allocated by thread T0 here:
    #0 0x55df04d1b432 in operator new(unsigned long) (<yosys>/yosys+0x13e6432) (BuildId: 95d502b0a92c0260f38d79ff6f081325acd5572f)
    #1 0x55df04efcb54 in Yosys::RTLIL::Module::addCell(Yosys::RTLIL::IdString, Yosys::RTLIL::IdString) <yosys>/kernel/rtlil.cc:2890:22
    #2 0x55df058433c4 in rtlil_frontend_yyparse() <yosys>/frontends/rtlil/rtlil_parser.y:250:34
    #3 0x55df05858d16 in Yosys::RTLILFrontend::execute(std::istream*&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>, Yosys::RTLIL::Design*) <yosys>/frontends/rtlil/rtlil_frontend.cc:99:3
    #4 0x55df04decc27 in Yosys::Frontend::execute(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>, Yosys::RTLIL::Design*) <yosys>/kernel/register.cc:412:3
    #5 0x55df04de80f8 in Yosys::Pass::call(Yosys::RTLIL::Design*, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>) <yosys>/kernel/register.cc:260:26
    #6 0x55df04de704d in Yosys::Pass::call(Yosys::RTLIL::Design*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>) <yosys>/kernel/register.cc:237:2
    #7 0x55df0508838a in Yosys::run_frontend(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, Yosys::RTLIL::Design*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*) <yosys>/kernel/yosys.cc:762:6
    #8 0x55df04d2e07d in main <yosys>/kernel/driver.cc:543:7
    #9 0x7fd5be8556b4 in __libc_start_call_main /usr/src/debug/glibc/glibc/csu/../sysdeps/nptl/libc_start_call_main.h:58:16
    #10 0x7fd5be855768 in __libc_start_main /usr/src/debug/glibc/glibc/csu/../csu/libc-start.c:360:3
    #11 0x55df04bdc7e4 in _start (<yosys>/yosys+0x12a77e4) (BuildId: 95d502b0a92c0260f38d79ff6f081325acd5572f)

SUMMARY: AddressSanitizer: heap-use-after-free <yosys>/./kernel/rtlil.h:297:66 in Yosys::RTLIL::IdString::IdString(Yosys::RTLIL::IdString const&)
Shadow bytes around the buggy address:
  0x510000002780: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x510000002800: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
  0x510000002880: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x510000002900: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
  0x510000002980: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x510000002a00: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd[fd]
  0x510000002a80: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x510000002b00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x510000002b80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x510000002c00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x510000002c80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
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
==790124==ABORTING

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions