< Summary - Results for net9.0, Release

Line coverage
83%
Covered lines: 70
Uncovered lines: 14
Coverable lines: 84
Total lines: 238
Line coverage: 83.3%
Branch coverage
57%
Covered branches: 8
Total branches: 14
Branch coverage: 57.1%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
File 1: Stat(...)100%11100%
File 1: GetPwUidR(...)100%11100%
File 2: GetInode(...)100%22100%
File 2: TryGetUid(...)50%2.26260%
File 2: GetUserName(...)25%9.49430%
File 2: TryGetUserName(...)50%5.4455.56%
File 2: .cctor()100%11100%
File 2: GetKnownCriticalProcesses()100%210%
File 2: IsProcessCritical(...)100%22100%

File(s)

/home/runner/work/LockCheck/LockCheck/artifacts/obj/LockCheck/release_net9.0/Microsoft.Interop.LibraryImportGenerator/Microsoft.Interop.LibraryImportGenerator/LibraryImports.g.cs

File '/home/runner/work/LockCheck/LockCheck/artifacts/obj/LockCheck/release_net9.0/Microsoft.Interop.LibraryImportGenerator/Microsoft.Interop.LibraryImportGenerator/LibraryImports.g.cs' does not exist (any more).

/home/runner/work/LockCheck/LockCheck/src/LockCheck/Linux/NativeMethods.cs

#LineLine coverage
 1using System;
 2using System.Collections.Generic;
 3using System.Diagnostics.CodeAnalysis;
 4using System.IO;
 5using System.Runtime.InteropServices;
 6using System.Text;
 7
 8#pragma warning disable IDE1006 // Naming Styles - off here, because we want to use native names
 9
 10namespace LockCheck.Linux;
 11
 12internal static partial class NativeMethods
 13{
 14    public const int EAGAIN = 11; // Resource unavailable, try again (same value as EWOULDBLOCK),
 15    public const int EACCES = 13; // Mandatory lock
 16    public const int EWOULDBLOCK = EAGAIN; // Operation would block.
 17    public const int ERANGE = 34;
 18
 19    public static long GetInode(string path)
 20    {
 221        if (Stat(path, out var status) >= 0)
 22        {
 223            return status.Ino;
 24        }
 25
 226        return -1;
 27    }
 28
 29    public static bool TryGetUid(string path, out uint uid)
 30    {
 231        if (Stat(path, out var status) >= 0)
 32        {
 233            uid = status.Uid;
 234            return true;
 35        }
 36
 037        uid = 0;
 038        return false;
 39    }
 40
 41    public static string? GetUserName(uint uid)
 42    {
 43        string? userName;
 44        unsafe
 45        {
 46            const int BufLen = Passwd.InitialBufferSize;
 247            byte* stackBuf = stackalloc byte[BufLen];
 248            if (TryGetUserName(uid, stackBuf, BufLen, out userName))
 49            {
 250                return userName;
 51            }
 52
 053            int lastBufLen = BufLen;
 054            while (true)
 55            {
 056                lastBufLen *= 2;
 057                byte[] heapBuf = new byte[lastBufLen];
 058                fixed (byte* buf = &heapBuf[0])
 59                {
 060                    if (TryGetUserName(uid, buf, heapBuf.Length, out userName))
 61                    {
 062                        return userName;
 63                    }
 64                }
 65            }
 66        }
 67    }
 68
 69    private static unsafe bool TryGetUserName(uint uid, byte* buf, int bufLen, out string? userName)
 70    {
 271        int error = GetPwUidR(uid, out Passwd passwd, buf, bufLen);
 72
 73        // positive error number returned -> failure other than entry-not-found
 274        if (error != 0)
 75        {
 076            userName = null;
 077            return false;
 78        }
 79
 80        // entry not found
 281        if (error == -1)
 82        {
 083            userName = null;
 084            return true;
 85        }
 86
 287        userName = Marshal.PtrToStringAnsi((IntPtr)passwd.Name);
 288        return true;
 89    }
 90
 91    private const string SystemNative = "System.Native";
 92
 93    [StructLayout(LayoutKind.Sequential)]
 94    internal struct FileStatus
 95    {
 96        internal int Flags;
 97        internal int Mode;
 98        internal uint Uid;
 99        internal uint Gid;
 100        internal long Size;
 101        internal long ATime;
 102        internal long ATimeNsec;
 103        internal long MTime;
 104        internal long MTimeNsec;
 105        internal long CTime;
 106        internal long CTimeNsec;
 107        internal long BirthTime;
 108        internal long BirthTimeNsec;
 109        internal long Dev;
 110        internal long RDev;
 111        internal long Ino;
 112        internal uint UserFlags;
 113    }
 114
 115    [LibraryImport(SystemNative, EntryPoint = "SystemNative_Stat", StringMarshalling = StringMarshalling.Utf8, SetLastEr
 116    private static partial int Stat(string pathname, out FileStatus status);
 117
 118    internal unsafe struct Passwd
 119    {
 120        internal const int InitialBufferSize = 256;
 121
 122        internal byte* Name;
 123        internal byte* Password;
 124        internal uint UserId;
 125        internal uint GroupId;
 126        internal byte* UserInfo;
 127        internal byte* HomeDirectory;
 128        internal byte* Shell;
 129    }
 130
 131    [LibraryImport(SystemNative, EntryPoint = "SystemNative_GetPwUidR", SetLastError = false)]
 132    internal static unsafe partial int GetPwUidR(uint uid, out Passwd pwd, byte* buf, int bufLen);
 133
 134    // TODO: Use this stuff.
 2135    private static readonly HashSet<string> s_critical =
 2136    [
 2137        // List is generated by ChatGPT, obviously ;-)
 2138        "/lib/systemd/systemd",                     // systemd init process (modern distros using systemd)
 2139        "/sbin/init",                               // init process (legacy or minimal distros not using systemd)
 2140        "/usr/sbin/cron",                           // cron scheduler (alternative path)
 2141        "/usr/sbin/crond",                          // cron scheduler (for Red Hat-based systems)
 2142        "/usr/sbin/rsyslogd",                       // syslog daemon (for system logging)
 2143        "/usr/sbin/syslogd",                        // alternative syslog daemon path (legacy or minimal systems)
 2144        "/usr/sbin/sshd",                           // OpenSSH daemon for remote access
 2145        "/usr/lib/NetworkManager/NetworkManager",   // network manager (for desktop/server environments)
 2146        "/sbin/dhcpcd",                             // DHCP client daemon (lightweight systems)
 2147        "/usr/sbin/dhclient",                       // DHCP client daemon (Debian/Ubuntu default)
 2148        "/usr/lib/polkit-1/polkitd",                // policy kit daemon for permissions (common in GUI-based systems)
 2149        "/usr/lib/upowerd",                         // power management daemon (laptops/desktops)
 2150        "/sbin/udevd",                              // udev device manager daemon (general)
 2151        "/usr/lib/udev/udevd",                      // udev device manager daemon (alternative path)
 2152        "/usr/sbin/ntpd",                           // NTP daemon for time synchronization (traditional)
 2153        "/usr/sbin/systemd-timesyncd",              // time sync daemon in systemd environments
 2154        "/usr/sbin/acpid",                          // ACPI daemon for power events (laptop/desktops)
 2155        "/usr/sbin/irqbalance",                     // IRQ balancing daemon (multi-core systems)
 2156        "/usr/sbin/lvmetad",                        // LVM metadata daemon (for managing logical volumes)
 2157        "/sbin/auditd",                             // audit daemon for tracking security events
 2158        "/usr/sbin/firewalld",                      // firewall daemon (often in Red Hat-based systems)
 2159        "/usr/lib/snapd/snapd",                     // snap daemon (Ubuntu, for managing snap packages)
 2160        "/usr/sbin/apparmor",                       // AppArmor security enforcement daemon (Ubuntu-based)
 2161        "/usr/sbin/ModemManager",                   // modem management (often in Linux desktop environments)
 2162        "/usr/sbin/cupsd",                          // CUPS printing service daemon
 2163        "/usr/sbin/bluetoothd",                     // Bluetooth service daemon (for desktops)
 2164        "/usr/libexec/fwupd/fwupd",                 // firmware update daemon (modern desktop systems)
 2165        "/usr/libexec/udisks2/udisksd",             // disk management daemon (common on desktops)
 2166        "/usr/lib/accounts-daemon/accounts-daemon", // user account management daemon (desktops)
 2167        "/usr/sbin/clamd",                          // ClamAV antivirus daemon (for email/AV filtering servers)
 2168        "/usr/bin/Xorg",                            // X server daemon (for X11 display server)
 2169        "/usr/bin/wayland-session",                 // Wayland session daemon (for Wayland display server)
 2170        "/usr/bin/gnome-session",                   // GNOME session manager (often used with Wayland)
 2171        "/usr/libexec/gnome-settings-daemon",       // GNOME settings daemon (for managing user settings)
 2172    ];
 173
 0174    internal static IEnumerable<string> GetKnownCriticalProcesses() => s_critical;
 175
 2176    internal static bool IsProcessCritical(string? executablePath) => executablePath != null && s_critical.Contains(exec
 177}