From 591a35d6fd9fa4f14ca1ac6a568673e2a2da0f60 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 16 Dec 2021 13:50:21 +0100 Subject: [PATCH] QThread: fix UB (invalid enum value) on Private::Priority The Unix code stores an additional flag, ThreadPriorityResetFlag, in the Policy enum, but ubsan does not approve: qthread_unix.cpp:303:30: runtime error: load of value 2147483648, which is not a valid value for type 'Priority' qthread_unix.cpp:304:75: runtime error: load of value 2147483648, which is not a valid value for type 'Priority' Fix by making the variable of std::underlying_type_t. The masking and unmasking code can now be simplified, too. In the Windows version, replace some switch targets with equivalent ones to keep -Wswitch-like warnings, though I hasten to note that both switches use a default case, so have anyway implicitly disabled said warning. Pick-to: 6.3 6.2 5.15 Change-Id: Ie4ea7d05e2928d2755ad12d36535197f85493191 Reviewed-by: Lars Knoll --- src/corelib/thread/qthread_p.h | 2 +- src/corelib/thread/qthread_unix.cpp | 6 +++--- src/corelib/thread/qthread_win.cpp | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/corelib/thread/qthread_p.h b/src/corelib/thread/qthread_p.h index 50d86ab51a7..0a3813ab3b5 100644 --- a/src/corelib/thread/qthread_p.h +++ b/src/corelib/thread/qthread_p.h @@ -164,7 +164,7 @@ public: int returnCode; uint stackSize; - QThread::Priority priority; + std::underlying_type_t priority; #ifdef Q_OS_UNIX QWaitCondition thread_done; diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp index 85fb5b10344..53395d9a95c 100644 --- a/src/corelib/thread/qthread_unix.cpp +++ b/src/corelib/thread/qthread_unix.cpp @@ -322,8 +322,8 @@ void *QThreadPrivate::start(void *arg) QMutexLocker locker(&thr->d_func()->mutex); // do we need to reset the thread priority? - if (qToUnderlying(thr->d_func()->priority) & ThreadPriorityResetFlag) { - thr->d_func()->setPriority(QThread::Priority(qToUnderlying(thr->d_func()->priority) & ~ThreadPriorityResetFlag)); + if (thr->d_func()->priority & ThreadPriorityResetFlag) { + thr->d_func()->setPriority(QThread::Priority(thr->d_func()->priority & ~ThreadPriorityResetFlag)); } // threadId is set in QThread::start() @@ -703,7 +703,7 @@ void QThread::start(Priority priority) // could not set scheduling hints, fallback to inheriting them // we'll try again from inside the thread pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED); - d->priority = Priority(qToUnderlying(priority) | ThreadPriorityResetFlag); + d->priority = qToUnderlying(priority) | ThreadPriorityResetFlag; } break; } diff --git a/src/corelib/thread/qthread_win.cpp b/src/corelib/thread/qthread_win.cpp index 820ffa11499..4b144ebda4b 100644 --- a/src/corelib/thread/qthread_win.cpp +++ b/src/corelib/thread/qthread_win.cpp @@ -457,7 +457,7 @@ void QThread::start(Priority priority) int prio; d->priority = priority; - switch (d->priority) { + switch (priority) { case IdlePriority: prio = THREAD_PRIORITY_IDLE; break; @@ -584,7 +584,7 @@ void QThreadPrivate::setPriority(QThread::Priority threadPriority) int prio; priority = threadPriority; - switch (priority) { + switch (threadPriority) { case QThread::IdlePriority: prio = THREAD_PRIORITY_IDLE; break;