# Go: Know if CAP_IPC_LOCK belongs to the process' effective set ```go package linux_cap import ( "bufio" "bytes" "fmt" "io/fs" "log" "strings" ) // It is possible that the user will have started the process without // CAP_IPC_LOCK in the bounding capability (i.e., set on the deployment). The // process will start fine without it as Memguard doesn't use much // memlocked memory. The argument `f` is meant for testing purposes, use // os.DirFS("/"). // // Read /proc/self/status to check for the capability CAP_IPC_LOCK in the // effective capabilities. Go's standard library doesn't have an API for that. func HasEffIpcLock(f fs.FS) (bool, error) { contents, err := fs.ReadFile(f, "proc/self/status") if err != nil { return false, fmt.Errorf("while checking capabilities in /proc/self/status: %w", err) } var capEff, capBnd, capPrm uint32 scanner := bufio.NewScanner(bytes.NewReader(contents)) for scanner.Scan() { line := scanner.Text() switch { case strings.HasPrefix(line, "CapEff:"): _, err := fmt.Sscanf(strings.TrimSpace(strings.TrimPrefix(line, "CapEff:")), "%x", &capEff) if err != nil { return false, fmt.Errorf("/proc/self/status: failed to parse CapEff: %w", err) } case strings.HasPrefix(line, "CapBnd:"): _, err := fmt.Sscanf(strings.TrimSpace(strings.TrimPrefix(line, "CapBnd:")), "%x", &capBnd) if err != nil { return false, fmt.Errorf("/proc/self/status: failed to parse CapBnd: %w", err) } case strings.HasPrefix(line, "CapPrm:"): _, err := fmt.Sscanf(strings.TrimSpace(strings.TrimPrefix(line, "CapPrm:")), "%x", &capPrm) if err != nil { return false, fmt.Errorf("/proc/self/status: failed to parse CapPrm: %w", err) } } } const capIpcLock uint32 = 0x0000000000004000 log.Printf("capEff: %x, capBnd: %x, capPrm: %x", capEff, capBnd, capPrm) return capEff&capIpcLock != 0, nil } ``` Tests: ```go package linux_cap import ( "testing" "testing/fstest" "github.com/stretchr/testify/assert" ) func TestHasEffIpcLock(t *testing.T) { tests := []struct { name string procStatusFile string want bool err string }{ { name: "effective bit is set", procStatusFile: ` CapInh: 0000000000000000 CapPrm: 0000000000004000 CapEff: 0000000000004000 CapBnd: 00000000a80465fb CapAmb: 0000000000000000 `, want: true, }, { name: "permitted cap is set but not effective", procStatusFile: ` CapInh: 0000000000000000 CapPrm: 0000000000004000 CapEff: 0000000000000000 CapBnd: 00000000a80465fb CapAmb: 0000000000000000 `, want: false, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got, err := HasEffIpcLock(fstest.MapFS{ "proc/self/status": {Data: []byte(tt.procStatusFile)}, }) if tt.err != "" { assert.EqualError(t, err, tt.err) return } assert.NoError(t, err) assert.Equal(t, tt.want, got) }) } } ```