Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-104096

Use-after-free in QWidget hierarcy

    XMLWordPrintable

Details

    • Bug
    • Resolution: Invalid
    • P1: Critical
    • None
    • 5.15.4, 6.3.0
    • None
    • Linux/X11

    Description

      Well, the issue may be easier to explain with code. Reproducibility of the issue has been consistent, although I haven't created a demo app to demonstrate this.

       

      Code with issue:

       

      void QWidgetPrivate::showChildren(bool spontaneous)
      {
          // here!
          QList<QObject*> childList = children;
          for (int i = 0; i < childList.size(); ++i) {
              QWidget *widget = qobject_cast<QWidget*>(childList.at(i));
              if (widget && widget->windowHandle() && !widget->testAttribute(Qt::WA_WState_ExplicitShowHide))
                  widget->setAttribute(Qt::WA_WState_Hidden, false);
              if (!widget
                  || widget->isWindow()
                  || widget->testAttribute(Qt::WA_WState_Hidden))
                  continue;
              if (spontaneous) {
                  widget->setAttribute(Qt::WA_Mapped);
                  widget->d_func()->showChildren(true);
                  QShowEvent e;
                  QApplication::sendSpontaneousEvent(widget, &e);
              } else {
                  if (widget->testAttribute(Qt::WA_WState_ExplicitShowHide))
                      widget->d_func()->show_recursive();
                  else
                      widget->show();
              }
          }
      }
      

      Here we get the list of children, but we then recursively traverse the list - which leads to code path which ends up destroying the children. But because the reference still exists in childList, this results in a crash.

      The text file showing the analysis of the crash: https://gist.githubusercontent.com/sh-zam/1700ea2337817cca638163a69cd4d40d/raw/3276c0b49193603a8f033d88b99abf9d6b6663e5/gdb.log

       

      The widget is setup something like this: a QMainWindow -> QStackedWidget (as central widget) -> QQuickWidget. I think it is the call to qApp->processEvents() that we do during busy wait which leads to this. Is there something that I'm missing or would fixing the reference to the children fix the bug?

       

      Thank you!

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            qt.team.quick.subscriptions Qt Quick and Widgets Team
            shzam Sharaf Zaman
            Votes:
            0 Vote for this issue
            Watchers:
            6 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes