CheckRequiredPermissions verifies if the current process has the specific capabilities required for Keploy to function correctly in Docker mode. On non-Linux systems, this check remains a no-op as capabilities are Linux-specific.
()
| 11 | // required for Keploy to function correctly in Docker mode. |
| 12 | // On non-Linux systems, this check remains a no-op as capabilities are Linux-specific. |
| 13 | func CheckRequiredPermissions() error { |
| 14 | if runtime.GOOS != "linux" { |
| 15 | return nil |
| 16 | } |
| 17 | |
| 18 | // Read /proc/self/status to find "CapEff". |
| 19 | content, err := os.ReadFile("/proc/self/status") |
| 20 | if err != nil { |
| 21 | return fmt.Errorf("failed to read process status: %w", err) |
| 22 | } |
| 23 | |
| 24 | lines := strings.Split(string(content), "\n") |
| 25 | var capEffHex string |
| 26 | for _, line := range lines { |
| 27 | if strings.HasPrefix(line, "CapEff:") { |
| 28 | parts := strings.Fields(line) |
| 29 | if len(parts) >= 2 { |
| 30 | capEffHex = parts[1] |
| 31 | } |
| 32 | break |
| 33 | } |
| 34 | } |
| 35 | |
| 36 | if capEffHex == "" { |
| 37 | return fmt.Errorf("could not find CapEff in /proc/self/status") |
| 38 | } |
| 39 | |
| 40 | // Parse hex string to uint64 |
| 41 | var capUtils uint64 |
| 42 | _, err = fmt.Sscanf(capEffHex, "%x", &capUtils) |
| 43 | if err != nil { |
| 44 | return fmt.Errorf("failed to parse CapEff hex '%s': %w", capEffHex, err) |
| 45 | } |
| 46 | |
| 47 | // Define required bits based on Linux Capability constants |
| 48 | // CAP_NET_ADMIN = 12 |
| 49 | // CAP_SYS_PTRACE = 19 |
| 50 | // CAP_SYS_RESOURCE = 24 |
| 51 | // CAP_BPF = 38 |
| 52 | // CAP_PERFMON = 39 |
| 53 | |
| 54 | required := map[string]uint{ |
| 55 | "NET_ADMIN": 12, |
| 56 | "SYS_PTRACE": 19, |
| 57 | "SYS_RESOURCE": 24, |
| 58 | "BPF": 38, |
| 59 | "PERFMON": 39, |
| 60 | } |
| 61 | |
| 62 | var missing []string |
| 63 | for name, bit := range required { |
| 64 | // specific check is: (cap_mask & (1 << bit)) |
| 65 | if (capUtils & (uint64(1) << bit)) == 0 { |
| 66 | missing = append(missing, name) |
| 67 | } |
| 68 | } |
| 69 | |
| 70 | if len(missing) > 0 { |