loopback: use fstat on the open file descriptor

move the stat call later after the file is already opened so it is
less vulnerable to the file being removed between the stat and the
open syscall.

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
This commit is contained in:
Giuseppe Scrivano 2024-07-23 11:00:55 +02:00
parent 1bf05dd5c1
commit b23e274b36
No known key found for this signature in database
GPG Key ID: 67E38F7A8BA21772
1 changed files with 16 additions and 13 deletions

View File

@ -6,6 +6,7 @@ package loopback
import (
"errors"
"fmt"
"io/fs"
"os"
"syscall"
@ -53,26 +54,28 @@ func openNextAvailableLoopback(index int, sparseName string, sparseFile *os.File
target := fmt.Sprintf("/dev/loop%d", index)
index++
fi, err := os.Stat(target)
if err != nil {
if os.IsNotExist(err) {
logrus.Error("There are no more loopback devices available.")
}
return nil, ErrAttachLoopbackDevice
}
if fi.Mode()&os.ModeDevice != os.ModeDevice {
logrus.Errorf("Loopback device %s is not a block device.", target)
continue
}
// OpenFile adds O_CLOEXEC
loopFile, err = os.OpenFile(target, os.O_RDWR, 0o644)
if err != nil {
if errors.Is(err, fs.ErrNotExist) {
continue
}
logrus.Errorf("Opening loopback device: %s", err)
return nil, ErrAttachLoopbackDevice
}
fi, err := loopFile.Stat()
if err != nil {
loopFile.Close()
logrus.Errorf("Stat loopback device: %s", err)
return nil, ErrAttachLoopbackDevice
}
if fi.Mode()&os.ModeDevice != os.ModeDevice {
loopFile.Close()
logrus.Errorf("Loopback device %s is not a block device.", target)
continue
}
// Try to attach to the loop file
if err := ioctlLoopSetFd(loopFile.Fd(), sparseFile.Fd()); err != nil {
loopFile.Close()