From b12b1ddf4880a5157b5edac05e0ef381e9148aae Mon Sep 17 00:00:00 2001 From: "Richard J. Moore" Date: Wed, 1 Jan 2014 16:58:19 +0000 Subject: Prevent foolish use of setuid when using Qt. In order to prevent people from shooting themselves in the foot, abort if we're running setuid. This behavior can be disabled by calling QCoreApplication::setSetuidAllowed(true) in order to support legacy code. [ChangeLog][QtCore][Important Behavior Changes] Running Qt applications that are setuid has been prevented. If you really need to do this then you can call QCoreApplication::setSetuidAllowed(true) before creating the QCoreApplication instance. Change-Id: I992a9a0cd8420693d438852a05666e3dbb2c9d6a Reviewed-by: Olivier Goffart Reviewed-by: Frederik Gladhorn Reviewed-by: Lars Knoll --- src/corelib/kernel/qcoreapplication.cpp | 46 +++++++++++++++++++++++++++++++++ src/corelib/kernel/qcoreapplication.h | 3 +++ src/corelib/kernel/qcoreapplication_p.h | 1 + 3 files changed, 50 insertions(+) (limited to 'src') diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index e83a6e2ac4..2dd56423ac 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -102,6 +102,7 @@ #ifdef Q_OS_UNIX # include # include +# include #endif #ifdef Q_OS_VXWORKS @@ -138,6 +139,8 @@ extern QString qAppFileName(); #endif int QCoreApplicationPrivate::app_compile_version = 0x050000; //we don't know exactly, but it's at least 5.0.0 +bool QCoreApplicationPrivate::setuidAllowed = false; + #if !defined(Q_OS_WIN) #ifdef Q_OS_MAC QString QCoreApplicationPrivate::macMenuBarName() @@ -413,6 +416,11 @@ QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv, uint #ifndef QT_NO_QOBJECT QCoreApplicationPrivate::is_app_closing = false; +# if defined(Q_OS_UNIX) + if (!setuidAllowed && (geteuid() != getuid())) + qFatal("FATAL: The application binary appears to be running setuid, this is a security hole."); +# endif // Q_OS_UNIX + # if defined(Q_OS_UNIX) qt_application_thread_id = QThread::currentThreadId(); # endif @@ -796,6 +804,44 @@ QCoreApplication::~QCoreApplication() #endif } +/*! + \since 5.3 + + Allows the application to run setuid on UNIX platforms if \a allow + is true. + + If \a allow is false (the default) and Qt detects the application is + running with an effective user id different than the real user id, + the application will be aborted when a QCoreApplication instance is + created. + + Qt is not an appropriate solution for setuid programs due to its + large attack surface. However some applications may be required + to run in this manner for historical reasons. This flag will + prevent Qt from aborting the application when this is detected, + and must be set before a QCoreApplication instance is created. + + \note It is strongly recommended not to enable this option since + it introduces security risks. +*/ +void QCoreApplication::setSetuidAllowed(bool allow) +{ + QCoreApplicationPrivate::setuidAllowed = allow; +} + +/*! + \since 5.3 + + Returns true if the application is allowed to run setuid on UNIX + platforms. + + \sa QCoreApplication::setSetuidAllowed() +*/ +bool QCoreApplication::isSetuidAllowed() +{ + return QCoreApplicationPrivate::setuidAllowed; +} + /*! Sets the attribute \a attribute if \a on is true; diff --git a/src/corelib/kernel/qcoreapplication.h b/src/corelib/kernel/qcoreapplication.h index ae17aeec0e..c2843030fd 100644 --- a/src/corelib/kernel/qcoreapplication.h +++ b/src/corelib/kernel/qcoreapplication.h @@ -112,6 +112,9 @@ public: static void setApplicationVersion(const QString &version); static QString applicationVersion(); + static void setSetuidAllowed(bool allow); + static bool isSetuidAllowed(); + static QCoreApplication *instance() { return self; } #ifndef QT_NO_QOBJECT diff --git a/src/corelib/kernel/qcoreapplication_p.h b/src/corelib/kernel/qcoreapplication_p.h index 0c00f396b5..c3d83112ae 100644 --- a/src/corelib/kernel/qcoreapplication_p.h +++ b/src/corelib/kernel/qcoreapplication_p.h @@ -153,6 +153,7 @@ public: static bool is_app_closing; #endif + static bool setuidAllowed; static uint attribs; static inline bool testAttribute(uint flag) { return attribs & (1 << flag); } static int app_compile_version; -- cgit v1.2.3