diff options
author | mae <matthias.ettrich@nokia.com> | 2012-06-04 17:26:37 +0200 |
---|---|---|
committer | Matthias Ettrich <matthias.ettrich@nokia.com> | 2012-06-05 11:48:36 +0200 |
commit | fe50c927544b3460312180da16a413aff144c53c (patch) | |
tree | 585df1a2ad060f7c566c58bc7b9e5e97a5ec7246 | |
parent | a2e64968fe0d1832e7b9326257b1111f539f59dd (diff) |
Security enablers
1. fix umask handling to be similar to uid/gid
2. add addition property "dropCapabilities"
Change-Id: I9ac7baece5f7c8b6c736dfd79bff6fab6d5b4f7a
Reviewed-by: Lasse Holmstedt <lasse.holmstedt@nokia.com>
-rw-r--r-- | src/core/core.pro | 1 | ||||
-rw-r--r-- | src/core/processinfo.cpp | 34 | ||||
-rw-r--r-- | src/core/processinfo.h | 12 | ||||
-rw-r--r-- | src/core/unixprocessbackend.cpp | 2 | ||||
-rw-r--r-- | src/core/unixsandboxprocess.cpp | 34 | ||||
-rw-r--r-- | src/core/unixsandboxprocess.h | 5 |
6 files changed, 74 insertions, 14 deletions
diff --git a/src/core/core.pro b/src/core/core.pro index 5c54a29..8a6a3c1 100644 --- a/src/core/core.pro +++ b/src/core/core.pro @@ -14,6 +14,7 @@ MODULE_PRI = ../../modules/qt_processmanager.pri QMAKE_CXXFLAGS += -fPIC -fvisibility=hidden -fvisibility-inlines-hidden LIBS += -ldl +linux*: LIBS += -lcap include($$PWD/core-lib.pri) diff --git a/src/core/processinfo.cpp b/src/core/processinfo.cpp index 0fb6f86..ba37fa5 100644 --- a/src/core/processinfo.cpp +++ b/src/core/processinfo.cpp @@ -315,23 +315,45 @@ void ProcessInfo::setGid(qint64 newGid) Return the process default umask */ -uint ProcessInfo::umask() const +qint64 ProcessInfo::umask() const { - return m_info.value(ProcessInfoConstants::Umask).toUInt(); + return m_info.value(ProcessInfoConstants::Umask).toLongLong(); } /*! Set the process default umask - If 0 (the default), the process inherits its parent's umask. + Initializing this value to -1 (or leaving it uninitialized) will result in the + process inheriting its parent's umask. */ -void ProcessInfo::setUmask(uint newUmask) +void ProcessInfo::setUmask(qint64 newUmask) { setValue(ProcessInfoConstants::Umask, newUmask); } /*! + Return the capabilities that the process will drop +*/ + +qint64 ProcessInfo::dropCapabilities() const +{ + return m_info.value(ProcessInfoConstants::DropCapabilities).toLongLong(); +} + +/*! + Set the capabilities that the process will drop + + Initializing this value to 0 (or leaving it uninitialized) will result in the + process not dropping any capabilities. +*/ + +void ProcessInfo::setDropCapabilities(qint64 dropCapabilities) +{ + setValue(ProcessInfoConstants::DropCapabilities, dropCapabilities); +} + +/*! Return the process priority */ @@ -506,6 +528,10 @@ void ProcessInfo::emitChangeSignal(const QString &key) emit uidChanged(); } else if (key == ProcessInfoConstants::Gid) { emit gidChanged(); + } else if (key == ProcessInfoConstants::Umask) { + emit umaskChanged(); + } else if (key == ProcessInfoConstants::DropCapabilities) { + emit dropCapabilitiesChanged(); } else if (key == ProcessInfoConstants::Priority) { emit priorityChanged(); } else if (key == ProcessInfoConstants::OomAdjustment) { diff --git a/src/core/processinfo.h b/src/core/processinfo.h index c667bbd..38721f7 100644 --- a/src/core/processinfo.h +++ b/src/core/processinfo.h @@ -58,6 +58,7 @@ const QLatin1String WorkingDirectory = QLatin1String("workingDirectory"); const QLatin1String Uid = QLatin1String("uid"); const QLatin1String Gid = QLatin1String("gid"); const QLatin1String Umask = QLatin1String("umask"); +const QLatin1String DropCapabilities = QLatin1String("dropCapabilities"); const QLatin1String Priority = QLatin1String("priority"); const QLatin1String OomAdjustment = QLatin1String("oomAdjustment"); const QLatin1String StartOutputPattern = QLatin1String("startOutputPattern"); @@ -73,7 +74,8 @@ class Q_ADDON_PROCESSMANAGER_EXPORT ProcessInfo : public QObject Q_PROPERTY(QString workingDirectory READ workingDirectory WRITE setWorkingDirectory NOTIFY workingDirectoryChanged) Q_PROPERTY(qint64 uid READ uid WRITE setUid NOTIFY uidChanged) Q_PROPERTY(qint64 gid READ gid WRITE setGid NOTIFY gidChanged) - Q_PROPERTY(uint umask READ umask WRITE setUmask NOTIFY umaskChanged) + Q_PROPERTY(qint64 umask READ umask WRITE setUmask NOTIFY umaskChanged) + Q_PROPERTY(qint64 dropCapabilities READ dropCapabilities WRITE setDropCapabilities NOTIFY dropCapabilitiesChanged) Q_PROPERTY(int priority READ priority WRITE setPriority NOTIFY priorityChanged) Q_PROPERTY(int oomAdjustment READ oomAdjustment WRITE setOomAdjustment NOTIFY oomAdjustmentChanged) Q_PROPERTY(QByteArray startOutputPattern READ startOutputPattern WRITE setStartOutputPattern NOTIFY startOutputPatternChanged) @@ -106,8 +108,11 @@ public: qint64 gid() const; void setGid(qint64 gid); - uint umask() const; - void setUmask(uint umask); + qint64 umask() const; + void setUmask(qint64 umask); + + qint64 dropCapabilities() const; + void setDropCapabilities(qint64 dropCapabilities); int priority() const; void setPriority(int priority); @@ -135,6 +140,7 @@ signals: void uidChanged(); void gidChanged(); void umaskChanged(); + void dropCapabilitiesChanged(); void priorityChanged(); void oomAdjustmentChanged(); void startOutputPatternChanged(); diff --git a/src/core/unixprocessbackend.cpp b/src/core/unixprocessbackend.cpp index 3840653..c211d63 100644 --- a/src/core/unixprocessbackend.cpp +++ b/src/core/unixprocessbackend.cpp @@ -169,7 +169,7 @@ bool UnixProcessBackend::createProcess() qint64 uid = (m_info.contains(ProcessInfoConstants::Uid) ? m_info.uid() : -1); qint64 gid = (m_info.contains(ProcessInfoConstants::Gid) ? m_info.gid() : -1); - m_process = new UnixSandboxProcess(uid, gid, m_info.umask(), this); + m_process = new UnixSandboxProcess(uid, gid, m_info.umask(), m_info.dropCapabilities(), this); m_process->setReadChannel(QProcess::StandardOutput); connect(m_process, SIGNAL(readyReadStandardOutput()), diff --git a/src/core/unixsandboxprocess.cpp b/src/core/unixsandboxprocess.cpp index 2b9ec19..24966e9 100644 --- a/src/core/unixsandboxprocess.cpp +++ b/src/core/unixsandboxprocess.cpp @@ -47,6 +47,7 @@ #include <unistd.h> #include <grp.h> #include <sys/prctl.h> +#include <sys/capability.h> #include <signal.h> #endif #include <pwd.h> @@ -64,17 +65,19 @@ QT_BEGIN_NAMESPACE_PROCESSMANAGER Construct a UnixProcessBackend with \a uid, \a gid, \a umask, and optional \a parent. */ -UnixSandboxProcess::UnixSandboxProcess(qint64 uid, qint64 gid, uint umask, QObject *parent) +UnixSandboxProcess::UnixSandboxProcess(qint64 uid, qint64 gid, qint64 umask, qint64 dropCapabilities, QObject *parent) : QProcess(parent) , m_uid(uid) , m_gid(gid) , m_umask(umask) + , m_dropCapabilities(dropCapabilities) { } /*! Set up child process UID, GID, and supplementary group list. - Also set the child process to be in its own process group and fix the umask. + Also set the child process to be in its own process group and fix the umask + and the POSIX capabilities to drop. Under Linux, the child process will be set to receive a SIGTERM signal when the parent process dies. @@ -133,8 +136,10 @@ void UnixSandboxProcess::setupChildProcess() if (::setpgid(0,0)) qFatal("UnixSandboxProcess setpgid(): %s", strerror(errno)); - if (m_umask) - ::umask(m_umask); + if (m_umask >= 0) { + mode_t umask = m_umask; + ::umask(umask); + } if (m_uid >= 0) { errno = 0; @@ -170,6 +175,27 @@ void UnixSandboxProcess::setupChildProcess() if (::setgid(m_gid)) qFatal("UnixSandboxProcess setgid(%ld): %s", (long) m_gid, strerror(errno)); } + + +#if defined (Q_OS_LINUX) + if (m_dropCapabilities >= 0) { + cap_t caps; + cap_value_t cap_list[63]; + quint64 bit = 1; + int n = 0; + for (int i = 0; i < 63; ++i) { + if (m_dropCapabilities & (bit << i)) + cap_list[n++] = i; + } + caps = ::cap_get_proc(); + ::cap_set_flag(caps, CAP_EFFECTIVE, n, cap_list, CAP_CLEAR); + ::cap_set_flag(caps, CAP_INHERITABLE, n, cap_list, CAP_CLEAR); + ::cap_set_flag(caps, CAP_PERMITTED, n, cap_list, CAP_CLEAR); + if (::cap_set_proc(caps) == -1) + qFatal("UnixSandboxProcess cap_set_proc (%ld): %s", (long) m_dropCapabilities, strerror(errno)); + ::cap_free(caps); + } +#endif } #include "moc_unixsandboxprocess.cpp" diff --git a/src/core/unixsandboxprocess.h b/src/core/unixsandboxprocess.h index 0d68715..e007250 100644 --- a/src/core/unixsandboxprocess.h +++ b/src/core/unixsandboxprocess.h @@ -51,7 +51,7 @@ class UnixSandboxProcess : public QProcess Q_OBJECT public: - UnixSandboxProcess(qint64 uid, qint64 gid, uint umask, QObject *parent=0); + UnixSandboxProcess(qint64 uid, qint64 gid, qint64 umask, qint64 dropCapabilites, QObject *parent=0); protected: void setupChildProcess(); @@ -59,7 +59,8 @@ protected: private: qint64 m_uid; qint64 m_gid; - uint m_umask; + qint64 m_umask; + qint64 m_dropCapabilities; }; QT_END_NAMESPACE_PROCESSMANAGER |