Skip to content

Commit 2839c9a

Browse files
committed
feat: add tests and docs for yama sub package
1 parent 7a41512 commit 2839c9a

File tree

3 files changed

+80
-5
lines changed

3 files changed

+80
-5
lines changed

lsm.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ func GetLoadedModules() map[string]bool {
2323
modules["selinux"] = selinux.IsSelinuxEnabled()
2424
appArmorEnabled, _ := apparmor.IsAppArmorEnabled()
2525
modules["apparmor"] = appArmorEnabled
26-
yamaEnabled, _ := yama.IsYamaEnabled()
26+
yamaEnabled, _ := yama.IsEnabled()
2727
modules["yama"] = yamaEnabled
2828
return modules
2929
}

yama/yama.go

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,63 @@ package yama
22

33
import (
44
"io/ioutil"
5+
"os"
6+
"strconv"
57
"strings"
68
)
79

8-
const (
10+
var (
911
ptrace_scope_file = "/proc/sys/kernel/yama/ptrace_scope"
1012
)
1113

12-
func IsYamaEnabled() (bool, error) {
13-
body, err := ioutil.ReadFile(ptrace_scope_file)
14+
func parsePtraceScopeFile(path string) (string, error) {
15+
if body, err := ioutil.ReadFile(path); err == nil {
16+
//Scope: from 0 (classic/disabled) to 4
17+
return strings.TrimSuffix(string(body), "\n"), nil
18+
} else if os.IsNotExist(err) {
19+
return "0", nil
20+
} else {
21+
return "", err
22+
}
23+
}
24+
25+
// IsEnabled checks whether YAMA is enabled or not
26+
func IsEnabled() (bool, error) {
27+
scope, err := parsePtraceScopeFile(ptrace_scope_file)
1428
if err != nil {
1529
return false, err
1630
}
1731
//Scope: from 0 (classic/disabled) to 4
18-
scope := strings.TrimSuffix(string(body), "\n")
1932
if scope == "1" || scope == "2" || scope == "3" {
2033
return true, nil
2134
}
2235
return false, nil
2336
}
37+
38+
// Scope gets the current YAMA scope of the system
39+
func Scope() (int, error) {
40+
scope, err := parsePtraceScopeFile(ptrace_scope_file)
41+
if err != nil {
42+
return 0, err
43+
}
44+
return strconv.Atoi(scope)
45+
}
46+
47+
// ScopeDecription describes a given scope
48+
//
49+
// Kernel docs:
50+
// https://www.kernel.org/doc/html/v4.15/admin-guide/LSM/Yama.html
51+
func ScopeDescription(scope string) string {
52+
switch scope {
53+
case "0":
54+
return "classic ptrace permissions"
55+
case "1":
56+
return "restricted ptrace"
57+
case "2":
58+
return "admin-only attach"
59+
case "3":
60+
return "no attach"
61+
default:
62+
return "unknown"
63+
}
64+
}

yama/yama_test.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package yama
2+
3+
import (
4+
"io/ioutil"
5+
"testing"
6+
)
7+
8+
func TestIsEnabled(t *testing.T) {
9+
var yamaFileTest = []struct {
10+
name string
11+
fileContent string
12+
out bool
13+
}{
14+
{"Not enabled, with default value", "0\n", false},
15+
{"Enabled, restricted", "1\n", true},
16+
}
17+
for _, tt := range yamaFileTest {
18+
t.Run(tt.name, func(t *testing.T) {
19+
f, err := ioutil.TempFile("", "testyamafile")
20+
if err != nil {
21+
t.Error(err)
22+
}
23+
ioutil.WriteFile(f.Name(), []byte(tt.fileContent), 0644)
24+
ptrace_scope_file = f.Name()
25+
enabled, err := IsEnabled()
26+
if err != nil {
27+
t.Error(err)
28+
}
29+
if enabled != tt.out {
30+
t.Errorf("got %t, want %t", enabled, tt.out)
31+
}
32+
})
33+
}
34+
}

0 commit comments

Comments
 (0)