Skip to content

Commit

Permalink
[WIP] Add support for running confidential WCOW UVMs
Browse files Browse the repository at this point in the history
Initial changes to allow creating confidential WCOW UVMs. uvmboot tool is also updated for
easier command line testing of confidential UVMs.

Signed-off-by: Amit Barve <ambarve@microsoft.com>
  • Loading branch information
ambarve committed Feb 28, 2025
1 parent 002d003 commit c6e6575
Show file tree
Hide file tree
Showing 8 changed files with 391 additions and 60 deletions.
2 changes: 2 additions & 0 deletions internal/hcs/schema2/chipset.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,6 @@ type Chipset struct {

// LinuxKernelDirect - Added in v2.2 Builds >=181117
LinuxKernelDirect *LinuxKernelDirect `json:"LinuxKernelDirect,omitempty"`

FirmwareFile *FirmwareFile `json:"FirmwareFile,omitempty"`
}
5 changes: 5 additions & 0 deletions internal/hcs/schema2/firmware.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package hcsschema

type FirmwareFile struct {
Parameters []byte `json:"Parameters,omitempty"`
}
2 changes: 2 additions & 0 deletions internal/hcs/schema2/windows_crash_reporting.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@ type WindowsCrashReporting struct {
DumpFileName string `json:"DumpFileName,omitempty"`

MaxDumpSize int64 `json:"MaxDumpSize,omitempty"`

DumpType string `json:"DumpType,omitempty"`
}
156 changes: 156 additions & 0 deletions internal/tools/uvmboot/conf_wcow.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
//go:build windows

package main

import (
"context"
"os"

"github.com/containerd/console"
"github.com/urfave/cli"

"github.com/Microsoft/hcsshim/internal/cmd"
"github.com/Microsoft/hcsshim/internal/log"
"github.com/Microsoft/hcsshim/internal/uvm"
)

const (
confidentialArgName = "confidential"
vmgsFilePathArgName = "vmgs-path"
disableSBArgName = "disable-secure-boot"
isolationTypeArgName = "isolation-type"
)

var (
cwcowBootVHD string
cwcowEFIVHD string
cwcowScratchVHD string
cwcowEnableConfidential bool

Check failure on line 28 in internal/tools/uvmboot/conf_wcow.go

View workflow job for this annotation

GitHub Actions / lint (windows)

var `cwcowEnableConfidential` is unused (unused)
cwcowVMGSPath string
cwcowDisableSecureBoot bool
cwcowIsolationMode string
)

var cwcowCommand = cli.Command{
Name: "cwcow",
Usage: "boot a confidential WCOW UVM",
Flags: []cli.Flag{
cli.StringFlag{
Name: "exec",
Usage: "Command to execute in the UVM.",
Destination: &wcowCommandLine,
},
cli.BoolFlag{
Name: "tty,t",
Usage: "create the process in the UVM with a TTY enabled",
Destination: &wcowUseTerminal,
},
cli.StringFlag{
Name: "efi-vhd",
Usage: "VHD at the provided path MUST have the EFI boot partition and be properly formatted for UEFI boot.",
Destination: &cwcowEFIVHD,
Required: true,
},
cli.StringFlag{
Name: "boot-cim-vhd",
Usage: "A VHD containing the block CIM that contains the OS files.",
Destination: &cwcowBootVHD,
Required: true,
},
cli.StringFlag{
Name: "scratch-vhd",
Usage: "A scratch VHD for the UVM",
Destination: &cwcowScratchVHD,
Required: true,
},
cli.StringFlag{
Name: vmgsFilePathArgName,
Usage: "VMGS file path (only applies when confidential mode is enabled). This option is only applicable in confidential mode.",
Destination: &cwcowVMGSPath,
Required: true,
},
cli.BoolFlag{
Name: disableSBArgName,
Usage: "Disables Secure Boot when running the UVM in confidential mode. This option is only applicable in confidential mode.",
Destination: &cwcowDisableSecureBoot,
},
cli.StringFlag{
Name: isolationTypeArgName,
Usage: "VM Isolation type (one of Disabled, GuestStateOnly, VirtualizationBasedSecurity, SecureNestedPaging or TrustDomain). Applicable only when using the confidential mode. This option is only applicable in confidential mode.",
Destination: &cwcowIsolationMode,
Required: true,
},
},
Action: func(c *cli.Context) error {
runMany(c, func(id string) error {
options := uvm.NewDefaultOptionsWCOW(id, "")
options.ProcessorCount = 2
options.MemorySizeInMB = 2048
options.AllowOvercommit = false
options.EnableDeferredCommit = false
options.DumpDirectoryPath = "C:\\crashdumps"

// confidential specific options
options.SecurityPolicyEnabled = true
options.DisableSecureBoot = cwcowDisableSecureBoot
options.GuestStateFilePath = cwcowVMGSPath
options.IsolationType = cwcowIsolationMode
// always enable graphics console with uvmboot - helps with testing/debugging
options.EnableGraphicsConsole = true
options.BootFiles = &uvm.WCOWBootFiles{
BootType: uvm.BlockCIMBoot,
BlockCIMFiles: &uvm.BlockCIMBootFiles{
BootCIMVHDPath: cwcowBootVHD,
EFIVHDPath: cwcowEFIVHD,
ScratchVHDPath: cwcowScratchVHD,
},
}
setGlobalOptions(c, options.Options)
tempDir, err := os.MkdirTemp("", "uvmboot")
if err != nil {
return err
}
defer os.RemoveAll(tempDir)

vm, err := uvm.CreateWCOW(context.TODO(), options)
if err != nil {
return err
}
defer vm.Close()
if err := vm.Start(context.TODO()); err != nil {
return err
}
if wcowCommandLine != "" {
cmd := cmd.Command(vm, "cmd.exe", "/c", wcowCommandLine)
cmd.Spec.User.Username = `NT AUTHORITY\SYSTEM`
cmd.Log = log.L.Dup()
if wcowUseTerminal {
cmd.Spec.Terminal = true
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
con, err := console.ConsoleFromFile(os.Stdin)
if err == nil {
err = con.SetRaw()
if err != nil {
return err
}
defer func() {
_ = con.Reset()
}()
}
} else {
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stdout
}
err = cmd.Run()
if err != nil {
return err
}
}
_ = vm.Terminate(context.TODO())
_ = vm.Wait()
return vm.ExitError()
})
return nil
},
}
6 changes: 6 additions & 0 deletions internal/tools/uvmboot/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ func main() {
app.Commands = []cli.Command{
lcowCommand,
wcowCommand,
cwcowCommand,
}

app.Before = func(c *cli.Context) error {
Expand Down Expand Up @@ -120,6 +121,11 @@ func setGlobalOptions(c *cli.Context, options *uvm.Options) {
if c.GlobalIsSet(enableDeferredCommitArgName) {
options.EnableDeferredCommit = c.GlobalBool(enableDeferredCommitArgName)
}
if c.GlobalIsSet(enableDeferredCommitArgName) {
options.EnableDeferredCommit = c.GlobalBool(enableDeferredCommitArgName)
}
// Always set the console pipe in uvmboot, it helps with testing/debugging
options.ConsolePipe = "\\\\.\\pipe\\uvmpipe"
}

// todo: add a context here to propagate cancel/timeouts to runFunc uvm
Expand Down
6 changes: 6 additions & 0 deletions internal/uvm/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@ type Options struct {
NumaProcessorCounts []uint32
// NumaMemoryBlocksCounts are the number of memory blocks per vNUMA node.
NumaMemoryBlocksCounts []uint64

EnableGraphicsConsole bool // If true, enable a graphics console for the utility VM
ConsolePipe string // The named pipe path to use for the serial console (COM1). eg \\.\pipe\vmpipe
}

func verifyWCOWBootFiles(bootFiles *WCOWBootFiles) error {
Expand Down Expand Up @@ -178,6 +181,9 @@ func verifyOptions(_ context.Context, options interface{}) error {
if err := verifyWCOWBootFiles(opts.BootFiles); err != nil {
return err
}
if opts.SecurityPolicyEnabled && opts.GuestStateFilePath == "" {
return fmt.Errorf("GuestStateFilePath must be provided when enabling security policy")
}
}
return nil
}
Expand Down
4 changes: 0 additions & 4 deletions internal/uvm/create_lcow.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,6 @@ type OptionsLCOW struct {
KernelDirect bool // Skip UEFI and boot directly to `kernel`
RootFSFile string // Filename under `BootFilesPath` for the UVMs root file system. Defaults to `InitrdFile`
KernelBootOptions string // Additional boot options for the kernel
EnableGraphicsConsole bool // If true, enable a graphics console for the utility VM
ConsolePipe string // The named pipe path to use for the serial console. eg \\.\pipe\vmpipe
UseGuestConnection bool // Whether the HCS should connect to the UVM's GCS. Defaults to true
ExecCommandLine string // The command line to exec from init. Defaults to GCS
ForwardStdout bool // Whether stdout will be forwarded from the executed program. Defaults to false
Expand Down Expand Up @@ -164,8 +162,6 @@ func NewDefaultOptionsLCOW(id, owner string) *OptionsLCOW {
KernelDirect: kernelDirectSupported,
RootFSFile: InitrdFile,
KernelBootOptions: "",
EnableGraphicsConsole: false,
ConsolePipe: "",
UseGuestConnection: true,
ExecCommandLine: fmt.Sprintf("/bin/gcs -v4 -log-format json -loglevel %s", logrus.StandardLogger().Level.String()),
ForwardStdout: false,
Expand Down
Loading

0 comments on commit c6e6575

Please sign in to comment.