Skip to content

Commit c168265

Browse files
committed
initdata-processor: gate insecure attestation via cmdline
1 parent 412b920 commit c168265

2 files changed

Lines changed: 73 additions & 3 deletions

File tree

initdata-processor/main.go

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ import (
1515
"net/http"
1616
"os"
1717
"path/filepath"
18+
"slices"
19+
"strings"
1820

1921
"github.com/edgelesssys/contrast/initdata-processor/policy"
2022
"github.com/edgelesssys/contrast/initdata-processor/validator"
@@ -27,7 +29,10 @@ const (
2729
insecureConfigPath = "/run/insecure-cfg"
2830
)
2931

30-
var version = "0.0.0-dev"
32+
var (
33+
version = "0.0.0-dev"
34+
kernelCmdlinePath = "/proc/cmdline"
35+
)
3136

3237
// We always exit with status code 0 so that the Kata agent can start and propagate errors to
3338
// the runtime.
@@ -100,10 +105,17 @@ func handleInitdata(doc initdata.Raw) (hostdata []byte, insecurePlatform bool, r
100105
return nil, false, fmt.Errorf("computing initdata digest: %w", err)
101106
}
102107

108+
allowInsecure, err := allowInsecureAttestation()
109+
if err != nil {
110+
return nil, false, err
111+
}
112+
103113
v, verr := validator.New()
104114
if errors.Is(verr, validator.ErrNoPlatform) {
115+
if !allowInsecure {
116+
return nil, false, fmt.Errorf("no TEE platform detected and insecure attestation is not allowed")
117+
}
105118
log.Print("WARNING: No TEE platform detected, skipping initdata digest validation. This is expected on insecure platforms.")
106-
insecurePlatform = true
107119
} else if verr != nil {
108120
return nil, false, fmt.Errorf("creating validator: %w", verr)
109121
} else if err := v.ValidateDigest(digest); err != nil {
@@ -121,7 +133,18 @@ func handleInitdata(doc initdata.Raw) (hostdata []byte, insecurePlatform bool, r
121133
return nil, false, fmt.Errorf("writing file %q: %w", path, err)
122134
}
123135
}
124-
return digest, insecurePlatform, nil
136+
return digest, allowInsecure, nil
137+
}
138+
139+
func allowInsecureAttestation() (bool, error) {
140+
cmdline, err := os.ReadFile(kernelCmdlinePath)
141+
if err != nil {
142+
return false, fmt.Errorf("reading kernel command line: %w", err)
143+
}
144+
if slices.Contains(strings.Fields(string(cmdline)), "contrast.allow_insecure_attestation=1") {
145+
return true, nil
146+
}
147+
return false, nil
125148
}
126149

127150
// serveHostdata starts an HTTP server that serves the hostdata digest.

initdata-processor/main_test.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Copyright 2026 Edgeless Systems GmbH
2+
// SPDX-License-Identifier: BUSL-1.1
3+
4+
package main
5+
6+
import (
7+
"os"
8+
"path/filepath"
9+
"testing"
10+
11+
"github.com/stretchr/testify/assert"
12+
"github.com/stretchr/testify/require"
13+
)
14+
15+
func TestAllowInsecureAttestation(t *testing.T) {
16+
oldKernelCmdlinePath := kernelCmdlinePath
17+
t.Cleanup(func() { kernelCmdlinePath = oldKernelCmdlinePath })
18+
19+
testCases := map[string]struct {
20+
cmdline string
21+
want bool
22+
}{
23+
"absent": {
24+
cmdline: "console=hvc0",
25+
want: false,
26+
},
27+
"disabled": {
28+
cmdline: "console=hvc0 contrast.allow_insecure_attestation=0",
29+
want: false,
30+
},
31+
"enabled": {
32+
cmdline: "console=hvc0 contrast.allow_insecure_attestation=1 quiet",
33+
want: true,
34+
},
35+
}
36+
37+
for name, tc := range testCases {
38+
t.Run(name, func(t *testing.T) {
39+
kernelCmdlinePath = filepath.Join(t.TempDir(), "cmdline")
40+
require.NoError(t, os.WriteFile(kernelCmdlinePath, []byte(tc.cmdline), 0o644))
41+
42+
got, err := allowInsecureAttestation()
43+
require.NoError(t, err)
44+
assert.Equal(t, tc.want, got)
45+
})
46+
}
47+
}

0 commit comments

Comments
 (0)