Skip to content

Commit d630be0

Browse files
committed
security : check /proc is mounted with secure options
Signed-off-by: Shahriyar Jalayeri <[email protected]>
1 parent b30a2c3 commit d630be0

File tree

2 files changed

+66
-1
lines changed

2 files changed

+66
-1
lines changed

Diff for: tests/sec/remote.go

+36
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package sec_test
22

33
import (
4+
"encoding/json"
45
"fmt"
56
"io"
67
"os"
@@ -11,6 +12,12 @@ import (
1112
"github.com/lf-edge/eden/pkg/utils"
1213
)
1314

15+
type mount struct {
16+
Point string `json:"point"`
17+
Type string `json:"type"`
18+
Options string `json:"options"`
19+
}
20+
1421
type remoteNode struct {
1522
openEVEC *openevec.OpenEVEC
1623
}
@@ -86,3 +93,32 @@ func (node *remoteNode) readFile(fileName string) ([]byte, error) {
8693
command := fmt.Sprintf("cat %s", fileName)
8794
return node.runCommand(command)
8895
}
96+
97+
func (node *remoteNode) getMountPoints(mtype string) ([]mount, error) {
98+
mount_command := "mount -l"
99+
if mtype != "" {
100+
mount_command = fmt.Sprintf("mount -l -t %s", mtype)
101+
}
102+
103+
command := mount_command + ` | awk '
104+
BEGIN { print " [ "}
105+
{
106+
printf " %s {\"point\": \"%s\", \"type\": \"%s\", \"options\": \"%s\"}", separator, $3, $5, $6;
107+
separator = ",";
108+
}
109+
END { print " ] " }
110+
'`
111+
112+
out, err := node.runCommand(command)
113+
if err != nil {
114+
return nil, err
115+
}
116+
117+
var mounts []mount
118+
if err := json.Unmarshal(out, &mounts); err != nil {
119+
return nil, err
120+
121+
}
122+
123+
return mounts, nil
124+
}

Diff for: tests/sec/sec_test.go

+30-1
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@ func TestMain(m *testing.M) {
9393
func TestAppArmorEnabled(t *testing.T) {
9494
log.Println("TestAppArmorEnabled started")
9595
defer log.Println("TestAppArmorEnabled finished")
96-
t.Parallel()
9796

9897
edgeNode := tc.GetEdgeNode(tc.WithTest(t))
9998
tc.WaitForState(edgeNode, 60)
@@ -108,3 +107,33 @@ func TestAppArmorEnabled(t *testing.T) {
108107
t.Fatal("AppArmor is not enabled")
109108
}
110109
}
110+
111+
func TestCheckProcMountOptions(t *testing.T) {
112+
log.Println("TestCheckProcMountOptions started")
113+
defer log.Println("TestCheckProcMountOptions finished")
114+
115+
edgeNode := tc.GetEdgeNode(tc.WithTest(t))
116+
tc.WaitForState(edgeNode, 60)
117+
118+
procMounts, err := rnode.getMountPoints("proc")
119+
if err != nil {
120+
t.Fatal(err)
121+
}
122+
123+
for _, mount := range procMounts {
124+
// check if mount options contains nosuid, nodev and noexec, hidepid=2
125+
if !strings.Contains(mount.Options, "nosuid") {
126+
t.Fatalf("Mount options for /proc on %s doesn't contain nosuid", mount.Point)
127+
}
128+
if !strings.Contains(mount.Options, "nodev") {
129+
t.Fatalf("Mount options for /proc on %s doesn't contain nodev", mount.Point)
130+
}
131+
if !strings.Contains(mount.Options, "noexec") {
132+
t.Fatalf("Mount options for /proc on %s doesn't contain noexec", mount.Point)
133+
}
134+
if !strings.Contains(mount.Options, "hidepid=2") {
135+
// TODO: set hidepid=2 and make this a fatal error
136+
t.Logf("[!!!WARNING!!!] Mount options for /proc on %s doesn't contain hidepid=2", mount.Point)
137+
}
138+
}
139+
}

0 commit comments

Comments
 (0)