github.com/u-root/u-root@v7.0.1-0.20200915234505-ad7babab0a8e+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 }