Skip to content

Commit c4e7639

Browse files
committed
go/runtime/bundle/component: Add ELF metadata
1 parent 76552be commit c4e7639

File tree

9 files changed

+86
-30
lines changed

9 files changed

+86
-30
lines changed

.changelog/5976.trivial.md

Whitespace-only changes.

go/oasis-test-runner/oasis/runtime.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -280,9 +280,11 @@ func (rt *Runtime) toRuntimeBundle(deploymentIndex int) (*bundle.Bundle, error)
280280
_ = bnd.Add(elfBin, bundle.NewBytesData(binBuf))
281281

282282
comp := &bundle.Component{
283-
Kind: compCfg.Kind,
284-
Version: compCfg.Version,
285-
Executable: elfBin,
283+
Kind: compCfg.Kind,
284+
Version: compCfg.Version,
285+
ELF: &bundle.ELFMetadata{
286+
Executable: elfBin,
287+
},
286288
}
287289

288290
if rt.teeHardware == node.TEEHardwareIntelSGX {

go/runtime/bundle/bundle.go

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,22 @@ func (bnd *Bundle) Validate() error {
5050
}
5151
var needFiles []bundleFile
5252
for id, comp := range bnd.Manifest.GetAvailableComponents() {
53-
needFiles = append(needFiles, bundleFile{
54-
descr: fmt.Sprintf("%s: ELF executable", id),
55-
fn: comp.Executable,
56-
optional: true,
57-
})
53+
if elf := comp.ELF; elf != nil {
54+
needFiles = append(needFiles,
55+
[]bundleFile{
56+
{
57+
descr: fmt.Sprintf("%s: ELF executable", id),
58+
fn: elf.Executable,
59+
},
60+
}...,
61+
)
62+
} else {
63+
needFiles = append(needFiles, bundleFile{
64+
descr: fmt.Sprintf("%s: ELF executable", id),
65+
fn: comp.Executable,
66+
optional: true,
67+
})
68+
}
5869
if sgx := comp.SGX; sgx != nil {
5970
needFiles = append(needFiles,
6071
[]bundleFile{
@@ -494,7 +505,11 @@ func (bnd *Bundle) WriteExploded(dataDir string) (string, error) {
494505
}
495506

496507
for id, comp := range bnd.Manifest.GetAvailableComponents() {
497-
if comp.Executable != "" {
508+
if comp.ELF != nil {
509+
if err := os.Chmod(bnd.ExplodedPath(dataDir, comp.ELF.Executable), 0o700); err != nil {
510+
return "", fmt.Errorf("runtime/bundle: failed to fixup executable permissions for '%s': %w", id, err)
511+
}
512+
} else if comp.Executable != "" {
498513
if err := os.Chmod(bnd.ExplodedPath(dataDir, comp.Executable), 0o700); err != nil {
499514
return "", fmt.Errorf("runtime/bundle: failed to fixup executable permissions for '%s': %w", id, err)
500515
}

go/runtime/bundle/bundle_test.go

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,10 @@ func TestBundle(t *testing.T) {
3030
}(),
3131
Components: []*Component{
3232
{
33-
Kind: component.RONL,
34-
Executable: "runtime.bin",
33+
Kind: component.RONL,
34+
ELF: &ELFMetadata{
35+
Executable: "runtime.bin",
36+
},
3537
SGX: &SGXMetadata{
3638
Executable: "runtime.sgx",
3739
},
@@ -54,7 +56,7 @@ func TestBundle(t *testing.T) {
5456
require.False(t, manifest.IsDetached(), "manifest with RONL component should not be detached")
5557

5658
t.Run("Add_Write", func(t *testing.T) {
57-
err := bundle.Add(manifest.Components[0].Executable, NewBytesData(randBuffer(3252)))
59+
err := bundle.Add(manifest.Components[0].ELF.Executable, NewBytesData(randBuffer(3252)))
5860
require.NoError(t, err, "bundle.Add(elf)")
5961
err = bundle.Add(manifest.Components[0].SGX.Executable, NewBytesData(randBuffer(6541)))
6062
require.NoError(t, err, "bundle.Add(sgx)")
@@ -84,15 +86,15 @@ func TestBundle(t *testing.T) {
8486

8587
t.Run("Open_WithManifestHash", func(t *testing.T) {
8688
var manifestHash hash.Hash
87-
err := manifestHash.UnmarshalHex("905e9866eccb967e8991698273f41d20c616cab4f9e9332a2a12d9d3a1c8a486")
89+
err := manifestHash.UnmarshalHex("2faad6101e24f0034a82b99aee10f4de909a00b1b2c125f7d6fb97d65dc7984b")
8890
require.NoError(t, err, "UnmarshalHex")
8991

9092
_, err = Open(bundleFn, WithManifestHash(manifestHash))
9193
require.NoError(t, err, "Open_WithManifestHash")
9294

9395
_, err = Open(bundleFn, WithManifestHash(hash.Hash{}))
9496
require.Error(t, err, "Open_WithManifestHash")
95-
require.ErrorContains(t, err, "invalid manifest (got: 905e9866eccb967e8991698273f41d20c616cab4f9e9332a2a12d9d3a1c8a486, expected: 0000000000000000000000000000000000000000000000000000000000000000)")
97+
require.ErrorContains(t, err, "invalid manifest (got: 2faad6101e24f0034a82b99aee10f4de909a00b1b2c125f7d6fb97d65dc7984b, expected: 0000000000000000000000000000000000000000000000000000000000000000)")
9698
})
9799

98100
t.Run("ResetManifest", func(t *testing.T) {
@@ -137,8 +139,10 @@ func TestDetachedBundle(t *testing.T) {
137139
Components: []*Component{
138140
// No RONL component in the manifest.
139141
{
140-
Kind: component.ROFL,
141-
Executable: "runtime.bin",
142+
Kind: component.ROFL,
143+
ELF: &ELFMetadata{
144+
Executable: "runtime.bin",
145+
},
142146
SGX: &SGXMetadata{
143147
Executable: "runtime.sgx",
144148
},
@@ -152,7 +156,7 @@ func TestDetachedBundle(t *testing.T) {
152156
require.True(t, manifest.IsDetached(), "manifest without RONL component should be detached")
153157

154158
t.Run("Add_Write", func(t *testing.T) {
155-
err := bundle.Add(manifest.Components[0].Executable, NewBytesData(randBuffer(2231)))
159+
err := bundle.Add(manifest.Components[0].ELF.Executable, NewBytesData(randBuffer(2231)))
156160
require.NoError(t, err, "bundle.Add(elf)")
157161
err = bundle.Add(manifest.Components[0].SGX.Executable, NewBytesData(randBuffer(7627)))
158162
require.NoError(t, err, "bundle.Add(sgx)")

go/runtime/bundle/component.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,12 @@ type Component struct {
4040
Version version.Version
4141

4242
// Executable is the name of the runtime ELF executable file if any.
43+
// NOTE: This may go away in the future, use `ELFMetadata` instead.
4344
Executable string `json:"executable,omitempty"`
4445

46+
// ELF is the ELF specific manifest metadata if any.
47+
ELF *ELFMetadata `json:"elf,omitempty"`
48+
4549
// SGX is the SGX specific manifest metadata if any.
4650
SGX *SGXMetadata `json:"sgx,omitempty"`
4751

@@ -78,6 +82,12 @@ func (c *Component) Validate() error {
7882
) {
7983
return fmt.Errorf("each component can only include metadata for a single TEE")
8084
}
85+
if c.ELF != nil {
86+
err := c.ELF.Validate()
87+
if err != nil {
88+
return fmt.Errorf("elf: %w", err)
89+
}
90+
}
8191
if c.SGX != nil {
8292
err := c.SGX.Validate()
8393
if err != nil {
@@ -96,7 +106,7 @@ func (c *Component) Validate() error {
96106
if c.Name != "" {
97107
return fmt.Errorf("RONL component must have an empty name")
98108
}
99-
if c.Executable == "" {
109+
if c.Executable == "" && c.ELF == nil {
100110
return fmt.Errorf("RONL component must define an executable")
101111
}
102112
if c.Disabled {
@@ -123,7 +133,7 @@ func (c *Component) IsNetworkAllowed() bool {
123133

124134
// IsTEERequired returns true iff the component only provides TEE executables.
125135
func (c *Component) IsTEERequired() bool {
126-
return c.Executable == "" && c.TEEKind() != component.TEEKindNone
136+
return c.Executable == "" && c.ELF == nil && c.TEEKind() != component.TEEKindNone
127137
}
128138

129139
// TEEKind returns the kind of TEE supported by the component.

go/runtime/bundle/manifest.go

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,10 +114,12 @@ func (m *Manifest) GetComponentByID(id component.ID) *Component {
114114
// We also support legacy manifests which define the RONL component at the top-level.
115115
if id.IsRONL() && m.IsLegacy() {
116116
return &Component{
117-
Kind: component.RONL,
118-
Executable: m.Executable,
119-
Version: m.Version,
120-
SGX: m.SGX,
117+
Kind: component.RONL,
118+
Version: m.Version,
119+
ELF: &ELFMetadata{
120+
Executable: m.Executable,
121+
},
122+
SGX: m.SGX,
121123
}
122124
}
123125
return nil
@@ -141,6 +143,20 @@ func (m *Manifest) GetVersion() version.Version {
141143
return m.Version
142144
}
143145

146+
// ELFMetadata is the ELF specific manifest metadata.
147+
type ELFMetadata struct {
148+
// Executable is the name of the ELF executable file.
149+
Executable string `json:"executable"`
150+
}
151+
152+
// Validate validates the ELF metadata structure for well-formedness.
153+
func (e *ELFMetadata) Validate() error {
154+
if e.Executable == "" {
155+
return fmt.Errorf("executable must be set")
156+
}
157+
return nil
158+
}
159+
144160
// SGXMetadata is the SGX specific manifest metadata.
145161
type SGXMetadata struct {
146162
// Executable is the name of the SGX enclave executable file.

go/runtime/bundle/registry.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -264,8 +264,10 @@ func (r *registry) GetComponents(runtimeID common.Namespace, version version.Ver
264264
return []*ExplodedComponent{
265265
{
266266
Component: &Component{
267-
Kind: component.RONL,
268-
Executable: "mock",
267+
Kind: component.RONL,
268+
ELF: &ELFMetadata{
269+
Executable: "mock",
270+
},
269271
},
270272
Detached: false,
271273
},

go/runtime/bundle/registry_test.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,11 @@ func createSyntheticBundle(dir string, runtimeID common.Namespace, version versi
2525
switch comp {
2626
case component.RONL:
2727
manifest.Components = append(manifest.Components, &Component{
28-
Kind: component.RONL,
29-
Version: version,
30-
Executable: "runtime.bin",
28+
Kind: component.RONL,
29+
Version: version,
30+
ELF: &ELFMetadata{
31+
Executable: "runtime.bin",
32+
},
3133
})
3234
case component.ROFL:
3335
manifest.Components = append(manifest.Components, &Component{
@@ -43,7 +45,7 @@ func createSyntheticBundle(dir string, runtimeID common.Namespace, version versi
4345
}
4446

4547
if slices.Contains(components, component.RONL) {
46-
if err := bnd.Add(manifest.Components[0].Executable, NewBytesData([]byte{1})); err != nil {
48+
if err := bnd.Add(manifest.Components[0].ELF.Executable, NewBytesData([]byte{1})); err != nil {
4749
return "", err
4850
}
4951
}

go/runtime/host/sandbox/sandbox.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -616,8 +616,13 @@ func DefaultGetSandboxConfig(logger *logging.Logger, sandboxBinaryPath string) G
616616
"provisioner", "sandbox",
617617
)
618618

619+
executable := comp.Executable
620+
if comp.ELF != nil {
621+
executable = comp.ELF.Executable
622+
}
623+
619624
return process.Config{
620-
Path: comp.ExplodedPath(comp.Executable),
625+
Path: comp.ExplodedPath(executable),
621626
SandboxBinaryPath: sandboxBinaryPath,
622627
Stdout: logWrapper,
623628
Stderr: logWrapper,

0 commit comments

Comments
 (0)