Skip to content

aarch64/risvc64 qemu emulation -static-pie alpine linux getrandom() error #22981

@userdocs

Description

@userdocs

qBittorrent & operating system versions

qBittorrent: 5.1.2
Linux/Debian/Alpine
Qt: 6.91
libtorrent-rasterbar: 2.0.11

What is the problem?

The introduction of this -static-pie patch in Alpine(edge) gcc master here has exposed a problem with qemu when I built a fully static binary.

note: The binary works fine on the native target but when emulated via qemu it has the getrandom() error. So not sure if this a qemu specific thing with a static-pie binary.

qbittorrent-nox: ELF 64-bit LSB pie executable, UCB RISC-V, RVC, double-float ABI, version 1 (SYSV), static-pie linked, stripped

Here is the qemu gdbbacktrace.

Reading symbols from ./qbittorrent-nox-dbg...
(gdb) set architecture riscv:rv64
The target architecture is set to "riscv:rv64".
(gdb) target remote localhost:1234
Remote debugging using localhost:1234
Reading /usr/lib/debug/.build-id/ad/45634e474aaba0a3571af5f6d6d350a091b1b6.debug from remote target...
warning: File transfers from remote targets can be slow. Use "set sysroot" to access files locally instead.
0x00005555559bad6a in _start ()
(gdb) break main
Breakpoint 1 at 0x5555559fa1e4: file /root/qbt-build/qBittorrent-release-5.1.2/src/app/main.cpp, line 175.
(gdb) continue
Continuing.

Breakpoint 1, main (argc=1, argv=0x7cc3ffb12dc8) at /root/qbt-build/qBittorrent-release-5.1.2/src/app/main.cpp:175
warning: 175    /root/qbt-build/qBittorrent-release-5.1.2/src/app/main.cpp: No such file or directory
(gdb) continue
Continuing.

Program received signal SIGABRT, Aborted.
0x0000555556b9d4c6 in __restore_sigs ()
(gdb) bt
#0  0x0000555556b9d4c6 in __restore_sigs ()
#1  0x0000555556b9d50e in raise ()
#2  0x0000555556b948ba in abort ()
#3  0x000055555695fe84 in qAbort () at /root/qbt-build/qtbase/src/corelib/global/qassert.cpp:46
#4  0x0000555556961b9c in qt_message_fatal<QString&> (context=..., message=...) at /root/qbt-build/qtbase/src/corelib/global/qlogging.cpp:2149
#5  0x00005555569624f4 in qt_message (msgType=msgType@entry=QtFatalMsg, context=..., msg=msg@entry=0x5555572d24f0 "getrandom() error. Reason: \"%s\". Error code: %d.", ap=ap@entry=0x7cc3ffb12660) at /root/qbt-build/qtbase/src/corelib/global/qlogging.cpp:381
#6  0x00005555569628aa in QMessageLogger::fatal (this=0x7cc3ffb126a8, msg=0x5555572d24f0 "getrandom() error. Reason: \"%s\". Error code: %d.") at /root/qbt-build/qtbase/src/corelib/global/qlogging.cpp:883
#7  0x0000555555cbba10 in (anonymous namespace)::RandomLayer::RandomLayer (this=0x555558018cd0 <Utils::Random::rand(unsigned int, unsigned int)::layer>) at /root/qbt-build/qBittorrent-release-5.1.2/src/base/utils/randomlayer_linux.cpp:60
#8  0x0000555555cbbd4c in Utils::Random::rand (min=1024, max=65535) at /root/qbt-build/qBittorrent-release-5.1.2/src/base/utils/random.cpp:45
#9  0x0000555555ab743c in BitTorrent::SessionImpl::SessionImpl (this=0x7cc3ff117020, parent=0x0) at /root/qbt-build/qBittorrent-release-5.1.2/src/base/bittorrent/sessionimpl.cpp:553
#10 0x0000555555ab29f2 in BitTorrent::Session::initInstance () at /root/qbt-build/qBittorrent-release-5.1.2/src/base/bittorrent/sessionimpl.cpp:342
#11 0x00005555559c9734 in Application::exec (this=0x7cc400166010) at /root/qbt-build/qBittorrent-release-5.1.2/src/app/application.cpp:852
#12 0x00005555559face8 in main (argc=1, argv=0x7cc3ffb12dc8) at /root/qbt-build/qBittorrent-release-5.1.2/src/app/main.cpp:328
(gdb)

Steps to reproduce

Not sure how to reproduce this as it need a fully static binary using the alpine gcc that is patched for static-pie. Hopefully the backtrace and patch is enough.

if i clear settings

rm -rf .config/qBittorrent/ .local/share/qBittorrent/

The start binary and press enter i will see

No further notices will be issued.

Press 'Enter' key to continue...
WebUI will be started shortly after internal preparations. Please wait...
getrandom() error. Reason: "Bad address". Error code: 14.
qemu: uncaught target signal 6 (Aborted) - core dumped
Aborted

Additional context

I used co-pilot to debug the backtrace and create a patch that worked to solve the problem and allow the binary to run via emulation.

Not advocating you use this patch, just that as a proof of concept it fixed the problem. So made the issue for you to access.

--- qBittorrent/src/base/utils/randomlayer_linux.cpp	2025-07-12 01:06:00.000004109 +0100
+++ randomlayer_linux.cpp	2025-07-12 01:05:21.889222100 +0100
@@ -30,10 +30,12 @@
 #include <cstdio>
 #include <cstring>
 #include <limits>
+#include <memory>
 
 #include <sys/random.h>
 
 #include <QtLogging>
+#include <QFile>
 
 namespace
 {
@@ -45,27 +47,24 @@
 
         RandomLayer()
         {
-            if (::getrandom(nullptr, 0, 0) < 0)
-            {
-                if (errno == ENOSYS)
-                {
-                    // underlying kernel does not implement this system call
-                    // fallback to `urandom`
-                    m_randDev = fopen("/dev/urandom", "rb");
-                    if (!m_randDev)
-                        qFatal("Failed to open /dev/urandom. Reason: \"%s\". Error code: %d.", std::strerror(errno), errno);
-                }
-                else
-                {
-                    qFatal("getrandom() error. Reason: \"%s\". Error code: %d.", std::strerror(errno), errno);
+            if (::getrandom(nullptr, 0, GRND_NONBLOCK) == -1) {
+                if (errno == ENOSYS || errno == EFAULT) {
+                    // Fallback to /dev/urandom for QEMU compatibility
+                    m_randDev = std::fopen("/dev/urandom", "rb");
+                    if (!m_randDev) {
+                        qFatal("Failed to open /dev/urandom");
+                    }
+                    return;
                 }
+
+                qFatal("getrandom() error. Reason: \"%s\". Error code: %d.", std::strerror(errno), errno);
             }
         }
 
         ~RandomLayer()
         {
             if (m_randDev)
-                fclose(m_randDev);
+                std::fclose(m_randDev);
         }
 
         static constexpr result_type min()
@@ -107,12 +106,12 @@
         result_type getRandomViaFile() const
         {
             result_type buf = 0;
-            if (fread(&buf, sizeof(buf), 1, m_randDev) == 1)
+            if (std::fread(&buf, sizeof(buf), 1, m_randDev) == 1)
                 return buf;
 
             qFatal("Read /dev/urandom error. Reason: \"%s\". Error code: %d.", std::strerror(errno), errno);
         }
 
-        FILE *m_randDev = nullptr;
+        std::FILE *m_randDev = nullptr;
     };
 }

Log(s) & preferences file(s)

n/a

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions