Skip to content

Commit 10b81d8

Browse files
committed
overlayWhiteoutConverter.ConvertRead: validate overlay whiteout targets
Validate overlay whiteout targets before creating the corresponding character device. Reject malformed entries whose target resolves to "." or "..". Archive path traversal remains handled by Untar's normal path validation. Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
1 parent 936af51 commit 10b81d8

2 files changed

Lines changed: 36 additions & 1 deletion

File tree

archive_linux.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,9 @@ func (c overlayWhiteoutConverter) ConvertRead(hdr *tar.Header, filePath string)
102102
// Regular file.
103103
return true, nil
104104
}
105-
105+
if !filepath.IsLocal(originalBase) {
106+
return false, fmt.Errorf("invalid whiteout entry %q", filePath)
107+
}
106108
// If a file was deleted, and we are using overlay, we need to create a character device.
107109
originalPath := filepath.Join(dir, originalBase)
108110
if err := unix.Mknod(originalPath, unix.S_IFCHR, 0); err != nil {

archive_linux_test.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,39 @@ func TestOverlayUntarWhiteoutLinkDir(t *testing.T) {
181181
assert.Check(t, os.IsNotExist(err))
182182
}
183183

184+
// TestOverlayUntarInvalidWhiteoutNames verifies that malformed whiteout names
185+
// are rejected. In particular, it rejects whiteout targets of "." and "..";
186+
// traversal in archive paths is handled by Untar's normal path validation.
187+
func TestOverlayUntarInvalidWhiteoutNames(t *testing.T) {
188+
tests := []struct {
189+
name string
190+
}{
191+
{name: WhiteoutPrefix},
192+
{name: WhiteoutPrefix + "."},
193+
{name: WhiteoutPrefix + ".."},
194+
}
195+
196+
for _, tc := range tests {
197+
t.Run(tc.name, func(t *testing.T) {
198+
var archive bytes.Buffer
199+
tw := tar.NewWriter(&archive)
200+
201+
err := tw.WriteHeader(&tar.Header{
202+
Name: tc.name,
203+
Typeflag: tar.TypeReg,
204+
Mode: 0o600,
205+
})
206+
assert.NilError(t, err)
207+
assert.NilError(t, tw.Close())
208+
209+
err = Untar(bytes.NewReader(archive.Bytes()), t.TempDir(), &TarOptions{
210+
WhiteoutFormat: OverlayWhiteoutFormat,
211+
})
212+
assert.ErrorContains(t, err, "invalid whiteout entry")
213+
})
214+
}
215+
}
216+
184217
func TestOverlayTarAUFSUntar(t *testing.T) {
185218
restore := overrideUmask(0)
186219
defer restore()

0 commit comments

Comments
 (0)