blob: dd7fdc0bfb4a580b34de48adb5ddcf7a1a9b8018 [file] [log] [blame] [edit]
// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Package cosboot exports utilities for interacting with the COS boot process.
package cosboot
import (
"bytes"
"debug/pe"
"fmt"
"strings"
)
type BootPath string
const (
UnknownBoot = BootPath("UnknownBoot")
GRUBBoot = BootPath("GRUBBoot")
UKI = BootPath("UKI")
)
func isShim(exe []byte) (bool, error) {
exeFile, err := pe.NewFile(bytes.NewReader(exe))
if err != nil {
// Invalid PE file - not shim
return false, nil
}
defer exeFile.Close()
section := exeFile.Section(".sbat")
if section == nil {
// No SBAT - not shim
return false, nil
}
data, err := section.Data()
if err != nil {
return false, err
}
sbat := string(data)
if strings.Contains(sbat, "https://github.com/rhboot/shim") {
return true, nil
}
return false, nil
}
func DiskBootPath(disk string) (BootPath, error) {
bootx64, err := ReadEFIFile(disk, "/efi/boot/bootx64.efi")
if err != nil {
return UnknownBoot, fmt.Errorf("could not read bootx64.efi: %v", err)
}
bootx64IsShim, err := isShim(bootx64)
if err != nil {
return UnknownBoot, fmt.Errorf("could not determine if bootx64.efi is shim: %v", err)
}
if bootx64IsShim {
return GRUBBoot, nil
} else {
return UKI, nil
}
}