github.com/mvdan/u-root-coreutils@v0.0.0-20230122170626-c2eef2898555/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/mvdan/u-root-coreutils/pkg/boot" 13 "github.com/mvdan/u-root-coreutils/pkg/boot/kexec" 14 "github.com/mvdan/u-root-coreutils/pkg/mount" 15 slaunch "github.com/mvdan/u-root-coreutils/pkg/securelaunch" 16 "github.com/mvdan/u-root-coreutils/pkg/securelaunch/measurement" 17 "github.com/mvdan/u-root-coreutils/pkg/uio" 18 ) 19 20 // Launcher 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 hashes the kernel and extends the measurement into a TPM PCR. 27 func (l *Launcher) MeasureKernel() error { 28 kernel := l.Params["kernel"] 29 30 if err := measurement.HashFile(kernel); err != nil { 31 return err 32 } 33 34 return nil 35 } 36 37 // MeasureInitrd hashes the initrd and extends the measurement into a TPM PCR. 38 func (l *Launcher) MeasureInitrd() error { 39 initrd := l.Params["initrd"] 40 41 if err := measurement.HashFile(initrd); err != nil { 42 return err 43 } 44 45 return nil 46 } 47 48 // Boot boots the target kernel based on information provided in the "launcher" 49 // section of the policy file. 50 // 51 // Summary of steps: 52 // - extract the kernel, initrd and cmdline from the "launcher" section of policy file. 53 // - measure the kernel and initrd file into the tpmDev (tpm device). 54 // - mount the disks where the kernel and initrd file are located. 55 // - kexec to boot into the target kernel. 56 // 57 // returns error 58 // - if measurement of kernel and initrd fails 59 // - if mount fails 60 // - if kexec fails 61 func (l *Launcher) Boot() error { 62 if l.Type != "kexec" { 63 log.Printf("launcher: Unsupported launcher type. Exiting.") 64 return fmt.Errorf("launcher: Unsupported launcher type. Exiting") 65 } 66 67 slaunch.Debug("Identified Launcher Type = Kexec") 68 69 // TODO: if kernel and initrd are on different devices. 70 kernel := l.Params["kernel"] 71 initrd := l.Params["initrd"] 72 cmdline := l.Params["cmdline"] 73 74 k, e := slaunch.GetMountedFilePath(kernel, mount.MS_RDONLY) 75 if e != nil { 76 log.Printf("launcher: ERR: kernel input %s couldnt be located, err=%v", kernel, e) 77 return e 78 } 79 80 i, e := slaunch.GetMountedFilePath(initrd, mount.MS_RDONLY) 81 if e != nil { 82 log.Printf("launcher: ERR: initrd input %s couldnt be located, err=%v", initrd, e) 83 return e 84 } 85 86 slaunch.Debug("Calling kexec") 87 image := &boot.LinuxImage{ 88 Kernel: uio.NewLazyFile(k), 89 Initrd: uio.NewLazyFile(i), 90 Cmdline: cmdline, 91 } 92 err := image.Load(false) 93 if err != nil { 94 log.Printf("kexec -l failed. err: %v", err) 95 return err 96 } 97 98 err = kexec.Reboot() 99 if err != nil { 100 log.Printf("kexec reboot failed. err=%v", err) 101 return err 102 } 103 return nil 104 }