github.com/andrewsun2898/u-root@v6.0.1-0.20200616011413-4b2895c1b815+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 "io" 11 "log" 12 13 "github.com/u-root/u-root/pkg/boot" 14 "github.com/u-root/u-root/pkg/boot/kexec" 15 "github.com/u-root/u-root/pkg/mount" 16 slaunch "github.com/u-root/u-root/pkg/securelaunch" 17 "github.com/u-root/u-root/pkg/securelaunch/measurement" 18 "github.com/u-root/u-root/pkg/uio" 19 ) 20 21 /* describes the "launcher" section of policy file */ 22 type Launcher struct { 23 Type string `json:"type"` 24 Params map[string]string `json:"params"` 25 } 26 27 // MeasureKernel calls file collector in measurement pkg that 28 // hashes kernel, initrd files and even store these hashes in tpm pcrs. 29 func (l *Launcher) MeasureKernel(tpmDev io.ReadWriteCloser) error { 30 31 kernel := l.Params["kernel"] 32 initrd := l.Params["initrd"] 33 34 if e := measurement.HashFile(tpmDev, kernel); e != nil { 35 log.Printf("ERR: measure kernel input=%s, err=%v", kernel, e) 36 return e 37 } 38 39 if e := measurement.HashFile(tpmDev, initrd); e != nil { 40 log.Printf("ERR: measure initrd input=%s, err=%v", initrd, e) 41 return e 42 } 43 return nil 44 } 45 46 /* 47 * Boot boots the target kernel based on information provided 48 * in the "launcher" section of policy file. 49 * 50 * Summary of steps: 51 * - extracts the kernel, initrd and cmdline from the "launcher" section of policy file. 52 * - measures the kernel and initrd file into the tpmDev (tpm device). 53 * - mounts the disks where the kernel and initrd file are located. 54 * - uses kexec to boot into the target kernel. 55 * returns error 56 * - if measurement of kernel and initrd fails 57 * - if mount fails 58 * - if kexec fails 59 */ 60 func (l *Launcher) Boot(tpmDev io.ReadWriteCloser) error { 61 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("********Step 7: kexec called ********") 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 }