diff --git a/Makefile.am b/Makefile.am index 085f763a..83ada450 100644 --- a/Makefile.am +++ b/Makefile.am @@ -119,23 +119,31 @@ myhtopheaders = \ # ----- linux_platform_headers = \ - linux/Platform.h \ - linux/IOPriorityPanel.h \ + linux/Battery.h \ linux/IOPriority.h \ + linux/IOPriorityPanel.h \ linux/LinuxProcess.h \ linux/LinuxProcessList.h \ - linux/Battery.h \ + linux/Platform.h \ linux/PressureStallMeter.h \ + linux/SELinuxMeter.h \ zfs/ZfsArcMeter.h \ - zfs/ZfsCompressedArcMeter.h \ - zfs/ZfsArcStats.h + zfs/ZfsArcStats.h \ + zfs/ZfsCompressedArcMeter.h if HTOP_LINUX AM_LDFLAGS += -rdynamic -myhtopplatsources = linux/Platform.c linux/IOPriorityPanel.c \ -linux/LinuxProcess.c linux/LinuxProcessList.c linux/Battery.c \ -linux/PressureStallMeter.c \ -zfs/ZfsArcMeter.c zfs/ZfsCompressedArcMeter.c zfs/ZfsArcStats.c +myhtopplatsources = \ + linux/Battery.c \ + linux/IOPriorityPanel.c \ + linux/LinuxProcess.c \ + linux/LinuxProcessList.c \ + linux/Platform.c \ + linux/PressureStallMeter.c \ + linux/SELinuxMeter.c \ + zfs/ZfsArcMeter.c \ + zfs/ZfsArcStats.c \ + zfs/ZfsCompressedArcMeter.c myhtopplatheaders = $(linux_platform_headers) endif diff --git a/linux/Platform.c b/linux/Platform.c index e0a03548..c7826418 100644 --- a/linux/Platform.c +++ b/linux/Platform.c @@ -28,6 +28,7 @@ in the source distribution for its full text. #include "zfs/ZfsArcMeter.h" #include "zfs/ZfsCompressedArcMeter.h" #include "LinuxProcess.h" +#include "SELinuxMeter.h" #include "StringUtils.h" #include @@ -139,6 +140,7 @@ const MeterClass* const Platform_meterTypes[] = { &ZfsArcMeter_class, &ZfsCompressedArcMeter_class, &DiskIOMeter_class, + &SELinuxMeter_class, NULL }; diff --git a/linux/SELinuxMeter.c b/linux/SELinuxMeter.c new file mode 100644 index 00000000..8562215b --- /dev/null +++ b/linux/SELinuxMeter.c @@ -0,0 +1,91 @@ +/* +htop - SELinuxMeter.c +(C) 2020 Christian Goettsche +Released under the GNU GPLv2, see the COPYING file +in the source distribution for its full text. +*/ + +#include "SELinuxMeter.h" + +#include "CRT.h" + +#include +#include +#include +#include +#include +#include +#include + + +static const int SELinuxMeter_attributes[] = { + METER_TEXT, +}; + +static bool enabled = false; +static bool enforcing = false; + +static bool hasSELinuxMount(void) { + struct statfs sfbuf; + int r = statfs("/sys/fs/selinux", &sfbuf); + if (r != 0) + return false; + + if (sfbuf.f_type != SELINUX_MAGIC) + return false; + + struct statvfs vfsbuf; + r = statvfs("/sys/fs/selinux", &vfsbuf); + if (r != 0 || (vfsbuf.f_flag & ST_RDONLY)) + return false; + + return true; +} + +static bool isSelinuxEnabled(void) { + return hasSELinuxMount() && (0 == access("/etc/selinux/config", F_OK)); +} + +static bool isSelinuxEnforcing(void) { + if (!enabled) + return false; + + int fd = open("/sys/fs/selinux/enforce", O_RDONLY); + if (fd < 0) + return false; + + char buf[20] = {0}; + int r = read(fd, buf, sizeof(buf) - 1); + close(fd); + if (r < 0) + return false; + + int enforce = 0; + if (sscanf(buf, "%d", &enforce) != 1) + return false; + + return !!enforce; +} + +static void SELinuxMeter_updateValues(ATTR_UNUSED Meter* this, char* buffer, int len) { + enabled = isSelinuxEnabled(); + enforcing = isSelinuxEnforcing(); + + xSnprintf(buffer, len, "%s%s", enabled ? "enabled" : "disabled", enabled ? (enforcing ? "; mode: enforcing" : "; mode: permissive") : ""); +} + +const MeterClass SELinuxMeter_class = { + .super = { + .extends = Class(Meter), + .delete = Meter_delete, + }, + .updateValues = SELinuxMeter_updateValues, + .defaultMode = TEXT_METERMODE, + .maxItems = 0, + .total = 100.0, + .attributes = SELinuxMeter_attributes, + .name = "SELinux", + .uiName = "SELinux", + .description = "SELinux state overview", + .caption = "SELinux: " +}; diff --git a/linux/SELinuxMeter.h b/linux/SELinuxMeter.h new file mode 100644 index 00000000..02362bf1 --- /dev/null +++ b/linux/SELinuxMeter.h @@ -0,0 +1,14 @@ +#ifndef HEADER_SELinuxMeter +#define HEADER_SELinuxMeter +/* +htop - SELinuxMeter.h +(C) 2020 Christian Goettsche +Released under the GNU GPLv2, see the COPYING file +in the source distribution for its full text. +*/ + +#include "Meter.h" + +extern const MeterClass SELinuxMeter_class; + +#endif /* HEADER_SELinuxMeter */