Skip to content

Commit

Permalink
lxd/storage/backend_lxd: Prevent import of OVA format for conversion
Browse files Browse the repository at this point in the history
An OVA (Open Virtualization Appliance) file is not a virtual disk format like VMDK and QCOW2.
Instead, it is an archive format used for distributing virtual appliances.

Since qemu-img info detects it as raw image format, we cannot use that to detect OVA files.
Instead we need to check whether the uploaded file is a tar archive (contains a tar header).

Note that we need to reset the file's read pointer after the file is uploaded and also open
file with read permission (in addition to already requested write permission).

Signed-off-by: Din Music <[email protected]>
  • Loading branch information
MusicDin committed Aug 5, 2024
1 parent c795f4d commit 7ed80c1
Showing 1 changed file with 15 additions and 2 deletions.
17 changes: 15 additions & 2 deletions lxd/storage/backend_lxd.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package storage

import (
"archive/tar"
"archive/zip"
"context"
"encoding/json"
Expand Down Expand Up @@ -1883,7 +1884,7 @@ func (b *lxdBackend) recvVolumeFiller(conn io.ReadWriteCloser, contentType drive
}
} else {
// Receive block volume.
to, err := os.OpenFile(rootBlockPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0600)
to, err := os.OpenFile(rootBlockPath, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0600)
if err != nil {
return -1, fmt.Errorf("Error opening file for writing %q: %w", rootBlockPath, err)
}
Expand Down Expand Up @@ -1929,6 +1930,18 @@ func (b *lxdBackend) recvBlockVol(toFile *os.File, volName string, conn io.ReadW
return fmt.Errorf("Error copying from migration connection to %q: %w", toFile.Name(), err)
}

// Reset the file's read pointer to the beginning, otherwise we cannot read the tar's header.
_, err = toFile.Seek(0, io.SeekStart)
if err != nil {
return err
}

// Ensure that the received file is not a tarball, which is also the case for OVA format.
_, err = tar.NewReader(toFile).Next()
if err == nil {
return fmt.Errorf("Instance cannot be imported from a tar archive or OVA file")
}

return toFile.Close()
}

Expand Down Expand Up @@ -2469,7 +2482,7 @@ func (b *lxdBackend) CreateInstanceFromConversion(inst instance.Instance, conn i
imgPath := filepath.Join(shared.VarPath("backups"), conversionID)

// Create new file in backups directory.
to, err := os.OpenFile(imgPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0600)
to, err := os.OpenFile(imgPath, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0600)
if err != nil {
return fmt.Errorf("Error opening file for writing %q: %w", imgPath, err)
}
Expand Down

0 comments on commit 7ed80c1

Please sign in to comment.