Menu

#19 Fix use after free in qucsMessageOutput

Unstable_(example)
open
nobody
None
5
2026-03-25
2026-03-25
artsurd
No

Hello,

I haven't used SourceForge like this before, but thought I'd give it a go. I've also made the same request on GitHub in case this is the wrong place.

I noticed a use-after-free in qucsMessageOutput. The problem is that toUtf8 returns a QByteArray, so the call to .data() is on an rvalue which gets freed after the expression ends.

On my machine, this results in intermittent crashes. I verified the fix by running the address sanitizer before and after.

Before:

 ./qucs/qucs
=================================================================
==138986==ERROR: AddressSanitizer: heap-use-after-free on address 0x7c74c41e3358 at pc 0x7f54ca07d276 bp 0x7fff103b8f70 sp 0x7fff103b86e8
READ of size 85 at 0x7c74c41e3358 thread T0
    #0 0x7f54ca07d275  (/usr/lib/libasan.so.8+0x7d275) (BuildId: de2d781fb7f18c0d865c9e63460465acc493f0f4)
    #1 0x7f54ca0a816c in vfprintf (/usr/lib/libasan.so.8+0xa816c) (BuildId: de2d781fb7f18c0d865c9e63460465acc493f0f4)
    #2 0x7f54ca0ab344 in fprintf (/usr/lib/libasan.so.8+0xab344) (BuildId: de2d781fb7f18c0d865c9e63460465acc493f0f4)
    #3 0x55b7d3060923 in qucsMessageOutput(QtMsgType, QMessageLogContext const&, QString const&) /home/artsurd/source/qucs/qucs/main.cpp:49
    #4 0x7f54c86f37d7  (/usr/lib/libQt5Core.so.5+0xf37d7) (BuildId: 168ffc14d4239e8cf2a2400257f9c95f00fa8b41)
    #5 0x7f54c86f38b0 in qt_message_output(QtMsgType, QMessageLogContext const&, QString const&) (/usr/lib/libQt5Core.so.5+0xf38b0) (BuildId: 168ffc14d4239e8cf2a2400257f9c95f00fa8b41)
    #6 0x7f54c87fa030 in QDebug::~QDebug() (/usr/lib/libQt5Core.so.5+0x1fa030) (BuildId: 168ffc14d4239e8cf2a2400257f9c95f00fa8b41)
    #7 0x55b7d3069e3b in main /home/artsurd/source/qucs/qucs/main.cpp:440
    #8 0x7f54c7e27c0d  (/usr/lib/libc.so.6+0x27c0d) (BuildId: 45bece07c9d751c2251242b44c114e38d08c5eff)
    #9 0x7f54c7e27d4a in __libc_start_main (/usr/lib/libc.so.6+0x27d4a) (BuildId: 45bece07c9d751c2251242b44c114e38d08c5eff)
    #10 0x55b7d3060614 in _start (/home/artsurd/source/qucs/qucs/qucs.real+0x6e6614) (BuildId: 6941858d755eb1433c6ed4f28164452aba7aa719)

0x7c74c41e3358 is located 24 bytes inside of 277-byte region [0x7c74c41e3340,0x7c74c41e3455)
freed by thread T0 here:
    #0 0x7f54ca17a8ad  (/usr/lib/libasan.so.8+0x17a8ad) (BuildId: de2d781fb7f18c0d865c9e63460465acc493f0f4)
    #1 0x55b7d3070ef8 in QTypedArrayData<char>::deallocate(QArrayData*) /usr/include/qt/QtCore/qarraydata.h:239
    #2 0x55b7d306deda in QByteArray::~QByteArray() /usr/include/qt/QtCore/qbytearray.h:497
    #3 0x55b7d30607da in qucsMessageOutput(QtMsgType, QMessageLogContext const&, QString const&) /home/artsurd/source/qucs/qucs/main.cpp:40
    #4 0x7f54c86f37d7  (/usr/lib/libQt5Core.so.5+0xf37d7) (BuildId: 168ffc14d4239e8cf2a2400257f9c95f00fa8b41)

previously allocated by thread T0 here:
    #0 0x7f54ca17bc7d in malloc (/usr/lib/libasan.so.8+0x17bc7d) (BuildId: de2d781fb7f18c0d865c9e63460465acc493f0f4)
    #1 0x7f54c8700820 in QArrayData::allocate(unsigned long, unsigned long, unsigned long, QFlags<QArrayData::AllocationOption>) (/usr/lib/libQt5Core.so.5+0x100820) (BuildId: 168ffc14d4239e8cf2a2400257f9c95f00fa8b41)

SUMMARY: AddressSanitizer: heap-use-after-free /home/artsurd/source/qucs/qucs/main.cpp:49 in qucsMessageOutput(QtMsgType, QMessageLogContext const&, QString const&)
Shadow bytes around the buggy address:
  0x7c74c41e3080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7c74c41e3100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7c74c41e3180: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
  0x7c74c41e3200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7c74c41e3280: 00 00 00 00 00 00 00 00 00 00 00 00 fa fa fa fa
=>0x7c74c41e3300: fa fa fa fa fa fa fa fa fd fd fd[fd]fd fd fd fd
  0x7c74c41e3380: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x7c74c41e3400: fd fd fd fd fd fd fd fd fd fd fd fa fa fa fa fa
  0x7c74c41e3480: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x7c74c41e3500: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x7c74c41e3580: 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
==138986==ABORTING

After:

[ no ASAN issue raised ]

Discussion

  • artsurd

    artsurd - 2026-03-25

    Here is the patch:

    From 4f8625ef32619a650ca78d1785e684077f5aac1d Mon Sep 17 00:00:00 2001
    From: artsurd <git@artsurd.info>
    Date: Wed, 25 Mar 2026 01:08:00 +0000
    Subject: [PATCH] Fix use after free in qucsMessageOutput
    
    ---
     qucs/main.cpp | 4 +++-
     1 file changed, 3 insertions(+), 1 deletion(-)
    
    diff --git a/qucs/main.cpp b/qucs/main.cpp
    index 0a50bd8d6..8879f84eb 100644
    --- a/qucs/main.cpp
    +++ b/qucs/main.cpp
    @@ -37,7 +37,9 @@
      */
     void qucsMessageOutput(QtMsgType type, const QMessageLogContext &, const QString &str)
     {
    
    -  const char *msg = str.toUtf8().data();
    +  const QByteArray utf8_msg = str.toUtf8();
    +  const char* msg = utf8_msg.data();
    +
       switch (type) {
       case QtInfoMsg:
         fprintf(stderr,"Info %s\n", msg);
    -- 
    2.53.0
    
     

    Last edit: artsurd 2026-03-25
  • artsurd

    artsurd - 2026-03-25
     
    • Felix

      Felix - 2026-03-25

      On Wed, Mar 25, 2026 at 01:29:27AM -0000, artsurd wrote:

      I haven't used SourceForge like this before, but thought I'd give it a go. I've also made the same request on GitHub in case this is the wrong place.

      Thanks.

      Since you raised it. I am not sure why the code was moved got github,
      probably just for the "git workflow". Today Codeberg might be a much
      better option, but I only recently created [1].

      I will look at your patch when I find some time.

      [1] https://codeberg.org/qucs/gui

       
      • artsurd

        artsurd - 2026-03-25

        Looks like the code was merged on GitHub
        https://github.com/Qucs/qucs/commit/4f8625ef32619a650ca78d1785e684077f5aac1d

        Which appears to have made it here too:
        https://sourceforge.net/p/qucs/git/ci/4f8625ef32619a650ca78d1785e684077f5aac1d/

        Glad it made it in!
        I agree Codeberg is good. Zig went there as a middle finger to GitHub and Microslop. My own GitHub is mostly taken down now because of all the LLMs not respecting licenses.

        Have had a go with Gitea and Codeberg. It's nice in a way; git was made to be dectranlised, it's getting to flex those muscles a bit and all seems to be going well. My projects on Gitea are well integrated with some on GitHub and I made a change no SourceForge (this one, first time!) as well as a RP on Codeberg. Woo!

        Happy to go where need be.

        edit: looks like the change made it to Codeberg too! I presume it's two-way mirroring then.
        https://codeberg.org/qucs/gui/commit/4f8625ef32619a650ca78d1785e684077f5aac1d

        edit 2: either that, or I got this SourceForge message way after you'd already applied the patch 😅

         

        Last edit: artsurd 2026-03-25

Log in to post a comment.

MongoDB Logo MongoDB