chunked: validate chunk digest

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
This commit is contained in:
Giuseppe Scrivano 2022-01-04 10:59:50 +01:00
parent 63be926601
commit 2edca4eb72
No known key found for this signature in database
GPG Key ID: 67E38F7A8BA21772
1 changed files with 35 additions and 1 deletions

View File

@ -1551,7 +1551,7 @@ func (c *chunkedDiffer) ApplyDiff(dest string, options *archive.TarOptions) (gra
if err != nil {
return output, err
}
if offset >= 0 {
if offset >= 0 && validateChunkChecksum(chunk, root, path, offset, c.copyBuffer) {
missingPartsSize -= size
mp.OriginFile = &originFile{
Root: root,
@ -1660,3 +1660,37 @@ func (c *chunkedDiffer) mergeTocEntries(fileType compressedFileType, entries []i
}
return mergedEntries, nil
}
// validateChunkChecksum checks if the file at $root/$path[offset:chunk.ChunkSize] has the
// same digest as chunk.ChunkDigest
func validateChunkChecksum(chunk *internal.FileMetadata, root, path string, offset int64, copyBuffer []byte) bool {
parentDirfd, err := unix.Open(root, unix.O_PATH, 0)
if err != nil {
return false
}
defer unix.Close(parentDirfd)
fd, err := openFileUnderRoot(path, parentDirfd, unix.O_RDONLY, 0)
if err != nil {
return false
}
defer fd.Close()
if _, err := unix.Seek(int(fd.Fd()), offset, 0); err != nil {
return false
}
r := io.LimitReader(fd, chunk.ChunkSize)
digester := digest.Canonical.Digester()
if _, err := io.CopyBuffer(digester.Hash(), r, copyBuffer); err != nil {
return false
}
digest, err := digest.Parse(chunk.ChunkDigest)
if err != nil {
return false
}
return digester.Digest() == digest
}