diff --git a/linux/LinuxProcess.c b/linux/LinuxProcess.c index 890c8a0f..2775122c 100644 --- a/linux/LinuxProcess.c +++ b/linux/LinuxProcess.c @@ -109,6 +109,7 @@ ProcessFieldData Process_fields[] = { [M_SWAP] = { .name = "M_SWAP", .title = " SWAP ", .description = "Size of the process's swapped pages", .flags = PROCESS_FLAG_LINUX_SMAPS, }, [M_PSSWP] = { .name = "M_PSSWP", .title = " PSSWP ", .description = "shows proportional swap share of this mapping, Unlike \"Swap\", this does not take into account swapped out page of underlying shmem objects.", .flags = PROCESS_FLAG_LINUX_SMAPS, }, [CTXT] = { .name = "CTXT", .title = " CTXT ", .description = "Context switches (incremental sum of voluntary_ctxt_switches and nonvoluntary_ctxt_switches)", .flags = PROCESS_FLAG_LINUX_CTXT, }, + [SECATTR] = { .name = "SECATTR", .title = " Security Attribute ", .description = "Security attribute of the process (e.g. SELinux or AppArmor)", .flags = PROCESS_FLAG_LINUX_SECATTR, }, [LAST_PROCESSFIELD] = { .name = "*** report bug! ***", .title = NULL, .description = NULL, .flags = 0, }, }; @@ -148,6 +149,7 @@ void Process_delete(Object* cast) { #ifdef HAVE_CGROUP free(this->cgroup); #endif + free(this->secattr); free(this->ttyDevice); free(this); } @@ -289,6 +291,7 @@ void LinuxProcess_writeField(Process* this, RichString* str, ProcessField field) attr |= A_BOLD; xSnprintf(buffer, n, "%5lu ", lp->ctxt_diff); break; + case SECATTR: snprintf(buffer, n, "%-30s ", lp->secattr ? lp->secattr : "?"); break; default: Process_writeField(this, str, field); return; @@ -374,6 +377,8 @@ long LinuxProcess_compare(const void* v1, const void* v2) { return LinuxProcess_effectiveIOPriority(p1) - LinuxProcess_effectiveIOPriority(p2); case CTXT: return ((long)p2->ctxt_diff - (long)p1->ctxt_diff); + case SECATTR: + return strcmp(p1->secattr ? p1->secattr : "", p2->secattr ? p2->secattr : ""); default: return Process_compare(v1, v2); } diff --git a/linux/LinuxProcess.h b/linux/LinuxProcess.h index 9972ee84..58774862 100644 --- a/linux/LinuxProcess.h +++ b/linux/LinuxProcess.h @@ -15,6 +15,7 @@ in the source distribution for its full text. #define PROCESS_FLAG_LINUX_OOM 0x1000 #define PROCESS_FLAG_LINUX_SMAPS 0x2000 #define PROCESS_FLAG_LINUX_CTXT 0x4000 +#define PROCESS_FLAG_LINUX_SECATTR 0x8000 typedef enum UnsupportedProcessFields { FLAGS = 9, @@ -82,7 +83,8 @@ typedef enum LinuxProcessFields { M_SWAP = 120, M_PSSWP = 121, CTXT = 122, - LAST_PROCESSFIELD = 123, + SECATTR = 123, + LAST_PROCESSFIELD = 124, } LinuxProcessField; #include "IOPriority.h" @@ -142,6 +144,7 @@ typedef struct LinuxProcess_ { #endif unsigned long ctxt_total; unsigned long ctxt_diff; + char *secattr; } LinuxProcess; #define Process_isKernelThread(_process) (((LinuxProcess*)(_process))->isKernelThread) diff --git a/linux/LinuxProcessList.c b/linux/LinuxProcessList.c index 1e472aff..1df7b32b 100644 --- a/linux/LinuxProcessList.c +++ b/linux/LinuxProcessList.c @@ -625,6 +625,32 @@ static void LinuxProcessList_readCtxtData(LinuxProcess* process, const char* dir process->ctxt_total = ctxt; } +static void LinuxProcessList_readSecattrData(LinuxProcess* process, const char* dirname, const char* name) { + char filename[MAX_NAME+1]; + xSnprintf(filename, sizeof(filename), "%s/%s/attr/current", dirname, name); + FILE* file = fopen(filename, "r"); + if (!file) { + free(process->secattr); + process->secattr = NULL; + return; + } + char buffer[PROC_LINE_LENGTH + 1]; + char *res = fgets(buffer, sizeof(buffer), file); + fclose(file); + if (!res) { + free(process->secattr); + process->secattr = NULL; + return; + } + char *newline = strchr(buffer, '\n'); + if (newline) + *newline = '\0'; + if (process->secattr && 0 == strcmp(process->secattr, buffer)) + return; + free(process->secattr); + process->secattr = xStrdup(buffer); +} + #ifdef HAVE_DELAYACCT static int handleNetlinkMsg(struct nl_msg *nlmsg, void *linuxProcess) { @@ -925,6 +951,9 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, const char* if (settings->flags & PROCESS_FLAG_LINUX_CTXT) LinuxProcessList_readCtxtData(lp, dirname, name); + if (settings->flags & PROCESS_FLAG_LINUX_SECATTR) + LinuxProcessList_readSecattrData(lp, dirname, name); + if (proc->state == 'Z' && (proc->basenameOffset == 0)) { proc->basenameOffset = -1; setCommand(proc, command, commLen);