mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/yunionio/cloudpods.git
synced 2026-09-20 08:03:53 +08:00
fix(image): reject images that declare a backing file (#25630)
Treat a non-empty backing filename as unsupported on upload, convert, probe, and ceph cache. Co-authored-by: Qiu Jian <qiujian@yunionyun.com> Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -569,6 +569,9 @@ func (self *SImage) SaveImageFromStream(reader io.Reader, totalSize int64, calCh
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "NewQemuImage %s", localPath)
|
||||
}
|
||||
if err := img.CheckNoBackingFile(); err != nil {
|
||||
return err
|
||||
}
|
||||
format = string(img.String2ImageFormat())
|
||||
virtualSizeBytes = img.SizeBytes
|
||||
|
||||
@@ -1217,7 +1220,14 @@ func (self *SImage) GetNewLocation(newLocalPath string) string {
|
||||
}
|
||||
|
||||
func (self *SImage) getQemuImage() (*qemuimg.SQemuImage, error) {
|
||||
return qemuimg.NewQemuImageWithIOLevel(self.GetLocalLocation(), qemuimg.IONiceIdle)
|
||||
img, err := qemuimg.NewQemuImageWithIOLevel(self.GetLocalLocation(), qemuimg.IONiceIdle)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := img.CheckNoBackingFile(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return img, nil
|
||||
}
|
||||
|
||||
func (self *SImage) StopTorrents() {
|
||||
@@ -1775,6 +1785,13 @@ func (image *SImage) doProbeImageInfo(ctx context.Context, userCred mcclient.Tok
|
||||
if len(diskPath) == 0 {
|
||||
return false, errors.Wrap(httperrors.ErrNotFound, "disk file not found")
|
||||
}
|
||||
qimg, err := qemuimg.NewQemuImage(diskPath)
|
||||
if err != nil {
|
||||
return false, errors.Wrap(err, "NewQemuImage")
|
||||
}
|
||||
if err := qimg.CheckNoBackingFile(); err != nil {
|
||||
return false, err
|
||||
}
|
||||
if deployclient.GetDeployClient() == nil {
|
||||
return false, fmt.Errorf("deploy client not init")
|
||||
}
|
||||
@@ -2231,6 +2248,17 @@ func (img *SImage) cacheToCephStorages(ctx context.Context) {
|
||||
}
|
||||
if cachedRbdimgStorageId == "" {
|
||||
// do cache img to ceph storage
|
||||
if fileutils2.Exists(localPath) {
|
||||
qimg, err := qemuimg.NewQemuImage(localPath)
|
||||
if err != nil {
|
||||
log.Errorf("skip cache img %s: NewQemuImage %s", img.Id, err)
|
||||
return
|
||||
}
|
||||
if err := qimg.CheckNoBackingFile(); err != nil {
|
||||
log.Errorf("skip cache img %s: %s", img.Id, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
for storageId := range storageCachedImages {
|
||||
storageConf := cephStorages.StorageIdConf[storageId]
|
||||
imgTmpName := "image_cache_" + img.Id + ".tmp"
|
||||
|
||||
@@ -37,7 +37,8 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
ErrUnsupportedFormat = errors.Error("unsupported format")
|
||||
ErrUnsupportedFormat = errors.Error("unsupported format")
|
||||
ErrBackingFileNotAllowed = errors.Error("image backing file is not allowed")
|
||||
|
||||
convertWorkInOrder = false
|
||||
convertCoroutines = 16
|
||||
@@ -230,7 +231,11 @@ func (img *SQemuImage) parse() error {
|
||||
img.ClusterSize = info.ClusterSize
|
||||
img.Compat = info.FormatSpecific.Data.Compat
|
||||
img.Encrypted = info.Encrypted
|
||||
img.BackFilePath, err = ParseQemuFilepath(info.FullBackingFilename)
|
||||
backing := info.FullBackingFilename
|
||||
if backing == "" {
|
||||
backing = info.BackingFilename
|
||||
}
|
||||
img.BackFilePath, err = ParseQemuFilepath(backing)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "ParseQemuFilepath")
|
||||
}
|
||||
@@ -267,6 +272,13 @@ func (img *SQemuImage) IsChained() bool {
|
||||
return len(img.BackFilePath) > 0
|
||||
}
|
||||
|
||||
func (img *SQemuImage) CheckNoBackingFile() error {
|
||||
if img.IsChained() {
|
||||
return ErrBackingFileNotAllowed
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (img *SQemuImage) GetBackingChain() ([]string, error) {
|
||||
if len(img.BackFilePath) > 0 {
|
||||
backImg, err := NewQemuImage(img.BackFilePath)
|
||||
|
||||
@@ -184,3 +184,14 @@ func TestParseBackingFile(t *testing.T) {
|
||||
t.Errorf("want: %s got: %s", want, path)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCheckNoBackingFile(t *testing.T) {
|
||||
img := &SQemuImage{}
|
||||
if err := img.CheckNoBackingFile(); err != nil {
|
||||
t.Fatalf("standalone image: %v", err)
|
||||
}
|
||||
img.BackFilePath = "nbd://127.0.0.1:10809/disk"
|
||||
if err := img.CheckNoBackingFile(); err == nil {
|
||||
t.Fatal("expected error when backing file is set")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user