Skip to content

Commit c4bfa1c

Browse files
committed
C-WCOW: PspDriver and hostdata changes in SecurityPolicy pkg
Signed-off-by: Mahati Chamarthy <mahati.chamarthy@gmail.com>
1 parent 87e9fc9 commit c4bfa1c

File tree

10 files changed

+85
-115
lines changed

10 files changed

+85
-115
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
@@ -111,37 +111,14 @@ func NewHost(rtime runtime.Runtime, vsock transport.Transport, initialEnforcer s
111111
}
112112
}
113113

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

118+
func (h *Host) SecurityOptions() *securitypolicy.SecurityOptions {
119+
return h.securityOptions
120+
}
121+
145122
func (h *Host) Transport() transport.Transport {
146123
return h.vsock
147124
}
@@ -665,7 +642,10 @@ func (h *Host) modifyHostSettings(ctx context.Context, containerID string, req *
665642
if !ok {
666643
return errors.New("the request's settings are not of type ConfidentialOptions")
667644
}
668-
return h.SetConfidentialUVMOptions(ctx, r)
645+
return h.securityOptions.SetConfidentialOptions(ctx,
646+
r.EnforcerType,
647+
r.EncodedSecurityPolicy,
648+
r.EncodedUVMReference)
669649
case guestresource.ResourceTypePolicyFragment:
670650
r, ok := req.Settings.(*guestresource.SecurityPolicyFragment)
671651
if !ok {
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)