Skip to content

Commit 83a71d4

Browse files
committed
C-WCOW: PspDriver and hostdata changes in SecurityPolicy pkg
Signed-off-by: Mahati Chamarthy <[email protected]>
1 parent 8809b5f commit 83a71d4

File tree

10 files changed

+85
-116
lines changed

10 files changed

+85
-116
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"
@@ -217,7 +216,7 @@ func main() {
217216
return
218217
}
219218

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

internal/gcs-sidecar/handlers.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,6 @@ func (b *Bridge) createContainer(req *request) (err error) {
8888
return fmt.Errorf("CreateContainer operation is denied by policy: %w", err)
8989
}
9090

91-
if err := b.hostState.SetupSecurityContextDir(ctx, &spec); err != nil {
92-
return err
93-
}
9491
commandLine := len(spec.Process.Args) > 0
9592
c := &Container{
9693
id: containerID,
@@ -549,9 +546,12 @@ func (b *Bridge) modifySettings(req *request) (err error) {
549546
case guestresource.ResourceTypeSecurityPolicy:
550547
securityPolicyRequest := modifyGuestSettingsRequest.Settings.(*guestresource.ConfidentialOptions)
551548
log.G(ctx).Tracef("WCOWConfidentialOptions: { %v}", securityPolicyRequest)
552-
err := b.hostState.SetWCOWConfidentialUVMOptions(req.ctx, securityPolicyRequest)
549+
err := b.hostState.securityOptions.SetConfidentialOptions(ctx,
550+
securityPolicyRequest.EnforcerType,
551+
securityPolicyRequest.EncodedSecurityPolicy,
552+
securityPolicyRequest.EncodedUVMReference)
553553
if err != nil {
554-
return errors.Wrap(err, "error creating enforcer")
554+
return errors.Wrap(err, "Failed to set Confidentia UVM Options")
555555
}
556556
// Send response back to shim
557557
resp := &prot.ResponseBase{

internal/gcs-sidecar/host.go

Lines changed: 2 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,14 @@ package bridge
66
import (
77
"context"
88
"io"
9-
"os"
10-
"path/filepath"
119
"sync"
1210

1311
"github.com/Microsoft/hcsshim/internal/bridgeutils/gcserr"
1412
hcsschema "github.com/Microsoft/hcsshim/internal/hcs/schema2"
1513
"github.com/Microsoft/hcsshim/internal/log"
1614
"github.com/Microsoft/hcsshim/internal/logfields"
17-
"github.com/Microsoft/hcsshim/internal/protocol/guestresource"
18-
"github.com/Microsoft/hcsshim/internal/pspdriver"
1915
"github.com/Microsoft/hcsshim/pkg/securitypolicy"
20-
specs "github.com/opencontainers/runtime-spec/specs-go"
21-
"github.com/pkg/errors"
16+
oci "github.com/opencontainers/runtime-spec/specs-go"
2217
"github.com/sirupsen/logrus"
2318
)
2419

@@ -30,7 +25,7 @@ type Host struct {
3025

3126
type Container struct {
3227
id string
33-
spec specs.Spec
28+
spec oci.Spec
3429
processesMutex sync.Mutex
3530
processes map[uint32]*containerProcess
3631
commandLine bool
@@ -59,34 +54,6 @@ func NewHost(initialEnforcer securitypolicy.SecurityPolicyEnforcer, logWriter io
5954
}
6055
}
6156

62-
func (h *Host) SetWCOWConfidentialUVMOptions(ctx context.Context, securityPolicyRequest *guestresource.ConfidentialOptions) error {
63-
if err := pspdriver.GetPspDriverError(); err != nil {
64-
// For this case gcs-sidecar will keep initial deny policy.
65-
return errors.Wrapf(err, "an error occurred while using PSP driver")
66-
}
67-
68-
// Fetch report and validate host_data
69-
hostData, err := securitypolicy.NewSecurityPolicyDigest(securityPolicyRequest.EncodedSecurityPolicy)
70-
if err != nil {
71-
return err
72-
}
73-
74-
if err := pspdriver.ValidateHostData(ctx, hostData[:]); err != nil {
75-
// For this case gcs-sidecar will keep initial deny policy.
76-
return err
77-
}
78-
79-
if err := h.securityOptions.SetConfidentialOptions(ctx,
80-
securityPolicyRequest.EnforcerType,
81-
securityPolicyRequest.EncodedSecurityPolicy,
82-
securityPolicyRequest.EncodedUVMReference,
83-
); err != nil {
84-
return errors.Wrapf(err, "SetWCOWConfidentialUVMOptions failed to set security options")
85-
}
86-
87-
return nil
88-
}
89-
9057
func (h *Host) AddContainer(ctx context.Context, id string, c *Container) error {
9158
h.containersMutex.Lock()
9259
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
@@ -112,37 +112,14 @@ func NewHost(rtime runtime.Runtime, vsock transport.Transport, initialEnforcer s
112112
}
113113
}
114114

115-
// SetConfidentialUVMOptions takes guestresource.ConfidentialOptions
116-
// to set up our internal data structures we use to store and enforce
117-
// security policy. The options can contain security policy enforcer type,
118-
// encoded security policy and signed UVM reference information The security
119-
// policy and uvm reference information can be further presented to workload
120-
// containers for validation and attestation purposes.
121-
func (h *Host) SetConfidentialUVMOptions(ctx context.Context, r *guestresource.ConfidentialOptions) error {
122-
hostData, err := securitypolicy.NewSecurityPolicyDigest(r.EncodedSecurityPolicy)
123-
if err != nil {
124-
return err
125-
}
126-
127-
if err := validateHostData(hostData[:]); err != nil {
128-
return err
129-
}
130-
131-
if err := h.securityOptions.SetConfidentialOptions(ctx,
132-
r.EnforcerType,
133-
r.EncodedSecurityPolicy,
134-
r.EncodedUVMReference,
135-
); err != nil {
136-
return errors.Wrapf(err, "SetWCOWConfidentialUVMOptions failed to set security options")
137-
}
138-
139-
return nil
140-
}
141-
142115
func (h *Host) SecurityPolicyEnforcer() securitypolicy.SecurityPolicyEnforcer {
143116
return h.securityOptions.PolicyEnforcer
144117
}
145118

119+
func (h *Host) SecurityOptions() *securitypolicy.SecurityOptions {
120+
return h.securityOptions
121+
}
122+
146123
func (h *Host) Transport() transport.Transport {
147124
return h.vsock
148125
}
@@ -696,7 +673,10 @@ func (h *Host) modifyHostSettings(ctx context.Context, containerID string, req *
696673
if !ok {
697674
return errors.New("the request's settings are not of type ConfidentialOptions")
698675
}
699-
return h.SetConfidentialUVMOptions(ctx, r)
676+
return h.securityOptions.SetConfidentialOptions(ctx,
677+
r.EnforcerType,
678+
r.EncodedSecurityPolicy,
679+
r.EncodedUVMReference)
700680
case guestresource.ResourceTypePolicyFragment:
701681
r, ok := req.Settings.(*guestresource.SecurityPolicyFragment)
702682
if !ok {
Lines changed: 8 additions & 9 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
}
@@ -305,19 +305,18 @@ func FetchParsedSNPReport(ctx context.Context, reportData []byte) (Report, error
305305
return r.report(), nil
306306
}
307307

308-
// TODO: Based on internal\guest\runtime\hcsv2\hostdata.go and it's duplicated.
309308
// ValidateHostData fetches SNP report (if applicable) and validates `hostData` against
310309
// HostData set at UVM launch.
311-
func ValidateHostData(ctx context.Context, hostData []byte) error {
310+
func ValidateHostDataPSP(hostData []byte) error {
312311
// If the UVM is not SNP, then don't try to fetch an SNP report.
313-
isSnpMode, err := IsSNPMode(ctx)
312+
isSnpMode, err := IsSNPMode()
314313
if err != nil {
315314
return err
316315
}
317316
if !isSnpMode {
318317
return nil
319318
}
320-
report, err := FetchParsedSNPReport(ctx, nil)
319+
report, err := FetchParsedSNPReport(nil)
321320
if err != nil {
322321
return err
323322
}

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)