//go:build linux package platform import ( "encoding/json" "os" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "golang.org/x/sys/unix" ) func TestReadLandlockPolicyFromFile(t *testing.T) { policy := &landlockExecPolicy{ Command: "/usr/bin/node", Args: []string{"index.js"}, Env: []string{"HOME=/home/user", "PATH=/usr/bin"}, FilesystemRules: []landlockPathRule{ {Path: "/usr", Access: 0x0C}, {Path: "/tmp", Access: 0xFF}, }, DenyPaths: []denyPathEntry{ {Path: "/home/user/.ssh/", Mode: denyBoth}, }, DenyExecPaths: []string{"/usr/bin/curl"}, AllowPTY: true, SkipPIDNamespace: false, SkipIPCNamespace: false, } // Write policy to temp file f, err := os.CreateTemp("", "pmg-test-policy-*.json") require.NoError(t, err) defer func() { if err := os.Remove(f.Name()); err != nil { t.Logf("remove temp policy: %v", err) } }() err = json.NewEncoder(f).Encode(policy) require.NoError(t, err) require.NoError(t, f.Close()) got, err := readLandlockPolicyFromFile(f.Name()) require.NoError(t, err) assert.Equal(t, "/usr/bin/node", got.Command) assert.Equal(t, []string{"index.js"}, got.Args) assert.Equal(t, []string{"HOME=/home/user", "PATH=/usr/bin"}, got.Env) assert.Len(t, got.FilesystemRules, 2) assert.Equal(t, "/usr", got.FilesystemRules[0].Path) assert.Equal(t, uint64(0x0C), got.FilesystemRules[0].Access) assert.Len(t, got.DenyPaths, 1) assert.Equal(t, "/home/user/.ssh/", got.DenyPaths[0].Path) assert.Equal(t, denyBoth, got.DenyPaths[0].Mode) assert.Equal(t, []string{"/usr/bin/curl"}, got.DenyExecPaths) assert.True(t, got.AllowPTY) assert.False(t, got.SkipPIDNamespace) assert.False(t, got.SkipIPCNamespace) } func TestReadLandlockPolicyFromFile_Invalid(t *testing.T) { tests := []struct { name string input string }{ { name: "invalid JSON", input: `{this is not json}`, }, { name: "empty command", input: `{"command":"","args":[]}`, }, { name: "empty input", input: ``, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { f, err := os.CreateTemp("", "pmg-test-policy-*.json") require.NoError(t, err) defer func() { if err := os.Remove(f.Name()); err != nil { t.Logf("remove temp policy: %v", err) } }() _, err = f.WriteString(tt.input) require.NoError(t, err) require.NoError(t, f.Close()) _, err = readLandlockPolicyFromFile(f.Name()) assert.Error(t, err) }) } } func TestReadLandlockPolicyFromFile_EmptyPath(t *testing.T) { _, err := readLandlockPolicyFromFile("") assert.Error(t, err) assert.Contains(t, err.Error(), "policy file path is empty") } func TestReadLandlockPolicyFromFile_NonexistentFile(t *testing.T) { _, err := readLandlockPolicyFromFile("/tmp/nonexistent-policy-file-12345.json") assert.Error(t, err) } func TestLandlockBuildCloneflags_Default(t *testing.T) { policy := &landlockExecPolicy{ Command: "/bin/sh", SkipPIDNamespace: false, SkipIPCNamespace: false, } flags := landlockBuildCloneflags(policy) expected := uintptr(unix.CLONE_NEWPID | unix.CLONE_NEWIPC | unix.CLONE_NEWNS) assert.Equal(t, expected, flags) } func TestLandlockBuildCloneflags_SkipPID(t *testing.T) { policy := &landlockExecPolicy{ Command: "/bin/sh", SkipPIDNamespace: true, SkipIPCNamespace: false, } flags := landlockBuildCloneflags(policy) expected := uintptr(unix.CLONE_NEWIPC) assert.Equal(t, expected, flags) } func TestLandlockBuildCloneflags_SkipIPC(t *testing.T) { policy := &landlockExecPolicy{ Command: "/bin/sh", SkipPIDNamespace: false, SkipIPCNamespace: true, } flags := landlockBuildCloneflags(policy) expected := uintptr(unix.CLONE_NEWPID | unix.CLONE_NEWNS) assert.Equal(t, expected, flags) } func TestLandlockBuildCloneflags_SkipBoth(t *testing.T) { policy := &landlockExecPolicy{ Command: "/bin/sh", SkipPIDNamespace: true, SkipIPCNamespace: true, } flags := landlockBuildCloneflags(policy) assert.Equal(t, uintptr(0), flags) }