gitee.com/mirrors_u-root/u-root@v7.0.0+incompatible/pkg/securelaunch/launcher/launcher.go (about)

     1  // Copyright 2019 the u-root Authors. All rights reserved
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Package launcher boots the target kernel.
     6  package launcher
     7  
     8  import (
     9  	"fmt"
    10  	"log"
    11  
    12  	"github.com/u-root/u-root/pkg/boot"
    13  	"github.com/u-root/u-root/pkg/boot/kexec"
    14  	"github.com/u-root/u-root/pkg/mount"
    15  	slaunch "github.com/u-root/u-root/pkg/securelaunch"
    16  	"github.com/u-root/u-root/pkg/securelaunch/measurement"
    17  	"github.com/u-root/u-root/pkg/uio"
    18  )
    19  
    20  /* describes the "launcher" section of policy file */
    21  type Launcher struct {
    22  	Type   string            `json:"type"`
    23  	Params map[string]string `json:"params"`
    24  }
    25  
    26  // MeasureKernel calls file collector in measurement pkg that
    27  // hashes kernel, initrd files and even store these hashes in tpm pcrs.
    28  func (l *Launcher) MeasureKernel() error {
    29  
    30  	kernel := l.Params["kernel"]
    31  	initrd := l.Params["initrd"]
    32  
    33  	if e := measurement.HashFile(kernel); e != nil {
    34  		log.Printf("ERR: measure kernel input=%s, err=%v", kernel, e)
    35  		return e
    36  	}
    37  
    38  	if e := measurement.HashFile(initrd); e != nil {
    39  		log.Printf("ERR: measure initrd input=%s, err=%v", initrd, e)
    40  		return e
    41  	}
    42  	return nil
    43  }
    44  
    45  /*
    46   * Boot boots the target kernel based on information provided
    47   * in the "launcher" section of policy file.
    48   *
    49   * Summary of steps:
    50   * - extracts the kernel, initrd and cmdline from the "launcher" section of policy file.
    51   * - measures the kernel and initrd file into the tpmDev (tpm device).
    52   * - mounts the disks where the kernel and initrd file are located.
    53   * - uses kexec to boot into the target kernel.
    54   * returns error
    55   * - if measurement of kernel and initrd fails
    56   * - if mount fails
    57   * - if kexec fails
    58   */
    59  func (l *Launcher) Boot() error {
    60  
    61  	if l.Type != "kexec" {
    62  		log.Printf("launcher: Unsupported launcher type. Exiting.")
    63  		return fmt.Errorf("launcher: Unsupported launcher type. Exiting")
    64  	}
    65  
    66  	slaunch.Debug("Identified Launcher Type = Kexec")
    67  
    68  	// TODO: if kernel and initrd are on different devices.
    69  	kernel := l.Params["kernel"]
    70  	initrd := l.Params["initrd"]
    71  	cmdline := l.Params["cmdline"]
    72  
    73  	k, e := slaunch.GetMountedFilePath(kernel, mount.MS_RDONLY)
    74  	if e != nil {
    75  		log.Printf("launcher: ERR: kernel input %s couldnt be located, err=%v", kernel, e)
    76  		return e
    77  	}
    78  
    79  	i, e := slaunch.GetMountedFilePath(initrd, mount.MS_RDONLY)
    80  	if e != nil {
    81  		log.Printf("launcher: ERR: initrd input %s couldnt be located, err=%v", initrd, e)
    82  		return e
    83  	}
    84  
    85  	slaunch.Debug("********Step 7: kexec called  ********")
    86  	image := &boot.LinuxImage{
    87  		Kernel:  uio.NewLazyFile(k),
    88  		Initrd:  uio.NewLazyFile(i),
    89  		Cmdline: cmdline,
    90  	}
    91  	err := image.Load(false)
    92  	if err != nil {
    93  		log.Printf("kexec -l failed. err: %v", err)
    94  		return err
    95  	}
    96  
    97  	err = kexec.Reboot()
    98  	if err != nil {
    99  		log.Printf("kexec reboot failed. err=%v", err)
   100  		return err
   101  	}
   102  	return nil
   103  }