Details
-
Bug
-
Resolution: Fixed
-
P2: Important
-
6.8.2
-
None
-
Linux 6.14-rc5
Qt 6.8.2
AMD Cyan Skillfish APU (Zen2 based)
AMD BC-250 board
-
-
1b8d08532 (dev), 192178393 (6.9), 599da84b3 (6.8)
Description
UPDATE
the real issue in RDSEED instruction, read the comments for details{}
For some reason, in some systems, such as based on the Zen2 core, the operation of the RDRAND instruction can be disrupted in various ways.
For example, AMD's Cyan Skillfish (aka Sony's PlayStation 5 APU) has not received a microcode update to address the RDRAND issue that was discovered in 2019 ( https://arstechnica.com/gadgets/2019/10/how-a-months-old-amd-microcode-bug-destroyed-my-weekend/ ).
This leads to QRandomGenerator::system()->generate() to return 0xFF
std::array<uint, 4> arr;
QRandomGenerator::system()->generate(&arr[0], &arr[4]);
for(uint val: arr){
std::cout << std::hex << val;
}
---
ffffffffffffffffffffffffffffffff
Qt tests are also broken
********* Start testing of tst_QRandomGenerator ********* Config: Using QtTest library 6.8.2, Qt 6.8.2 (x86_64-little_endian-lp64 shared (dynamic) debug build; by GCC 14.2.1 20250220 [revision 9ffecde121af883b60bbe60d00425036bc873048]), opensuse-tumbleweed 20250307 PASS : tst_QRandomGenerator::initTestCase() PASS : tst_QRandomGenerator::basics() PASS : tst_QRandomGenerator::knownSequence() PASS : tst_QRandomGenerator::discard() PASS : tst_QRandomGenerator::copying() PASS : tst_QRandomGenerator::copyingGlobal() FAIL! : tst_QRandomGenerator::copyingSystem() 'sameCount < 20' returned FALSE. () Loc: [/home/bc250/Experiments/qt-build/qtbase-everywhere-src-6.8.2/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp(258)] PASS : tst_QRandomGenerator::systemRng() FAIL! : tst_QRandomGenerator::securelySeeding() 'sameCount < 20' returned FALSE. () Loc: [/home/bc250/Experiments/qt-build/qtbase-everywhere-src-6.8.2/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp(298)] PASS : tst_QRandomGenerator::generate32(fixed) FAIL! : tst_QRandomGenerator::generate32(global) 'rng.generate() != rng.generate()' returned FALSE. (3rd try) Loc: [/home/bc250/Experiments/qt-build/qtbase-everywhere-src-6.8.2/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp(330)] FAIL! : tst_QRandomGenerator::generate32(hwrng) 'rng.generate() != rng.generate()' returned FALSE. (3rd try) Loc: [/home/bc250/Experiments/qt-build/qtbase-everywhere-src-6.8.2/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp(330)] PASS : tst_QRandomGenerator::generate32(system) PASS : tst_QRandomGenerator::generate64(fixed) FAIL! : tst_QRandomGenerator::generate64(global) 'rng.generate64() != rng.generate64()' returned FALSE. (3rd try) Loc: [/home/bc250/Experiments/qt-build/qtbase-everywhere-src-6.8.2/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp(348)] FAIL! : tst_QRandomGenerator::generate64(hwrng) 'rng.generate64() != rng.generate64()' returned FALSE. (3rd try) Loc: [/home/bc250/Experiments/qt-build/qtbase-everywhere-src-6.8.2/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp(348)] PASS : tst_QRandomGenerator::generate64(system) PASS : tst_QRandomGenerator::quality(fixed) QDEBUG : tst_QRandomGenerator::quality(global) 27 above threshold: 227 FAIL! : tst_QRandomGenerator::quality(global) 'v < FailureThreshold' returned FALSE. (27) Loc: [/home/bc250/Experiments/qt-build/qtbase-everywhere-src-6.8.2/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp(404)] QDEBUG : tst_QRandomGenerator::quality(hwrng) 255 above threshold: 2048 FAIL! : tst_QRandomGenerator::quality(hwrng) 'v < FailureThreshold' returned FALSE. (255) Loc: [/home/bc250/Experiments/qt-build/qtbase-everywhere-src-6.8.2/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp(404)] QDEBUG : tst_QRandomGenerator::quality(system) Average: 8 (expected 8 ideally) Max: 19 at 65 Min: 2 at 136 PASS : tst_QRandomGenerator::quality(system) PASS : tst_QRandomGenerator::fillRangeUInt(fixed) FAIL! : tst_QRandomGenerator::fillRangeUInt(global) '[&] { T array[2] = {}; rng.fillRange(array); return array[0] != array[1]; }()' returned FALSE. (3rd try) Loc: [/home/bc250/Experiments/qt-build/qtbase-everywhere-src-6.8.2/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp(428)] FAIL! : tst_QRandomGenerator::fillRangeUInt(hwrng) '[&] { T array[2] = {}; rng.fillRange(array); return array[0] != array[1]; }()' returned FALSE. (3rd try) Loc: [/home/bc250/Experiments/qt-build/qtbase-everywhere-src-6.8.2/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp(428)] PASS : tst_QRandomGenerator::fillRangeUInt(system) PASS : tst_QRandomGenerator::fillRangeULong(fixed) FAIL! : tst_QRandomGenerator::fillRangeULong(global) '[&] { T array[2] = {}; rng.fillRange(array); return array[0] != array[1]; }()' returned FALSE. (3rd try) Loc: [/home/bc250/Experiments/qt-build/qtbase-everywhere-src-6.8.2/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp(428)] FAIL! : tst_QRandomGenerator::fillRangeULong(hwrng) '[&] { T array[2] = {}; rng.fillRange(array); return array[0] != array[1]; }()' returned FALSE. (3rd try) Loc: [/home/bc250/Experiments/qt-build/qtbase-everywhere-src-6.8.2/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp(428)] PASS : tst_QRandomGenerator::fillRangeULong(system) PASS : tst_QRandomGenerator::fillRangeULLong(fixed) FAIL! : tst_QRandomGenerator::fillRangeULLong(global) '[&] { T array[2] = {}; rng.fillRange(array); return array[0] != array[1]; }()' returned FALSE. (3rd try) Loc: [/home/bc250/Experiments/qt-build/qtbase-everywhere-src-6.8.2/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp(428)] FAIL! : tst_QRandomGenerator::fillRangeULLong(hwrng) '[&] { T array[2] = {}; rng.fillRange(array); return array[0] != array[1]; }()' returned FALSE. (3rd try) Loc: [/home/bc250/Experiments/qt-build/qtbase-everywhere-src-6.8.2/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp(428)] PASS : tst_QRandomGenerator::fillRangeULLong(system) PASS : tst_QRandomGenerator::generateUInt(fixed) PASS : tst_QRandomGenerator::generateUInt(global) PASS : tst_QRandomGenerator::generateUInt(hwrng) PASS : tst_QRandomGenerator::generateUInt(system) PASS : tst_QRandomGenerator::generateULLong(fixed) PASS : tst_QRandomGenerator::generateULLong(global) PASS : tst_QRandomGenerator::generateULLong(hwrng) PASS : tst_QRandomGenerator::generateULLong(system) PASS : tst_QRandomGenerator::generateNonContiguous(fixed) PASS : tst_QRandomGenerator::generateNonContiguous(global) PASS : tst_QRandomGenerator::generateNonContiguous(hwrng) PASS : tst_QRandomGenerator::generateNonContiguous(system) PASS : tst_QRandomGenerator::bounded(0,1) PASS : tst_QRandomGenerator::bounded(25,200) PASS : tst_QRandomGenerator::bounded(50,200) PASS : tst_QRandomGenerator::bounded(75,200) PASS : tst_QRandomGenerator::boundedQuality(fixed) QDEBUG : tst_QRandomGenerator::boundedQuality(global) 12 above threshold: 289 QDEBUG : tst_QRandomGenerator::boundedQuality(global) 20 above threshold: 230 QDEBUG : tst_QRandomGenerator::boundedQuality(global) 47 above threshold: 207 QDEBUG : tst_QRandomGenerator::boundedQuality(global) 79 above threshold: 278 QDEBUG : tst_QRandomGenerator::boundedQuality(global) 81 above threshold: 516 FAIL! : tst_QRandomGenerator::boundedQuality(global) 'v < FailureThreshold' returned FALSE. (81) Loc: [/home/bc250/Experiments/qt-build/qtbase-everywhere-src-6.8.2/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp(626)] QDEBUG : tst_QRandomGenerator::boundedQuality(hwrng) 282 above threshold: 9056 FAIL! : tst_QRandomGenerator::boundedQuality(hwrng) 'v < FailureThreshold' returned FALSE. (282) Loc: [/home/bc250/Experiments/qt-build/qtbase-everywhere-src-6.8.2/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp(626)] QDEBUG : tst_QRandomGenerator::boundedQuality(system) Average: 32 (expected 32 ideally) Max: 46 at 78 Min: 13 at 56 PASS : tst_QRandomGenerator::boundedQuality(system) PASS : tst_QRandomGenerator::bounded64(0,1) PASS : tst_QRandomGenerator::bounded64(16,200) PASS : tst_QRandomGenerator::bounded64(32,200) PASS : tst_QRandomGenerator::bounded64(128,200) PASS : tst_QRandomGenerator::bounded64Quality(fixed) QDEBUG : tst_QRandomGenerator::bounded64Quality(global) 115 above threshold: 147 QDEBUG : tst_QRandomGenerator::bounded64Quality(global) 137 above threshold: 136 QDEBUG : tst_QRandomGenerator::bounded64Quality(global) 152 above threshold: 284 QDEBUG : tst_QRandomGenerator::bounded64Quality(global) 201 above threshold: 134 QDEBUG : tst_QRandomGenerator::bounded64Quality(global) 231 above threshold: 202 QDEBUG : tst_QRandomGenerator::bounded64Quality(global) 232 above threshold: 436 QDEBUG : tst_QRandomGenerator::bounded64Quality(global) Average: 32 (expected 32 ideally) Max: 436 at 232 Min: 0 at 29 PASS : tst_QRandomGenerator::bounded64Quality(global) --- HANGS HERE ---
However manual invocation of RDRAND does not reproduce the issue
unsigned long long result = 0ULL; _rdrand64_step(&result); std::cout << std::hex << result; --- 37d82748c155d5c9
Disabling RDRAND in qsimd_p.h file fixes all the qt tests:
static inline bool qHasHwrng() { - return qCpuHasFeature(RDRND); + return false; }
********* Start testing of tst_QRandomGenerator ********* Config: Using QtTest library 6.8.2, Qt 6.8.2 (x86_64-little_endian-lp64 shared (dynamic) debug build; by GCC 14.2.1 20250220 [revision 9ffecde121af883b60bbe60d00425036bc873048]), opensuse-tumbleweed 20250307 PASS : tst_QRandomGenerator::initTestCase() PASS : tst_QRandomGenerator::basics() PASS : tst_QRandomGenerator::knownSequence() PASS : tst_QRandomGenerator::discard() PASS : tst_QRandomGenerator::copying() PASS : tst_QRandomGenerator::copyingGlobal() PASS : tst_QRandomGenerator::copyingSystem() PASS : tst_QRandomGenerator::systemRng() PASS : tst_QRandomGenerator::securelySeeding() PASS : tst_QRandomGenerator::generate32(fixed) PASS : tst_QRandomGenerator::generate32(global) PASS : tst_QRandomGenerator::generate32(system) PASS : tst_QRandomGenerator::generate64(fixed) PASS : tst_QRandomGenerator::generate64(global) PASS : tst_QRandomGenerator::generate64(system) PASS : tst_QRandomGenerator::quality(fixed) QDEBUG : tst_QRandomGenerator::quality(global) Average: 8 (expected 8 ideally) Max: 18 at 151 Min: 2 at 56 PASS : tst_QRandomGenerator::quality(global) QDEBUG : tst_QRandomGenerator::quality(system) Average: 8 (expected 8 ideally) Max: 18 at 211 Min: 1 at 219 PASS : tst_QRandomGenerator::quality(system) PASS : tst_QRandomGenerator::fillRangeUInt(fixed) PASS : tst_QRandomGenerator::fillRangeUInt(global) PASS : tst_QRandomGenerator::fillRangeUInt(system) PASS : tst_QRandomGenerator::fillRangeULong(fixed) PASS : tst_QRandomGenerator::fillRangeULong(global) PASS : tst_QRandomGenerator::fillRangeULong(system) PASS : tst_QRandomGenerator::fillRangeULLong(fixed) PASS : tst_QRandomGenerator::fillRangeULLong(global) PASS : tst_QRandomGenerator::fillRangeULLong(system) PASS : tst_QRandomGenerator::generateUInt(fixed) PASS : tst_QRandomGenerator::generateUInt(global) PASS : tst_QRandomGenerator::generateUInt(system) PASS : tst_QRandomGenerator::generateULLong(fixed) PASS : tst_QRandomGenerator::generateULLong(global) PASS : tst_QRandomGenerator::generateULLong(system) PASS : tst_QRandomGenerator::generateNonContiguous(fixed) PASS : tst_QRandomGenerator::generateNonContiguous(global) PASS : tst_QRandomGenerator::generateNonContiguous(system) PASS : tst_QRandomGenerator::bounded(0,1) PASS : tst_QRandomGenerator::bounded(25,200) PASS : tst_QRandomGenerator::bounded(50,200) PASS : tst_QRandomGenerator::bounded(75,200) PASS : tst_QRandomGenerator::boundedQuality(fixed) QDEBUG : tst_QRandomGenerator::boundedQuality(global) Average: 32 (expected 32 ideally) Max: 51 at 23 Min: 17 at 62 PASS : tst_QRandomGenerator::boundedQuality(global) QDEBUG : tst_QRandomGenerator::boundedQuality(system) Average: 32 (expected 32 ideally) Max: 50 at 29 Min: 18 at 112 PASS : tst_QRandomGenerator::boundedQuality(system) PASS : tst_QRandomGenerator::bounded64(0,1) PASS : tst_QRandomGenerator::bounded64(16,200) PASS : tst_QRandomGenerator::bounded64(32,200) PASS : tst_QRandomGenerator::bounded64(128,200) PASS : tst_QRandomGenerator::bounded64Quality(fixed) QDEBUG : tst_QRandomGenerator::bounded64Quality(global) Average: 32 (expected 32 ideally) Max: 55 at 54 Min: 16 at 177 PASS : tst_QRandomGenerator::bounded64Quality(global) QDEBUG : tst_QRandomGenerator::bounded64Quality(system) Average: 32 (expected 32 ideally) Max: 56 at 13 Min: 17 at 134 PASS : tst_QRandomGenerator::bounded64Quality(system) PASS : tst_QRandomGenerator::generateReal(fixed) PASS : tst_QRandomGenerator::generateReal(global) PASS : tst_QRandomGenerator::generateReal(system) PASS : tst_QRandomGenerator::qualityReal(fixed) QINFO : tst_QRandomGenerator::qualityReal(global) Halfway distribution: 49.8 - 50.2 QINFO : tst_QRandomGenerator::qualityReal(global) 12.7 below 1/8 (expected 12.5% ideally) QINFO : tst_QRandomGenerator::qualityReal(global) 12.7 above 7/8 (expected 12.5% ideally) PASS : tst_QRandomGenerator::qualityReal(global) QINFO : tst_QRandomGenerator::qualityReal(system) Halfway distribution: 50.0 - 50.0 QINFO : tst_QRandomGenerator::qualityReal(system) 12.5 below 1/8 (expected 12.5% ideally) QINFO : tst_QRandomGenerator::qualityReal(system) 12.5 above 7/8 (expected 12.5% ideally) PASS : tst_QRandomGenerator::qualityReal(system) PASS : tst_QRandomGenerator::seedStdRandomEngines() PASS : tst_QRandomGenerator::stdUniformIntDistribution(system:0) PASS : tst_QRandomGenerator::stdUniformIntDistribution(global:0) PASS : tst_QRandomGenerator::stdUniformIntDistribution(system:1) PASS : tst_QRandomGenerator::stdUniformIntDistribution(global:1) PASS : tst_QRandomGenerator::stdUniformIntDistribution(system:199) PASS : tst_QRandomGenerator::stdUniformIntDistribution(global:199) PASS : tst_QRandomGenerator::stdUniformIntDistribution(system:4294967295) PASS : tst_QRandomGenerator::stdUniformIntDistribution(global:4294967295) PASS : tst_QRandomGenerator::stdGenerateCanonical(fixed) PASS : tst_QRandomGenerator::stdGenerateCanonical(global) PASS : tst_QRandomGenerator::stdGenerateCanonical(system) PASS : tst_QRandomGenerator::stdUniformRealDistribution(system:0-0) PASS : tst_QRandomGenerator::stdUniformRealDistribution(global:0-0) PASS : tst_QRandomGenerator::stdUniformRealDistribution(system:0-1) PASS : tst_QRandomGenerator::stdUniformRealDistribution(global:0-1) PASS : tst_QRandomGenerator::stdUniformRealDistribution(system:0-200) PASS : tst_QRandomGenerator::stdUniformRealDistribution(global:0-200) PASS : tst_QRandomGenerator::stdUniformRealDistribution(system:0-4.29497e+09) PASS : tst_QRandomGenerator::stdUniformRealDistribution(global:0-4.29497e+09) PASS : tst_QRandomGenerator::stdUniformRealDistribution(system:0-1.84467e+19) PASS : tst_QRandomGenerator::stdUniformRealDistribution(global:0-1.84467e+19) PASS : tst_QRandomGenerator::stdUniformRealDistribution(system:-1-1.6) PASS : tst_QRandomGenerator::stdUniformRealDistribution(global:-1-1.6) PASS : tst_QRandomGenerator::stdRandomDistributions() PASS : tst_QRandomGenerator::cleanupTestCase() Totals: 82 passed, 0 failed, 0 skipped, 0 blacklisted, 35ms ********* Finished testing of tst_QRandomGenerator *********
Probably on Linux systems, Qt should not use RDRAND and rely on /dev/urandom, which should produce the best possible hardware random on the system
Attachments
For Gerrit Dashboard: QTBUG-134538 | ||||||
---|---|---|---|---|---|---|
# | Subject | Branch | Project | Status | CR | V |
631183,1 | qsimd: perform RDSEED sanity check in case if available | tqtc/lts-6.5 | qt/tqtc-qtbase | Status: NEW | 0 | 0 |
630478,9 | qsimd: perform RDSEED sanity check in case if available | dev | qt/qtbase | Status: MERGED | +2 | 0 |
630763,2 | qsimd: perform RDSEED sanity check in case if available | 6.9 | qt/qtbase | Status: MERGED | +2 | 0 |
630830,2 | qsimd: perform RDSEED sanity check in case if available | 6.8 | qt/qtbase | Status: MERGED | +2 | 0 |