# 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)
})
}
}
```