Skip to content

Commit cf40507

Browse files
committed
Tighten legacy instance config disk permissions on startup
1 parent 62db5d3 commit cf40507

3 files changed

Lines changed: 50 additions & 0 deletions

File tree

lib/instances/manager.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,9 @@ func NewManagerWithConfigE(p *paths.Paths, imageManager images.Manager, systemMa
311311
// Restrict permissions on metadata written by older versions (may be 0644
312312
// and contains env values / credential bindings).
313313
m.tightenMetadataPermissions()
314+
// Restrict permissions on guest config disks written by older versions
315+
// (may be 0644 and embed config.json with env values).
316+
m.tightenConfigDiskPermissions()
314317

315318
return m, nil
316319
}

lib/instances/metadata_permissions_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,26 @@ func TestManagerTightensLegacyMetadataPermissions(t *testing.T) {
8686
"legacy 0644 metadata must be tightened to 0600 at startup")
8787
}
8888

89+
// TestManagerTightensLegacyConfigDiskPermissions proves the startup sweep
90+
// upgrades config disks written by older versions (mode 0644) to 0600.
91+
func TestManagerTightensLegacyConfigDiskPermissions(t *testing.T) {
92+
t.Parallel()
93+
dataDir := t.TempDir()
94+
p := paths.New(dataDir)
95+
id := "inst-config-disk-legacy"
96+
97+
// Simulate a legacy config disk written with world-readable permissions.
98+
require.NoError(t, os.MkdirAll(p.InstanceDir(id), 0755))
99+
require.NoError(t, os.WriteFile(p.InstanceConfigDisk(id), []byte("ext4-bytes-placeholder"), 0644))
100+
101+
newPermTestManager(t, dataDir)
102+
103+
info, err := os.Stat(p.InstanceConfigDisk(id))
104+
require.NoError(t, err)
105+
require.Equal(t, os.FileMode(0600), info.Mode().Perm(),
106+
"legacy 0644 config disks must be tightened to 0600 at startup")
107+
}
108+
89109
// TestMergeEnvUpdateSkipsRedactionSentinel proves a redacted read response
90110
// round-tripped into an env update cannot clobber real secret values.
91111
func TestMergeEnvUpdateSkipsRedactionSentinel(t *testing.T) {

lib/instances/storage.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,33 @@ func (m *manager) tightenMetadataPermissions() {
154154
}
155155
}
156156

157+
// tightenConfigDiskPermissions restricts existing guest config disk files to
158+
// owner-only access. Disks written before restrictive permissions were
159+
// introduced may be mode 0644; they embed config.json with environment values.
160+
// Best-effort: individual failures are logged, not fatal.
161+
func (m *manager) tightenConfigDiskPermissions() {
162+
log := logger.FromContext(context.Background())
163+
entries, err := os.ReadDir(m.paths.GuestsDir())
164+
if err != nil {
165+
return // no guests directory yet
166+
}
167+
for _, entry := range entries {
168+
if !entry.IsDir() {
169+
continue
170+
}
171+
configDiskPath := m.paths.InstanceConfigDisk(entry.Name())
172+
info, err := os.Stat(configDiskPath)
173+
if err != nil {
174+
continue
175+
}
176+
if info.Mode().Perm() != 0600 {
177+
if err := os.Chmod(configDiskPath, 0600); err != nil {
178+
log.Warn("failed to tighten instance config disk permissions", "path", configDiskPath, "error", err)
179+
}
180+
}
181+
}
182+
}
183+
157184
// createOverlayDisk creates a sparse overlay disk for the instance
158185
func (m *manager) createOverlayDisk(id string, sizeBytes int64) error {
159186
overlayPath := m.paths.InstanceOverlay(id)

0 commit comments

Comments
 (0)