diff --git a/processcore/process.h b/processcore/process.h --- a/processcore/process.h +++ b/processcore/process.h @@ -215,6 +215,9 @@ QString cGroup() const; void setCGroup(const QString &cGroup); ///< Linux Control Group (cgroup) + QString seLinuxContext() const; + void setSELinuxContext(const QString &seLinuxContext); ///< SELinux Context + /** This is the number of 1/1000ths of a second since this * particular process was last updated compared to when all the processes * were updated. The purpose is to allow a more fine tracking of the time diff --git a/processcore/process.cpp b/processcore/process.cpp --- a/processcore/process.cpp +++ b/processcore/process.cpp @@ -84,6 +84,7 @@ int elapsedTimeMilliSeconds; int noNewPrivileges; QString cGroup; + QString seLinuxContext; }; Process::Process() @@ -493,6 +494,11 @@ return d->cGroup; } +QString Process::seLinuxContext() const +{ + return d->seLinuxContext; +} + void Process::setParentPid(long int parent_pid) { d->parent_pid = parent_pid; @@ -789,4 +795,10 @@ d->changes |= Process::Status; } +void Process::setSELinuxContext(const QString &_seLinuxContext) { + if(d->seLinuxContext == _seLinuxContext) return; + d->seLinuxContext = _seLinuxContext; + d->changes |= Process::Status; +} + } diff --git a/processcore/processes_linux_p.cpp b/processcore/processes_linux_p.cpp --- a/processcore/processes_linux_p.cpp +++ b/processcore/processes_linux_p.cpp @@ -113,6 +113,7 @@ inline bool readProcStatm(const QString &dir, Process *process); inline bool readProcCmdline(const QString &dir, Process *process); inline bool readProcCGroup(const QString &dir, Process *process); + inline bool readProcAttr(const QString &dir, Process *process); inline bool getNiceness(long pid, Process *process); inline bool getIOStatistics(const QString &dir, Process *process); QFile mFile; @@ -217,6 +218,19 @@ return true; } +bool ProcessesLocal::Private::readProcAttr(const QString &dir, Process *process) +{ + mFile.setFileName(dir + QStringLiteral("attr/current")); + if(!mFile.open(QIODevice::ReadOnly)) + return false; /* process has terminated in the meantime */ + + if( mFile.readLine( mBuffer, sizeof(mBuffer)) > 0) { //-1 indicates an error + process->setSELinuxContext(QString::fromLocal8Bit(mBuffer).trimmed()); + } + mFile.close(); + return true; +} + long ProcessesLocal::getParentPid(long pid) { if (pid <= 0) return -1; @@ -542,6 +556,7 @@ if(!d->readProcStatm(dir, process)) success = false; if(!d->readProcCmdline(dir, process)) success = false; if(!d->readProcCGroup(dir, process)) success = false; + if(!d->readProcAttr(dir, process)) success = false; if(!d->getNiceness(pid, process)) success = false; if(mUpdateFlags.testFlag(Processes::IOStatistics) && !d->getIOStatistics(dir, process)) success = false; diff --git a/processcore/processes_remote_p.cpp b/processcore/processes_remote_p.cpp --- a/processcore/processes_remote_p.cpp +++ b/processcore/processes_remote_p.cpp @@ -42,7 +42,8 @@ statusColumn = userColumn = systemColumn = niceColumn = vmSizeColumn = vmRSSColumn = loginColumn = commandColumn = tracerPidColumn = ttyColumn = ioprioClassColumn = ioprioColumn = - vmURSSColumn = noNewPrivilegesColumn = cGroupColumn = -1; + vmURSSColumn = noNewPrivilegesColumn = cGroupColumn = + seLinuxContextColumn = -1; usedMemory = freeMemory;} ~Private() {} QString host; @@ -71,6 +72,7 @@ int ttyColumn; int noNewPrivilegesColumn; int cGroupColumn; + int seLinuxContextColumn; int numColumns; @@ -141,6 +143,7 @@ if(d->ioprioClassColumn!= -1) process->setIoPriorityClass((KSysGuard::Process::IoPriorityClass)(p.at(d->ioprioClassColumn).toInt())); if(d->noNewPrivilegesColumn!= -1) process->setNoNewPrivileges(p.at(d->noNewPrivilegesColumn).toLong()); if(d->cGroupColumn!= -1) process->setCGroup(QString::fromUtf8(p.at(d->cGroupColumn))); + if(d->seLinuxContextColumn!= -1) process->setSELinuxContext(QString::fromUtf8(p.at(d->seLinuxContextColumn))); return true; } @@ -250,6 +253,8 @@ d->noNewPrivilegesColumn = i; else if(info[i] == "CGroup") d->cGroupColumn = i; + else if(info[i] == "SELinux Context") + d->seLinuxContextColumn = i; } d->havePsInfo = true; break; diff --git a/processui/ProcessModel.h b/processui/ProcessModel.h --- a/processui/ProcessModel.h +++ b/processui/ProcessModel.h @@ -138,7 +138,7 @@ * setup header function, and make sure you increase PROCESSHEADERVERSION. This will ensure * that old saved settings won't be used */ -#define PROCESSHEADERVERSION 8 +#define PROCESSHEADERVERSION 9 enum { HeadingName=0, HeadingUser, HeadingPid, @@ -156,7 +156,8 @@ HeadingCommand, HeadingXMemory, HeadingXTitle, - HeadingCGroup + HeadingCGroup, + HeadingSELinuxContext }; enum { UidRole = Qt::UserRole, SortingValueRole, WindowIdRole, PlainValueRole, PercentageRole, PercentageHistoryRole }; diff --git a/processui/ProcessModel.cpp b/processui/ProcessModel.cpp --- a/processui/ProcessModel.cpp +++ b/processui/ProcessModel.cpp @@ -764,6 +764,8 @@ emit q->dataChanged(index, index); index = q->createIndex(row, ProcessModel::HeadingCGroup, process); emit q->dataChanged(index, index); + index = q->createIndex(row, ProcessModel::HeadingSELinuxContext, process); + emit q->dataChanged(index, index); } if(process->changes() & KSysGuard::Process::NiceLevels) { totalUpdated++; @@ -1033,6 +1035,8 @@ return i18n("The number of bytes written. See What's This for more information."); case HeadingCGroup: return i18n("The control group (cgroup) where this process belongs."); + case HeadingSELinuxContext: + return i18n("SELinux context for this process."); default: return QVariant(); } @@ -1089,6 +1093,8 @@ "Technical information: This data is collected from /proc/*/io and is documented further in Documentation/accounting and Documentation/filesystems/proc.txt in the kernel source."); case HeadingCGroup: return i18n("Technical information: This shows Linux Control Group (cgroup) membership, retrieved from /proc/[pid]/cgroup. Control groups are used by Systemd and containers for limiting process group's usage of resources and to monitor them."); + case HeadingSELinuxContext: + return i18n("Technical information: This shows SELinux (Security Enhanced Linux) context, retrieved from /proc/[pid]/attr/current."); default: return QVariant(); } @@ -1413,6 +1419,8 @@ #endif case HeadingCGroup: return process->cGroup(); + case HeadingSELinuxContext: + return process->seLinuxContext(); default: return QVariant(); } @@ -1794,6 +1802,8 @@ #endif case HeadingCGroup: return process->cGroup(); + case HeadingSELinuxContext: + return process->seLinuxContext(); default: return QVariant(); } @@ -1978,6 +1988,7 @@ } #endif headings << i18nc("process heading", "CGroup"); + headings << i18nc("process heading", "SELinux Context"); if(d->mHeadings.isEmpty()) { // If it's empty, this is the first time this has been called, so insert the headings beginInsertColumns(QModelIndex(), 0, headings.count()-1);