github.com/hugh712/snapd@v0.0.0-20200910133618-1a99902bd583/bootloader/efi/efi_test.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2020 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 efi_test 21 22 import ( 23 "io/ioutil" 24 "os" 25 "path/filepath" 26 "strings" 27 "testing" 28 29 . "gopkg.in/check.v1" 30 31 "github.com/snapcore/snapd/bootloader/bootloadertest" 32 "github.com/snapcore/snapd/bootloader/efi" 33 "github.com/snapcore/snapd/dirs" 34 "github.com/snapcore/snapd/osutil" 35 "github.com/snapcore/snapd/testutil" 36 ) 37 38 type efiVarsSuite struct { 39 testutil.BaseTest 40 41 rootdir string 42 } 43 44 var _ = Suite(&efiVarsSuite{}) 45 46 func TestBoot(t *testing.T) { TestingT(t) } 47 48 func (s *efiVarsSuite) SetUpTest(c *C) { 49 s.BaseTest.SetUpTest(c) 50 51 s.rootdir = c.MkDir() 52 dirs.SetRootDir(s.rootdir) 53 s.AddCleanup(func() { dirs.SetRootDir("") }) 54 55 err := os.MkdirAll(filepath.Join(s.rootdir, "/sys/firmware/efi/efivars"), 0755) 56 c.Assert(err, IsNil) 57 58 efivarfsMount := ` 59 38 24 0:32 / /sys/firmware/efi/efivars rw,nosuid,nodev,noexec,relatime shared:13 - efivarfs efivarfs rw 60 ` 61 restore := osutil.MockMountInfo(strings.TrimSpace(efivarfsMount)) 62 s.AddCleanup(restore) 63 } 64 65 func (s *efiVarsSuite) TestNoEFISystem(c *C) { 66 // no efivarfs 67 osutil.MockMountInfo("") 68 69 _, _, err := efi.ReadVarBytes("my-cool-efi-var") 70 c.Check(err, Equals, efi.ErrNoEFISystem) 71 72 _, _, err = efi.ReadVarString("my-cool-efi-var") 73 c.Check(err, Equals, efi.ErrNoEFISystem) 74 } 75 76 func (s *efiVarsSuite) TestSizeError(c *C) { 77 // mock the efi var file 78 varPath := filepath.Join(s.rootdir, "/sys/firmware/efi/efivars", "my-cool-efi-var") 79 err := ioutil.WriteFile(varPath, []byte("\x06"), 0644) 80 c.Assert(err, IsNil) 81 82 _, _, err = efi.ReadVarBytes("my-cool-efi-var") 83 c.Check(err, ErrorMatches, `cannot read EFI var "my-cool-efi-var": unexpected size: 1`) 84 } 85 86 func (s *efiVarsSuite) TestReadVarBytes(c *C) { 87 // mock the efi var file 88 varPath := filepath.Join(s.rootdir, "/sys/firmware/efi/efivars", "my-cool-efi-var") 89 err := ioutil.WriteFile(varPath, []byte("\x06\x00\x00\x00\x01"), 0644) 90 c.Assert(err, IsNil) 91 92 data, attr, err := efi.ReadVarBytes("my-cool-efi-var") 93 c.Assert(err, IsNil) 94 c.Check(attr, Equals, efi.VariableBootServiceAccess|efi.VariableRuntimeAccess) 95 c.Assert(string(data), Equals, "\x01") 96 } 97 98 func (s *efiVarsSuite) TestReadVarString(c *C) { 99 // mock the efi var file 100 varPath := filepath.Join(s.rootdir, "/sys/firmware/efi/efivars", "my-cool-efi-var") 101 err := ioutil.WriteFile(varPath, []byte("\x06\x00\x00\x00A\x009\x00F\x005\x00C\x009\x004\x009\x00-\x00A\x00B\x008\x009\x00-\x005\x00B\x004\x007\x00-\x00A\x007\x00B\x00F\x00-\x005\x006\x00D\x00D\x002\x008\x00F\x009\x006\x00E\x006\x005\x00\x00\x00"), 0644) 102 c.Assert(err, IsNil) 103 104 data, attr, err := efi.ReadVarString("my-cool-efi-var") 105 c.Assert(err, IsNil) 106 c.Check(attr, Equals, efi.VariableBootServiceAccess|efi.VariableRuntimeAccess) 107 c.Assert(data, Equals, "A9F5C949-AB89-5B47-A7BF-56DD28F96E65") 108 } 109 110 func (s *efiVarsSuite) TestEmpty(c *C) { 111 // mock the efi var file 112 varPath := filepath.Join(s.rootdir, "/sys/firmware/efi/efivars", "my-cool-efi-var") 113 err := ioutil.WriteFile(varPath, []byte("\x06\x00\x00\x00"), 0644) 114 c.Assert(err, IsNil) 115 116 b, _, err := efi.ReadVarBytes("my-cool-efi-var") 117 c.Assert(err, IsNil) 118 c.Check(b, HasLen, 0) 119 120 v, _, err := efi.ReadVarString("my-cool-efi-var") 121 c.Assert(err, IsNil) 122 c.Check(v, HasLen, 0) 123 } 124 125 func (s *efiVarsSuite) TestMockVars(c *C) { 126 restore := efi.MockVars(map[string][]byte{ 127 "a": []byte("\x01"), 128 "b": []byte("\x02"), 129 }, map[string]efi.VariableAttr{ 130 "b": efi.VariableNonVolatile | efi.VariableRuntimeAccess | efi.VariableBootServiceAccess, 131 }) 132 defer restore() 133 134 b, attr, err := efi.ReadVarBytes("a") 135 c.Assert(err, IsNil) 136 c.Check(attr, Equals, efi.VariableBootServiceAccess|efi.VariableRuntimeAccess) 137 c.Assert(string(b), Equals, "\x01") 138 139 b, attr, err = efi.ReadVarBytes("b") 140 c.Assert(err, IsNil) 141 c.Check(attr, Equals, efi.VariableBootServiceAccess|efi.VariableRuntimeAccess|efi.VariableNonVolatile) 142 c.Assert(string(b), Equals, "\x02") 143 144 } 145 146 func (s *efiVarsSuite) TestMockStringVars(c *C) { 147 restore := efi.MockVars(map[string][]byte{ 148 "a": bootloadertest.UTF16Bytes("foo-bar-baz"), 149 }, nil) 150 defer restore() 151 152 v, attr, err := efi.ReadVarString("a") 153 c.Assert(err, IsNil) 154 c.Check(attr, Equals, efi.VariableBootServiceAccess|efi.VariableRuntimeAccess) 155 c.Assert(v, Equals, "foo-bar-baz") 156 } 157 158 func (s *efiVarsSuite) TestMockVarsNoEFISystem(c *C) { 159 restore := efi.MockVars(nil, nil) 160 defer restore() 161 162 _, _, err := efi.ReadVarBytes("a") 163 c.Check(err, Equals, efi.ErrNoEFISystem) 164 } 165 166 func (s *efiVarsSuite) TestStringOddSize(c *C) { 167 restore := efi.MockVars(map[string][]byte{ 168 "a": []byte("\x0a"), 169 }, nil) 170 defer restore() 171 172 _, _, err := efi.ReadVarString("a") 173 c.Check(err, ErrorMatches, `EFI var "a" is not a valid UTF16 string, it has an extra byte`) 174 }