Skip to content

Commit 5d6a794

Browse files
committed
C-WCOW: PspDriver and hostdata changes in SecurityPolicy pkg
Signed-off-by: Mahati Chamarthy <[email protected]>
1 parent 41a8a2c commit 5d6a794

File tree

10 files changed

+83
-108
lines changed

10 files changed

+83
-108
lines changed

cmd/gcs-sidecar/main.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import (
1515
"github.com/Microsoft/hcsshim/internal/gcs/prot"
1616
shimlog "github.com/Microsoft/hcsshim/internal/log"
1717
"github.com/Microsoft/hcsshim/internal/oc"
18-
"github.com/Microsoft/hcsshim/internal/pspdriver"
1918
"github.com/Microsoft/hcsshim/pkg/securitypolicy"
2019
"github.com/sirupsen/logrus"
2120
"go.opencensus.io/trace"
@@ -214,7 +213,7 @@ func main() {
214213
return
215214
}
216215

217-
if err := pspdriver.StartPSPDriver(ctx); err != nil {
216+
if err := securitypolicy.StartPSPDriver(ctx); err != nil {
218217
// When error happens, pspdriver.GetPspDriverError() returns true.
219218
// In that case, gcs-sidecar should keep the initial "deny" policy
220219
// and reject all requests from the host.

internal/gcs-sidecar/handlers.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -551,9 +551,12 @@ func (b *Bridge) modifySettings(req *request) (err error) {
551551
case guestresource.ResourceTypeSecurityPolicy:
552552
securityPolicyRequest := modifyGuestSettingsRequest.Settings.(*guestresource.ConfidentialOptions)
553553
log.G(ctx).Tracef("WCOWConfidentialOptions: { %v}", securityPolicyRequest)
554-
err := b.hostState.SetWCOWConfidentialUVMOptions(req.ctx, securityPolicyRequest)
554+
err := b.hostState.securityOptions.SetConfidentialOptions(ctx,
555+
securityPolicyRequest.EnforcerType,
556+
securityPolicyRequest.EncodedSecurityPolicy,
557+
securityPolicyRequest.EncodedUVMReference)
555558
if err != nil {
556-
return errors.Wrap(err, "error creating enforcer")
559+
return errors.Wrap(err, "Failed to set Confidentia UVM Options")
557560
}
558561
// Send response back to shim
559562
resp := &prot.ResponseBase{

internal/gcs-sidecar/host.go

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,8 @@ import (
1212
hcsschema "github.com/Microsoft/hcsshim/internal/hcs/schema2"
1313
"github.com/Microsoft/hcsshim/internal/log"
1414
"github.com/Microsoft/hcsshim/internal/logfields"
15-
"github.com/Microsoft/hcsshim/internal/protocol/guestresource"
16-
"github.com/Microsoft/hcsshim/internal/pspdriver"
1715
"github.com/Microsoft/hcsshim/pkg/securitypolicy"
1816
oci "github.com/opencontainers/runtime-spec/specs-go"
19-
"github.com/pkg/errors"
2017
"github.com/sirupsen/logrus"
2118
)
2219

@@ -55,34 +52,6 @@ func NewHost(initialEnforcer securitypolicy.SecurityPolicyEnforcer, logWriter io
5552
}
5653
}
5754

58-
func (h *Host) SetWCOWConfidentialUVMOptions(ctx context.Context, securityPolicyRequest *guestresource.ConfidentialOptions) error {
59-
if err := pspdriver.GetPspDriverError(); err != nil {
60-
// For this case gcs-sidecar will keep initial deny policy.
61-
return errors.Wrapf(err, "an error occurred while using PSP driver")
62-
}
63-
64-
// Fetch report and validate host_data
65-
hostData, err := securitypolicy.NewSecurityPolicyDigest(securityPolicyRequest.EncodedSecurityPolicy)
66-
if err != nil {
67-
return err
68-
}
69-
70-
if err := pspdriver.ValidateHostData(ctx, hostData[:]); err != nil {
71-
// For this case gcs-sidecar will keep initial deny policy.
72-
return err
73-
}
74-
75-
if err := h.securityOptions.SetConfidentialOptions(ctx,
76-
securityPolicyRequest.EnforcerType,
77-
securityPolicyRequest.EncodedSecurityPolicy,
78-
securityPolicyRequest.EncodedUVMReference,
79-
); err != nil {
80-
return errors.Wrapf(err, "SetWCOWConfidentialUVMOptions failed to set security options")
81-
}
82-
83-
return nil
84-
}
85-
8655
func (h *Host) AddContainer(ctx context.Context, id string, c *Container) error {
8756
h.containersMutex.Lock()
8857
defer h.containersMutex.Unlock()

internal/guest/runtime/hcsv2/hostdata.go

Lines changed: 0 additions & 33 deletions
This file was deleted.

internal/guest/runtime/hcsv2/uvm.go

Lines changed: 8 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -89,37 +89,14 @@ func NewHost(rtime runtime.Runtime, vsock transport.Transport, initialEnforcer s
8989
}
9090
}
9191

92-
// SetConfidentialUVMOptions takes guestresource.ConfidentialOptions
93-
// to set up our internal data structures we use to store and enforce
94-
// security policy. The options can contain security policy enforcer type,
95-
// encoded security policy and signed UVM reference information The security
96-
// policy and uvm reference information can be further presented to workload
97-
// containers for validation and attestation purposes.
98-
func (h *Host) SetConfidentialUVMOptions(ctx context.Context, r *guestresource.ConfidentialOptions) error {
99-
hostData, err := securitypolicy.NewSecurityPolicyDigest(r.EncodedSecurityPolicy)
100-
if err != nil {
101-
return err
102-
}
103-
104-
if err := validateHostData(hostData[:]); err != nil {
105-
return err
106-
}
107-
108-
if err := h.securityOptions.SetConfidentialOptions(ctx,
109-
r.EnforcerType,
110-
r.EncodedSecurityPolicy,
111-
r.EncodedUVMReference,
112-
); err != nil {
113-
return errors.Wrapf(err, "SetWCOWConfidentialUVMOptions failed to set security options")
114-
}
115-
116-
return nil
117-
}
118-
11992
func (h *Host) SecurityPolicyEnforcer() securitypolicy.SecurityPolicyEnforcer {
12093
return h.securityOptions.PolicyEnforcer
12194
}
12295

96+
func (h *Host) SecurityOptions() *securitypolicy.SecurityOptions {
97+
return h.securityOptions
98+
}
99+
123100
func (h *Host) Transport() transport.Transport {
124101
return h.vsock
125102
}
@@ -496,7 +473,10 @@ func (h *Host) modifyHostSettings(ctx context.Context, containerID string, req *
496473
if !ok {
497474
return errors.New("the request's settings are not of type ConfidentialOptions")
498475
}
499-
return h.SetConfidentialUVMOptions(ctx, r)
476+
return h.securityOptions.SetConfidentialOptions(ctx,
477+
r.EnforcerType,
478+
r.EncodedSecurityPolicy,
479+
r.EncodedUVMReference)
500480
case guestresource.ResourceTypePolicyFragment:
501481
r, ok := req.Settings.(*guestresource.SecurityPolicyFragment)
502482
if !ok {

internal/pspdriver/pspdriver.go renamed to pkg/securitypolicy/pspdriver.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//go:build windows
22
// +build windows
33

4-
package pspdriver
4+
package securitypolicy
55

66
import (
77
"bytes"
@@ -217,7 +217,7 @@ func GetPspDriverError() error {
217217
}
218218

219219
// IsSNPMode() returns true if it's in SNP mode.
220-
func IsSNPMode(ctx context.Context) (bool, error) {
220+
func IsSNPMode() (bool, error) {
221221

222222
if pspDriverError != nil {
223223
return false, pspDriverError
@@ -249,7 +249,7 @@ func IsSNPMode(ctx context.Context) (bool, error) {
249249
}
250250

251251
// FetchRawSNPReport returns attestation report bytes.
252-
func FetchRawSNPReport(ctx context.Context, reportData []byte) ([]byte, error) {
252+
func FetchRawSNPReport(reportData []byte) ([]byte, error) {
253253
if pspDriverError != nil {
254254
return nil, pspDriverError
255255
}
@@ -291,8 +291,8 @@ func FetchRawSNPReport(ctx context.Context, reportData []byte) ([]byte, error) {
291291
}
292292

293293
// FetchParsedSNPReport parses raw attestation response into proper structs.
294-
func FetchParsedSNPReport(ctx context.Context, reportData []byte) (Report, error) {
295-
rawBytes, err := FetchRawSNPReport(ctx, reportData)
294+
func FetchParsedSNPReport(reportData []byte) (Report, error) {
295+
rawBytes, err := FetchRawSNPReport(reportData)
296296
if err != nil {
297297
return Report{}, err
298298
}
@@ -308,16 +308,16 @@ func FetchParsedSNPReport(ctx context.Context, reportData []byte) (Report, error
308308
// TODO: Based on internal\guest\runtime\hcsv2\hostdata.go and it's duplicated.
309309
// ValidateHostData fetches SNP report (if applicable) and validates `hostData` against
310310
// HostData set at UVM launch.
311-
func ValidateHostData(ctx context.Context, hostData []byte) error {
311+
func ValidateHostDataPSP(hostData []byte) error {
312312
// If the UVM is not SNP, then don't try to fetch an SNP report.
313-
isSnpMode, err := IsSNPMode(ctx)
313+
isSnpMode, err := IsSNPMode()
314314
if err != nil {
315315
return err
316316
}
317317
if !isSnpMode {
318318
return nil
319319
}
320-
report, err := FetchParsedSNPReport(ctx, nil)
320+
report, err := FetchParsedSNPReport(nil)
321321
if err != nil {
322322
return err
323323
}

pkg/securitypolicy/securitypolicy_linux.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@
44
package securitypolicy
55

66
import (
7+
"bytes"
78
"fmt"
89
"os"
910
"path/filepath"
1011
"strconv"
1112

1213
specInternal "github.com/Microsoft/hcsshim/internal/guest/spec"
14+
"github.com/Microsoft/hcsshim/pkg/amdsevsnp"
1315
"github.com/moby/sys/user"
1416
oci "github.com/opencontainers/runtime-spec/specs-go"
1517
"github.com/pkg/errors"
@@ -18,6 +20,28 @@ import (
1820
//nolint:unused
1921
const osType = "linux"
2022

23+
// validateHostData fetches SNP report (if applicable) and validates `hostData` against
24+
// HostData set at UVM launch.
25+
func validateHostData(hostData []byte) error {
26+
// If the UVM is not SNP, then don't try to fetch an SNP report.
27+
if !amdsevsnp.IsSNP() {
28+
return nil
29+
}
30+
report, err := amdsevsnp.FetchParsedSNPReport(nil)
31+
if err != nil {
32+
return err
33+
}
34+
35+
if !bytes.Equal(hostData, report.HostData) {
36+
return fmt.Errorf(
37+
"security policy digest %q doesn't match HostData provided at launch %q",
38+
hostData,
39+
report.HostData,
40+
)
41+
}
42+
return nil
43+
}
44+
2145
func ExtendPolicyWithNetworkingMounts(sandboxID string, enforcer SecurityPolicyEnforcer, spec *oci.Spec) error {
2246
roSpec := &oci.Spec{
2347
Root: spec.Root,

pkg/securitypolicy/securitypolicy_options.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,29 @@ func NewSecurityOptions(enforcer SecurityPolicyEnforcer, enforcerSet bool, uvmRe
3939
}
4040
}
4141

42+
// SetConfidentialOptions takes guestresource.ConfidentialOptions
43+
// to set up our internal data structures we use to store and enforce
44+
// security policy. The options can contain security policy enforcer type,
45+
// encoded security policy and signed UVM reference information The security
46+
// policy and uvm reference information can be further presented to workload
47+
// containers for validation and attestation purposes.
4248
func (s *SecurityOptions) SetConfidentialOptions(ctx context.Context, enforcerType string, encodedSecurityPolicy string, encodedUVMReference string) error {
4349
s.policyMutex.Lock()
4450
defer s.policyMutex.Unlock()
4551

4652
if s.PolicyEnforcerSet {
4753
return errors.New("security policy has already been set")
4854
}
55+
56+
hostData, err := NewSecurityPolicyDigest(encodedSecurityPolicy)
57+
if err != nil {
58+
return err
59+
}
60+
61+
if err := validateHostData(hostData[:]); err != nil {
62+
return err
63+
}
64+
4965
// This limit ensures messages are below the character truncation limit that
5066
// can be imposed by an orchestrator
5167
maxErrorMessageLength := 3 * 1024

pkg/securitypolicy/securitypolicy_windows.go

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,29 @@
33

44
package securitypolicy
55

6-
import oci "github.com/opencontainers/runtime-spec/specs-go"
6+
import (
7+
oci "github.com/opencontainers/runtime-spec/specs-go"
8+
"github.com/pkg/errors"
9+
)
710

811
//nolint:unused
912
const osType = "windows"
1013

14+
// validateHostData fetches SNP report (if applicable) and validates `hostData` against
15+
// HostData set at UVM launch.
16+
func validateHostData(hostData []byte) error {
17+
if err := GetPspDriverError(); err != nil {
18+
// For this case gcs-sidecar will keep initial deny policy.
19+
return errors.Wrapf(err, "an error occurred while using PSP driver")
20+
}
21+
22+
if err := ValidateHostDataPSP(hostData[:]); err != nil {
23+
// For this case gcs-sidecar will keep initial deny policy.
24+
return err
25+
}
26+
return nil
27+
}
28+
1129
// SandboxMountsDir returns sandbox mounts directory inside UVM/host.
1230
func SandboxMountsDir(sandboxID string) string {
1331
return ""

test/gcs/main_test.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import (
2222
"github.com/Microsoft/hcsshim/internal/guest/transport"
2323
"github.com/Microsoft/hcsshim/internal/guestpath"
2424
"github.com/Microsoft/hcsshim/internal/oc"
25-
"github.com/Microsoft/hcsshim/internal/protocol/guestresource"
2625
"github.com/Microsoft/hcsshim/pkg/securitypolicy"
2726

2827
"github.com/Microsoft/hcsshim/test/internal/util"
@@ -167,9 +166,9 @@ func getHost(_ context.Context, tb testing.TB, rt runtime.Runtime) *hcsv2.Host {
167166

168167
func getHostErr(rt runtime.Runtime, tp transport.Transport) (*hcsv2.Host, error) {
169168
h := hcsv2.NewHost(rt, tp, &securitypolicy.OpenDoorSecurityPolicyEnforcer{}, os.Stdout)
170-
if err := h.SetConfidentialUVMOptions(
169+
if err := h.SecurityOptions().SetConfidentialOptions(
171170
context.Background(),
172-
&guestresource.ConfidentialOptions{},
171+
"", "", "",
173172
); err != nil {
174173
return nil, fmt.Errorf("could not set host security policy: %w", err)
175174
}

0 commit comments

Comments
 (0)