github.com/meulengracht/snapd@v0.0.0-20210719210640-8bde69bcc84e/sandbox/selinux/label_linux_test.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2018 Canonical Ltd 5 * 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 3 as 8 * published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 * 18 */ 19 20 package selinux_test 21 22 import ( 23 "fmt" 24 "io/ioutil" 25 "os/exec" 26 "path/filepath" 27 28 "gopkg.in/check.v1" 29 30 "github.com/snapcore/snapd/sandbox/selinux" 31 "github.com/snapcore/snapd/testutil" 32 ) 33 34 type labelSuite struct { 35 path string 36 } 37 38 var _ = check.Suite(&labelSuite{}) 39 40 func (l *labelSuite) SetUpTest(c *check.C) { 41 l.path = filepath.Join(c.MkDir(), "foo") 42 ioutil.WriteFile(l.path, []byte("foo"), 0644) 43 } 44 45 func (l *labelSuite) TestVerifyHappyOk(c *check.C) { 46 cmd := testutil.MockCommand(c, "matchpathcon", "") 47 defer cmd.Restore() 48 49 ok, err := selinux.VerifyPathContext(l.path) 50 c.Assert(err, check.IsNil) 51 c.Assert(ok, check.Equals, true) 52 c.Assert(cmd.Calls(), check.DeepEquals, [][]string{ 53 {"matchpathcon", "-V", l.path}, 54 }) 55 } 56 57 func (l *labelSuite) TestVerifyFailGibberish(c *check.C) { 58 cmd := testutil.MockCommand(c, "matchpathcon", "echo gibberish; exit 1 ") 59 defer cmd.Restore() 60 61 ok, err := selinux.VerifyPathContext(l.path) 62 c.Assert(err, check.ErrorMatches, "exit status 1") 63 c.Assert(ok, check.Equals, false) 64 } 65 66 func (l *labelSuite) TestVerifyFailStatus(c *check.C) { 67 cmd := testutil.MockCommand(c, "matchpathcon", "echo gibberish; exit 5 ") 68 defer cmd.Restore() 69 70 ok, err := selinux.VerifyPathContext(l.path) 71 c.Assert(err, check.ErrorMatches, "exit status 5") 72 c.Assert(ok, check.Equals, false) 73 } 74 75 func (l *labelSuite) TestVerifyFailNoPath(c *check.C) { 76 cmd := testutil.MockCommand(c, "matchpathcon", ``) 77 defer cmd.Restore() 78 79 ok, err := selinux.VerifyPathContext("does-not-exist") 80 c.Assert(err, check.ErrorMatches, ".* does-not-exist: no such file or directory") 81 c.Assert(ok, check.Equals, false) 82 } 83 84 func (l *labelSuite) TestVerifyFailNoTool(c *check.C) { 85 if _, err := exec.LookPath("matchpathcon"); err == nil { 86 c.Skip("matchpathcon found in $PATH") 87 } 88 ok, err := selinux.VerifyPathContext(l.path) 89 c.Assert(err, check.ErrorMatches, `exec: "matchpathcon": executable file not found in \$PATH`) 90 c.Assert(ok, check.Equals, false) 91 } 92 93 func (l *labelSuite) TestVerifyHappyMismatch(c *check.C) { 94 cmd := testutil.MockCommand(c, "matchpathcon", fmt.Sprintf(` 95 echo %s has context unconfined_u:object_r:user_home_t:s0, should be unconfined_u:object_r:snappy_home_t:s0 96 exit 1`, l.path)) 97 defer cmd.Restore() 98 99 ok, err := selinux.VerifyPathContext(l.path) 100 c.Assert(err, check.IsNil) 101 c.Assert(ok, check.Equals, false) 102 } 103 104 func (l *labelSuite) TestRestoreHappy(c *check.C) { 105 cmd := testutil.MockCommand(c, "restorecon", "") 106 defer cmd.Restore() 107 108 err := selinux.RestoreContext(l.path, selinux.RestoreMode{}) 109 c.Assert(err, check.IsNil) 110 c.Assert(cmd.Calls(), check.DeepEquals, [][]string{ 111 {"restorecon", l.path}, 112 }) 113 114 cmd.ForgetCalls() 115 116 err = selinux.RestoreContext(l.path, selinux.RestoreMode{Recursive: true}) 117 c.Assert(err, check.IsNil) 118 c.Assert(cmd.Calls(), check.DeepEquals, [][]string{ 119 {"restorecon", "-R", l.path}, 120 }) 121 } 122 123 func (l *labelSuite) TestRestoreFailNoTool(c *check.C) { 124 if _, err := exec.LookPath("matchpathcon"); err == nil { 125 c.Skip("matchpathcon found in $PATH") 126 } 127 err := selinux.RestoreContext(l.path, selinux.RestoreMode{}) 128 c.Assert(err, check.ErrorMatches, `exec: "restorecon": executable file not found in \$PATH`) 129 } 130 131 func (l *labelSuite) TestRestoreFail(c *check.C) { 132 cmd := testutil.MockCommand(c, "restorecon", "exit 1") 133 defer cmd.Restore() 134 135 err := selinux.RestoreContext(l.path, selinux.RestoreMode{}) 136 c.Assert(err, check.ErrorMatches, "exit status 1") 137 138 err = selinux.RestoreContext("does-not-exist", selinux.RestoreMode{}) 139 c.Assert(err, check.ErrorMatches, ".* does-not-exist: no such file or directory") 140 }