diff --git a/efi/grub.go b/efi/grub.go index 6e3d5a3a..49c9bfa6 100644 --- a/efi/grub.go +++ b/efi/grub.go @@ -56,9 +56,12 @@ type grubModule struct { *io.SectionReader } +// grubImageHandle corresponds to a grub image. type grubImageHandle interface { peImageHandle + // Prefix returns the path that grub uses to load its configuration + // from the ESP. Prefix() (string, error) } diff --git a/efi/grub_test.go b/efi/grub_test.go new file mode 100644 index 00000000..4b76f741 --- /dev/null +++ b/efi/grub_test.go @@ -0,0 +1,66 @@ +// -*- Mode: Go; indent-tabs-mode: t -*- + +/* + * Copyright (C) 2023 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package efi_test + +import ( + . "gopkg.in/check.v1" + + . "github.com/snapcore/secboot/efi" +) + +type grubSuite struct{} + +var _ = Suite(&grubSuite{}) + +func (s *grubSuite) TestGrubImageHandlePrefix1(c *C) { + image, err := OpenPeImage(NewFileImage("testdata/amd64/mockgrub.efi")) + c.Assert(err, IsNil) + defer image.Close() + + grubImage := NewGrubImageHandle(image) + + prefix, err := grubImage.Prefix() + c.Check(err, IsNil) + c.Check(prefix, Equals, "/EFI/ubuntu") +} + +func (s *grubSuite) TestGrubImageHandlePrefix2(c *C) { + image, err := OpenPeImage(NewFileImage("testdata/amd64/mockgrub_debian.efi")) + c.Assert(err, IsNil) + defer image.Close() + + grubImage := NewGrubImageHandle(image) + + prefix, err := grubImage.Prefix() + c.Check(err, IsNil) + c.Check(prefix, Equals, "/EFI/debian") +} + +func (s *grubSuite) TestGrubImageHandlePrefixNone(c *C) { + image, err := OpenPeImage(NewFileImage("testdata/amd64/mockgrub_no_prefix.efi")) + c.Assert(err, IsNil) + defer image.Close() + + grubImage := NewGrubImageHandle(image) + + prefix, err := grubImage.Prefix() + c.Check(err, IsNil) + c.Check(prefix, Equals, "") +} diff --git a/efi/pe_test.go b/efi/pe_test.go index 8b0304bc..2098309c 100644 --- a/efi/pe_test.go +++ b/efi/pe_test.go @@ -127,7 +127,7 @@ func (s *peSuite) TestPeImageHandleSbatComponents1(c *C) { func (s *peSuite) TestPeImageHandleSbatComponents2(c *C) { s.testPeImageHandleSbatComponents( - c, "testdata/amd64/mockgrub1.efi.signed.shim.1", + c, "testdata/amd64/mockgrub.efi", []SbatComponent{ {Name: "grub", Generation: 1, VendorName: "Free Software Foundation", VendorPackageName: "grub", VendorVersion: "2.06", VendorUrl: "https://www.gnu.org/software/grub/"}, {Name: "grub.acme", Generation: 1, VendorName: "Acme Corporation", VendorPackageName: "grub", VendorVersion: "1", VendorUrl: "https://acme.invalid/grub"}, @@ -158,7 +158,7 @@ func (s *peSuite) TestPeImageHandleImageDigest1(c *C) { } func (s *peSuite) TestPeImageHandleImageDigest2(c *C) { - s.testPeImageHandleImageDigest(c, "testdata/amd64/mockgrub1.efi.signed.shim.1", crypto.SHA256) + s.testPeImageHandleImageDigest(c, "testdata/amd64/mockgrub.efi", crypto.SHA256) } func (s *peSuite) TestPeImageHandleImageDigestSHA1(c *C) { diff --git a/efi/testdata/amd64/mockgrub.efi b/efi/testdata/amd64/mockgrub.efi new file mode 100644 index 00000000..3648f23c Binary files /dev/null and b/efi/testdata/amd64/mockgrub.efi differ diff --git a/efi/testdata/amd64/mockgrub1.efi.signed.shim.1 b/efi/testdata/amd64/mockgrub1.efi.signed.shim.1 index 6f73204b..2db4a6f3 100644 Binary files a/efi/testdata/amd64/mockgrub1.efi.signed.shim.1 and b/efi/testdata/amd64/mockgrub1.efi.signed.shim.1 differ diff --git a/efi/testdata/amd64/mockgrub_debian.efi b/efi/testdata/amd64/mockgrub_debian.efi new file mode 100644 index 00000000..7a125b1c Binary files /dev/null and b/efi/testdata/amd64/mockgrub_debian.efi differ diff --git a/efi/testdata/amd64/mockgrub_no_prefix.efi b/efi/testdata/amd64/mockgrub_no_prefix.efi new file mode 100644 index 00000000..4ee68074 Binary files /dev/null and b/efi/testdata/amd64/mockgrub_no_prefix.efi differ diff --git a/efi/testdata/amd64/mockshim.efi.signed.1.1.1 b/efi/testdata/amd64/mockshim.efi.signed.1.1.1 index 18f8aee9..77103be2 100644 Binary files a/efi/testdata/amd64/mockshim.efi.signed.1.1.1 and b/efi/testdata/amd64/mockshim.efi.signed.1.1.1 differ diff --git a/efi/testdata/amd64/mockshim.efi.signed.1.2.1+1.1.1 b/efi/testdata/amd64/mockshim.efi.signed.1.2.1+1.1.1 index 70a332d6..11603a72 100644 Binary files a/efi/testdata/amd64/mockshim.efi.signed.1.2.1+1.1.1 and b/efi/testdata/amd64/mockshim.efi.signed.1.2.1+1.1.1 differ diff --git a/efi/testdata/amd64/mockshim_initial_sbat.efi.signed.1.1.1 b/efi/testdata/amd64/mockshim_initial_sbat.efi.signed.1.1.1 index 218f6f83..22e4e142 100644 Binary files a/efi/testdata/amd64/mockshim_initial_sbat.efi.signed.1.1.1 and b/efi/testdata/amd64/mockshim_initial_sbat.efi.signed.1.1.1 differ diff --git a/efi/testdata/amd64/mockshim_no_sbat.efi.signed.1.1.1 b/efi/testdata/amd64/mockshim_no_sbat.efi.signed.1.1.1 index b66819e8..a8b98574 100644 Binary files a/efi/testdata/amd64/mockshim_no_sbat.efi.signed.1.1.1 and b/efi/testdata/amd64/mockshim_no_sbat.efi.signed.1.1.1 differ diff --git a/efi/testdata/amd64/mockshim_no_vendor_cert.efi.signed.1.1.1 b/efi/testdata/amd64/mockshim_no_vendor_cert.efi.signed.1.1.1 index 3ab45db6..50295a97 100644 Binary files a/efi/testdata/amd64/mockshim_no_vendor_cert.efi.signed.1.1.1 and b/efi/testdata/amd64/mockshim_no_vendor_cert.efi.signed.1.1.1 differ diff --git a/efi/testdata/amd64/mockshim_vendor_db.efi.signed.1.1.1 b/efi/testdata/amd64/mockshim_vendor_db.efi.signed.1.1.1 index 0b1a67d4..6a4e06a9 100644 Binary files a/efi/testdata/amd64/mockshim_vendor_db.efi.signed.1.1.1 and b/efi/testdata/amd64/mockshim_vendor_db.efi.signed.1.1.1 differ diff --git a/efi/testdata/src/grub/Makefile b/efi/testdata/src/grub/Makefile index 4647a201..ef68df56 100644 --- a/efi/testdata/src/grub/Makefile +++ b/efi/testdata/src/grub/Makefile @@ -13,6 +13,9 @@ NAME ?= mock SBAT_CSV ?= $(TOPDIR)/sbat.csv CPPFLAGS += -DNAME=\"$(NAME)\" +ifneq ($(origin GRUB_PREFIX), undefined) + CPPFLAGS += -DGRUB_PREFIX=\"$(GRUB_PREFIX)\" +endif sbat_data.o: $(SBAT_CSV) $(CC) $(CFLAGS) -x c -c -o $@ /dev/null @@ -20,7 +23,7 @@ sbat_data.o: $(SBAT_CSV) --set-section-flags .sbat=contents,alloc,load,readonly,data \ $@ -OBJS = main_$(ARCH).o data.o +OBJS = main_$(ARCH).o data.o mods.o ifneq ($(origin WITH_SBAT), undefined) OBJS += sbat_data.o endif @@ -32,4 +35,4 @@ $(NAME).so: $(OBJS) $(LD) $(LDFLAGS) $(OBJS) -o $@ %.efi: %.so - $(OBJCOPY) -j .text -j .data -j .reloc -j .sbat --target=efi-app-$(ARCH) $^ $@ + $(OBJCOPY) -j .text -j .data -j .reloc -j .sbat -jmods --target=efi-app-$(ARCH) $^ $@ diff --git a/efi/testdata/src/grub/mods.S b/efi/testdata/src/grub/mods.S new file mode 100644 index 00000000..3686304d --- /dev/null +++ b/efi/testdata/src/grub/mods.S @@ -0,0 +1,17 @@ + .section mods, "a", %progbits + .balignl 8, 0 +.Lgrub_module_info: + .4byte 0x676d696d + .balignl 8, 0 + .8byte .Lgrub_modules_start - .Lgrub_module_info + .8byte .Lgrub_modules_end - .Lgrub_module_info +.Lgrub_modules_start: +#ifdef GRUB_PREFIX +.Lgrub_prefix_start: + .4byte 3 + .4byte .Lgrub_prefix_end - .Lgrub_prefix_start + .ascii GRUB_PREFIX + .byte 0 +.Lgrub_prefix_end: +#endif +.Lgrub_modules_end: diff --git a/tools/make-efi-testdata/apps.go b/tools/make-efi-testdata/apps.go index 8db3a832..d4ef0fb5 100644 --- a/tools/make-efi-testdata/apps.go +++ b/tools/make-efi-testdata/apps.go @@ -108,13 +108,29 @@ func newMockAppData(srcDir, vendorCertDir string, certs map[string][]byte) []moc signCerts: [][]byte{certs["TestUefiSigning1.1.1"]}, filename: "mockshim_no_sbat.efi.signed.1.1.1", }, + { + path: filepath.Join(srcDir, "grub"), + name: "mockgrub", + makeExtraArgs: []string{ + "GRUB_PREFIX=/EFI/ubuntu", + "WITH_SBAT=1", + }, + filename: "mockgrub.efi", + }, + { + path: filepath.Join(srcDir, "grub"), + name: "mockgrub_debian", + makeExtraArgs: []string{ + "GRUB_PREFIX=/EFI/debian", + "WITH_SBAT=1", + }, + filename: "mockgrub_debian.efi", + }, { path: filepath.Join(srcDir, "grub"), - name: "mockgrub1", + name: "mockgrub_no_prefix", makeExtraArgs: []string{"WITH_SBAT=1"}, - signKeys: []string{filepath.Join(srcDir, "keys", "TestShimVendorSigning.1.key")}, - signCerts: [][]byte{certs["TestShimVendorSigning.1"]}, - filename: "mockgrub1.efi.signed.shim.1", + filename: "mockgrub_no_prefix.efi", }, { path: filepath.Join(srcDir, "kernel"),