github.com/xyproto/u-root@v6.0.1-0.20200302025726-5528e0c77a3c+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 /* 28 * Boot boots the target kernel based on information provided 29 * in the "launcher" section of policy file. 30 * 31 * Summary of steps: 32 * - extracts the kernel, initrd and cmdline from the "launcher" section of policy file. 33 * - measures the kernel and initrd file into the tpmDev (tpm device). 34 * - mounts the disks where the kernel and initrd file are located. 35 * - uses kexec to boot into the target kernel. 36 * returns error 37 * - if measurement of kernel and initrd fails 38 * - if mount fails 39 * - if kexec fails 40 */ 41 func (l *Launcher) Boot(tpmDev io.ReadWriteCloser) error { 42 43 if l.Type != "kexec" { 44 log.Printf("launcher: Unsupported launcher type. Exiting.") 45 return fmt.Errorf("launcher: Unsupported launcher type. Exiting") 46 } 47 48 slaunch.Debug("Identified Launcher Type = Kexec") 49 50 // TODO: if kernel and initrd are on different devices. 51 kernel := l.Params["kernel"] 52 initrd := l.Params["initrd"] 53 cmdline := l.Params["cmdline"] 54 55 slaunch.Debug("********Step 6: Measuring kernel, initrd ********") 56 if e := measurement.HashFile(tpmDev, kernel); e != nil { 57 log.Printf("launcher: ERR: measure kernel input=%s, err=%v", kernel, e) 58 return e 59 } 60 61 if e := measurement.HashFile(tpmDev, initrd); e != nil { 62 log.Printf("launcher: ERR: measure initrd input=%s, err=%v", initrd, e) 63 return e 64 } 65 66 k, _, e := slaunch.GetMountedFilePath(kernel, mount.MS_RDONLY) 67 if e != nil { 68 log.Printf("launcher: ERR: kernel input %s couldnt be located, err=%v", kernel, e) 69 return e 70 } 71 72 i, _, e := slaunch.GetMountedFilePath(initrd, mount.MS_RDONLY) 73 if e != nil { 74 log.Printf("launcher: ERR: initrd input %s couldnt be located, err=%v", initrd, e) 75 return e 76 } 77 78 slaunch.Debug("********Step 7: kexec called ********") 79 image := &boot.LinuxImage{ 80 Kernel: uio.NewLazyFile(k), 81 Initrd: uio.NewLazyFile(i), 82 Cmdline: cmdline, 83 } 84 if err := image.Load(false); err != nil { 85 log.Printf("kexec -l failed. err: %v", err) 86 return err 87 } 88 89 err := kexec.Reboot() 90 if err != nil { 91 log.Printf("kexec reboot failed. err=%v", err) 92 } 93 return nil 94 }