aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAleksandr Nogikh <nogikh@google.com>2025-02-06 15:06:26 +0100
committerAleksandr Nogikh <nogikh@google.com>2025-02-06 15:31:42 +0100
commit55e0929fab461fee7733a18f8b543f9a5d6b9f6f (patch)
tree3cc63faa3c1b4695cccd89cf5c85ec9b5163901e
parent8d4a47e6d71a9ca2dd769765a52e01c9c897c946 (diff)
all: enable run_fsck by default
Check for the existence of fsck binaries and report their absence only once.
-rw-r--r--pkg/image/fsck.go26
-rw-r--r--pkg/image/fsck_test.go9
-rw-r--r--pkg/mgrconfig/config.go1
-rw-r--r--pkg/mgrconfig/load.go1
-rw-r--r--syz-manager/manager.go6
5 files changed, 34 insertions, 9 deletions
diff --git a/pkg/image/fsck.go b/pkg/image/fsck.go
index e749871f9..fbaeca9c4 100644
--- a/pkg/image/fsck.go
+++ b/pkg/image/fsck.go
@@ -11,7 +11,9 @@ import (
"os/exec"
"strconv"
"strings"
+ "sync"
+ "github.com/google/syzkaller/pkg/log"
"github.com/google/syzkaller/pkg/osutil"
)
@@ -59,3 +61,27 @@ func Fsck(r io.Reader, fsckCmd string) ([]byte, bool, error) {
prefix := fsckCmd + " exited with status code " + strconv.Itoa(exitCode) + "\n"
return append([]byte(prefix), output...), exitCode == 0, nil
}
+
+type FsckChecker struct {
+ mu sync.Mutex
+ exists map[string]bool
+}
+
+func (fc *FsckChecker) Exists(cmd string) bool {
+ fc.mu.Lock()
+ defer fc.mu.Unlock()
+ bin := strings.Fields(cmd)[0]
+ if ret, ok := fc.exists[bin]; ok {
+ return ret
+ }
+ if fc.exists == nil {
+ fc.exists = map[string]bool{}
+ }
+ _, err := exec.LookPath(bin)
+ found := err == nil
+ if !found {
+ log.Logf(0, "%s not found, images won't be checked", bin)
+ }
+ fc.exists[bin] = found
+ return found
+}
diff --git a/pkg/image/fsck_test.go b/pkg/image/fsck_test.go
index aae102ec7..e901e089f 100644
--- a/pkg/image/fsck_test.go
+++ b/pkg/image/fsck_test.go
@@ -7,7 +7,6 @@ import (
"fmt"
"io"
"os"
- "os/exec"
"path/filepath"
"strings"
"testing"
@@ -24,16 +23,12 @@ import (
const corruptedFs = "IAmACorruptedFs"
-func fsckAvailable(cmd string) bool {
- _, err := exec.LookPath(strings.Fields(cmd)[0])
- return err == nil
-}
-
func TestFsck(t *testing.T) {
target, err := prog.GetTarget(targets.Linux, targets.AMD64)
if err != nil {
t.Fatal(err)
}
+ fsckChecker := FsckChecker{}
// Use the images generated by syz-imagegen as a collection of clean file systems.
cleanFsProgs, err := filepath.Glob(filepath.Join("..", "sys", "linux", "test", "syz_mount_image_*_0"))
@@ -56,7 +51,7 @@ func TestFsck(t *testing.T) {
}
fsckCmd := c.Meta.Attrs.Fsck
// Tolerate missing fsck commands except during CI runs.
- skip := !fsckAvailable(fsckCmd) && os.Getenv("CI") == ""
+ skip := !fsckChecker.Exists(fsckCmd) && os.Getenv("CI") == ""
fsName := strings.TrimPrefix(c.Meta.Name, "syz_mount_image$")
// Check that the file system in the image is detected as clean.
diff --git a/pkg/mgrconfig/config.go b/pkg/mgrconfig/config.go
index a02c00c67..42730eef4 100644
--- a/pkg/mgrconfig/config.go
+++ b/pkg/mgrconfig/config.go
@@ -206,6 +206,7 @@ type Config struct {
// Note: you may need to install 3rd-party dependencies for this to work.
// fsck commands that can be run by syz-manager are specified in mount
// syscall descriptions - typically in sys/linux/filesystem.txt.
+ // Enabled by default.
RunFsck bool `json:"run_fsck"`
// Type of virtual machine to use, e.g. "qemu", "gce", "android", "isolated", etc.
diff --git a/pkg/mgrconfig/load.go b/pkg/mgrconfig/load.go
index 0624dae00..81ff2871a 100644
--- a/pkg/mgrconfig/load.go
+++ b/pkg/mgrconfig/load.go
@@ -94,6 +94,7 @@ func defaultValues() *Config {
MaxCrashLogs: 100,
Procs: 6,
PreserveCorpus: true,
+ RunFsck: true,
Experimental: Experimental{
RemoteCover: true,
CoverEdges: true,
diff --git a/syz-manager/manager.go b/syz-manager/manager.go
index fdb4929d7..b0354ea61 100644
--- a/syz-manager/manager.go
+++ b/syz-manager/manager.go
@@ -106,6 +106,7 @@ type Manager struct {
benchFile *os.File
assetStorage *asset.Storage
+ fsckChecker image.FsckChecker
reproLoop *manager.ReproLoop
@@ -944,10 +945,11 @@ func (mgr *Manager) uploadReproAssets(repro *repro.Result) []dashapi.NewAsset {
return
}
// Report file systems that fail fsck with a separate tag.
- if mgr.cfg.RunFsck && dashTyp == dashapi.MountInRepro && c.Meta.Attrs.Fsck != "" {
+ if mgr.cfg.RunFsck && dashTyp == dashapi.MountInRepro &&
+ c.Meta.Attrs.Fsck != "" && mgr.fsckChecker.Exists(c.Meta.Attrs.Fsck) {
logs, isClean, err := image.Fsck(r2, c.Meta.Attrs.Fsck)
if err != nil {
- log.Logf(1, "fsck of the asset %v failed: %v", name, err)
+ log.Errorf("fsck of the asset %v failed: %v", name, err)
} else {
asset.FsckLog = logs
asset.FsIsClean = isClean