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