summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormae <matthias.ettrich@nokia.com>2012-06-04 17:26:37 +0200
committerMatthias Ettrich <matthias.ettrich@nokia.com>2012-06-05 11:48:36 +0200
commitfe50c927544b3460312180da16a413aff144c53c (patch)
tree585df1a2ad060f7c566c58bc7b9e5e97a5ec7246
parenta2e64968fe0d1832e7b9326257b1111f539f59dd (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.pro1
-rw-r--r--src/core/processinfo.cpp34
-rw-r--r--src/core/processinfo.h12
-rw-r--r--src/core/unixprocessbackend.cpp2
-rw-r--r--src/core/unixsandboxprocess.cpp34
-rw-r--r--src/core/unixsandboxprocess.h5
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