blob: 9e5c408be0144842d908ab029792f21c24f0ad72 [file]
// 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) {
efiPath, bootEFI, err := BootEFIFile(disk)
if err != nil {
return UnknownBoot, err
}
bootEFIIsShim, err := isShim(bootEFI)
if err != nil {
return UnknownBoot, fmt.Errorf("could not determine if %s is shim: %v", efiPath, err)
}
if bootEFIIsShim {
return GRUBBoot, nil
} else {
return UKI, nil
}
}